From 107b39b8a346a4d08f7061901a25036be5bb4337 Mon Sep 17 00:00:00 2001 From: zhangxianbiao Date: Tue, 21 Jul 2026 15:46:47 +0800 Subject: [PATCH] feat: update home room and chat experience --- android/app/src/main/AndroidManifest.xml | 2 +- .../yumiparty/VoiceRoomForegroundService.kt | 32 + android/gradle.properties | 4 + assets/l10n/intl_ar.json | 12 +- assets/l10n/intl_bn.json | 8 +- assets/l10n/intl_en.json | 8 +- assets/l10n/intl_fr.json | 8 +- assets/l10n/intl_it.json | 8 +- assets/l10n/intl_pt.json | 8 +- assets/l10n/intl_tr.json | 14 +- design-qa.md | 38 + docs/后端接口对接规范.md | 456 + .../config/configs/sc_variant1_config.dart | 2 +- lib/app/constants/sc_room_msg_type.dart | 1 + lib/app_localizations.dart | 13 + lib/main.dart | 9 +- .../auth/edit/sc_edit_profile_page.dart | 27 + lib/modules/chat/message/sc_message_page.dart | 395 +- lib/modules/chat/message_chat_page.dart | 85 +- lib/modules/gift/gift_page.dart | 6 +- lib/modules/home/index_home_page.dart | 133 +- .../popular/follow/sc_room_follow_page.dart | 245 +- .../popular/history/sc_room_history_page.dart | 229 +- .../home/popular/mine/sc_home_mine_page.dart | 377 +- .../popular/mine/sc_home_mine_room_card.dart | 149 + .../popular/party/sc_home_party_page.dart | 721 +- lib/modules/index/index_page.dart | 213 +- lib/modules/index/main_route.dart | 1 + lib/modules/room/chat/all/all_chat_page.dart | 2 +- lib/modules/room/chat/chat/chat_page.dart | 2 +- .../room/chat/gift/gift_chat_page.dart | 2 +- lib/modules/room/seat/sc_seat_item.dart | 15 +- lib/modules/room/voice_room_page.dart | 13 +- lib/modules/user/me_page2.dart | 606 +- lib/modules/user/task/task_page.dart | 393 +- lib/modules/webview/webview_page.dart | 4 +- lib/services/audio/rtc_manager.dart | 35 +- lib/services/audio/rtm_manager.dart | 376 +- .../general/sc_app_general_manager.dart | 47 +- .../models/res/sc_room_emoji_res.dart | 324 +- .../local/floating_screen_manager.dart | 223 +- .../tools/sc_chat_bubble_message_data.dart | 83 + .../tools/sc_conversation_time_formatter.dart | 18 + lib/shared/tools/sc_google_auth_utils.dart | 3 + .../msg/message_conversation_list_page.dart | 444 +- .../room/cp/room_cp_invite_dialog.dart | 12 +- .../rocket/room_rocket_floating_entry.dart | 8 +- .../widgets/room/room_bottom_widget.dart | 23 +- .../widgets/room/room_emoji_asset_image.dart | 57 +- lib/ui_kit/widgets/room/room_msg_input.dart | 154 +- lib/ui_kit/widgets/room/room_msg_item.dart | 220 +- .../widgets/sc_home_shell_background.dart | 94 + .../CHANGELOG.md | 319 + .../CODEOWNERS | 1 + .../LICENSE | 21 + .../README-ZH.md | 616 + .../README.md | 605 + .../analysis_options.yaml | 203 + .../example/README.md | 16 + .../example/analysis_options.yaml | 203 + .../example/android/app/build.gradle | 67 + .../android/app/src/debug/AndroidManifest.xml | 7 + .../android/app/src/main/AndroidManifest.xml | 33 + .../com/example/example/MainActivity.kt | 6 + .../res/drawable-v21/launch_background.xml | 12 + .../main/res/drawable/launch_background.xml | 12 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 544 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 442 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 721 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 1031 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 1443 bytes .../app/src/main/res/values-night/styles.xml | 18 + .../app/src/main/res/values/styles.xml | 18 + .../app/src/profile/AndroidManifest.xml | 7 + .../example/android/build.gradle | 30 + .../example/android/gradle.properties | 3 + .../gradle/wrapper/gradle-wrapper.properties | 5 + .../example/android/settings.gradle | 29 + .../example/assets/1.png | Bin 0 -> 6890 bytes .../example/assets/10.png | Bin 0 -> 8188 bytes .../example/assets/11.png | Bin 0 -> 10136 bytes .../example/assets/12.png | Bin 0 -> 9039 bytes .../example/assets/13.png | Bin 0 -> 7408 bytes .../example/assets/14.png | Bin 0 -> 6557 bytes .../example/assets/15.png | Bin 0 -> 9840 bytes .../example/assets/16.png | Bin 0 -> 7282 bytes .../example/assets/17.png | Bin 0 -> 6412 bytes .../example/assets/18.png | Bin 0 -> 7863 bytes .../example/assets/19.png | Bin 0 -> 6870 bytes .../example/assets/2.png | Bin 0 -> 7854 bytes .../example/assets/20.png | Bin 0 -> 7381 bytes .../example/assets/21.png | Bin 0 -> 7814 bytes .../example/assets/22.png | Bin 0 -> 7559 bytes .../example/assets/23.png | Bin 0 -> 7803 bytes .../example/assets/24.png | Bin 0 -> 9121 bytes .../example/assets/25.png | Bin 0 -> 7623 bytes .../example/assets/26.png | Bin 0 -> 6077 bytes .../example/assets/27.png | Bin 0 -> 7643 bytes .../example/assets/28.png | Bin 0 -> 7023 bytes .../example/assets/29.png | Bin 0 -> 5710 bytes .../example/assets/3.png | Bin 0 -> 7690 bytes .../example/assets/30.png | Bin 0 -> 7751 bytes .../example/assets/31.png | Bin 0 -> 5884 bytes .../example/assets/32.png | Bin 0 -> 5776 bytes .../example/assets/33.png | Bin 0 -> 9367 bytes .../example/assets/34.png | Bin 0 -> 6999 bytes .../example/assets/35.png | Bin 0 -> 7523 bytes .../example/assets/36.png | Bin 0 -> 7370 bytes .../example/assets/37.png | Bin 0 -> 5197 bytes .../example/assets/38.png | Bin 0 -> 4358 bytes .../example/assets/39.png | Bin 0 -> 10638 bytes .../example/assets/4.png | Bin 0 -> 7796 bytes .../example/assets/40.png | Bin 0 -> 7304 bytes .../example/assets/41.png | Bin 0 -> 8129 bytes .../example/assets/42.png | Bin 0 -> 6184 bytes .../example/assets/43.png | Bin 0 -> 5292 bytes .../example/assets/44.png | Bin 0 -> 4036 bytes .../example/assets/45.png | Bin 0 -> 8064 bytes .../example/assets/46.png | Bin 0 -> 6627 bytes .../example/assets/47.png | Bin 0 -> 6272 bytes .../example/assets/48.png | Bin 0 -> 4614 bytes .../example/assets/5.png | Bin 0 -> 8364 bytes .../example/assets/6.png | Bin 0 -> 7345 bytes .../example/assets/7.png | Bin 0 -> 8209 bytes .../example/assets/8.png | Bin 0 -> 7875 bytes .../example/assets/9.png | Bin 0 -> 7640 bytes .../example/assets/flutter_candies_logo.png | Bin 0 -> 131155 bytes .../example/ff_annotation_route_commands | 1 + .../ios/Flutter/AppFrameworkInfo.plist | 26 + .../example/ios/Flutter/Debug.xcconfig | 2 + .../example/ios/Flutter/Release.xcconfig | 2 + .../example/ios/Podfile | 41 + .../example/ios/Podfile.lock | 22 + .../ios/Runner.xcodeproj/project.pbxproj | 566 + .../contents.xcworkspacedata | 7 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../xcshareddata/xcschemes/Runner.xcscheme | 91 + .../contents.xcworkspacedata | 10 + .../xcshareddata/IDEWorkspaceChecks.plist | 8 + .../xcshareddata/WorkspaceSettings.xcsettings | 8 + .../example/ios/Runner/AppDelegate.swift | 13 + .../AppIcon.appiconset/Contents.json | 122 + .../Icon-App-1024x1024@1x.png | Bin 0 -> 10932 bytes .../AppIcon.appiconset/Icon-App-20x20@1x.png | Bin 0 -> 564 bytes .../AppIcon.appiconset/Icon-App-20x20@2x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-20x20@3x.png | Bin 0 -> 1588 bytes .../AppIcon.appiconset/Icon-App-29x29@1x.png | Bin 0 -> 1025 bytes .../AppIcon.appiconset/Icon-App-29x29@2x.png | Bin 0 -> 1716 bytes .../AppIcon.appiconset/Icon-App-29x29@3x.png | Bin 0 -> 1920 bytes .../AppIcon.appiconset/Icon-App-40x40@1x.png | Bin 0 -> 1283 bytes .../AppIcon.appiconset/Icon-App-40x40@2x.png | Bin 0 -> 1895 bytes .../AppIcon.appiconset/Icon-App-40x40@3x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@2x.png | Bin 0 -> 2665 bytes .../AppIcon.appiconset/Icon-App-60x60@3x.png | Bin 0 -> 3831 bytes .../AppIcon.appiconset/Icon-App-76x76@1x.png | Bin 0 -> 1888 bytes .../AppIcon.appiconset/Icon-App-76x76@2x.png | Bin 0 -> 3294 bytes .../Icon-App-83.5x83.5@2x.png | Bin 0 -> 3612 bytes .../LaunchImage.imageset/Contents.json | 23 + .../LaunchImage.imageset/LaunchImage.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 0 -> 68 bytes .../LaunchImage.imageset/README.md | 5 + .../Runner/Base.lproj/LaunchScreen.storyboard | 37 + .../ios/Runner/Base.lproj/Main.storyboard | 26 + .../example/ios/Runner/Info.plist | 49 + .../ios/Runner/Runner-Bridging-Header.h | 1 + .../example/lib/common/button.dart | 70 + .../example/lib/common/toggle_button.dart | 49 + .../example/lib/data/mock_data.dart | 50395 ++++++++++++++++ .../example/lib/data/tu_chong_repository.dart | 91 + .../example/lib/data/tu_chong_source.dart | 559 + .../example/lib/example_route.dart | 118 + .../example/lib/example_routes.dart | 108 + .../lib/generated_plugin_registrant.dart | 17 + .../example/lib/main.dart | 38 + .../example/lib/pages/complex/text_demo.dart | 424 + .../example/lib/pages/main_page.dart | 172 + .../lib/pages/simple/custom_toolbar.dart | 141 + .../example/lib/pages/simple/no_keyboard.dart | 430 + .../lib/pages/simple/selectable_text.dart | 33 + .../example/lib/pages/simple/widget_span.dart | 194 + .../example/lib/special_text/at_text.dart | 62 + .../example/lib/special_text/dollar_text.dart | 43 + .../lib/special_text/email_span_builder.dart | 32 + .../example/lib/special_text/email_text.dart | 115 + .../example/lib/special_text/emoji_text.dart | 52 + .../example/lib/special_text/image_text.dart | 88 + .../my_extended_text_selection_controls.dart | 106 + .../my_special_text_span_builder.dart | 45 + .../macos/Flutter/Flutter-Debug.xcconfig | 2 + .../macos/Flutter/Flutter-Release.xcconfig | 2 + .../Flutter/GeneratedPluginRegistrant.swift | 12 + .../example/macos/Podfile | 40 + .../example/macos/Podfile.lock | 22 + .../macos/Runner.xcodeproj/project.pbxproj | 633 + .../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 -> 46993 bytes .../AppIcon.appiconset/app_icon_128.png | Bin 0 -> 3276 bytes .../AppIcon.appiconset/app_icon_16.png | Bin 0 -> 1429 bytes .../AppIcon.appiconset/app_icon_256.png | Bin 0 -> 5933 bytes .../AppIcon.appiconset/app_icon_32.png | Bin 0 -> 1243 bytes .../AppIcon.appiconset/app_icon_512.png | Bin 0 -> 14800 bytes .../AppIcon.appiconset/app_icon_64.png | Bin 0 -> 1874 bytes .../macos/Runner/Base.lproj/MainMenu.xib | 343 + .../macos/Runner/Configs/AppInfo.xcconfig | 14 + .../macos/Runner/Configs/Debug.xcconfig | 2 + .../macos/Runner/Configs/Release.xcconfig | 2 + .../macos/Runner/Configs/Warnings.xcconfig | 13 + .../macos/Runner/DebugProfile.entitlements | 14 + .../example/macos/Runner/Info.plist | 32 + .../macos/Runner/MainFlutterWindow.swift | 15 + .../example/macos/Runner/Release.entitlements | 10 + .../example/pubspec.yaml | 99 + .../example/web/favicon.png | Bin 0 -> 917 bytes .../example/web/icons/Icon-192.png | Bin 0 -> 5292 bytes .../example/web/icons/Icon-512.png | Bin 0 -> 8252 bytes .../example/web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes .../example/web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes .../example/web/index.html | 104 + .../example/web/manifest.json | 35 + .../example/windows/CMakeLists.txt | 95 + .../example/windows/flutter/CMakeLists.txt | 102 + .../flutter/generated_plugin_registrant.cc | 14 + .../flutter/generated_plugin_registrant.h | 15 + .../windows/flutter/generated_plugins.cmake | 24 + .../example/windows/runner/CMakeLists.txt | 18 + .../example/windows/runner/Runner.rc | 121 + .../example/windows/runner/flutter_window.cpp | 64 + .../example/windows/runner/flutter_window.h | 39 + .../example/windows/runner/main.cpp | 36 + .../example/windows/runner/resource.h | 16 + .../windows/runner/resources/app_icon.ico | Bin 0 -> 33772 bytes .../example/windows/runner/run_loop.cpp | 66 + .../example/windows/runner/run_loop.h | 40 + .../windows/runner/runner.exe.manifest | 20 + .../example/windows/runner/utils.cpp | 22 + .../example/windows/runner/utils.h | 8 + .../example/windows/runner/win32_window.cpp | 244 + .../example/windows/runner/win32_window.h | 98 + .../lib/extended_text_field.dart | 9 + .../spell_check_suggestions_toolbar.dart | 167 + .../extended/material/selectable_text.dart | 290 + .../spell_check_suggestions_toolbar.dart | 269 + .../lib/src/extended/rendering/editable.dart | 199 + .../lib/src/extended/utils.dart | 14 + .../src/extended/widgets/editable_text.dart | 1087 + .../lib/src/extended/widgets/spell_check.dart | 111 + .../lib/src/extended/widgets/text_field.dart | 649 + .../src/extended/widgets/text_selection.dart | 222 + .../lib/src/keyboard/binding.dart | 86 + .../lib/src/keyboard/focus_node.dart | 9 + .../official/material/selectable_text.dart | 835 + .../lib/src/official/rendering/editable.dart | 3136 + .../src/official/widgets/editable_text.dart | 6031 ++ .../lib/src/official/widgets/spell_check.dart | 419 + .../lib/src/official/widgets/text_field.dart | 1804 + .../src/official/widgets/text_selection.dart | 2996 + .../pubspec.yaml | 66 + .../on_audio_query/OnAudioQueryPlugin.kt | 21 +- .../controllers/PermissionController.kt | 36 +- .../on_audio_query/queries/AudioQuery.kt | 75 +- .../on_audio_query/utils/CursorProjection.kt | 20 +- pubspec.lock | 615 +- pubspec.yaml | 18 +- sc_images/index/sc_home_shell_bg.png | Bin 0 -> 334396 bytes sc_images/index/sc_icon_me_admin.svg | 5 + sc_images/index/sc_icon_me_agency_center.svg | 5 + sc_images/index/sc_icon_me_host_center.svg | 5 + sc_images/index/sc_icon_me_language.svg | 9 + sc_images/index/sc_icon_me_manager_center.svg | 5 + .../index/sc_icon_me_recharge_agency.svg | 11 + sc_images/index/sc_icon_me_settings.svg | 8 + sc_images/index/sc_icon_serach.png | Bin 7361 -> 5870 bytes sc_images/index/sc_icon_task_game.png | Bin 466 -> 120360 bytes sc_images/index/sc_icon_task_gift.png | Bin 377 -> 113066 bytes sc_images/index/sc_icon_task_mic.png | Bin 422 -> 117989 bytes sc_images/index/sc_icon_task_recharge.png | Bin 0 -> 106299 bytes sc_images/index/sc_me_action_panel_bg.png | Bin 0 -> 870683 bytes sc_images/index/sc_me_action_panel_bg.svg | 16 + sc_images/index/sc_me_entry_bag.png | Bin 0 -> 48178 bytes sc_images/index/sc_me_entry_cp.png | Bin 0 -> 42920 bytes sc_images/index/sc_me_entry_level.png | Bin 0 -> 39972 bytes sc_images/index/sc_me_entry_store.png | Bin 0 -> 48475 bytes sc_images/index/sc_party_rank_charm_bg.png | Bin 0 -> 1269059 bytes .../index/sc_party_rank_frame_bronze.png | Bin 0 -> 347216 bytes sc_images/index/sc_party_rank_frame_gold.png | Bin 0 -> 302863 bytes .../index/sc_party_rank_frame_silver.png | Bin 0 -> 329936 bytes sc_images/index/sc_party_rank_ribbons.svg | 5 + sc_images/index/sc_party_rank_room_bg.png | Bin 0 -> 1255148 bytes sc_images/index/sc_party_rank_wealth_bg.png | Bin 0 -> 1643455 bytes sc_images/index/sc_tab_chat_off.png | Bin 0 -> 12966 bytes sc_images/index/sc_tab_chat_on.png | Bin 0 -> 35489 bytes sc_images/index/sc_tab_me_off.png | Bin 0 -> 11276 bytes sc_images/index/sc_tab_me_on.png | Bin 0 -> 30502 bytes sc_images/index/sc_tab_room_off.png | Bin 0 -> 13936 bytes sc_images/index/sc_tab_room_on.png | Bin 0 -> 35779 bytes sc_images/index/sc_tab_task_off.png | Bin 0 -> 12510 bytes sc_images/index/sc_tab_task_on.png | Bin 0 -> 34106 bytes sc_images/index/sc_task_action_claim_bg.png | Bin 0 -> 2838 bytes sc_images/index/sc_task_action_claimed_bg.png | Bin 0 -> 2836 bytes sc_images/index/sc_task_action_go_bg.png | Bin 0 -> 3224 bytes sc_images/index/sc_task_title_sparkle.png | Bin 0 -> 1228 bytes test/cp_relation_broadcast_test.dart | 67 + test/floating_screen_visibility_test.dart | 51 + test/room_bottom_widget_test.dart | 73 + test/room_contribution_refresh_test.dart | 57 + test/room_rocket_entry_sync_test.dart | 111 + test/room_rocket_status_transition_test.dart | 80 + test/sc_chat_bubble_message_data_test.dart | 55 + test/sc_conversation_time_formatter_test.dart | 38 + test/sc_home_shell_gradient_text_test.dart | 48 + test/sc_room_emoji_res_test.dart | 34 + 318 files changed, 82661 insertions(+), 2883 deletions(-) create mode 100644 design-qa.md create mode 100644 docs/后端接口对接规范.md create mode 100644 lib/modules/home/popular/mine/sc_home_mine_room_card.dart create mode 100644 lib/shared/tools/sc_chat_bubble_message_data.dart create mode 100644 lib/shared/tools/sc_conversation_time_formatter.dart create mode 100644 lib/ui_kit/widgets/sc_home_shell_background.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/CHANGELOG.md create mode 100644 local_packages/extended_text_field-16.0.2-patched/CODEOWNERS create mode 100644 local_packages/extended_text_field-16.0.2-patched/LICENSE create mode 100644 local_packages/extended_text_field-16.0.2-patched/README-ZH.md create mode 100644 local_packages/extended_text_field-16.0.2-patched/README.md create mode 100644 local_packages/extended_text_field-16.0.2-patched/analysis_options.yaml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/README.md create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/analysis_options.yaml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/build.gradle create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/debug/AndroidManifest.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/AndroidManifest.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable/launch_background.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values-night/styles.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values/styles.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/app/src/profile/AndroidManifest.xml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/build.gradle create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/gradle.properties create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/gradle/wrapper/gradle-wrapper.properties create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/android/settings.gradle create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/1.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/10.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/11.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/12.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/13.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/14.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/15.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/16.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/17.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/18.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/19.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/2.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/20.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/21.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/22.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/23.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/24.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/25.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/26.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/27.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/28.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/29.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/3.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/30.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/31.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/32.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/33.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/34.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/35.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/36.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/37.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/38.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/39.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/4.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/40.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/41.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/42.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/43.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/44.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/45.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/46.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/47.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/48.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/5.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/6.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/7.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/8.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/9.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/assets/flutter_candies_logo.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ff_annotation_route_commands create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/AppFrameworkInfo.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Debug.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Release.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile.lock create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.pbxproj create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/AppDelegate.swift create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/LaunchScreen.storyboard create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/Main.storyboard create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Info.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Runner-Bridging-Header.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/common/button.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/common/toggle_button.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/data/mock_data.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_repository.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_source.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/example_route.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/example_routes.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/generated_plugin_registrant.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/main.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/complex/text_demo.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/main_page.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/custom_toolbar.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/no_keyboard.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/selectable_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/widget_span.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/at_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/dollar_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_span_builder.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/emoji_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/image_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_extended_text_selection_controls.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_special_text_span_builder.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Release.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/GeneratedPluginRegistrant.swift create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile.lock create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.pbxproj create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/AppDelegate.swift create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Base.lproj/MainMenu.xib create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/AppInfo.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Debug.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Release.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Warnings.xcconfig create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/DebugProfile.entitlements create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Info.plist create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/MainFlutterWindow.swift create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Release.entitlements create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/pubspec.yaml create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/favicon.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-192.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-512.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-192.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-512.png create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/index.html create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/web/manifest.json create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/CMakeLists.txt create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/CMakeLists.txt create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.cc create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugins.cmake create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/CMakeLists.txt create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/Runner.rc create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.cpp create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/main.cpp create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resource.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resources/app_icon.ico create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.cpp create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/runner.exe.manifest create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.cpp create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.cpp create mode 100644 local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.h create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/extended_text_field.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/cupertino/spell_check_suggestions_toolbar.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/selectable_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/spell_check_suggestions_toolbar.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/rendering/editable.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/utils.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/editable_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/spell_check.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_field.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_selection.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/binding.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/focus_node.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/material/selectable_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/rendering/editable.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/editable_text.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/spell_check.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_field.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_selection.dart create mode 100644 local_packages/extended_text_field-16.0.2-patched/pubspec.yaml create mode 100644 sc_images/index/sc_home_shell_bg.png create mode 100644 sc_images/index/sc_icon_me_admin.svg create mode 100644 sc_images/index/sc_icon_me_agency_center.svg create mode 100644 sc_images/index/sc_icon_me_host_center.svg create mode 100644 sc_images/index/sc_icon_me_language.svg create mode 100644 sc_images/index/sc_icon_me_manager_center.svg create mode 100644 sc_images/index/sc_icon_me_recharge_agency.svg create mode 100644 sc_images/index/sc_icon_me_settings.svg create mode 100644 sc_images/index/sc_icon_task_recharge.png create mode 100644 sc_images/index/sc_me_action_panel_bg.png create mode 100644 sc_images/index/sc_me_action_panel_bg.svg create mode 100644 sc_images/index/sc_me_entry_bag.png create mode 100644 sc_images/index/sc_me_entry_cp.png create mode 100644 sc_images/index/sc_me_entry_level.png create mode 100644 sc_images/index/sc_me_entry_store.png create mode 100644 sc_images/index/sc_party_rank_charm_bg.png create mode 100644 sc_images/index/sc_party_rank_frame_bronze.png create mode 100644 sc_images/index/sc_party_rank_frame_gold.png create mode 100644 sc_images/index/sc_party_rank_frame_silver.png create mode 100644 sc_images/index/sc_party_rank_ribbons.svg create mode 100644 sc_images/index/sc_party_rank_room_bg.png create mode 100644 sc_images/index/sc_party_rank_wealth_bg.png create mode 100644 sc_images/index/sc_tab_chat_off.png create mode 100644 sc_images/index/sc_tab_chat_on.png create mode 100644 sc_images/index/sc_tab_me_off.png create mode 100644 sc_images/index/sc_tab_me_on.png create mode 100644 sc_images/index/sc_tab_room_off.png create mode 100644 sc_images/index/sc_tab_room_on.png create mode 100644 sc_images/index/sc_tab_task_off.png create mode 100644 sc_images/index/sc_tab_task_on.png create mode 100644 sc_images/index/sc_task_action_claim_bg.png create mode 100644 sc_images/index/sc_task_action_claimed_bg.png create mode 100644 sc_images/index/sc_task_action_go_bg.png create mode 100644 sc_images/index/sc_task_title_sparkle.png create mode 100644 test/cp_relation_broadcast_test.dart create mode 100644 test/floating_screen_visibility_test.dart create mode 100644 test/room_bottom_widget_test.dart create mode 100644 test/room_contribution_refresh_test.dart create mode 100644 test/room_rocket_entry_sync_test.dart create mode 100644 test/room_rocket_status_transition_test.dart create mode 100644 test/sc_chat_bubble_message_data_test.dart create mode 100644 test/sc_conversation_time_formatter_test.dart create mode 100644 test/sc_home_shell_gradient_text_test.dart create mode 100644 test/sc_room_emoji_res_test.dart diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index fe588ea..bb74be6 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -138,7 +138,7 @@ android:name=".VoiceRoomForegroundService" android:exported="false" android:foregroundServiceType="mediaPlayback|microphone" - android:stopWithTask="false" /> + android:stopWithTask="true" /> = Build.VERSION_CODES.Q) { @@ -116,6 +144,9 @@ class VoiceRoomForegroundService : Service() { private const val EXTRA_ROOM_NAME = "room_name" private const val DEFAULT_ROOM_NAME = "Voice room is running" + @Volatile + private var explicitStopRequested = false + fun start(context: Context, roomName: String?) { val intent = Intent(context, VoiceRoomForegroundService::class.java) .putExtra(EXTRA_ROOM_NAME, roomName) @@ -127,6 +158,7 @@ class VoiceRoomForegroundService : Service() { } fun stop(context: Context) { + explicitStopRequested = true context.stopService(Intent(context, VoiceRoomForegroundService::class.java)) } } diff --git a/android/gradle.properties b/android/gradle.properties index 7ddb02c..6b65932 100644 --- a/android/gradle.properties +++ b/android/gradle.properties @@ -7,3 +7,7 @@ android.enableJetifier=true systemProp.https.protocols=TLSv1.2 systemProp.jdk.tls.client.protocols=TLSv1.2 systemProp.java.net.preferIPv4Stack=true +# This builtInKotlin flag was added automatically by Flutter migrator +android.builtInKotlin=false +# This newDsl flag was added automatically by Flutter migrator +android.newDsl=false diff --git a/assets/l10n/intl_ar.json b/assets/l10n/intl_ar.json index c5e1c51..4aade5f 100644 --- a/assets/l10n/intl_ar.json +++ b/assets/l10n/intl_ar.json @@ -129,6 +129,7 @@ "redEnvelopeNotYetClaimed": "المظروف الأحمر لم يُستلم بعد", "redEnvelopeAmount": "مبلغ الظرف الأحمر: {1} عملات", "followed": "تمت المتابعة", + "joined": "انضممت", "newMessage": "رسالة جديدة", "keep": "الاحتفاظ", "open": "فتح", @@ -233,7 +234,8 @@ "alreadyAnTourist": "أنت بالفعل سائح", "deleteConversationTips": "هل أنت متأكد أنك تريد حذف سجل المحادثة مع هذا المستخدم؟", "account": "الحساب", - "youHaventFollowed": "أنت لم تتابع أي غرفة", + "youHaventFollowed": "أنت لم تتابع أي غرفة", + "youHaventJoinedAnyRoomsYet": "لم أنضم إلى أي غرف بعد.", "messageHasBeenRecalled": "تم استرجاع هذه الرسالة", "propMessagePrompt": "موجه رسالة دعائية", "deleteFromMyDevice": "احذف من جهازي", @@ -559,7 +561,8 @@ "coinsReceived": "العملات المستلمة", "hotRooms": "الغرف الرائجة", "viewMore": "عرض المزيد", - "noData": "لا توجد بيانات", + "noData": "لا توجد بيانات", + "noRoomRecordsRecently": "لا توجد سجلات غرف حديثة.", "recommend": "موصى به", "follow": "متابعة", "monthly": "شهريًا", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "لم تحصل على مكافآت. حظًا أوفر في المرة القادمة.", "roomRocketRecordEmptyText": "لا توجد سجلات مكافآت", "launchRocket": "إطلاق الصاروخ", - "roomRocketFuelFullNotice": "اكتمل وقود الصاروخ! سيتم الإطلاق بعد {1} ثانية!" + "roomRocketFuelFullNotice": "اكتمل وقود الصاروخ! سيتم الإطلاق بعد {1} ثانية!", + "leaderboardWealth": "الثروة", + "leaderboardCharm": "الجاذبية", + "leaderboardRoom": "الغرفة" } diff --git a/assets/l10n/intl_bn.json b/assets/l10n/intl_bn.json index 5f1aa2d..b7d2dcb 100644 --- a/assets/l10n/intl_bn.json +++ b/assets/l10n/intl_bn.json @@ -258,6 +258,7 @@ "youDontHaveAnyCouponsYet": "আপনার এখনও কোনো কুপন নেই।", "recall": "প্রত্যাহার করুন", "youHaventFollowed": "আপনি কোনো রুম ফলো করেন না", + "youHaventJoinedAnyRoomsYet": "আমি এখনও কোনো রুমে যোগ দিইনি।", "deleteFromMyDevice": "আমার ডিভাইস থেকে মুছে ফেলুন", "deleteOnAllDevices": "সমস্ত ডিভাইসে মুছে ফেলুন", "messageHasBeenRecalled": "এই বার্তাটি প্রত্যাহার করা হয়েছে", @@ -387,6 +388,7 @@ "hotRooms": "হট রুম", "viewMore": "আরও দেখুন", "noData": "ডেটা নেই", + "noRoomRecordsRecently": "সম্প্রতি কোনো রুমের রেকর্ড নেই।", "users": "ব্যবহারকারী", "rooms": "রুম", "coins": "কয়েন", @@ -646,6 +648,7 @@ "purchaseIsSuccessful": "ক্রয় সফল", "buy": "কিনুন", "followed": "ফলো করা হয়েছে", + "joined": "যোগদান করা", "follow2": "ফলো:{1}", "fans2": "ফ্যান:{1}", "vistors2": "ভিজিটর:{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "কোনো পুরস্কার পাওয়া যায়নি। পরের বার শুভকামনা।", "roomRocketRecordEmptyText": "কোনো পুরস্কারের রেকর্ড নেই", "launchRocket": "রকেট চালু করুন", - "roomRocketFuelFullNotice": "রকেটের জ্বালানি পূর্ণ! {1} সেকেন্ড পরে উৎক্ষেপণ!" + "roomRocketFuelFullNotice": "রকেটের জ্বালানি পূর্ণ! {1} সেকেন্ড পরে উৎক্ষেপণ!", + "leaderboardWealth": "সম্পদ", + "leaderboardCharm": "আকর্ষণ", + "leaderboardRoom": "রুম" } diff --git a/assets/l10n/intl_en.json b/assets/l10n/intl_en.json index 667bcb3..41e6390 100644 --- a/assets/l10n/intl_en.json +++ b/assets/l10n/intl_en.json @@ -228,6 +228,7 @@ "youDontHaveAnyCouponsYet": "You don't have any coupons yet.", "recall": "Recall", "youHaventFollowed": "You haven't followed any room", + "youHaventJoinedAnyRoomsYet": "I haven't joined any rooms yet.", "deleteFromMyDevice": "Delete from my device", "deleteOnAllDevices": "Delete on all devices", "messageHasBeenRecalled": "This message has been recalled", @@ -357,6 +358,7 @@ "hotRooms": "Hot Rooms", "viewMore": "View more", "noData": "No data", + "noRoomRecordsRecently": "No room records recently.", "users": "Users", "rooms": "Rooms", "coins": "coins", @@ -646,6 +648,7 @@ "purchaseIsSuccessful": "Purchase is successful", "buy": "Buy", "followed": "Followed", + "joined": "Joined", "follow2": "Follow:{1}", "fans2": "Fans:{1}", "vistors2": "Visitors:{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "No reward", "roomRocketRecordEmptyText": "No reward records", "launchRocket": "Launch Rocket", - "roomRocketFuelFullNotice": "Rocket fuel is full! Launching in {1}s!" + "roomRocketFuelFullNotice": "Rocket fuel is full! Launching in {1}s!", + "leaderboardWealth": "Wealth", + "leaderboardCharm": "Charm", + "leaderboardRoom": "Room" } diff --git a/assets/l10n/intl_fr.json b/assets/l10n/intl_fr.json index 9d3a0f5..303a73d 100644 --- a/assets/l10n/intl_fr.json +++ b/assets/l10n/intl_fr.json @@ -228,6 +228,7 @@ "youDontHaveAnyCouponsYet": "Vous n'avez pas encore de coupons.", "recall": "Rappel", "youHaventFollowed": "Vous n'avez suivi aucune pièce", + "youHaventJoinedAnyRoomsYet": "Je n’ai encore rejoint aucune salle.", "deleteFromMyDevice": "Supprimer de mon appareil", "deleteOnAllDevices": "Supprimer sur tous les appareils", "messageHasBeenRecalled": "Ce message a été rappelé", @@ -357,6 +358,7 @@ "hotRooms": "Chambres chaudes", "viewMore": "Voir plus", "noData": "Aucune donnée", + "noRoomRecordsRecently": "Aucun historique de salle récent.", "users": "Utilisateurs", "rooms": "Chambres", "coins": "pièces de monnaie", @@ -646,6 +648,7 @@ "purchaseIsSuccessful": "L'achat est réussi", "buy": "Acheter", "followed": "Suivi", + "joined": "Rejointes", "follow2": "Suivre : {1}", "fans2": "Ventilateurs : {1}", "vistors2": "Visiteurs :{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "Aucune récompense gagnée. Plus de chance la prochaine fois.", "roomRocketRecordEmptyText": "Aucun enregistrement de récompense", "launchRocket": "Lancement de fusée", - "roomRocketFuelFullNotice": "Le carburant de la fusée est plein ! Lancement dans {1} s !" + "roomRocketFuelFullNotice": "Le carburant de la fusée est plein ! Lancement dans {1} s !", + "leaderboardWealth": "Richesse", + "leaderboardCharm": "Charme", + "leaderboardRoom": "Salle" } diff --git a/assets/l10n/intl_it.json b/assets/l10n/intl_it.json index c9e2737..be8297a 100644 --- a/assets/l10n/intl_it.json +++ b/assets/l10n/intl_it.json @@ -228,6 +228,7 @@ "youDontHaveAnyCouponsYet": "Non hai ancora alcun coupon.", "recall": "Ricorda", "youHaventFollowed": "Non hai seguito nessuna stanza", + "youHaventJoinedAnyRoomsYet": "Non ho ancora partecipato a nessuna stanza.", "deleteFromMyDevice": "Elimina dal mio dispositivo", "deleteOnAllDevices": "Elimina su tutti i dispositivi", "messageHasBeenRecalled": "Questo messaggio è stato richiamato", @@ -357,6 +358,7 @@ "hotRooms": "Camere calde", "viewMore": "Visualizza altro", "noData": "Nessun dato", + "noRoomRecordsRecently": "Nessun record recente delle stanze.", "users": "Utenti", "rooms": "Camere", "coins": "monete", @@ -646,6 +648,7 @@ "purchaseIsSuccessful": "L'acquisto è andato a buon fine", "buy": "Acquista", "followed": "Seguito", + "joined": "Partecipate", "follow2": "Segui:{1}", "fans2": "Ventole:{1}", "vistors2": "Visitatori:{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "Nessun premio guadagnato. Più fortuna la prossima volta.", "roomRocketRecordEmptyText": "Nessun record di ricompensa", "launchRocket": "Lancia il razzo", - "roomRocketFuelFullNotice": "Carburante del razzo pieno! Lancio tra {1} s!" + "roomRocketFuelFullNotice": "Carburante del razzo pieno! Lancio tra {1} s!", + "leaderboardWealth": "Ricchezza", + "leaderboardCharm": "Fascino", + "leaderboardRoom": "Stanza" } diff --git a/assets/l10n/intl_pt.json b/assets/l10n/intl_pt.json index ddd7523..ad430c8 100644 --- a/assets/l10n/intl_pt.json +++ b/assets/l10n/intl_pt.json @@ -228,6 +228,7 @@ "youDontHaveAnyCouponsYet": "Você ainda não tem cupons.", "recall": "Lembre-se", "youHaventFollowed": "Você não seguiu nenhuma sala", + "youHaventJoinedAnyRoomsYet": "Ainda não entrei em nenhuma sala.", "deleteFromMyDevice": "Excluir do meu dispositivo", "deleteOnAllDevices": "Excluir em todos os dispositivos", "messageHasBeenRecalled": "Esta mensagem foi recuperada", @@ -357,6 +358,7 @@ "hotRooms": "Salas Quentes", "viewMore": "Ver mais", "noData": "Sem dados", + "noRoomRecordsRecently": "Nenhum registro recente de salas.", "users": "Usuários", "rooms": "Quartos", "coins": "moedas", @@ -646,6 +648,7 @@ "purchaseIsSuccessful": "A compra foi bem-sucedida", "buy": "Comprar", "followed": "Seguido", + "joined": "Participadas", "follow2": "Siga: {1}", "fans2": "Fãs: {1}", "vistors2": "Visitantes:{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "Nenhuma recompensa ganha. Melhor sorte da próxima vez.", "roomRocketRecordEmptyText": "Nenhum registro de recompensa", "launchRocket": "Lançar foguete", - "roomRocketFuelFullNotice": "Combustível do foguete cheio! Lançamento em {1}s!" + "roomRocketFuelFullNotice": "Combustível do foguete cheio! Lançamento em {1}s!", + "leaderboardWealth": "Riqueza", + "leaderboardCharm": "Charme", + "leaderboardRoom": "Sala" } diff --git a/assets/l10n/intl_tr.json b/assets/l10n/intl_tr.json index c996f5d..53b384e 100644 --- a/assets/l10n/intl_tr.json +++ b/assets/l10n/intl_tr.json @@ -216,7 +216,8 @@ "sendCoupontips": "Bu kuponu bu kullanıcıya göndermek istediğinizden emin misiniz?", "youDontHaveAnyCouponsYet": "Henüz hiç kuponunuz yok.", "recall": "Geri Çağır", - "youHaventFollowed": "Hiç oda takip etmediniz", + "youHaventFollowed": "Hiç oda takip etmediniz", + "youHaventJoinedAnyRoomsYet": "Henüz hiçbir odaya katılmadım.", "deleteFromMyDevice": "Cihazımdan Sil", "deleteOnAllDevices": "Tüm Cihazlarda Sil", "messageHasBeenRecalled": "Bu mesaj geri çekildi", @@ -355,7 +356,8 @@ "history": "Tarihçe", "hotRooms": "Popüler Odalar", "viewMore": "Daha Fazlasını Gör", - "noData": "Veri yok", + "noData": "Veri yok", + "noRoomRecordsRecently": "Yakın zamanda oda kaydı yok.", "users": "Kullanıcılar", "rooms": "Odalar", "coins": "jetton", @@ -614,7 +616,8 @@ "mountains": "Araçlar", "purchaseIsSuccessful": "Satın alma başarılı", "buy": "Satın Al", - "followed": "Takip Edildi", + "followed": "Takip Edildi", + "joined": "Katıldıklarım", "follow2": "Takip:{1}", "fans2": "Hayranlar:{1}", "vistors2": "Ziyaretçiler:{1}", @@ -748,5 +751,8 @@ "roomRocketRewardEmptyText": "Ödül kazanmadın. Bir dahaki sefere bol şans.", "roomRocketRecordEmptyText": "Ödül kaydı yok", "launchRocket": "Roketi Fırlat", - "roomRocketFuelFullNotice": "Roket yakıtı doldu! {1} saniye sonra fırlatılıyor!" + "roomRocketFuelFullNotice": "Roket yakıtı doldu! {1} saniye sonra fırlatılıyor!", + "leaderboardWealth": "Servet", + "leaderboardCharm": "Cazibe", + "leaderboardRoom": "Oda" } diff --git a/design-qa.md b/design-qa.md new file mode 100644 index 0000000..63d0dfb --- /dev/null +++ b/design-qa.md @@ -0,0 +1,38 @@ +**Design QA** + +- Source visual truth: Figma `3351:5626` and `/var/folders/pb/pgzxbnfd2jd8nmtbykd31h2h0000gn/T/codex-clipboard-5ea92794-9b5a-469e-bf5c-7eec4b63206d.png` +- Implementation screenshots: `/tmp/yumi_party_after_closed.png` and `/tmp/yumi_tab_after_wait.png` +- Combined comparison: `/tmp/yumi_party_design_comparison.png` +- Viewport: Pixel 6a, 1080 x 2400, Android 16 +- State: logged-in Home/Party and Me screens with live API data + +**Full-view comparison evidence** + +- The supplied 375 x 727 moon background begins at the top of the app content and continues to the bottom navigation on Home and Me. +- Wealth uses the 172 x 172 transparent treasure artwork clipped inside the 172 x 130 card instead of stretching it as a full background. +- Charm and Room use 66 x 66 artwork at the Figma offsets. +- All leaderboard avatars are circular cover crops and retain a visible gold, silver, or bronze frame. + +**Focused region comparison evidence** + +- Compared the 355 x 130 leaderboard region in Figma with the same region from the Pixel 6a screenshot. +- Dynamic banner, avatar, country, and room API content differs from Figma sample content as expected; layout geometry and image treatment match the requested surfaces. + +**Findings** + +- No actionable P0, P1, or P2 mismatch remains for the requested background, leaderboard artwork placement, avatar cover mode, or avatar frames. +- P3: live banner and room content cannot be pixel-identical to Figma placeholder content. + +**Comparison history** + +- Initial: square decoration assets were stretched or mispositioned, and leaderboard avatars had no rank frames. +- Fix: applied Figma layer dimensions and offsets, added frame assets, and forced static and GIF avatars to `BoxFit.cover`. +- Post-fix: the combined comparison and device screenshots show correct artwork placement, framed avatars, and no visible overflow. + +**Verification** + +- `flutter analyze --no-fatal-infos --no-fatal-warnings` completed with exit code 0 for the six affected Dart files. +- Android debug APK built, installed, and launched successfully on the Pixel 6a. +- No load failure from the new local background/rank-frame assets and no RenderFlex overflow was observed. An existing empty network-image exception was emitted while navigating outside the leaderboard flow; it is not produced by the guarded leaderboard avatar builder. + +final result: passed diff --git a/docs/后端接口对接规范.md b/docs/后端接口对接规范.md new file mode 100644 index 0000000..c45cfdc --- /dev/null +++ b/docs/后端接口对接规范.md @@ -0,0 +1,456 @@ +# Yumi Flutter 后端接口对接规范 + +> 适用仓库:`yumi-flutter` +> 后端代码:`yumi-java` + `yumi-golang` +> 最后核对:2026-07-10 + +## 1. 目标与适用范围 + +本文档用于统一 Yumi Flutter 与 Java、Go 后端的接口对接方式,覆盖接口事实来源、路由归属、前端分层、响应解析、鉴权、错误处理、验证和问题流转。 + +核心原则: + +- 先查代码和配置,再实现;禁止根据页面或旧模型猜测后端契约。 +- Flutter 线程对两个后端仓库仅有只读权限,发现后端问题只记录证据和建议。 +- 所有业务 HTTP 请求必须经过项目现有网络层,页面不直接解析原始响应。 +- 接口失败时禁止使用本地假数据、硬编码列表或伪造成功结果还原页面。 +- Bug 修复必须先说明 Root Cause 和影响面,经确认后再做最小改动并提供验证证据。 + +--- + +## 2. 仓库位置与责任边界 + +### 2.1 Flutter 客户端 + +```text +/Users/pinpaibu/flutter_code/yumi-flutter +``` + +当前技术和分层事实: + +- 网络:Dio,统一客户端为 `lib/shared/data_sources/sources/remote/net/network_client.dart`。 +- 响应封装:`ResponseData`。 +- 仓储接口:`lib/shared/business_logic/repositories/`。 +- 仓储实现:`lib/shared/data_sources/sources/repositories/`。 +- 请求/响应模型:`lib/shared/business_logic/models/req/` 与 `res/`。 +- 功能模块:`lib/modules/`;独立功能也可在模块内保留 `data/api/repository/models` 边界,例如 `lib/modules/room_game/data/`。 +- 页面状态:Provider + ChangeNotifier,全局管理器在 `lib/services/`。 +- 路由:Fluro,入口为 `lib/main.dart`。 + +### 2.2 Java 后端 + +```text +/Users/pinpaibu/server_code/yumi-java +``` + +客户端相关的主要边界: + +- `rc-gateway/`:Spring Cloud Gateway,是 Flutter 默认 HTTP 入口。 +- `nacos_config/rc-gateway/application.yml`:外部路径到 Java/Go 服务的路由事实。 +- `rc-auth/`:登录凭证和内部 Token 校验。 +- `rc-service/rc-service-other/`:用户、配置、礼物、任务、房间外围等大量 App 业务。 +- `rc-service/rc-service-live/`:语音房在线、麦位等实时业务。 +- `rc-service/rc-service-wallet/`:钱包、余额、流水。 +- `rc-service/rc-service-order/`:订单与支付。 +- `rc-service/rc-service-external/`:文件、短信、IM/TRTC 等外部能力。 +- `rc-service/rc-inner-api/`:Java 服务内部 Feign 契约,Flutter 不直接调用。 + +Java `README.md` 可用于快速定位模块,但其端口和模块说明可能滞后;联调时必须以 Gateway/Nacos 路由和当前 Controller 为准。 + +### 2.3 Go 后端 + +```text +/Users/pinpaibu/server_code/yumi-golang +``` + +当前主要边界: + +- `cmd/api/`:HTTP API 启动和依赖装配。 +- `cmd/consumer/`:事件消费入口。 +- `internal/router/`:Gin 路由、请求绑定、鉴权中间件和统一响应。 +- `internal/service//`:按业务模块拆分的业务逻辑。 +- `internal/integration/`:Go 调用 Java 服务的网关封装。 +- `internal/common/`:`AppError`、`AuthUser` 等跨模块类型。 +- `internal/model/` 与 `migrations/`:表映射和数据库迁移。 +- `internal/config/config.go`:运行配置与 Java 下游地址。 + +Go 本地 HTTP 默认监听 `:2900`,但 Flutter 默认仍应通过 Java Gateway 访问,不应在业务代码中硬编码内部端口。 + +--- + +## 3. 后端仓库只读红线 + +在 Flutter 对接任务中,`yumi-java` 和 `yumi-golang` 一律视为只读证据源。 + +允许: + +- 使用 `rg`、`find`、`sed -n`、`git status --short`、`git diff`、`git show` 查看和搜索。 +- 读取路由、Controller/Handler、DTO、Service、错误码、配置和测试。 +- 在 Flutter 文档中记录后端证据路径和待确认事项。 + +禁止: + +- 在后端仓库创建、修改、删除、移动或格式化任何代码、文档、配置、SQL、生成文件和测试。 +- 运行会产生文件的命令,如 `gofmt -w`、`goimports -w`、`go mod tidy`、Maven 打包、代码生成、数据库迁移。 +- 默认启动后端、Docker、消费者、定时任务或执行后端测试;确有必要时必须先说明作用和文件/数据影响,并得到用户明确授权。 +- 在后端仓库执行暂存、提交、切分支、合并、拉取或推送。 +- 把调试标记或前端待办写入后端源码。 + +--- + +## 4. 实际请求拓扑与路由归属 + +### 4.1 默认链路 + +```text +Flutter + -> Java Gateway(API_HOST) + -> Java auth / external / order / wallet / live / other + -> Go API + -> MySQL / Redis / MQ + -> Java 内部服务(鉴权、用户、钱包、奖励等) +``` + +Flutter 默认基地址由 `SCVariant1Config.apiHost` 提供,可通过编译参数覆盖: + +```bash +flutter run --dart-define=API_HOST=https://example-gateway/ +``` + +不得在 Repository、Manager 或 Widget 中硬编码生产/测试域名。 + +### 4.2 Java Gateway 路由要点 + +以 `yumi-java/nacos_config/rc-gateway/application.yml` 为准,当前关键对外路径如下: + +| Flutter 请求路径 | Gateway 处理 | 实际归属 | +| --- | --- | --- | +| `/auth/**` | 去掉 `/auth` | Java auth | +| `/external/**` | 去掉 `/external` | Java external | +| `/order/**` | 去掉 `/order` | Java order | +| `/wallet/**` | 去掉 `/wallet` | Java wallet | +| `/live/**` | 去掉 `/live` | Java live | +| `/go/**` | 去掉 `/go` | Go API | +| `/app/game/**` | 保留原路径 | Go API | +| 未匹配的普通路径 | 默认转发 | Java other | +| 带 `Req-Likei: true` 的加密路由 | `ForwardRoute` 解析后转发 | 由解析结果决定 | + +Gateway 还对部分活动、回调和后台路径做了专用路由;对接具体接口时必须搜索完整 path,不能只根据前缀推断服务归属。 + +### 4.3 Go 路径的两种对接形式 + +- 经 Gateway 的 `/go` 路由:Flutter 请求 `/go/app/vip/status`,Go 实际接收 `/app/vip/status`。 +- Gateway 专用路由:例如 Flutter 请求 `/app/game/providers`,Go 仍接收 `/app/game/providers`。 + +除已有调试边界外,新增 App 接口优先使用同一 `API_HOST` 经 Gateway 访问。项目已有两个可选直连覆盖: + +- `VIP_API_HOST`:VIP Go API 调试。 +- `GAME_API_HOST`:房间游戏 Go API 调试。 + +仅在确认需要绕过 Gateway 联调时使用;不得为单个页面随意新增直连域名。 + +--- + +## 5. 接口事实参考顺序 + +当前两个后端仓库没有可覆盖全部 App 接口的统一 OpenAPI 契约,因此必须以可执行代码和当前路由配置为主证据。 + +### 5.1 先确定请求归属 + +1. 在 `nacos_config/rc-gateway/application.yml` 搜索完整 path 或前缀。 +2. 判断请求是否会 `StripPrefix`,记录 Flutter path 与下游 path。 +3. 确认该路由是否在 `gateway.ignorePaths` 中;“忽略 Gateway 鉴权”不等于“业务无需鉴权”,还要继续检查下游实现。 + +### 5.2 Java 接口 + +按以下顺序核对: + +1. `*-adapter/src/main/java/**/**RestController.java`:`@RequestMapping` + `@Get/Post/Put/DeleteMapping` 确认 method/path。 +2. Controller 方法参数:确认 query/path/form/json、`@Validated` 和必填规则。 +3. `*-client` / `*-inner` 中的 Command、CO、DTO、Enum:确认字段名、类型、枚举和响应数据。 +4. `*-application` 中对应 Service:确认业务条件、空值和错误分支。 +5. 错误码枚举、`ApiException` 和统一响应框架:确认业务失败语义。 +6. 最后查看相关测试和 README/docs,用于补充流程,不用于覆盖当前代码。 + +### 5.3 Go 接口 + +按以下顺序核对: + +1. `internal/router/_routes.go`:确认 method/path、鉴权中间件、query/path/body 绑定。 +2. `internal/service//types.go` 及对应业务文件:确认请求/响应字段、默认值、业务规则和 `AppError`。 +3. `internal/integration/`:如业务依赖 Java,确认实际下游 endpoint、Header 和数值转换。 +4. `internal/model/`、`migrations/` 和 `internal/config/`:仅用于理解字段来源、持久化和运行限制。 +5. `*_test.go`:核对边界值和已固化行为。 + +### 5.4 证据冲突时 + +- Gateway 配置决定外部请求实际到达哪个服务。 +- 当前 Router/Controller 实现决定 method、path 和参数接收方式。 +- 当前 Service/DTO 实现决定业务语义和字段。 +- README、注释、历史文档和 Flutter 旧模型只是补充证据。 +- 冲突时以当前可到达的执行代码作为“现状事实”,同时记录“待后端确认”,Flutter 不自行改后端消除差异。 + +--- + +## 6. 已确认的网络契约 + +### 6.1 请求 Header + +`ApiInterceptor` 会统一补充: + +- `Authorization: Bearer `(本地存在 Token 时) +- `req-lang` +- `req-imei` +- `req-app-intel` +- `req-client` +- `req-sys-origin` +- `Host` +- 已确认的加密路由才会添加 `Req-Likei: true` + +对接时不得在 Widget/Manager 重复手工组装这些公共 Header,也不得在代码或日志中写死 Token、密钥或完整鉴权数据。 + +Go App 路由的 `authMiddleware` 会读取 Bearer Token,并调用 Java auth 校验凭证;因此 Go 接口鉴权仍与 Java 登录态一致。 + +### 6.2 Java/Go 兼容响应 + +Flutter `ResponseData` 当前兼容两类字段: + +```json +{ + "status": true, + "errorCode": 0, + "errorCodeName": "", + "errorMsg": "success", + "body": {}, + "time": 0 +} +``` + +以及: + +```json +{ + "code": 200, + "message": "OK", + "data": {} +} +``` + +Go `writeOK` / `writeError` 会同时输出 `status/errorCode/errorMsg/body` 与 `code/message/data` 两套兼容字段。Flutter 解析规则为: + +- 数据优先读取 `body`,不存在时读取 `data`。 +- 优先用 `status` 判定成败;缺失时,`code == 0` 或 `code == 200` 视为成功。 +- 错误码读取 `errorCode` 或 `code`,错误信息读取 `errorMsg` 或 `message`。 +- HTTP 200 不代表业务成功,仍必须检查 envelope。 +- HTTP 4xx/5xx 与业务失败都必须进入明确错误状态。 + +新接口不得在页面层再实现一套 envelope 判定逻辑。 + +### 6.3 空响应 + +- 只有后端契约明确表示成功无数据时,才允许使用可空泛型和 `allowNullBody: true`。 +- 不得用 `false`、`0`、空字符串或空列表掩盖本应返回对象的契约问题。 +- 列表本身合法为空时,空列表是真实业务结果,不是接口失败的替代值。 + +### 6.4 路径与加密路由 + +- 旧接口在 Repository 中仍可能使用哈希形式的路由键,`network_client.dart` 会用 `_localRouteOverrides` 转为已知明文 path。 +- 新对接优先使用后端路由中已确认的明文 path,不复制或自行生成哈希。 +- 若线上 Gateway 明确要求加密路由,必须先获得后端路由键/转发规则并在网络层集中处理,页面层不得设置 `Req-Likei`。 + +--- + +## 7. Flutter 对接落地规范 + +### 7.1 分层责任 + +```text +Widget / Page + -> Provider / ChangeNotifier / Manager + -> Repository abstraction + -> Repository implementation / feature Api + -> NetworkClient + -> Java Gateway -> Java or Go +``` + +- `Widget / Page`:只负责渲染、交互与发出意图;不直接调 Dio,不解析 JSON。 +- `Provider / ChangeNotifier / Manager`:编排加载、成功、空态和错误状态,调用 Repository,不处理原始 envelope。 +- `Repository abstraction`:定义业务语义明确的方法和返回类型。 +- `Repository implementation / feature Api`:定义 method/path/query/body,调用 `http.get/post/put/delete`,完成 model 映射。 +- `NetworkClient`:统一 base URL、Header、Token、超时、envelope 和通用错误处理。 + +对现有模块增加接口时,优先延续该模块的已有分层,不为单个接口引入第二套网络或状态管理方案。 + +### 7.2 Model 与字段 + +- 字段命名、类型、可空性、枚举值和时间单位必须有后端证据。 +- 后端 `int64/Long` 字段如可能以数字或数字字符串返回,只能在 Model 解析边界做兼容,不得在 Widget 中反复转换。 +- 时间字段必须明确是秒、毫秒还是 ISO-8601,禁止通过数值长度猜测。 +- 金额、金币和比例必须确认单位与精度,不得在 UI 层暗中乘除。 +- 枚举未知值应有安全的“未知/不支持”分支,但不得把未知值伪装成某个已知业务类型。 +- 不在 Model 中根据页面需求虚构后端未返回的业务字段。 + +### 7.3 请求参数 + +- GET 查询使用 `queryParams`,path variable 只用已确认的 URL 片段。 +- JSON 请求使用 `data`,参数命名与后端契约一致。 +- 文件上传使用 `FormData`/`MultipartFile`,必须同时确认表单字段名、MIME、扩展名、大小上限和超时。 +- 幂等写操作的 key 由调用方在一次用户意图开始时创建,同一次超时重试必须复用;不得在每次底层请求时重新生成。 +- 分页必须记录是 cursor、page/size 还是 lastId,不得混用。 + +### 7.4 错误和登录态 + +- 网络层负责超时、HTTP 错误、通用业务错误和当前登录态校验。 +- Manager/Provider 只负责将错误转为页面可表达的错误状态,必要时提供重试入口。 +- Widget 不得看 `errorCode` 决定登出,不得自行重试鉴权失败。 +- 不得把服务端内部堆栈、SQL、密钥、完整 Token 或敏感请求体输出到生产日志。 +- 同一页面需要部分容错时,必须先定义每个数据源的独立成功/失败语义,不能用本地假数据补齐失败部分。 + +--- + +## 8. 严禁本地数据兜底 + +接口错误、超时、解析失败或返回不完整时,禁止: + +- 返回内置 mock 列表、本地 JSON、调试 assets 或硬编码对象。 +- 把异常转换为空列表、`false`、`0` 或“成功”,使页面误以为接口已成功。 +- 因为新接口不可用而静默切换到语义不同的旧接口。 +- 用占位数据触发下游支付、送礼、发奖、扣费、房间状态或其他写操作。 + +允许的仅是产品明确设计的本地能力,例如: + +- 加载骨架、空态插图、错误提示和重试按钮,但不得表示为服务端真实数据。 +- 明确定义的离线缓存,但必须保留“旧数据/离线”语义,不能覆盖本次请求失败事实。 +- 纯 UI 预览和单元测试中的 Fake/Fixture,必须与生产请求路径隔离。 + +--- + +## 9. 标准对接流程 + +1. 明确本次业务范围,不顺手改无关模块。 +2. 在 Flutter 中搜索现有接口、Model、Manager 和测试,确认已有状态和兼容要求。 +3. 查 Java Gateway 路由,确定请求归属和外部 path。 +4. 按第 5 节读取 Java 或 Go 的 Router/Controller、DTO/Service、错误和测试。 +5. 先写一份接口事实记录,至少包含 method/path/auth/request/response/error/evidence。 +6. 说明改动对现有路由、网络层、登录态、模型和页面的影响;若为 Bug,先提供 Root Cause 并等待用户确认。 +7. 在 Flutter 做能解决问题的最小变更,不重构无关代码。 +8. 增加 Model/envelope/分页/错误分支的针对性测试。 +9. 按第 11 节执行验证,并记录真实 API 联调结果。 +10. 如后端需要调整,只记录待确认项和证据,由用户协调后端处理。 + +--- + +## 10. 接口事实记录模板 + +```text +### 接口名称 + +- 业务模块: +- 调用链路:Flutter -> Java Gateway -> Java / Go -> 下游 +- Flutter Method / Path: +- 下游 Method / Path: +- Gateway 路由处理:保留路径 / StripPrefix / 加密转发 +- Auth:无 / Bearer / 其他 +- Request: + - path: + - query: + - header: + - body/form: +- Response body/data: +- 空值与默认值: +- 业务错误码: +- 时间/金额/分页/幂等语义: +- 后端证据: + - Gateway: + - Router / Controller: + - DTO / Service: + - Test / Doc: +- Flutter 落地: + - repository/api: + - model: + - manager/provider: + - view: + - test: +- 待后端确认: +- 当前状态:未对接 / 对接中 / 已对接 / 等后端 +``` + +--- + +## 11. 验证规范 + +### 11.1 静态与自动化验证 + +只格式化本次改动的 Dart 文件,然后执行: + +```bash +flutter analyze +flutter test +``` + +网络 envelope 或通用解析改动至少运行: + +```bash +flutter test test/network_response_data_test.dart +``` + +业务 Model 改动应运行或新增对应 `*_test.dart`;不能只依赖 Widget 手工观察。 + +### 11.2 真实接口联调 + +至少验证: + +1. 实际请求 method/path 与 Gateway 转发后 path 正确。 +2. 需鉴权接口携带当前 Bearer Token,无 Token/失效 Token 进入错误态。 +3. 成功、真实空数据、业务失败、HTTP 失败、超时、解析失败各至少覆盖相关分支。 +4. 重复点击、翻页、刷新和页面销毁不会产生重复写入或过期状态覆盖。 +5. 接口失败时页面不出现本地假数据,也不把失败当作空数据。 +6. 错误信息可理解、可重试,且日志不包含敏感信息。 + +### 11.3 回归影响 + +每次交付要明确说明: + +- 是否修改公共 `NetworkClient`、`ResponseData`、公共 Header 或 Token 处理。 +- 是否影响旧哈希路由、明文路由或 base URL override。 +- 是否影响其他共用 Model、Repository、Provider 或实时消息。 +- 针对上述影响执行了哪些测试,结果是什么。 + +--- + +## 12. 后端问题流转 + +出现以下情况时,Flutter 不修改后端: + +- Gateway 路由与 Router/Controller 不一致。 +- Java/Go 响应字段、可空性、数值类型或枚举不一致。 +- HTTP 状态码、`errorCode/code` 和业务语义不能支持前端分支。 +- 鉴权、幂等、分页、排序、时区、时间单位或金额单位不清晰。 +- Go 路由存在但 Java Gateway 没有可到达转发。 +- 后端仅有占位实现、返回 mock,或所需下游能力未上线。 + +记录模板: + +```text +- 【待后端确认|业务模块|YYYY-MM-DD HH:mm CST】 + 问题: + 现象: + 证据: + - Gateway: + - Java / Go: + - Flutter: + Root Cause 判断: + 前端影响: + 建议后端处理: + 联调验收条件: +``` + +--- + +## 13. 文档维护要求 + +- 本文档记录稳定规则;具体接口事实应写入对应业务文档,避免把本文档变成无法维护的接口大全。 +- 引用后端证据时写明仓库和相对路径,必要时补充类/函数名,不复制大段实现。 +- 不在文档中记录真实 Token、密码、密钥、DSN、云服务凭证或内网敏感信息。 +- 后端路由或响应契约变更后,同步更新相关业务接口记录和验证日期。 +- 文档中的“已对接”必须同时满足:Flutter 代码已落地、自动化验证通过、真实接口联调通过、不存在本地假数据兜底。 diff --git a/lib/app/config/configs/sc_variant1_config.dart b/lib/app/config/configs/sc_variant1_config.dart index c31ecf2..e4502ee 100644 --- a/lib/app/config/configs/sc_variant1_config.dart +++ b/lib/app/config/configs/sc_variant1_config.dart @@ -16,7 +16,7 @@ class SCVariant1Config implements AppConfig { @override String get apiHost => const String.fromEnvironment( 'API_HOST', - defaultValue: 'http://192.168.110.64:1100/', + defaultValue: 'https://jvapi.haiyihy.com/', ); // 默认连本地接口,本地调试可通过 --dart-define=API_HOST 覆盖,线上“https://jvapi.haiyihy.com/” @override diff --git a/lib/app/constants/sc_room_msg_type.dart b/lib/app/constants/sc_room_msg_type.dart index 2693dba..130fc59 100644 --- a/lib/app/constants/sc_room_msg_type.dart +++ b/lib/app/constants/sc_room_msg_type.dart @@ -4,6 +4,7 @@ class SCRoomMsgType { static const String joinRoom = "JOIN_ROOM"; static const String systemTips = "SYSTEM_TIPS"; static const String cpSystemNotice = "CP_SYSTEM_NOTICE"; + static const String cpRelationBroadcast = "CP_RELATION_BROADCAST"; ///表情包 static const String emoticons = "EMOTICONS"; diff --git a/lib/app_localizations.dart b/lib/app_localizations.dart index ee41d9f..bfa709d 100644 --- a/lib/app_localizations.dart +++ b/lib/app_localizations.dart @@ -1195,6 +1195,12 @@ class SCAppLocalizations { String get charm => translate('charm'); + String get leaderboardWealth => translate('leaderboardWealth'); + + String get leaderboardCharm => translate('leaderboardCharm'); + + String get leaderboardRoom => translate('leaderboardRoom'); + String get specialEffectsManagement => translate('specialEffectsManagement'); String get giftCounter => translate('giftCounter'); @@ -1533,6 +1539,8 @@ class SCAppLocalizations { String get followed => translate('followed'); + String get joined => translate('joined'); + String get following => translate('following'); String get history => translate('history'); @@ -1543,6 +1551,11 @@ class SCAppLocalizations { String get noData => translate('noData'); + String get noRoomRecordsRecently => translate('noRoomRecordsRecently'); + + String get youHaventJoinedAnyRoomsYet => + translate('youHaventJoinedAnyRoomsYet'); + String get freePrice => translate('freePrice'); String get purchase => translate('purchase'); diff --git a/lib/main.dart b/lib/main.dart index e6a7b06..b2cd350 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -29,6 +29,7 @@ import 'shared/tools/sc_deep_link_handler.dart'; import 'shared/tools/sc_deviceId_utils.dart'; import 'shared/tools/sc_gift_vap_svga_manager.dart'; import 'shared/data_sources/sources/local/user_manager.dart'; +import 'shared/data_sources/sources/local/floating_screen_manager.dart'; import 'modules/splash/splash_page.dart'; import 'services/general/sc_app_general_manager.dart'; import 'services/payment/apple_payment_manager.dart'; @@ -279,6 +280,8 @@ final GlobalKey navigatorKey = GlobalKey(); final RouteObserver routeObserver = RouteObserver(); final RouteObserver> modalRouteObserver = RouteObserver>(); +final NavigatorObserver floatingScreenRouteObserver = + SCFloatingScreenRouteObserver(); class YumiApplication extends StatefulWidget { const YumiApplication({super.key}); @@ -451,7 +454,11 @@ class _YumiApplicationState extends State ); }, ), - navigatorObservers: [routeObserver, modalRouteObserver], + navigatorObservers: [ + routeObserver, + modalRouteObserver, + floatingScreenRouteObserver, + ], ), ), ); diff --git a/lib/modules/auth/edit/sc_edit_profile_page.dart b/lib/modules/auth/edit/sc_edit_profile_page.dart index d6fd5ad..0946f0e 100644 --- a/lib/modules/auth/edit/sc_edit_profile_page.dart +++ b/lib/modules/auth/edit/sc_edit_profile_page.dart @@ -19,6 +19,7 @@ import 'package:yumi/shared/tools/sc_google_auth_utils.dart'; import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/shared/data_sources/models/enum/sc_auth_type.dart'; +import 'package:yumi/shared/business_logic/models/req/sc_user_profile_cmd.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/services/general/sc_app_general_manager.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; @@ -56,9 +57,35 @@ class _SCEditProfilePageState extends State { ); Provider.of(context, listen: false).selectCountryInfo = null; + _prefillGoogleRegistrationProfile(); _fillInvitationCodeFromInstallReferrer(); } + void _prefillGoogleRegistrationProfile() { + final authProvider = Provider.of( + context, + listen: false, + ); + if (authProvider.authType != SCAuthType.GOOGLE.name) { + return; + } + + birthdayDate = DateTime(2000, 1, 1); + final googleUser = authProvider.user ?? SCGoogleAuthService.currentUser; + final googleName = googleUser?.displayName?.trim() ?? ""; + final googleAvatar = googleUser?.photoURL?.trim() ?? ""; + if (googleName.isNotEmpty) { + nicknameController.text = googleName; + } + if (googleAvatar.isNotEmpty) { + final editUser = userProvider?.editUser ?? SCUserProfileCmd(); + if ((editUser.userAvatar ?? "").trim().isEmpty) { + editUser.setUserAvatar = googleAvatar; + } + userProvider?.editUser = editUser; + } + } + @override void dispose() { nicknameController.dispose(); diff --git a/lib/modules/chat/message/sc_message_page.dart b/lib/modules/chat/message/sc_message_page.dart index f81fbe3..325c4a2 100644 --- a/lib/modules/chat/message/sc_message_page.dart +++ b/lib/modules/chat/message/sc_message_page.dart @@ -3,7 +3,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; -import 'package:yumi/ui_kit/components/text/sc_text.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart'; @@ -15,6 +14,7 @@ import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/ui_kit/theme/socialchat_theme.dart'; import 'package:yumi/ui_kit/widgets/msg/message_conversation_list_page.dart'; +import 'package:yumi/ui_kit/widgets/sc_home_shell_background.dart'; import '../chat_route.dart'; @@ -94,101 +94,29 @@ class _MessagePageState extends State { Widget build(BuildContext context) { return Stack( children: [ - widget.isFromRoom - ? Image.asset( - _strategy.getMessagePageIndexMaskIcon(), - width: ScreenUtil().screenWidth, - fit: BoxFit.cover, - ) - : Container(), - DefaultTabController( - length: 1, - child: Scaffold( - backgroundColor: Colors.transparent, - appBar: AppBar( - backgroundColor: Colors.transparent, - leading: null, - title: - _isSearchingMessages - ? _messageSearchField() - : TabBar( - tabs: - [SCAppLocalizations.of(context)!.message] - .map( - (e) => Padding( - padding: EdgeInsets.only( - bottom: 3.w, - top: 4.w, - ), - child: Text(e), - ), - ) - .toList(), - dividerColor: Colors.transparent, - labelStyle: TextStyle( - fontSize: 16.sp, - fontWeight: FontWeight.bold, - fontStyle: FontStyle.italic, - ), - unselectedLabelStyle: TextStyle( - fontSize: 15.sp, - color: Colors.white, - fontWeight: FontWeight.normal, - ), - indicator: BoxDecoration(), - //TabBarIndicator(), - indicatorSize: TabBarIndicatorSize.label, - isScrollable: true, - tabAlignment: TabAlignment.start, - labelColor: SocialChatTheme.primaryLight, - ), - actions: [ - SCDebounceWidget( - child: Container( - padding: EdgeInsetsDirectional.only(start: 10.w, end: 10.w), - child: - _isSearchingMessages - ? Icon(Icons.close, size: 22.w, color: Colors.white) - : Image.asset( - "sc_images/index/sc_icon_serach.png", - width: 20.w, - height: 20.w, - ), - ), - onTap: () { - if (_isSearchingMessages) { - _stopMessageSearch(); - } else { - _startMessageSearch(); - } - }, - ), - ], - ), - body: TabBarView( + const Positioned.fill(child: SCHomeShellBackground()), + if (widget.isFromRoom) + Image.asset( + _strategy.getMessagePageIndexMaskIcon(), + width: ScreenUtil().screenWidth, + fit: BoxFit.cover, + ), + Scaffold( + backgroundColor: Colors.transparent, + body: SafeArea( + bottom: false, + child: Column( children: [ - Consumer( - builder: (_, provider, __) { - return Container( - margin: EdgeInsetsDirectional.symmetric(horizontal: 10.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "sc_images/index/sc_index_msg_content_bg.png", - ), - fit: BoxFit.fill, - ), - ), - child: Column( + _buildTopBar(), + Expanded( + child: Consumer( + builder: (_, provider, __) { + return Column( children: [ if (!_isSearchingMessages) _headMenu(provider), Expanded( - child: Container( - margin: EdgeInsets.only( - top: 0.w, - left: 8.w, - right: 8.w, - ), + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), child: MessageConversationListPage( false, searchQuery: _messageSearchText, @@ -196,9 +124,9 @@ class _MessagePageState extends State { ), ), ], - ), - ); - }, + ); + }, + ), ), ], ), @@ -208,6 +136,51 @@ class _MessagePageState extends State { ); } + Widget _buildTopBar() { + return SizedBox( + height: 44.w, + child: Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Row( + children: [ + Expanded( + child: + _isSearchingMessages + ? _messageSearchField() + : SCHomeShellGradientText( + SCAppLocalizations.of(context)!.message, + style: scHomeShellTitleStyle(), + ), + ), + SCDebounceWidget( + child: SizedBox( + width: 38.w, + height: 38.w, + child: Center( + child: + _isSearchingMessages + ? Icon(Icons.close, size: 22.w, color: Colors.white) + : Image.asset( + "sc_images/index/sc_icon_serach.png", + width: 24.w, + height: 24.w, + ), + ), + ), + onTap: () { + if (_isSearchingMessages) { + _stopMessageSearch(); + } else { + _startMessageSearch(); + } + }, + ), + ], + ), + ), + ); + } + Widget _messageSearchField() { return Container( height: 36.w, @@ -232,7 +205,7 @@ class _MessagePageState extends State { focusNode: _messageSearchFocusNode, autofocus: true, cursorColor: SocialChatTheme.primaryLight, - style: TextStyle(color: Colors.white, fontSize: 14.sp), + style: TextStyle(color: Colors.black, fontSize: 14.sp), decoration: InputDecoration( hintText: "${SCAppLocalizations.of(context)!.search} ID/${SCAppLocalizations.of(context)!.userName}", @@ -275,72 +248,42 @@ class _MessagePageState extends State { Widget _headMenu(RtmProvider provider) { return Container( - margin: EdgeInsetsDirectional.symmetric( - horizontal: 20.w, - ).copyWith(top: 10.w), - child: Column( - spacing: 15.w, + margin: EdgeInsets.fromLTRB(10.w, 25.w, 10.w, 10.w), + height: 114.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all( + color: scHomeShellAccentColor.withValues(alpha: 0.2), + width: 1.w, + ), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + const Color(0xFF111A1B).withValues(alpha: 0.86), + const Color(0xFF2C4D42).withValues(alpha: 0.68), + ], + ), + ), + child: Row( children: [ - SCDebounceWidget( - child: Stack( - children: [ - Row( - children: [ - SizedBox(height: 3.w), - Image.asset( - _strategy.getMessagePageActivityMessageIcon(), - width: 45.w, - height: 45.w, - ), - SizedBox(width: 5.w), - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text( - SCAppLocalizations.of(context)!.activity, - textColor: Colors.white, - fontSize: 14.sp, - fontWeight: FontWeight.bold, - ), - SizedBox(height: 3.w), - text( - "[${SCAppLocalizations.of(context)!.newMessage}]", - fontSize: 12.sp, - textColor: Colors.white54, - ), - ], - ), - ], - ), - PositionedDirectional( - bottom: 0, - end: 10.w, - child: Visibility( - visible: provider.activityUnReadCount > 0, - child: Container( - padding: EdgeInsets.symmetric(horizontal: 6.w), - alignment: Alignment.center, - height: 16.w, - decoration: BoxDecoration( - //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]), - color: Colors.red, - shape: BoxShape.circle, - //borderRadius: BorderRadius.all(Radius.circular(7.w)), - ), - child: Text( - "${provider.activityUnReadCount > 99 ? '99+' : provider.activityUnReadCount}", - style: TextStyle( - fontSize: 10.sp, - color: Color(0xffffffff), - fontWeight: FontWeight.w400, - decoration: TextDecoration.none, - ), - ), - ), - ), - ), - ], - ), + _buildMessageShortcut( + label: SCAppLocalizations.of(context)!.notifcation, + icon: _strategy.getMessagePageNotificationMessageIcon(), + unreadCount: provider.notifcationUnReadCount, + onTap: () { + provider.updateNotificationCount(0); + SCNavigatorUtils.push( + context, + SCChatRouter.notifcation, + replace: false, + ); + }, + ), + _buildMessageShortcut( + label: SCAppLocalizations.of(context)!.activity, + icon: _strategy.getMessagePageActivityMessageIcon(), + unreadCount: provider.activityUnReadCount, onTap: () { provider.updateActivityCount(0); SCNavigatorUtils.push( @@ -350,45 +293,10 @@ class _MessagePageState extends State { ); }, ), - SCDebounceWidget( - child: Row( - children: [ - SizedBox(height: 3.w), - Image.asset( - _strategy.getMessagePageSystemMessageIcon(), - width: 45.w, - height: 45.w, - ), - SizedBox(width: 6.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text( - SCAppLocalizations.of(context)!.system, - textColor: Colors.white, - fontSize: 14.sp, - fontWeight: FontWeight.bold, - ), - SizedBox(height: 3.w), - Row( - children: [ - Expanded( - child: text( - "[${SCAppLocalizations.of(context)!.newMessage}]", - fontSize: 12.sp, - textColor: Colors.white54, - ), - ), - SizedBox(width: 5.w), - _unreadBadge(provider.systemUnReadCount), - ], - ), - ], - ), - ), - ], - ), + _buildMessageShortcut( + label: SCAppLocalizations.of(context)!.system, + icon: _strategy.getMessagePageSystemMessageIcon(), + unreadCount: provider.systemUnReadCount, onTap: () async { var conversation = provider.getPreferredSystemConversation(); provider.updateSystemCount(0); @@ -401,55 +309,49 @@ class _MessagePageState extends State { ); }, ), - SCDebounceWidget( - child: Row( + ], + ), + ); + } + + Widget _buildMessageShortcut({ + required String label, + required String icon, + required int unreadCount, + required VoidCallback onTap, + }) { + return Expanded( + child: SCDebounceWidget( + onTap: onTap, + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + clipBehavior: Clip.none, children: [ - SizedBox(height: 3.w), - Image.asset( - _strategy.getMessagePageNotificationMessageIcon(), - width: 45.w, - height: 45.w, - ), - SizedBox(width: 6.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - text( - SCAppLocalizations.of(context)!.notifcation, - textColor: Colors.white, - fontSize: 14.sp, - fontWeight: FontWeight.bold, - ), - SizedBox(height: 3.w), - Row( - children: [ - Expanded( - child: text( - "[${SCAppLocalizations.of(context)!.newMessage}]", - fontSize: 12.sp, - textColor: Colors.white54, - ), - ), - SizedBox(width: 5.w), - _unreadBadge(provider.notifcationUnReadCount), - ], - ), - ], + Image.asset(icon, width: 52.w, height: 52.w), + if (unreadCount > 0) + PositionedDirectional( + top: -2.w, + end: -6.w, + child: _unreadBadge(unreadCount), ), - ), ], ), - onTap: () { - provider.updateNotificationCount(0); - SCNavigatorUtils.push( - context, - SCChatRouter.notifcation, - replace: false, - ); - }, - ), - ], + SizedBox(height: 10.w), + Text( + label, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.w700, + height: 1.2, + ), + ), + ], + ), ), ); } @@ -460,7 +362,8 @@ class _MessagePageState extends State { child: Container( padding: EdgeInsets.symmetric(horizontal: 6.w), alignment: Alignment.center, - height: 16.w, + height: 18.w, + constraints: BoxConstraints(minWidth: 18.w), decoration: BoxDecoration(color: Colors.red, shape: BoxShape.circle), child: Text( "${unreadCount > 99 ? '99+' : unreadCount}", diff --git a/lib/modules/chat/message_chat_page.dart b/lib/modules/chat/message_chat_page.dart index f1f6d06..9ba3937 100644 --- a/lib/modules/chat/message_chat_page.dart +++ b/lib/modules/chat/message_chat_page.dart @@ -53,6 +53,7 @@ import 'package:yumi/app/config/business_logic_strategy.dart'; import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart'; +import 'package:yumi/shared/tools/sc_chat_bubble_message_data.dart'; import 'package:yumi/shared/tools/sc_keybord_util.dart'; import 'package:yumi/shared/tools/sc_message_notifier.dart'; import 'package:yumi/shared/tools/sc_path_utils.dart'; @@ -2623,6 +2624,17 @@ class _MessageItem extends StatelessWidget { } Widget _buildTextBubble(String content) { + final snapshot = scDecodeChatBubbleMessageSnapshot(message.cloudCustomData); + if (snapshot.hasSnapshot) { + if (snapshot.imageUrl.isNotEmpty) { + return _buildVipTextBubble( + content: content, + imageUrl: snapshot.imageUrl, + ); + } + return _buildDefaultTextBubble(content); + } + final chatBubble = (message.isSelf ?? false) ? _currentUserChatBubble() @@ -2697,8 +2709,8 @@ class _MessageItem extends StatelessWidget { 260.w, ); final multilineMaxTextWidth = math.max( - 82.w, - multilineMaxBubbleWidth - 76.w, + 60.w, + multilineMaxBubbleWidth - 52.w, ); final multilineTextPainter = TextPainter( text: TextSpan(text: content, style: textStyle), @@ -2728,34 +2740,24 @@ class _MessageItem extends StatelessWidget { required Size textSize, required double maxBubbleWidth, }) { - final leftPadding = 34.w; - final rightPadding = 42.w; - final topPadding = 16.w; - final bottomPadding = 18.w; + final leftPadding = 24.w; + final rightPadding = 28.w; + final topPadding = 10.w; + final bottomPadding = 12.w; final bubbleWidth = math - .max(126.w, textSize.width + leftPadding + rightPadding) - .clamp(126.w, maxBubbleWidth); + .max(92.w, textSize.width + leftPadding + rightPadding) + .clamp(92.w, maxBubbleWidth); final textMaxWidth = math.max( - 64.w, + 40.w, bubbleWidth - leftPadding - rightPadding, ); final textPainter = TextPainter( text: TextSpan(text: content, style: textStyle), textDirection: Directionality.of(context), )..layout(maxWidth: textMaxWidth); - final lineMetrics = textPainter.computeLineMetrics(); - final lineCount = math.max(1, lineMetrics.length); - final lineHeight = - lineMetrics.isEmpty - ? textPainter.preferredLineHeight - : lineMetrics.fold( - 0, - (height, line) => math.max(height, line.height), - ); - final lineSafetyPadding = lineHeight * math.max(0, lineCount - 1) * 0.55; - final textBoxHeight = textPainter.size.height + lineSafetyPadding; + final textBoxHeight = textPainter.size.height + 2.w; final bubbleHeight = math.max( - 76.w, + 52.w, textBoxHeight + topPadding + bottomPadding, ); @@ -2797,13 +2799,13 @@ class _MessageItem extends StatelessWidget { required String imageUrl, required TextStyle textStyle, }) { - final leftPadding = 22.w; - final rightPadding = 24.w; - final topPadding = 12.w; - final bottomPadding = 16.w; - final minSkinWidth = 50.w; - final minSkinHeight = 58.w; - final textWidthSafety = 10.w; + final leftPadding = 16.w; + final rightPadding = 18.w; + final topPadding = 8.w; + final bottomPadding = 10.w; + final minSkinWidth = 56.w; + final minSkinHeight = 52.w; + final textWidthSafety = 4.w; final maxTextWidth = width(220); final maxBubbleWidth = maxTextWidth + leftPadding + rightPadding; final textSize = _measureTextSize( @@ -2964,32 +2966,7 @@ class _MessageItem extends StatelessWidget { } String _resolveChatBubbleImageUrl(PropsResources? resource) { - final candidates = [ - resource?.imSendCoverUrl, - resource?.imOpenedUrl, - resource?.imOpenedUrlTwo, - resource?.imNotOpenedUrl, - resource?.roomSendCoverUrl, - resource?.roomOpenedUrl, - resource?.roomNotOpenedUrl, - resource?.cover, - resource?.expand, - resource?.sourceUrl, - ]; - return _firstNonBlank([ - ...candidates.where((value) => SCNetworkSvgaWidget.isSvga(value)), - ...candidates, - ]); - } - - String _firstNonBlank(Iterable values) { - for (final value in values) { - final text = value?.trim(); - if (text != null && text.isNotEmpty) { - return text; - } - } - return ""; + return scResolveChatBubbleImageUrl(resource); } void _showMsgItemMenu(BuildContext ct, String content) { diff --git a/lib/modules/gift/gift_page.dart b/lib/modules/gift/gift_page.dart index b377174..d2e5ff9 100644 --- a/lib/modules/gift/gift_page.dart +++ b/lib/modules/gift/gift_page.dart @@ -1650,9 +1650,9 @@ class _GiftPageState extends State with TickerProviderStateMixin { if (!request.isBackpackGiftRequest && _isInsufficientMoneyError(e, errorMessage)) { RoomGiftComboSendController().hide(); - RoomRechargeBottomSheet.show( - navigatorKey.currentState?.context ?? context, - ); + // RoomRechargeBottomSheet.show( + // navigatorKey.currentState?.context ?? context, + // ); return; } SCTts.show(errorMessage); diff --git a/lib/modules/home/index_home_page.dart b/lib/modules/home/index_home_page.dart index 8b711ba..db6ce21 100644 --- a/lib/modules/home/index_home_page.dart +++ b/lib/modules/home/index_home_page.dart @@ -7,8 +7,8 @@ import 'package:yumi/modules/index/main_route.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; import 'package:provider/provider.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; -import 'package:yumi/ui_kit/theme/socialchat_theme.dart'; import 'package:yumi/ui_kit/widgets/countdown_timer.dart'; +import 'package:yumi/ui_kit/widgets/sc_home_shell_background.dart'; ///Home页面 class SCIndexHomePage extends StatefulWidget { @@ -69,6 +69,25 @@ class _SCIndexHomePageState extends State super.dispose(); } + Widget _buildStyledTab(Widget tab, int index) { + final controller = _tabController!; + if (tab is! Tab || tab.text == null) return tab; + return Tab( + height: tab.height, + child: AnimatedBuilder( + animation: controller.animation!, + builder: (context, child) { + if (controller.index != index) return child!; + return SCHomeShellGradientText( + tab.text!, + style: DefaultTextStyle.of(context).style, + ); + }, + child: Text(tab.text!), + ), + ); + } + @override Widget build(BuildContext context) { if (_tabController == null || _pages.isEmpty || _tabs.isEmpty) { @@ -87,6 +106,7 @@ class _SCIndexHomePageState extends State return Stack( children: [ + const Positioned.fill(child: SCHomeShellBackground()), Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Colors.transparent, @@ -94,56 +114,71 @@ class _SCIndexHomePageState extends State children: [ // 自定义顶部栏(包含状态栏和 TabBar) SafeArea( - child: Row( - children: [ - // TabBar 直接放在这里 - Expanded( - child: TabBar( - tabAlignment: TabAlignment.start, - isScrollable: true, - splashFactory: NoSplash.splashFactory, - overlayColor: WidgetStateProperty.all( - Colors.transparent, - ), - indicator: const BoxDecoration(), - labelStyle: TextStyle( - fontWeight: FontWeight.bold, - fontStyle: FontStyle.italic, - fontSize: 19.sp, - color: SocialChatTheme.primaryLight, - ), - unselectedLabelStyle: TextStyle( - fontWeight: FontWeight.normal, - fontSize: 14.sp, - color: Colors.white, - ), - indicatorColor: Colors.transparent, - dividerColor: Colors.transparent, - controller: _tabController, - tabs: _tabs, - ), - ), - Container( - padding: EdgeInsets.symmetric(horizontal: 16), - child: Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - IconButton( - icon: Image.asset( - "sc_images/index/sc_icon_serach.png", - width: 25.w, - height: 25.w, - ), - onPressed: - () => SCNavigatorUtils.push( - context, - SCMainRoute.mainSearch, - ), + bottom: false, + child: SizedBox( + height: 44.w, + child: Row( + children: [ + // TabBar 直接放在这里 + Expanded( + child: TabBar( + tabAlignment: TabAlignment.start, + isScrollable: true, + labelPadding: EdgeInsets.symmetric(horizontal: 10.w), + splashFactory: NoSplash.splashFactory, + overlayColor: WidgetStateProperty.all( + Colors.transparent, ), - ], + indicator: const BoxDecoration(), + labelStyle: TextStyle( + fontWeight: FontWeight.w900, + fontStyle: FontStyle.italic, + fontSize: 28.sp, + color: scHomeShellGoldColor, + shadows: const [ + Shadow( + color: Color(0xB3000000), + offset: Offset(0, 1), + blurRadius: 1, + ), + ], + ), + unselectedLabelStyle: TextStyle( + fontWeight: FontWeight.w600, + fontSize: 16.sp, + color: Colors.white, + ), + indicatorColor: Colors.transparent, + dividerColor: Colors.transparent, + controller: _tabController, + tabs: List.generate( + _tabs.length, + (index) => _buildStyledTab(_tabs[index], index), + ), + ), ), - ), - ], + Container( + padding: EdgeInsetsDirectional.only(end: 10.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + IconButton( + icon: Image.asset( + "sc_images/index/sc_icon_serach.png", + width: 25.w, + height: 25.w, + ), + onPressed: + () => SCNavigatorUtils.push( + context, + SCMainRoute.mainSearch, + ), + ), + ], + ), + ), + ], + ), ), ), // TabBarView 直接作为剩余空间 diff --git a/lib/modules/home/popular/follow/sc_room_follow_page.dart b/lib/modules/home/popular/follow/sc_room_follow_page.dart index 8f4e4c1..e502904 100644 --- a/lib/modules/home/popular/follow/sc_room_follow_page.dart +++ b/lib/modules/home/popular/follow/sc_room_follow_page.dart @@ -3,19 +3,13 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app_localizations.dart'; -import 'package:provider/provider.dart'; -import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/sc_page_list.dart'; -import 'package:yumi/ui_kit/components/text/sc_text.dart'; -import 'package:yumi/ui_kit/widgets/room/room_live_audio_indicator.dart'; -import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/business_logic/models/res/follow_room_res.dart'; -import 'package:yumi/services/general/sc_app_general_manager.dart'; -import 'package:yumi/services/audio/rtc_manager.dart'; +import '../mine/sc_home_mine_room_card.dart'; import '../mine/sc_home_mine_skeleton.dart'; -///关注房间 +///加入的房间 class SCRoomFollowPage extends SCPageList { const SCRoomFollowPage({super.key}); @@ -28,7 +22,6 @@ class _RoomFollowPageState with WidgetsBindingObserver, AutomaticKeepAliveClientMixin { static const Duration _roomListRefreshInterval = Duration(seconds: 15); - String? lastId; Timer? _roomListRefreshTimer; bool _isSilentRefreshingRooms = false; bool _wasTickerModeEnabled = false; @@ -41,10 +34,17 @@ class _RoomFollowPageState void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); - enablePullUp = true; + enablePullUp = false; backgroundColor = Colors.transparent; isGridView = true; gridViewCount = 2; + gridDelegate = SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 172 / 200, + mainAxisSpacing: 8.w, + crossAxisSpacing: 10.w, + ); + padding = EdgeInsets.only(top: 8.w, bottom: 10.w); loadData(1); _startRoomListAutoRefresh(); } @@ -97,202 +97,38 @@ class _RoomFollowPageState @override Widget buildItem(FollowRoomRes roomRes) { - return GestureDetector( - child: Container( - margin: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12.w), - color: Colors.transparent, - ), - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Container( - padding: EdgeInsets.all(3.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("sc_images/index/sc_icon_room_bord.png"), - fit: BoxFit.fill, - ), - ), - child: netImage( - url: resolveRoomCoverUrl( - roomRes.roomProfile?.id, - roomRes.roomProfile?.roomCover, - ), - defaultImg: kRoomCoverDefaultImg, - borderRadius: BorderRadius.circular(12.w), - width: 200.w, - height: 200.w, - ), - ), - Container( - padding: EdgeInsets.symmetric(vertical: 6.w), - margin: EdgeInsets.symmetric(horizontal: 1.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "sc_images/index/sc_icon_index_room_brd.png", - ), - fit: BoxFit.fill, - ), - ), - child: Row( - children: [ - SizedBox(width: 10.w), - Consumer( - builder: (_, provider, __) { - return netImage( - url: - "${provider.findCountryByName(roomRes.roomProfile?.countryName ?? "")?.nationalFlag}", - width: 20.w, - height: 13.w, - borderRadius: BorderRadius.circular(2.w), - ); - }, - ), - SizedBox(width: 5.w), - Expanded( - child: SizedBox( - height: 17.w, - child: Align( - alignment: Alignment.centerLeft, - child: Transform.translate( - offset: Offset(0, -0.6.w), - child: text( - roomRes.roomProfile?.roomName ?? "", - fontSize: 13.sp, - textColor: Color(0xffffffff), - fontWeight: FontWeight.w400, - lineHeight: 1, - ), - ), - ), - // (roomRes.roomProfile?.roomName?.length ?? 0) > 10 - // ? Marquee( - // text: roomRes.roomProfile?.roomName ?? "", - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // scrollAxis: Axis.horizontal, - // crossAxisAlignment: CrossAxisAlignment.start, - // blankSpace: 20.0, - // velocity: 40.0, - // pauseAfterRound: Duration(seconds: 1), - // accelerationDuration: Duration(seconds: 1), - // accelerationCurve: Curves.easeOut, - // decelerationDuration: Duration( - // milliseconds: 500, - // ), - // decelerationCurve: Curves.easeOut, - // ) - // : Text( - // roomRes.roomProfile?.roomName ?? "", - // maxLines: 1, - // overflow: TextOverflow.ellipsis, - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // ), - ), - ), - SizedBox(width: 5.w), - roomRes.roomProfile?.extValues?.existsPassword != true - ? SCRoomLiveAudioIndicator(width: 14.w, height: 14.w) - : Image.asset( - "sc_images/index/sc_icon_room_suo.png", - width: 20.w, - height: 20.w, - ), - roomRes.roomProfile?.extValues?.existsPassword != true - ? SizedBox(width: 3.w) - : Container(height: 10.w), - roomRes.roomProfile?.extValues?.existsPassword != true - ? text( - roomRes.roomProfile?.displayMemberCount ?? "0", - fontSize: 10.sp, - lineHeight: 1, - ) - : Container(height: 10.w), - SizedBox(width: 10.w), - ], - ), - ), - getRoomCoverHeaddress(roomRes).isNotEmpty - ? Transform.translate( - offset: Offset(0, -5.w), - child: Transform.scale( - scaleX: 1.1, - scaleY: 1.12, - child: Image.asset(getRoomCoverHeaddress(roomRes)), - ), - ) - : Container(), - - (roomRes.roomProfile?.roomGameIcon?.isNotEmpty ?? false) - ? PositionedDirectional( - top: 8.w, - end: 8.w, - child: netImage( - url: roomRes.roomProfile?.roomGameIcon ?? "", - width: 25.w, - height: 25.w, - borderRadius: BorderRadius.circular(4.w), - ), - ) - : Container(), - ], - ), - ), - onTap: () { - Provider.of(context, listen: false).joinVoiceRoomSession( - context, - roomRes.roomProfile?.id ?? "", - previewData: RoomEntryPreviewData.fromFollowRoom(roomRes), - ); - }, - ); - } - - String getRoomCoverHeaddress(FollowRoomRes roomRes) { - return ""; + return SCHomeMineRoomCard(room: roomRes); } @override empty() { - List list = []; - list.add(SizedBox(height: height(30))); - list.add( - Image.asset( - 'sc_images/general/sc_icon_loading.png', - width: 120.w, - height: 120.w, - ), - ); - list.add(SizedBox(height: height(15))); - list.add( - Text( - SCAppLocalizations.of(context)!.youHaventFollowed, - style: TextStyle( - fontSize: sp(14), - color: Color(0xff999999), - fontWeight: FontWeight.w400, - decoration: TextDecoration.none, - height: 1, + return Align( + alignment: Alignment.topCenter, + child: Container( + width: double.infinity, + height: 76.w, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all(color: const Color(0x3306FFC0)), + gradient: const LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0x99111A1B), Color(0x992C4D42)], + ), + ), + child: Text( + SCAppLocalizations.of(context)!.youHaventJoinedAnyRoomsYet, + style: TextStyle( + fontSize: 14.sp, + color: Colors.white, + fontWeight: FontWeight.w600, + decoration: TextDecoration.none, + height: 20 / 14, + ), ), ), ); - return Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: list, - ); } ///加载数据 @@ -302,14 +138,8 @@ class _RoomFollowPageState required Function(List) onSuccess, Function? onErr, }) async { - if (page == 1) { - lastId = null; - } try { - var roomList = await SCAccountRepository().followRoomList(lastId: lastId); - if (roomList.isNotEmpty) { - lastId = roomList.last.id; - } + final roomList = await SCAccountRepository().joined(); if (page == 1) { _hasCompletedInitialLoad = true; } @@ -369,7 +199,6 @@ class _RoomFollowPageState items ..clear() ..addAll(latestRooms); - lastId = latestRooms.isNotEmpty ? latestRooms.last.id : null; return true; } @@ -391,7 +220,7 @@ class _RoomFollowPageState } _isSilentRefreshingRooms = true; try { - final latestRooms = await SCAccountRepository().followRoomList(); + final latestRooms = await SCAccountRepository().joined(); if (!mounted || !TickerMode.valuesOf(context).enabled) { return; } diff --git a/lib/modules/home/popular/history/sc_room_history_page.dart b/lib/modules/home/popular/history/sc_room_history_page.dart index cebdea6..c746206 100644 --- a/lib/modules/home/popular/history/sc_room_history_page.dart +++ b/lib/modules/home/popular/history/sc_room_history_page.dart @@ -4,15 +4,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; -import 'package:provider/provider.dart'; -import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/sc_page_list.dart'; -import 'package:yumi/ui_kit/components/text/sc_text.dart'; -import 'package:yumi/ui_kit/widgets/room/room_live_audio_indicator.dart'; -import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/shared/business_logic/models/res/follow_room_res.dart'; -import 'package:yumi/services/general/sc_app_general_manager.dart'; -import 'package:yumi/services/audio/rtc_manager.dart'; +import '../mine/sc_home_mine_room_card.dart'; import '../mine/sc_home_mine_skeleton.dart'; ///历史房间 @@ -45,6 +39,13 @@ class _SCRoomHistoryPageState backgroundColor = Colors.transparent; isGridView = true; gridViewCount = 2; + gridDelegate = SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 2, + childAspectRatio: 172 / 200, + mainAxisSpacing: 8.w, + crossAxisSpacing: 10.w, + ); + padding = EdgeInsets.only(top: 8.w, bottom: 10.w); loadData(1); _startRoomListAutoRefresh(); } @@ -97,202 +98,38 @@ class _SCRoomHistoryPageState @override Widget buildItem(FollowRoomRes roomRes) { - return GestureDetector( - child: Container( - margin: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12.w), - color: Colors.transparent, - ), - child: Stack( - alignment: Alignment.bottomCenter, - children: [ - Container( - padding: EdgeInsets.all(3.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("sc_images/index/sc_icon_room_bord.png"), - fit: BoxFit.fill, - ), - ), - child: netImage( - url: resolveRoomCoverUrl( - roomRes.roomProfile?.id, - roomRes.roomProfile?.roomCover, - ), - defaultImg: kRoomCoverDefaultImg, - borderRadius: BorderRadius.circular(12.w), - width: 200.w, - height: 200.w, - ), - ), - Container( - padding: EdgeInsets.symmetric(vertical: 6.w), - margin: EdgeInsets.symmetric(horizontal: 1.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "sc_images/index/sc_icon_index_room_brd.png", - ), - fit: BoxFit.fill, - ), - ), - child: Row( - children: [ - SizedBox(width: 10.w), - Consumer( - builder: (_, provider, __) { - return netImage( - url: - "${provider.findCountryByName(roomRes.roomProfile?.countryName ?? "")?.nationalFlag}", - width: 20.w, - height: 13.w, - borderRadius: BorderRadius.circular(2.w), - ); - }, - ), - SizedBox(width: 5.w), - Expanded( - child: SizedBox( - height: 17.w, - child: Align( - alignment: Alignment.centerLeft, - child: Transform.translate( - offset: Offset(0, -0.6.w), - child: text( - roomRes.roomProfile?.roomName ?? "", - fontSize: 13.sp, - textColor: Color(0xffffffff), - fontWeight: FontWeight.w400, - lineHeight: 1, - ), - ), - ), - - // (roomRes.roomProfile?.roomName?.length ?? 0) > 10 - // ? Marquee( - // text: roomRes.roomProfile?.roomName ?? "", - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // scrollAxis: Axis.horizontal, - // crossAxisAlignment: CrossAxisAlignment.start, - // blankSpace: 20.0, - // velocity: 40.0, - // pauseAfterRound: Duration(seconds: 1), - // accelerationDuration: Duration(seconds: 1), - // accelerationCurve: Curves.easeOut, - // decelerationDuration: Duration( - // milliseconds: 500, - // ), - // decelerationCurve: Curves.easeOut, - // ) - // : Text( - // roomRes.roomProfile?.roomName ?? "", - // maxLines: 1, - // overflow: TextOverflow.ellipsis, - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // ), - ), - ), - SizedBox(width: 5.w), - roomRes.roomProfile?.extValues?.existsPassword != true - ? SCRoomLiveAudioIndicator(width: 14.w, height: 14.w) - : Image.asset( - "sc_images/index/sc_icon_room_suo.png", - width: 20.w, - height: 20.w, - ), - roomRes.roomProfile?.extValues?.existsPassword != true - ? SizedBox(width: 3.w) - : Container(height: 10.w), - roomRes.roomProfile?.extValues?.existsPassword != true - ? text( - roomRes.roomProfile?.displayMemberCount ?? "0", - fontSize: 10.sp, - lineHeight: 1, - ) - : Container(height: 10.w), - SizedBox(width: 10.w), - ], - ), - ), - getRoomCoverHeaddress(roomRes).isNotEmpty - ? Transform.translate( - offset: Offset(0, -5.w), - child: Transform.scale( - scaleX: 1.1, - scaleY: 1.12, - child: Image.asset(getRoomCoverHeaddress(roomRes)), - ), - ) - : Container(), - (roomRes.roomProfile?.roomGameIcon?.isNotEmpty ?? false) - ? PositionedDirectional( - top: 8.w, - end: 8.w, - child: netImage( - url: roomRes.roomProfile?.roomGameIcon ?? "", - width: 25.w, - height: 25.w, - borderRadius: BorderRadius.circular(4.w), - ), - ) - : Container(), - ], - ), - ), - onTap: () { - Provider.of(context, listen: false).joinVoiceRoomSession( - context, - roomRes.roomProfile?.id ?? "", - previewData: RoomEntryPreviewData.fromFollowRoom(roomRes), - ); - }, - ); + return SCHomeMineRoomCard(room: roomRes); } @override empty() { - List list = []; - list.add(SizedBox(height: height(30))); - list.add( - Image.asset( - 'sc_images/general/sc_icon_loading.png', - width: 120.w, - height: 120.w, - ), - ); - list.add(SizedBox(height: height(15))); - list.add( - Text( - SCAppLocalizations.of(context)!.noData, - style: TextStyle( - fontSize: sp(14), - color: Color(0xff999999), - fontWeight: FontWeight.w400, - decoration: TextDecoration.none, - height: 1, + return Align( + alignment: Alignment.topCenter, + child: Container( + width: double.infinity, + height: 76.w, + alignment: Alignment.center, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all(color: const Color(0x3306FFC0)), + gradient: const LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: [Color(0x99111A1B), Color(0x992C4D42)], + ), + ), + child: Text( + SCAppLocalizations.of(context)!.noRoomRecordsRecently, + style: TextStyle( + fontSize: 14.sp, + color: Colors.white, + fontWeight: FontWeight.w600, + decoration: TextDecoration.none, + height: 20 / 14, + ), ), ), ); - return Column( - mainAxisSize: MainAxisSize.max, - crossAxisAlignment: CrossAxisAlignment.center, - children: list, - ); - } - - String getRoomCoverHeaddress(FollowRoomRes roomRes) { - return ""; } ///加载数据 diff --git a/lib/modules/home/popular/mine/sc_home_mine_page.dart b/lib/modules/home/popular/mine/sc_home_mine_page.dart index 634c705..3183887 100644 --- a/lib/modules/home/popular/mine/sc_home_mine_page.dart +++ b/lib/modules/home/popular/mine/sc_home_mine_page.dart @@ -9,7 +9,7 @@ import '../../../../services/general/sc_app_general_manager.dart'; import '../../../../services/audio/rtc_manager.dart'; import '../../../../services/room/rc_room_manager.dart'; import '../../../../ui_kit/components/sc_compontent.dart'; -import '../../../../ui_kit/theme/socialchat_theme.dart'; +import '../../../../ui_kit/widgets/sc_home_shell_background.dart'; import '../follow/sc_room_follow_page.dart'; import '../history/sc_room_history_page.dart'; import 'sc_home_mine_skeleton.dart'; @@ -51,72 +51,79 @@ class _HomeMinePageState extends State super.build(context); _tabs.clear(); _tabs.add(Tab(text: SCAppLocalizations.of(context)!.recent)); - _tabs.add(Tab(text: SCAppLocalizations.of(context)!.followed)); - return Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Consumer( - builder: (_, provider, __) { - if (provider.isMyRoomLoading && provider.myRoom == null) { - return const SCHomeSkeletonShimmer( - builder: _buildMineRoomSkeletonContent, + _tabs.add(Tab(text: SCAppLocalizations.of(context)!.joined)); + return Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildSectionLabel(SCAppLocalizations.of(context)!.myRoom), + Consumer( + builder: (_, provider, __) { + if (provider.isMyRoomLoading && provider.myRoom == null) { + return const SCHomeSkeletonShimmer( + builder: _buildMineRoomSkeletonContent, + ); + } + return SizedBox( + width: double.infinity, + height: 85.w, + child: _buildMyRoom(provider), ); - } - return Container( - margin: EdgeInsets.symmetric(horizontal: 12.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - provider.myRoom == null - ? "sc_images/index/sc_icon_my_room_no_bg.png" - : "sc_images/index/sc_icon_my_room_has_bg.png", - ), - fit: BoxFit.fill, - ), - ), - width: ScreenUtil().screenWidth, - height: 85.w, - child: _buildMyRoom(provider), - ); - }, - ), - SizedBox(height: 5.w), - Row( - children: [ - SizedBox(width: 5.w), - TabBar( - tabAlignment: TabAlignment.start, - labelPadding: EdgeInsets.symmetric(horizontal: 12.w), - labelColor: SocialChatTheme.primaryLight, - isScrollable: true, - splashFactory: NoSplash.splashFactory, - overlayColor: WidgetStateProperty.all(Colors.transparent), - indicator: BoxDecoration(), - unselectedLabelColor: Colors.white, - labelStyle: TextStyle( - fontWeight: FontWeight.bold, - fontStyle: FontStyle.italic, - fontSize: 19.sp, - ), - unselectedLabelStyle: TextStyle( - fontWeight: FontWeight.normal, - fontSize: 14.sp, - ), - indicatorColor: Colors.transparent, - dividerColor: Colors.transparent, - controller: _tabController, - tabs: _tabs, - ), - ], - ), - Expanded( - child: TabBarView( - controller: _tabController, - physics: NeverScrollableScrollPhysics(), - children: _pages, + }, ), + SizedBox(height: 10.w), + Row( + children: [ + TabBar( + tabAlignment: TabAlignment.start, + labelPadding: EdgeInsetsDirectional.only(end: 18.w), + labelColor: scHomeShellAccentColor, + isScrollable: true, + splashFactory: NoSplash.splashFactory, + overlayColor: WidgetStateProperty.all(Colors.transparent), + indicator: BoxDecoration(), + unselectedLabelColor: Colors.white, + labelStyle: TextStyle( + fontWeight: FontWeight.bold, + fontSize: 16.sp, + ), + unselectedLabelStyle: TextStyle( + fontWeight: FontWeight.w500, + fontSize: 14.sp, + ), + indicatorColor: Colors.transparent, + dividerColor: Colors.transparent, + controller: _tabController, + tabs: _tabs, + ), + ], + ), + SizedBox(height: 6.w), + Expanded( + child: TabBarView( + controller: _tabController, + physics: NeverScrollableScrollPhysics(), + children: _pages, + ), + ), + ], + ), + ); + } + + Widget _buildSectionLabel(String title) { + return Padding( + padding: EdgeInsetsDirectional.only(start: 8.w, bottom: 10.w), + child: Text( + title, + style: TextStyle( + color: scHomeShellAccentColor, + fontSize: 16.sp, + fontWeight: FontWeight.w800, + height: 1.4, ), - ], + ), ); } @@ -131,61 +138,58 @@ class _HomeMinePageState extends State return provider.myRoom != null ? GestureDetector( behavior: HitTestBehavior.opaque, - child: Row( - children: [ - SizedBox(width: 10.w), - netImage( - url: resolveRoomCoverUrl( - provider.myRoom?.id, - provider.myRoom?.roomCover, + child: _buildMineRoomShell( + child: Row( + children: [ + netImage( + url: resolveRoomCoverUrl( + provider.myRoom?.id, + provider.myRoom?.roomCover, + ), + defaultImg: kRoomCoverDefaultImg, + borderRadius: BorderRadius.all(Radius.circular(12.w)), + width: 56.w, + height: 56.w, ), - defaultImg: kRoomCoverDefaultImg, - borderRadius: BorderRadius.all(Radius.circular(8.w)), - width: 70.w, - ), - SizedBox(width: 10.w), - Expanded( - child: Stack( - children: [ - Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - SizedBox(height: 6.w), - Row( - children: [ - netImage( - url: - Provider.of( - context, - listen: false, - ) - .findCountryByName( - AccountStorage() - .getCurrentUser() - ?.userProfile - ?.countryName ?? - "", - ) - ?.nationalFlag ?? - "", - borderRadius: BorderRadius.all( - Radius.circular(3.w), - ), - width: 19.w, - height: 14.w, + SizedBox(width: 10.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + children: [ + netImage( + url: + Provider.of( + context, + listen: false, + ) + .findCountryByName( + AccountStorage() + .getCurrentUser() + ?.userProfile + ?.countryName ?? + "", + ) + ?.nationalFlag ?? + "", + borderRadius: BorderRadius.all( + Radius.circular(3.w), ), - SizedBox(width: 3.w), - Container( - constraints: BoxConstraints( - maxWidth: 200.w, - maxHeight: 24.w, - ), + width: 19.w, + height: 14.w, + ), + SizedBox(width: 3.w), + Expanded( + child: SizedBox( + height: 20.w, child: (provider.myRoom?.roomName?.length ?? 0) > 18 ? Marquee( text: provider.myRoom?.roomName ?? "", style: TextStyle( - fontSize: 16.sp, + fontSize: 14.sp, color: Colors.white, fontWeight: FontWeight.bold, decoration: TextDecoration.none, @@ -210,32 +214,36 @@ class _HomeMinePageState extends State maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - fontSize: 16.sp, + fontSize: 14.sp, color: Colors.white, fontWeight: FontWeight.bold, decoration: TextDecoration.none, ), ), ), - ], - ), - text( - provider.myRoom?.roomDesc ?? "", - fontSize: 14.sp, - textColor: Colors.white, - ), - text( - "ID:${provider.myRoom?.roomAccount}", - fontSize: 12.sp, - textColor: Colors.white, - ), - ], - ), - ], + ), + ], + ), + text( + provider.myRoom?.roomDesc ?? "", + fontSize: 14.sp, + textColor: Colors.white.withValues(alpha: 0.72), + ), + text( + "ID:${provider.myRoom?.roomAccount}", + fontSize: 10.sp, + textColor: Colors.white.withValues(alpha: 0.64), + ), + ], + ), ), - ), - SizedBox(width: 12.w), - ], + Icon( + Icons.chevron_right, + color: Colors.white.withValues(alpha: 0.92), + size: 26.w, + ), + ], + ), ), onTap: () { final roomManager = Provider.of( @@ -262,51 +270,78 @@ class _HomeMinePageState extends State }, ) : GestureDetector( - child: Row( - children: [ - SizedBox(width: 10.w), - Image.asset( - "sc_images/index/sc_icon_index_creat_room_tag.png", - height: 70.w, - width: 70.w, - ), - SizedBox(width: 10.w), - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - text( - SCAppLocalizations.of(context)!.crateMyRoom, - fontSize: 14.sp, - fontWeight: FontWeight.bold, - textColor: Colors.white, - ), - text( - SCAppLocalizations.of(context)!.startYourBrandNewJourney, - fontSize: 12.sp, - textColor: Colors.white, - ), - ], + child: _buildMineRoomShell( + child: Row( + children: [ + Container( + width: 56.w, + height: 56.w, + alignment: Alignment.center, + decoration: BoxDecoration( + color: scHomeShellAccentColor.withValues(alpha: 0.1), + borderRadius: BorderRadius.circular(12.w), + ), + child: Icon(Icons.add, color: Colors.white, size: 28.w), ), - ), - Image.asset( - "sc_images/index/sc_icon_my_room_tag2.png", - height: 25.w, - width: 25.w, - ), - SizedBox(width: 10.w), - Icon( - Icons.chevron_right_outlined, - color: Colors.white, - size: 20.w, - ), - SizedBox(width: 15.w), - ], + SizedBox(width: 10.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisAlignment: MainAxisAlignment.center, + children: [ + text( + SCAppLocalizations.of(context)!.crateMyRoom, + fontSize: 14.sp, + fontWeight: FontWeight.w800, + textColor: Colors.white, + ), + SizedBox(height: 4.w), + text( + SCAppLocalizations.of( + context, + )!.startYourBrandNewJourney, + fontSize: 10.sp, + textColor: Colors.white, + ), + ], + ), + ), + Image.asset( + "sc_images/index/sc_icon_my_room_tag2.png", + height: 30.w, + width: 30.w, + ), + SizedBox(width: 8.w), + Icon(Icons.chevron_right, color: Colors.white, size: 26.w), + ], + ), ), onTap: () { provider.createNewRoom(context); }, ); } + + Widget _buildMineRoomShell({required Widget child}) { + return Container( + width: double.infinity, + padding: EdgeInsets.all(10.w), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all( + color: scHomeShellAccentColor.withValues(alpha: 0.2), + width: 1.w, + ), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: [ + const Color(0xFF111A1B).withValues(alpha: 0.86), + const Color(0xFF2C4D42).withValues(alpha: 0.72), + ], + ), + ), + child: child, + ); + } } diff --git a/lib/modules/home/popular/mine/sc_home_mine_room_card.dart b/lib/modules/home/popular/mine/sc_home_mine_room_card.dart new file mode 100644 index 0000000..e4cef06 --- /dev/null +++ b/lib/modules/home/popular/mine/sc_home_mine_room_card.dart @@ -0,0 +1,149 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:provider/provider.dart'; +import 'package:yumi/services/audio/rtc_manager.dart'; +import 'package:yumi/services/general/sc_app_general_manager.dart'; +import 'package:yumi/shared/business_logic/models/res/follow_room_res.dart'; +import 'package:yumi/ui_kit/components/sc_compontent.dart'; +import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; +import 'package:yumi/ui_kit/components/text/sc_text.dart'; +import 'package:yumi/ui_kit/widgets/room/room_live_audio_indicator.dart'; + +const Color _kHomeMineRoomAccent = Color(0xFF18F2B1); + +class SCHomeMineRoomCard extends StatelessWidget { + const SCHomeMineRoomCard({super.key, required this.room}); + + final FollowRoomRes room; + + @override + Widget build(BuildContext context) { + final profile = room.roomProfile; + return SCDebounceWidget( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 1, + child: Container( + decoration: BoxDecoration( + color: const Color(0xFF222222), + borderRadius: BorderRadius.circular(12.w), + border: Border.all( + color: _kHomeMineRoomAccent.withValues(alpha: 0.2), + ), + ), + clipBehavior: Clip.antiAlias, + child: ClipRRect( + borderRadius: BorderRadius.circular(12.w), + child: Stack( + children: [ + Positioned.fill( + child: netImage( + url: resolveRoomCoverUrl( + profile?.id, + profile?.roomCover, + ), + defaultImg: kRoomCoverDefaultImg, + fit: BoxFit.cover, + ), + ), + Positioned.fill( + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.w), + border: Border.all( + color: _kHomeMineRoomAccent.withValues(alpha: 0.2), + width: 1.w, + ), + ), + ), + ), + PositionedDirectional( + start: 8.w, + bottom: 9.w, + child: + profile?.extValues?.existsPassword != true + ? Row( + children: [ + SCRoomLiveAudioIndicator( + width: 14.w, + height: 14.w, + ), + SizedBox(width: 3.w), + text( + profile?.displayMemberCount ?? "0", + fontSize: 10.sp, + lineHeight: 1, + ), + ], + ) + : Image.asset( + "sc_images/index/sc_icon_room_suo.png", + width: 20.w, + height: 20.w, + ), + ), + ], + ), + ), + ), + ), + SizedBox(height: 6.w), + Row( + children: [ + Consumer( + builder: (_, provider, __) { + final flagUrl = + _trimToNull(profile?.nationalFlag) ?? + _trimToNull( + provider + .findCountryByName(profile?.countryName ?? "") + ?.nationalFlag, + ); + if (flagUrl == null) { + return const SizedBox.shrink(); + } + return Padding( + padding: EdgeInsetsDirectional.only(end: 4.w), + child: netImage( + url: flagUrl, + width: 22.w, + height: 16.w, + borderRadius: BorderRadius.circular(3.w), + ), + ); + }, + ), + Expanded( + child: Text( + (profile?.roomName ?? "").toUpperCase(), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.w700, + height: 16 / 14, + ), + ), + ), + ], + ), + ], + ), + onTap: () { + Provider.of(context, listen: false).joinVoiceRoomSession( + context, + profile?.id ?? "", + previewData: RoomEntryPreviewData.fromFollowRoom(room), + ); + }, + ); + } +} + +String? _trimToNull(String? value) { + final normalized = value?.trim(); + return normalized == null || normalized.isEmpty ? null : normalized; +} diff --git a/lib/modules/home/popular/party/sc_home_party_page.dart b/lib/modules/home/popular/party/sc_home_party_page.dart index 69be8f6..fcdaf0f 100644 --- a/lib/modules/home/popular/party/sc_home_party_page.dart +++ b/lib/modules/home/popular/party/sc_home_party_page.dart @@ -2,6 +2,7 @@ import 'package:carousel_slider/carousel_slider.dart'; import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:provider/provider.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; @@ -19,7 +20,6 @@ import '../../../../services/home/home_room_preload_manager.dart'; import '../../../../ui_kit/components/sc_compontent.dart'; import '../../../../ui_kit/components/text/sc_text.dart'; import '../../../../ui_kit/widgets/room/room_live_audio_indicator.dart'; -import '../../../../ui_kit/widgets/svga/sc_svga_asset_widget.dart'; import '../../../index/main_route.dart'; const Duration _kPartySkeletonAnimationDuration = Duration(milliseconds: 1450); @@ -28,6 +28,7 @@ const Color _kPartySkeletonShellStrong = Color(0xFF1A4A41); const Color _kPartySkeletonBoneBase = Color(0xFF2B5C53); const Color _kPartySkeletonBoneHighlight = Color(0xFF5F8177); const Color _kPartySkeletonBorder = Color(0x66D8B57B); +const Color _kPartyAccent = Color(0xFF18F2B1); class _RoomCountryFilterOption { const _RoomCountryFilterOption({ @@ -56,11 +57,20 @@ class _HomePartyPageState extends State static const Duration _roomListRefreshInterval = Duration(seconds: 15); static const Duration _roomCounterHydrationMinGap = Duration(seconds: 20); static const int _roomCounterHydrationLimit = 6; - static const List _topRankBorderAssets = [ - "sc_images/index/sc_icon_home_room_rank_border_1.svga", - "sc_images/index/sc_icon_home_room_rank_border_2.svga", - "sc_images/index/sc_icon_home_room_rank_border_3.svga", - ]; + static const String _wealthRankBackgroundAsset = + 'sc_images/index/sc_party_rank_wealth_bg.png'; + static const String _charmRankBackgroundAsset = + 'sc_images/index/sc_party_rank_charm_bg.png'; + static const String _roomRankBackgroundAsset = + 'sc_images/index/sc_party_rank_room_bg.png'; + static const String _rankFrameGoldAsset = + 'sc_images/index/sc_party_rank_frame_gold.png'; + static const String _rankFrameSilverAsset = + 'sc_images/index/sc_party_rank_frame_silver.png'; + static const String _rankFrameBronzeAsset = + 'sc_images/index/sc_party_rank_frame_bronze.png'; + static const String _rankRibbonsAsset = + 'sc_images/index/sc_party_rank_ribbons.svg'; List historyRooms = []; String? lastId; @@ -140,6 +150,7 @@ class _HomePartyPageState extends State }, onLoading: () {}, child: SingleChildScrollView( + padding: EdgeInsets.only(top: 10.w, bottom: 10.w), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -149,7 +160,7 @@ class _HomePartyPageState extends State return const SizedBox.shrink(); } return Padding( - padding: EdgeInsets.only(bottom: 12.w), + padding: EdgeInsets.only(bottom: 8.w), child: Stack( alignment: AlignmentDirectional.center, children: [ @@ -425,7 +436,7 @@ class _HomePartyPageState extends State children: [ CarouselSlider( options: CarouselOptions( - height: 95.w, + height: 100.w, autoPlay: hasMultipleBanners, // 启用自动播放 enlargeCenterPage: false, @@ -448,12 +459,20 @@ class _HomePartyPageState extends State items: banners.map((item) { return GestureDetector( - child: netImage( - url: item.cover ?? "", - height: 95.w, - width: ScreenUtil().screenWidth * 0.9, - fit: BoxFit.fill, - borderRadius: BorderRadius.circular(12.w), + child: Container( + width: ScreenUtil().screenWidth - 20.w, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(12.w), + ), + clipBehavior: Clip.antiAlias, + child: netImage( + url: item.cover ?? "", + height: 100.w, + width: ScreenUtil().screenWidth - 20.w, + fit: BoxFit.cover, + borderRadius: BorderRadius.circular(12.w), + ), ), onTap: () { SCBannerUtils.openBanner(item, context); @@ -466,13 +485,15 @@ class _HomePartyPageState extends State children: banners.asMap().entries.map((entry) { return Container( - width: 6.0, - height: 6.0, - margin: EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0), + width: _currentIndex == entry.key ? 10.w : 4.w, + height: 3.w, + margin: EdgeInsets.symmetric(vertical: 6.w, horizontal: 2.w), decoration: BoxDecoration( - shape: BoxShape.circle, + borderRadius: BorderRadius.circular(999.w), color: - _currentIndex == entry.key ? Colors.blue : Colors.white, + _currentIndex == entry.key + ? _kPartyAccent + : _kPartyAccent.withValues(alpha: 0.45), ), ); }).toList(), @@ -579,113 +600,66 @@ class _HomePartyPageState extends State charmOneAvatar.isEmpty) { return Container(); } - return SizedBox( - height: 130.w, + return Padding( + padding: EdgeInsets.symmetric(horizontal: 10.w), child: Row( children: [ - Expanded( - child: GestureDetector( - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - PositionedDirectional( - start: 26.w, - top: 65.w, - child: head(url: wealthTwoAvatar, width: 30.w), - ), - Positioned( - top: 35.w, - child: head(url: wealthOneAvatar, width: 36.w), - ), - PositionedDirectional( - end: 24.w, - top: 65.w, - child: head(url: wealthThreeAvatar, width: 30.w), - ), - Image.asset( - SCGlobalConfig.businessLogicStrategy - .getPopularLeaderboardBackgroundImage('wealth'), - fit: BoxFit.fill, - ), - ], - ), - onTap: () { - SCNavigatorUtils.push( - context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.wealthRankUrl)}&showTitle=false", - replace: false, - ); - }, - ), + _buildLargeLeaderboardCard( + title: SCAppLocalizations.of(context)!.leaderboardWealth, + borderColor: const Color(0xFF05C58A), + gradientColors: const [Color(0xFF235045), Color(0xFF152121)], + imageAsset: _wealthRankBackgroundAsset, + avatars: [wealthTwoAvatar, wealthOneAvatar, wealthThreeAvatar], + onTap: () { + SCNavigatorUtils.push( + context, + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.wealthRankUrl)}&showTitle=false", + replace: false, + ); + }, ), + SizedBox(width: 11.w), Expanded( - child: GestureDetector( - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - PositionedDirectional( - start: 24.w, - top: 68.w, - child: head(url: roomGiftTwoAvatar, width: 30.w), - ), - Positioned( - top: 35.w, - child: head(url: roomGiftOneAvatar, width: 38.w), - ), - PositionedDirectional( - end: 25.w, - top: 69.w, - child: head(url: roomGiftThreeAvatar, width: 30.w), - ), - Image.asset( - SCGlobalConfig.businessLogicStrategy - .getPopularLeaderboardBackgroundImage('room'), - fit: BoxFit.fill, - ), - ], - ), - onTap: () { - SCNavigatorUtils.push( - context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.roomRankUrl)}&showTitle=false", - replace: false, - ); - }, - ), - ), - Expanded( - child: GestureDetector( - child: Stack( - alignment: AlignmentDirectional.center, - children: [ - PositionedDirectional( - start: 26.w, - top: 66.w, - child: head(url: charmTwoAvatar, width: 30.w), - ), - Positioned( - top: 38.w, - child: head(url: charmOneAvatar, width: 37.w), - ), - PositionedDirectional( - end: 25.w, - top: 66.w, - child: head(url: charmThreeAvatar, width: 30.w), - ), - Image.asset( - SCGlobalConfig.businessLogicStrategy - .getPopularLeaderboardBackgroundImage('charm'), - fit: BoxFit.fill, - ), - ], - ), - onTap: () { - SCNavigatorUtils.push( - context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.charmRankUrl)}&showTitle=false", - replace: false, - ); - }, + child: Column( + children: [ + _buildSmallLeaderboardCard( + title: SCAppLocalizations.of(context)!.leaderboardCharm, + borderColor: const Color(0xFF6800E1), + gradientColors: const [Color(0x99632CBA), Color(0x998747CB)], + imageAsset: _charmRankBackgroundAsset, + imageTop: -3, + imageEnd: 13, + avatars: [charmTwoAvatar, charmOneAvatar, charmThreeAvatar], + onTap: () { + SCNavigatorUtils.push( + context, + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.charmRankUrl)}&showTitle=false", + replace: false, + ); + }, + ), + SizedBox(height: 10.w), + _buildSmallLeaderboardCard( + title: SCAppLocalizations.of(context)!.leaderboardRoom, + borderColor: const Color(0xFF0A88F5), + gradientColors: const [Color(0xCC2169A3), Color(0xCC2F7F9D)], + imageAsset: _roomRankBackgroundAsset, + imageTop: 2, + imageEnd: 8, + avatars: [ + roomGiftTwoAvatar, + roomGiftOneAvatar, + roomGiftThreeAvatar, + ], + onTap: () { + SCNavigatorUtils.push( + context, + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.roomRankUrl)}&showTitle=false", + replace: false, + ); + }, + ), + ], ), ), ], @@ -693,6 +667,221 @@ class _HomePartyPageState extends State ); } + Widget _buildLargeLeaderboardCard({ + required String title, + required Color borderColor, + required List gradientColors, + required String imageAsset, + required List avatars, + required VoidCallback onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Container( + width: 172.w, + height: 130.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all(color: borderColor, width: 1.w), + gradient: LinearGradient( + begin: Alignment.topLeft, + end: Alignment.bottomRight, + colors: gradientColors, + ), + ), + clipBehavior: Clip.antiAlias, + child: Stack( + children: [ + Positioned( + left: 0, + top: -6.w, + width: 172.w, + height: 172.w, + child: Image.asset(imageAsset, fit: BoxFit.contain), + ), + _buildLeaderboardTitle(title, borderColor), + PositionedDirectional( + start: 25.w, + bottom: 6.w, + width: 123.w, + height: 16.w, + child: SvgPicture.asset(_rankRibbonsAsset, fit: BoxFit.fill), + ), + PositionedDirectional( + start: 8.w, + bottom: 12.w, + child: _buildLeaderboardAvatar( + avatar: avatars[0], + size: 45.w, + avatarSize: 43.w, + frameAsset: _rankFrameSilverAsset, + ), + ), + Positioned( + left: 0, + right: 0, + bottom: 20.w, + child: Center( + child: _buildLeaderboardAvatar( + avatar: avatars[1], + size: 55.w, + avatarSize: 50.w, + frameAsset: _rankFrameGoldAsset, + ), + ), + ), + PositionedDirectional( + end: 9.w, + bottom: 12.w, + child: _buildLeaderboardAvatar( + avatar: avatars[2], + size: 45.w, + avatarSize: 43.w, + frameAsset: _rankFrameBronzeAsset, + ), + ), + ], + ), + ), + ); + } + + Widget _buildSmallLeaderboardCard({ + required String title, + required Color borderColor, + required List gradientColors, + required String imageAsset, + required double imageTop, + required double imageEnd, + required List avatars, + required VoidCallback onTap, + }) { + return GestureDetector( + onTap: onTap, + child: Container( + height: 60.w, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(14.w), + border: Border.all(color: borderColor, width: 1.w), + gradient: LinearGradient( + begin: Alignment.centerLeft, + end: Alignment.centerRight, + colors: gradientColors, + ), + ), + clipBehavior: Clip.antiAlias, + child: Stack( + children: [ + PositionedDirectional( + end: imageEnd.w, + top: imageTop.w, + width: 66.w, + height: 66.w, + child: Image.asset(imageAsset, fit: BoxFit.contain), + ), + _buildLeaderboardTitle(title, borderColor), + PositionedDirectional( + start: 10.w, + bottom: 6.w, + child: Row( + children: List.generate(avatars.length, (index) { + const frameAssets = [ + _rankFrameSilverAsset, + _rankFrameGoldAsset, + _rankFrameBronzeAsset, + ]; + return Padding( + padding: EdgeInsetsDirectional.only( + end: index == avatars.length - 1 ? 0 : 3.2.w, + ), + child: _buildLeaderboardAvatar( + avatar: avatars[index], + size: 24.w, + avatarSize: 22.w, + frameAsset: frameAssets[index], + ), + ); + }), + ), + ), + ], + ), + ), + ); + } + + Widget _buildLeaderboardAvatar({ + required String avatar, + required double size, + required double avatarSize, + required String frameAsset, + }) { + final url = avatar.trim(); + final avatarWidget = + url.isEmpty + ? ClipOval( + child: Image.asset( + 'sc_images/general/sc_icon_avar_defalt.png', + width: avatarSize, + height: avatarSize, + fit: BoxFit.cover, + ), + ) + : head( + url: url, + width: avatarSize, + height: avatarSize, + fit: BoxFit.cover, + gifFit: BoxFit.cover, + ); + return SizedBox( + width: size, + height: size, + child: Stack( + alignment: Alignment.center, + children: [ + avatarWidget, + Positioned.fill( + child: IgnorePointer( + child: Image.asset(frameAsset, fit: BoxFit.contain), + ), + ), + ], + ), + ); + } + + Widget _buildLeaderboardTitle(String title, Color color) { + return PositionedDirectional( + start: 0, + top: 0, + child: Container( + height: 20.w, + constraints: BoxConstraints(minWidth: 70.w, maxWidth: 90.w), + padding: EdgeInsetsDirectional.only(start: 10.w, end: 14.w), + alignment: AlignmentDirectional.centerStart, + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadiusDirectional.only( + bottomEnd: Radius.circular(8.w), + ), + ), + child: Text( + title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: const Color(0xFFDEFFF7), + fontSize: 14.sp, + fontStyle: FontStyle.italic, + fontWeight: FontWeight.w800, + height: 1, + ), + ), + ), + ); + } + Widget _buildRoomsSection() { if (!_hasCompletedInitialRoomLoad && isLoading && rooms.isEmpty) { return _buildRoomGridSkeleton(); @@ -730,9 +919,9 @@ class _HomePartyPageState extends State physics: const NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 2, - childAspectRatio: 1, - mainAxisSpacing: 10, - crossAxisSpacing: 10, + childAspectRatio: 172 / 200, + mainAxisSpacing: 8.w, + crossAxisSpacing: 10.w, ), padding: EdgeInsets.fromLTRB(10.w, 8.w, 10.w, 10.w), itemCount: visibleRooms.length, @@ -751,15 +940,15 @@ class _HomePartyPageState extends State return const SizedBox.shrink(); } return Padding( - padding: EdgeInsetsDirectional.fromSTEB(0, 10.w, 0, 8.w), + padding: EdgeInsetsDirectional.fromSTEB(0, 10.w, 0, 0), child: SizedBox( - height: 26.w, + height: 28.w, child: ListView.separated( scrollDirection: Axis.horizontal, physics: const BouncingScrollPhysics(), padding: EdgeInsetsDirectional.symmetric(horizontal: 10.w), itemCount: countryOptions.length + 1, - separatorBuilder: (context, index) => SizedBox(width: 5.w), + separatorBuilder: (context, index) => SizedBox(width: 8.w), itemBuilder: (context, index) { if (index == 0) { return _buildCountryFilterChip( @@ -811,37 +1000,26 @@ class _HomePartyPageState extends State child: AnimatedContainer( duration: const Duration(milliseconds: 180), curve: Curves.easeOut, - height: 24.w, - constraints: BoxConstraints(minWidth: 45.w, maxWidth: 95.w), + height: 28.w, + constraints: BoxConstraints(minWidth: countryKey == null ? 63.w : 0), alignment: AlignmentDirectional.center, - padding: EdgeInsets.symmetric(horizontal: 8.w), + padding: EdgeInsets.symmetric(horizontal: 14.w), decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: - isSelected - ? const [Color(0xFF5C4430), Color(0xFF231B14)] - : [ - Colors.black.withValues(alpha: 0.34), - const Color(0xFF0F3730).withValues(alpha: 0.38), - ], - ), + color: + isSelected + ? Colors.transparent + : const Color(0xFF06392C).withValues(alpha: 0.86), borderRadius: BorderRadius.circular(999.w), border: Border.all( - color: - isSelected - ? const Color(0xFFE8C681) - : const Color(0x66D8B57B), + color: isSelected ? _kPartyAccent : Colors.transparent, width: 1.w, ), boxShadow: isSelected ? [ BoxShadow( - color: const Color(0xFFE8C681).withValues(alpha: 0.16), - blurRadius: 5.w, - offset: Offset(0, 2.w), + color: _kPartyAccent.withValues(alpha: 0.18), + blurRadius: 6.w, ), ] : null, @@ -869,13 +1047,10 @@ class _HomePartyPageState extends State textAlign: TextAlign.center, textDirection: Directionality.of(context), style: TextStyle( - color: - isSelected - ? const Color(0xFFFFE4A3) - : Colors.white.withValues(alpha: 0.92), - fontSize: 8.sp, - fontWeight: - isSelected ? FontWeight.w700 : FontWeight.w500, + color: _kPartyAccent, + fontSize: 12.sp, + fontWeight: FontWeight.w500, + height: 1, ), ), ), @@ -1267,161 +1442,113 @@ class _HomePartyPageState extends State } _buildItem(SocialChatRoomRes res, int index) { - final rankBorderAsset = - index < _topRankBorderAssets.length - ? _topRankBorderAssets[index] - : null; - final rankBorderOverflow = 12.w; - final rankInfoHorizontalInset = rankBorderAsset != null ? 10.w : 0.w; - final rankInfoBottomInset = rankBorderAsset != null ? 9.w : 0.w; return SCDebounceWidget( - child: Container( - margin: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w), - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(12.w), - color: Colors.transparent, - ), - child: Stack( - clipBehavior: Clip.none, - alignment: Alignment.bottomCenter, - children: [ - Container( - padding: EdgeInsets.all(3.w), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + AspectRatio( + aspectRatio: 1, + child: Container( decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("sc_images/index/sc_icon_room_bord.png"), - fit: BoxFit.fill, - ), - ), - child: netImage( - url: resolveRoomCoverUrl(res.id, res.roomCover), - defaultImg: kRoomCoverDefaultImg, + color: const Color(0xFF222222), borderRadius: BorderRadius.circular(12.w), - width: 200.w, - height: 200.w, + border: Border.all(color: _kPartyAccent.withAlpha(51)), ), - ), - Padding( - padding: EdgeInsets.only( - left: rankInfoHorizontalInset, - right: rankInfoHorizontalInset, - bottom: rankInfoBottomInset, - ), - child: Container( - padding: EdgeInsets.symmetric(vertical: 6.w), - margin: EdgeInsets.symmetric(horizontal: 1.w), - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "sc_images/index/sc_icon_index_room_brd.png", - ), - fit: BoxFit.fill, - ), - ), - child: Row( + clipBehavior: Clip.antiAlias, + child: ClipRRect( + borderRadius: BorderRadius.circular(12.w), + child: Stack( children: [ - SizedBox(width: 10.w), - Consumer( - builder: (_, provider, __) { - return netImage( - url: - "${provider.findCountryByName(res.countryName ?? "")?.nationalFlag}", - width: 20.w, - height: 13.w, - borderRadius: BorderRadius.circular(2.w), - ); - }, - ), - SizedBox(width: 5.w), - Expanded( - child: SizedBox( - height: 17.w, - child: Align( - alignment: Alignment.centerLeft, - child: Transform.translate( - offset: Offset(0, -0.6.w), - child: text( - res.roomName ?? "", - fontSize: 13.sp, - textColor: Color(0xffffffff), - fontWeight: FontWeight.w400, - lineHeight: 1, - ), - ), - ), - // (roomRes.roomProfile?.roomName?.length ?? 0) > 10 - // ? Marquee( - // text: roomRes.roomProfile?.roomName ?? "", - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // scrollAxis: Axis.horizontal, - // crossAxisAlignment: CrossAxisAlignment.start, - // blankSpace: 20.0, - // velocity: 40.0, - // pauseAfterRound: Duration(seconds: 1), - // accelerationDuration: Duration(seconds: 1), - // accelerationCurve: Curves.easeOut, - // decelerationDuration: Duration( - // milliseconds: 500, - // ), - // decelerationCurve: Curves.easeOut, - // ) - // : Text( - // roomRes.roomProfile?.roomName ?? "", - // maxLines: 1, - // overflow: TextOverflow.ellipsis, - // style: TextStyle( - // fontSize: 15.sp, - // color: Color(0xffffffff), - // fontWeight: FontWeight.w400, - // decoration: TextDecoration.none, - // ), - // ), + Positioned.fill( + child: netImage( + url: resolveRoomCoverUrl(res.id, res.roomCover), + defaultImg: kRoomCoverDefaultImg, + fit: BoxFit.cover, ), ), - SizedBox(width: 5.w), - res.extValues?.existsPassword != true - ? SCRoomLiveAudioIndicator(width: 14.w, height: 14.w) - : Image.asset( - "sc_images/index/sc_icon_room_suo.png", - width: 20.w, - height: 20.w, + Positioned.fill( + child: DecoratedBox( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(12.w), + border: Border.all( + color: _kPartyAccent.withValues(alpha: 0.2), + width: 1.w, + ), ), - res.extValues?.existsPassword != true - ? SizedBox(width: 3.w) - : Container(height: 10.w), - res.extValues?.existsPassword != true - ? text( - res.displayMemberCount, - fontSize: 10.sp, - lineHeight: 1, - ) - : Container(height: 10.w), - SizedBox(width: 10.w), + ), + ), + PositionedDirectional( + start: 8.w, + bottom: 9.w, + child: + res.extValues?.existsPassword != true + ? Row( + children: [ + SCRoomLiveAudioIndicator( + width: 14.w, + height: 14.w, + ), + SizedBox(width: 3.w), + text( + res.displayMemberCount, + fontSize: 10.sp, + lineHeight: 1, + ), + ], + ) + : Image.asset( + "sc_images/index/sc_icon_room_suo.png", + width: 20.w, + height: 20.w, + ), + ), ], ), ), ), - if (rankBorderAsset != null) - Positioned.fill( - top: -rankBorderOverflow, - left: -rankBorderOverflow, - right: -rankBorderOverflow, - bottom: -rankBorderOverflow, - child: SCSvgaAssetWidget( - assetPath: rankBorderAsset, - active: true, - loop: true, - fit: BoxFit.fill, - allowDrawingOverflow: true, + ), + SizedBox(height: 6.w), + Row( + children: [ + Consumer( + builder: (_, provider, __) { + final flagUrl = + _trimToNull(res.nationalFlag) ?? + _trimToNull( + provider + .findCountryByName(res.countryName ?? "") + ?.nationalFlag, + ); + if (flagUrl == null) { + return const SizedBox.shrink(); + } + return Padding( + padding: EdgeInsetsDirectional.only(end: 4.w), + child: netImage( + url: flagUrl, + width: 22.w, + height: 16.w, + borderRadius: BorderRadius.circular(3.w), + ), + ); + }, + ), + Expanded( + child: Text( + (res.roomName ?? "").toUpperCase(), + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, + fontSize: 14.sp, + fontWeight: FontWeight.w700, + height: 16 / 14, + ), ), ), - ], - ), + ], + ), + ], ), onTap: () { Provider.of(context, listen: false).joinVoiceRoomSession( diff --git a/lib/modules/index/index_page.dart b/lib/modules/index/index_page.dart index 5839ec9..659a0bc 100644 --- a/lib/modules/index/index_page.dart +++ b/lib/modules/index/index_page.dart @@ -15,13 +15,13 @@ import 'package:yumi/services/audio/rtm_manager.dart'; import 'package:provider/provider.dart'; import 'package:wakelock_plus/wakelock_plus.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; +import 'package:yumi/ui_kit/widgets/sc_home_shell_background.dart'; import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/tools/sc_dialog_utils.dart'; import 'package:yumi/services/general/sc_app_general_manager.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; -import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart'; import '../../shared/tools/sc_heartbeat_utils.dart'; import '../../shared/tools/sc_entry_popup_coordinator.dart'; import '../../shared/tools/sc_lk_event_bus.dart'; @@ -175,7 +175,8 @@ class _SCIndexPageState extends State if (!mounted && visible) { return; } - OverlayManager().setHomeRootTabsVisible(visible); + final tabAllowsFloating = _currentIndex == 0 || _currentIndex == 2; + OverlayManager().setHomeRootTabsVisible(visible && tabAllowsFloating); if (visible) { unawaited( Provider.of( @@ -201,58 +202,46 @@ class _SCIndexPageState extends State }, child: Stack( children: [ - Image.asset( - "sc_images/index/sc_icon_index_bg.png", - width: ScreenUtil().screenWidth, - height: ScreenUtil().screenHeight, - fit: BoxFit.fill, - ), - SafeArea( - top: false, - child: Scaffold( - resizeToAvoidBottomInset: false, - backgroundColor: Colors.transparent, - body: _buildCachedBody(), - bottomNavigationBar: Container( - height: 85.w, - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage( - "sc_images/index/sc_index_bottom_navigation_bar_bg.png", + const Positioned.fill(child: SCHomeShellBackground()), + Scaffold( + resizeToAvoidBottomInset: false, + backgroundColor: Colors.transparent, + body: _buildCachedBody(), + bottomNavigationBar: Builder( + builder: (context) { + final bottomInset = MediaQuery.viewPaddingOf(context).bottom; + return Container( + height: 72.w + bottomInset, + decoration: BoxDecoration( + color: const Color(0xFF06291F).withValues(alpha: 0.96), + borderRadius: BorderRadius.vertical( + top: Radius.circular(10.w), ), - fit: BoxFit.fill, - ), - ), - child: Theme( - data: Theme.of(context).copyWith( - splashFactory: NoSplash.splashFactory, - splashColor: Colors.transparent, - highlightColor: Colors.transparent, - hoverColor: Colors.transparent, - ), - child: BottomNavigationBar( - elevation: 0, - enableFeedback: false, - backgroundColor: Colors.transparent, - selectedLabelStyle: TextStyle( - fontWeight: FontWeight.w600, - fontSize: 14.sp, + border: Border( + top: BorderSide( + color: scHomeShellAccentColor.withValues(alpha: 0.72), + width: 1.w, + ), + left: BorderSide( + color: scHomeShellAccentColor.withValues(alpha: 0.72), + width: 1.w, + ), + right: BorderSide( + color: scHomeShellAccentColor.withValues(alpha: 0.72), + width: 1.w, + ), ), - unselectedLabelStyle: TextStyle( - fontWeight: FontWeight.w500, - fontSize: 13.sp, - ), - type: BottomNavigationBarType.fixed, - selectedItemColor: Color(0xffBF854A), - unselectedItemColor: Color(0xffC4C4C4), - showUnselectedLabels: true, - showSelectedLabels: true, - items: _bottomItems, - currentIndex: _currentIndex, - onTap: _switchBottomTab, + boxShadow: [ + BoxShadow( + color: Colors.black.withValues(alpha: 0.26), + blurRadius: 18.w, + offset: Offset(0, -6.w), + ), + ], ), - ), - ), + child: _buildCustomBottomNavigation(bottomInset), + ); + }, ), ), ], @@ -307,6 +296,79 @@ class _SCIndexPageState extends State ); } + Widget _buildCustomBottomNavigation(double bottomInset) { + return Theme( + data: Theme.of(context).copyWith( + splashFactory: NoSplash.splashFactory, + splashColor: Colors.transparent, + highlightColor: Colors.transparent, + hoverColor: Colors.transparent, + ), + child: Stack( + clipBehavior: Clip.none, + children: [ + PositionedDirectional( + start: 0, + end: 0, + top: 0, + height: 72.w, + child: Row( + children: List.generate(_bottomItems.length, (index) { + return Expanded(child: _buildCustomBottomTab(index)); + }), + ), + ), + PositionedDirectional( + start: 0, + end: 0, + bottom: 0, + height: bottomInset, + child: const SizedBox.shrink(), + ), + ], + ), + ); + } + + Widget _buildCustomBottomTab(int index) { + final item = _bottomItems[index]; + final active = index == _currentIndex; + return GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => _switchBottomTab(index), + child: SizedBox( + height: 72.w, + child: Stack( + clipBehavior: Clip.none, + alignment: Alignment.topCenter, + children: [ + Positioned(top: 0, child: active ? item.activeIcon : item.icon), + PositionedDirectional( + start: 0, + end: 0, + bottom: 4.w, + child: Text( + item.label ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: TextStyle( + color: + active + ? scHomeShellGoldColor + : Colors.white.withValues(alpha: 0.84), + fontSize: active ? 14.sp : 10.sp, + fontWeight: active ? FontWeight.w600 : FontWeight.w500, + height: 1, + ), + ), + ), + ], + ), + ), + ); + } + void _switchBottomTab(int index) { if (AccountStorage().isGuestMode && index != 0) { // 任务、消息和“我的”均为账号能力,游客点击时再引导登录。 @@ -324,6 +386,7 @@ class _SCIndexPageState extends State _currentIndexNotifier.value = index; _builtPageIndexes.add(index); }); + _setHomeRootTabsVisible(_routeObserverRoute?.isCurrent ?? true); } void _rebuildBottomItemsIfNeeded() { @@ -338,13 +401,11 @@ class _SCIndexPageState extends State BottomNavigationBarItem( icon: _buildBottomTabIcon( active: false, - svgaPath: "sc_images/index/sc_icon_home_anim.svga", - fallbackPath: "sc_images/index/sc_icon_home_no.png", + fallbackPath: "sc_images/index/sc_tab_room_off.png", ), activeIcon: _buildBottomTabIcon( active: true, - svgaPath: "sc_images/index/sc_icon_home_anim.svga", - fallbackPath: "sc_images/index/sc_icon_home_en.png", + fallbackPath: "sc_images/index/sc_tab_room_on.png", ), label: SCAppLocalizations.of(context)!.home, ), @@ -375,14 +436,12 @@ class _SCIndexPageState extends State alignment: AlignmentDirectional.topEnd, child: _buildBottomTabIcon( active: false, - svgaPath: "sc_images/index/sc_icon_message_anim.svga", - fallbackPath: "sc_images/index/sc_icon_message_no.png", + fallbackPath: "sc_images/index/sc_tab_chat_off.png", ), ) : _buildBottomTabIcon( active: false, - svgaPath: "sc_images/index/sc_icon_message_anim.svga", - fallbackPath: "sc_images/index/sc_icon_message_no.png", + fallbackPath: "sc_images/index/sc_tab_chat_off.png", ); }, ), @@ -402,14 +461,12 @@ class _SCIndexPageState extends State alignment: AlignmentDirectional.topEnd, child: _buildBottomTabIcon( active: true, - svgaPath: "sc_images/index/sc_icon_message_anim.svga", - fallbackPath: "sc_images/index/sc_icon_message_en.png", + fallbackPath: "sc_images/index/sc_tab_chat_on.png", ), ) : _buildBottomTabIcon( active: true, - svgaPath: "sc_images/index/sc_icon_message_anim.svga", - fallbackPath: "sc_images/index/sc_icon_message_en.png", + fallbackPath: "sc_images/index/sc_tab_chat_on.png", ); }, ), @@ -420,13 +477,11 @@ class _SCIndexPageState extends State BottomNavigationBarItem( icon: _buildBottomTabIcon( active: false, - svgaPath: "sc_images/index/sc_icon_me_anim.svga", - fallbackPath: "sc_images/index/sc_icon_me_no.png", + fallbackPath: "sc_images/index/sc_tab_me_off.png", ), activeIcon: _buildBottomTabIcon( active: true, - svgaPath: "sc_images/index/sc_icon_me_anim.svga", - fallbackPath: "sc_images/index/sc_icon_me_en.png", + fallbackPath: "sc_images/index/sc_tab_me_on.png", ), label: SCAppLocalizations.of(context)!.me, ), @@ -614,16 +669,19 @@ class _SCIndexPageState extends State Widget _buildBottomTabIcon({ required bool active, - required String svgaPath, required String fallbackPath, }) { - return SCSvgaAssetWidget( - assetPath: svgaPath, - width: 35.w, - height: 35.w, - active: active, - loop: false, - fallback: Image.asset(fallbackPath, width: 35.w, height: 35.w), + return SizedBox( + width: 50.w, + height: 50.w, + child: Center( + child: Image.asset( + fallbackPath, + width: 50.w, + height: 50.w, + fit: BoxFit.contain, + ), + ), ); } @@ -633,11 +691,10 @@ class _SCIndexPageState extends State builder: (_, claimableCount, __) { final icon = _buildBottomTabIcon( active: active, - svgaPath: "sc_images/index/sc_icon_explore_anim.svga", fallbackPath: active - ? "sc_images/index/sc_icon_explore_en.png" - : "sc_images/index/sc_icon_explore_no.png", + ? "sc_images/index/sc_tab_task_on.png" + : "sc_images/index/sc_tab_task_off.png", ); if (claimableCount <= 0) { return icon; diff --git a/lib/modules/index/main_route.dart b/lib/modules/index/main_route.dart index 0523a15..8aaea84 100644 --- a/lib/modules/index/main_route.dart +++ b/lib/modules/index/main_route.dart @@ -211,6 +211,7 @@ class SCMainRoute implements SCIRouterProvider { title: params['title']?.first ?? "", url: decodedUrl, showTitle: params['showTitle']?.first ?? "", + safeTop: params['safeTop']?.first == "true", ); }, ), diff --git a/lib/modules/room/chat/all/all_chat_page.dart b/lib/modules/room/chat/all/all_chat_page.dart index 6f3ce3e..87488b7 100644 --- a/lib/modules/room/chat/all/all_chat_page.dart +++ b/lib/modules/room/chat/all/all_chat_page.dart @@ -138,7 +138,7 @@ class _AllChatPageState extends State { children: [ Text( SCAppLocalizations.of(context)!.scrollToTheBottom, - style: TextStyle(fontSize: 10.sp), + style: TextStyle(fontSize: 10.sp, color: Colors.black), ), SizedBox(width: 4.w), Icon(Icons.chevron_right, size: 10.w), diff --git a/lib/modules/room/chat/chat/chat_page.dart b/lib/modules/room/chat/chat/chat_page.dart index dcf2179..b4ee388 100644 --- a/lib/modules/room/chat/chat/chat_page.dart +++ b/lib/modules/room/chat/chat/chat_page.dart @@ -137,7 +137,7 @@ class _ChatPageState extends State { children: [ Text( SCAppLocalizations.of(context)!.scrollToTheBottom, - style: TextStyle(fontSize: 10.sp), + style: TextStyle(fontSize: 10.sp, color: Colors.black), ), SizedBox(width: 4.w), Icon(Icons.chevron_right, size: 10.w), diff --git a/lib/modules/room/chat/gift/gift_chat_page.dart b/lib/modules/room/chat/gift/gift_chat_page.dart index 63cb977..d0d54b2 100644 --- a/lib/modules/room/chat/gift/gift_chat_page.dart +++ b/lib/modules/room/chat/gift/gift_chat_page.dart @@ -130,7 +130,7 @@ class _GiftChatPageState extends State { children: [ Text( SCAppLocalizations.of(context)!.scrollToTheBottom, - style: TextStyle(fontSize: 10.sp), + style: TextStyle(fontSize: 10.sp, color: Colors.black), ), SizedBox(width: 4.w), Icon(Icons.chevron_right, size: 10.w), diff --git a/lib/modules/room/seat/sc_seat_item.dart b/lib/modules/room/seat/sc_seat_item.dart index d517ab6..7653e4e 100644 --- a/lib/modules/room/seat/sc_seat_item.dart +++ b/lib/modules/room/seat/sc_seat_item.dart @@ -619,15 +619,12 @@ class _EmoticonsState extends State with TickerProviderStateMixin { if (path.isEmpty) { return SizedBox(width: width, height: width); } - if (path.startsWith("assets/") || path.startsWith("sc_images/")) { - return RoomEmojiAssetImage( - key: ValueKey(path), - asset: path, - width: width, - height: width, - ); - } - return netImage(url: path, width: width); + return RoomEmojiAssetImage( + key: ValueKey(path), + asset: path, + width: width, + height: width, + ); } void _checkStart() { diff --git a/lib/modules/room/voice_room_page.dart b/lib/modules/room/voice_room_page.dart index 7c6387b..63c709a 100644 --- a/lib/modules/room/voice_room_page.dart +++ b/lib/modules/room/voice_room_page.dart @@ -175,6 +175,7 @@ class _VoiceRoomPageState extends State void _handleRoomRouteVisible() { _releaseCoveredRouteGuard(); _setRoomRouteVisible(true); + _scheduleEnsureRoomVisualEffectsEnabled(); } void _scheduleRoomRouteVisible() { @@ -253,9 +254,15 @@ class _VoiceRoomPageState extends State void _ensureRoomVisualEffectsEnabled() { final rtcProvider = Provider.of(context, listen: false); - if (rtcProvider.currenRoom == null || - !_roomRouteVisible || - rtcProvider.roomVisualEffectsEnabled) { + if (rtcProvider.currenRoom == null || !_roomRouteVisible) { + return; + } + final rtmProvider = Provider.of(context, listen: false); + final needsListenerRebind = + rtmProvider.msgFloatingGiftListener != _floatingGiftListener || + rtmProvider.msgLuckyGiftRewardTickerListener != + _luckyGiftRewardTickerListener; + if (rtcProvider.roomVisualEffectsEnabled && !needsListenerRebind) { return; } _enableRoomVisualEffects(); diff --git a/lib/modules/user/me_page2.dart b/lib/modules/user/me_page2.dart index 795d265..026b92c 100644 --- a/lib/modules/user/me_page2.dart +++ b/lib/modules/user/me_page2.dart @@ -3,6 +3,7 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; +import 'package:flutter_svg/flutter_svg.dart'; import 'package:provider/provider.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; @@ -13,6 +14,7 @@ import 'package:yumi/modules/user/settings/settings_route.dart'; import 'package:yumi/modules/user/vip/vip_route.dart'; import 'package:yumi/modules/wallet/wallet_route.dart'; import 'package:yumi/services/auth/user_profile_manager.dart'; +import 'package:yumi/services/general/sc_app_general_manager.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart'; import 'package:yumi/shared/business_logic/models/res/sc_vip_res.dart'; @@ -23,7 +25,7 @@ import 'package:yumi/shared/tools/sc_lk_event_bus.dart'; import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:yumi/ui_kit/widgets/id/sc_special_id_badge.dart'; -import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart'; +import 'package:yumi/ui_kit/widgets/sc_home_shell_background.dart'; class MePage2 extends StatefulWidget { const MePage2({super.key, this.currentIndexListenable, this.tabIndex = 3}); @@ -41,7 +43,6 @@ class _MePage2State extends State with WidgetsBindingObserver { 'https://h5.global-interaction.com/activity/cp-space/yumi.html'; static const String _inviteActivityUrl = 'https://h5.haiyihy.com/app-invite/index.html'; - static const double _inviteActivityHorizontalScale = 750 / 662; Map _counterMap = {}; SCVipStatusRes? _vipStatus; @@ -330,56 +331,79 @@ class _MePage2State extends State with WidgetsBindingObserver { @override Widget build(BuildContext context) { - return SafeArea( - top: true, - bottom: false, - child: Consumer( - builder: (context, profileManager, child) { - return SingleChildScrollView( - physics: const BouncingScrollPhysics(), - padding: EdgeInsets.fromLTRB(10.w, 12.w, 10.w, 24.w), - child: Column( - children: [ - _buildProfileSection(profileManager), - SizedBox(height: 12.w), - _buildStatsCard(), - SizedBox(height: 12.w), - _buildEntryRow(), - SizedBox(height: 12.w), - _buildWalletVipRow(profileManager), - _buildInviteActivityBanner(), - _buildMenuCard2(), - SizedBox(height: 12.w), - _buildMenuCard([ - _MenuRowData( - title: SCAppLocalizations.of(context)!.settings, - assetIcon: 'sc_images/index/sc_icon_settings.png', - onTap: () { - SCNavigatorUtils.push( - context, - SettingsRoute.settings, - replace: false, - ); - }, - ), - _MenuRowData( - title: SCAppLocalizations.of(context)!.language, - assetIcon: 'sc_images/general/sc_icon_setting_language.png', - onTap: () { - SCNavigatorUtils.push(context, SCMainRoute.language); - }, - ), - ]), - ], - ), - ); - }, - ), + return Stack( + fit: StackFit.expand, + children: [ + const Positioned.fill(child: SCHomeShellBackground()), + SafeArea( + top: true, + bottom: false, + child: Consumer( + builder: (context, profileManager, child) { + return SingleChildScrollView( + physics: const BouncingScrollPhysics(), + padding: EdgeInsets.fromLTRB(10.w, 10.w, 10.w, 24.w), + child: Column( + children: [ + Consumer( + builder: (context, generalManager, child) { + final profile = profileManager.currentUserProfile; + final country = + generalManager.findCountryByName( + profile?.countryName ?? '', + ) ?? + generalManager.findCountryByCode( + profile?.countryCode ?? '', + ); + final flagUrl = country?.nationalFlag?.trim() ?? ''; + return _buildProfileSection( + profileManager, + flagUrl: flagUrl, + ); + }, + ), + SizedBox(height: 12.w), + _buildStatsCard(), + SizedBox(height: 14.w), + _buildProfileActionPanel(profileManager), + SizedBox(height: 18.w), + _buildMenuGridCard([ + ..._identityMenuItems(profileManager), + _MenuRowData( + title: SCAppLocalizations.of(context)!.settings, + assetIcon: 'sc_images/index/sc_icon_me_settings.svg', + onTap: () { + SCNavigatorUtils.push( + context, + SettingsRoute.settings, + replace: false, + ); + }, + ), + _MenuRowData( + title: SCAppLocalizations.of(context)!.language, + assetIcon: 'sc_images/index/sc_icon_me_language.svg', + onTap: () { + SCNavigatorUtils.push(context, SCMainRoute.language); + }, + ), + ]), + ], + ), + ); + }, + ), + ), + ], ); } - Widget _buildProfileSection(SocialChatUserProfileManager profileManager) { + Widget _buildProfileSection( + SocialChatUserProfileManager profileManager, { + required String flagUrl, + }) { final profile = profileManager.currentUserProfile; + final avatarUrl = profile?.userAvatar?.trim() ?? ''; return SCDebounceWidget( onTap: () { @@ -389,119 +413,202 @@ class _MePage2State extends State with WidgetsBindingObserver { replace: false, ); }, - child: Column( + child: Row( children: [ - SizedBox( - width: 240.w, - height: 130.w, - child: Stack( - alignment: Alignment.topCenter, + head( + url: avatarUrl, + width: 72.w, + height: 72.w, + shape: BoxShape.circle, + headdress: + avatarUrl.isEmpty ? null : profile?.getHeaddress()?.sourceUrl, + headdressCover: + avatarUrl.isEmpty ? null : profile?.getHeaddress()?.cover, + showDefault: true, + ), + SizedBox(width: 24.w), + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - head( - url: profile?.userAvatar ?? '', - width: 96.w, - height: 96.w, - shape: BoxShape.circle, - border: Border.all(color: Colors.white, width: 1), - headdress: profile?.getHeaddress()?.sourceUrl, - headdressCover: profile?.getHeaddress()?.cover, - showDefault: true, + Row( + children: [ + if (flagUrl.isNotEmpty) ...[ + netImage( + url: flagUrl, + width: 20.w, + height: 14.w, + fit: BoxFit.cover, + noDefaultImg: true, + ), + SizedBox(width: 5.w), + ], + Flexible( + child: Text( + profile?.userNickname ?? '', + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white, + fontSize: 15.sp, + fontWeight: FontWeight.w600, + height: 1.4, + ), + ), + ), + if (profile?.userSex != null) ...[ + SizedBox(width: 4.w), + Container( + width: 18.w, + height: 16.w, + alignment: Alignment.center, + decoration: BoxDecoration( + shape: BoxShape.circle, + image: DecorationImage( + image: AssetImage( + profile?.userSex == 0 + ? 'sc_images/login/sc_icon_sex_woman_bg.png' + : 'sc_images/login/sc_icon_sex_man_bg.png', + ), + fit: BoxFit.cover, + ), + ), + child: xb(profile?.userSex, height: 10.w, color: null), + ), + ], + ], + ), + SizedBox(height: 6.w), + Padding( + padding: EdgeInsetsDirectional.only(start: 3.w), + child: SCSpecialIdBadge( + idText: profile?.getID() ?? '', + showAnimated: profile?.hasSpecialId() ?? false, + assetPath: SCSpecialIdAssets.userIdLarge, + animationWidth: 80.w, + animationHeight: 32.w, + showTextBesideAnimated: true, + animatedTextSpacing: 0, + showAnimatedGradientText: + profile?.shouldShowColoredSpecialIdText() ?? false, + animationTextStyle: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w500, + ), + normalTextStyle: TextStyle( + color: Colors.white, + fontSize: 12.sp, + fontWeight: FontWeight.w400, + ), + animationFit: BoxFit.contain, + ), ), ], ), ), - SizedBox(height: 8.w), - Text( - profile?.userNickname ?? '', - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Colors.white, - fontSize: 18.sp, - fontWeight: FontWeight.w700, - ), - ), - SizedBox(height: 2.w), - SCSpecialIdBadge( - idText: profile?.getID() ?? '', - showAnimated: profile?.hasSpecialId() ?? false, - assetPath: SCSpecialIdAssets.userIdLarge, - animationWidth: 80.w, - animationHeight: 32.w, - showTextBesideAnimated: true, - animatedTextSpacing: 0, - showAnimatedGradientText: - profile?.shouldShowColoredSpecialIdText() ?? false, - animationTextStyle: TextStyle( - color: Colors.white, - fontSize: 16.sp, - fontWeight: FontWeight.w700, - ), - normalTextStyle: TextStyle( - color: Colors.white, - fontSize: 16.sp, - fontWeight: FontWeight.w600, - ), - animationFit: BoxFit.contain, - ), ], ), ); } Widget _buildStatsCard() { - return _buildGlassCard( - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 10.w), - radius: 8.w, - child: Row( + return Row( + children: [ + _buildStatItem( + value: _counterText('INTERVIEW'), + label: SCAppLocalizations.of(context)!.vistors, + onTap: () => SCNavigatorUtils.push(context, SCMainRoute.vistors), + ), + _buildStatDivider(), + _buildStatItem( + value: _counterText('SUBSCRIPTION'), + label: SCAppLocalizations.of(context)!.following, + onTap: () => SCNavigatorUtils.push(context, SCMainRoute.follow), + ), + _buildStatDivider(), + _buildStatItem( + value: _counterText('FANS'), + label: SCAppLocalizations.of(context)!.friends, + onTap: () => SCNavigatorUtils.push(context, SCMainRoute.fans), + ), + ], + ); + } + + Widget _buildProfileActionPanel(SocialChatUserProfileManager profileManager) { + return SizedBox( + width: double.infinity, + height: 260.w, + child: Stack( + clipBehavior: Clip.none, children: [ - _buildStatItem( - value: _counterText('INTERVIEW'), - label: SCAppLocalizations.of(context)!.vistors, - onTap: () => SCNavigatorUtils.push(context, SCMainRoute.vistors), + Positioned.fill(child: _buildActionPanelBackground()), + PositionedDirectional( + start: 0, + end: 0, + top: 0, + height: 76.w, + child: SCDebounceWidget( + onTap: _openInviteActivity, + child: const SizedBox.expand(), + ), ), - _buildStatDivider(), - _buildStatItem( - value: _counterText('SUBSCRIPTION'), - label: SCAppLocalizations.of(context)!.following, - onTap: () => SCNavigatorUtils.push(context, SCMainRoute.follow), + PositionedDirectional( + start: 11.w, + end: 11.w, + top: 82.w, + child: _buildWalletVipRow(profileManager), ), - _buildStatDivider(), - _buildStatItem( - value: _counterText('FANS'), - label: SCAppLocalizations.of(context)!.friends, - onTap: () => SCNavigatorUtils.push(context, SCMainRoute.fans), + PositionedDirectional( + start: 18.w, + end: 18.w, + top: 161.w, + child: _buildEntryRow(), ), ], ), ); } + Widget _buildActionPanelBackground() { + return Image.asset( + 'sc_images/index/sc_me_action_panel_bg.png', + fit: BoxFit.fill, + errorBuilder: (context, error, stackTrace) { + return Padding( + padding: EdgeInsets.only(top: 52.w), + child: SvgPicture.asset( + 'sc_images/index/sc_me_action_panel_bg.svg', + fit: BoxFit.fill, + ), + ); + }, + ); + } + Widget _buildEntryRow() { return Row( children: [ _buildEntryItem( title: SCAppLocalizations.of(context)!.store, - iconPath: 'sc_images/index/sc_icon_shop.png', + iconPath: 'sc_images/index/sc_me_entry_store.png', onTap: () => SCNavigatorUtils.push(context, StoreRoute.list), ), - SizedBox(width: 10.w), - _buildEntryItem( - title: SCAppLocalizations.of(context)!.level, - iconPath: 'sc_images/index/sc_icon_level.png', - onTap: () => SCNavigatorUtils.push(context, SCMainRoute.levelList), - ), - SizedBox(width: 10.w), _buildEntryItem( title: SCAppLocalizations.of(context)!.bag, - iconPath: 'sc_images/index/sc_icon_bag.png', + iconPath: 'sc_images/index/sc_me_entry_bag.png', onTap: () => SCNavigatorUtils.push(context, StoreRoute.bags), ), - SizedBox(width: 10.w), _buildEntryItem( - title: 'cp', - iconPath: 'sc_images/index/sc_icon_cp_entry.png', - iconWidth: 47, + title: SCAppLocalizations.of(context)!.level, + iconPath: 'sc_images/index/sc_me_entry_level.png', + onTap: () => SCNavigatorUtils.push(context, SCMainRoute.levelList), + ), + _buildEntryItem( + title: 'CP', + iconPath: 'sc_images/index/sc_me_entry_cp.png', + iconWidth: 46, iconHeight: 50, onTap: _openCpActivity, ), @@ -526,6 +633,7 @@ class _MePage2State extends State with WidgetsBindingObserver { height: 68.w, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.w), + border: Border.all(color: scHomeShellGoldColor, width: 1.w), image: const DecorationImage( image: AssetImage('sc_images/index/sc_icon_wallet_bg.png'), fit: BoxFit.fill, @@ -565,12 +673,12 @@ class _MePage2State extends State with WidgetsBindingObserver { child: Consumer( builder: (context, ref, child) { return Text( - ':${_balanceText(ref.myBalance)}', + '${_balanceText(ref.myBalance)}', maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( color: Colors.white, - fontSize: 18.sp, + fontSize: 12.sp, fontWeight: FontWeight.w700, fontStyle: FontStyle.italic, height: 1, @@ -780,68 +888,9 @@ class _MePage2State extends State with WidgetsBindingObserver { ); } - Widget _buildInviteActivityBanner() { - return SCDebounceWidget( - onTap: _openInviteActivity, - child: LayoutBuilder( - builder: (context, constraints) { - final width = - constraints.maxWidth.isFinite - ? constraints.maxWidth - : ScreenUtil().screenWidth - 20.w; - final height = width / 5; - - return SizedBox( - width: width, - height: height, - child: Stack( - clipBehavior: Clip.none, - alignment: Alignment.center, - children: [ - Positioned.fill( - child: Transform( - alignment: Alignment.center, - transform: Matrix4.diagonal3Values( - _inviteActivityHorizontalScale, - 1.0, - 1.0, - ), - child: SCSvgaAssetWidget( - assetPath: _inviteActivitySvgaAsset, - width: width, - height: height, - active: true, - loop: true, - fit: BoxFit.fill, - allowDrawingOverflow: true, - ), - ), - ), - ], - ), - ); - }, - ), - ); - } - - String get _inviteActivitySvgaAsset { - switch (SCGlobalConfig.lang) { - case 'ar': - return 'sc_images/index/sc_invite_activity_rtl.svga'; - case 'bn': - case 'fa': - return 'sc_images/index/sc_invite_activity_fa.svga'; - case 'tr': - case 'pt': - return 'sc_images/index/sc_invite_activity_pt.svga'; - default: - return 'sc_images/index/sc_invite_activity.svga'; - } - } - - Widget _buildMenuCard2() { - final userProfile = context.watch(); + List<_MenuRowData> _identityMenuItems( + SocialChatUserProfileManager userProfile, + ) { final items = <_MenuRowData>[]; final hasCurrentUser = userProfile.currentUserProfile != null; final isAgent = userProfile.userIdentity?.agent ?? false; @@ -862,11 +911,11 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.agentCenter, - assetIcon: 'sc_images/index/sc_icon_agent_center.png', + assetIcon: 'sc_images/index/sc_icon_me_agency_center.svg', onTap: () { SCNavigatorUtils.push( context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.agencyCenterUrl)}&showTitle=false", + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.agencyCenterUrl)}&showTitle=false&safeTop=true", ); }, ), @@ -875,11 +924,11 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.hostCenter, - assetIcon: 'sc_images/index/sc_icon_host_center.png', + assetIcon: 'sc_images/index/sc_icon_me_host_center.svg', onTap: () { SCNavigatorUtils.push( context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false", + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.hostCenterUrl)}&showTitle=false&safeTop=true", ); }, ), @@ -893,11 +942,11 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.admin, - assetIcon: 'sc_images/index/sc_icon_bd_leader.png', + assetIcon: 'sc_images/index/sc_icon_me_admin.svg', onTap: () { SCNavigatorUtils.push( context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdLeaderUrl)}&showTitle=false", + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.bdLeaderUrl)}&showTitle=false&safeTop=true", ); }, ), @@ -923,11 +972,11 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.rechargeAgency, - assetIcon: 'sc_images/index/sc_icon_recharge_agency.png', + assetIcon: 'sc_images/index/sc_icon_me_recharge_agency.svg', onTap: () { SCNavigatorUtils.push( context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false", + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.coinSellerUrl)}&showTitle=false&safeTop=true", ); }, ), @@ -939,11 +988,11 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.adminCenter, - assetIcon: 'sc_images/index/sc_icon_admin_center.png', + assetIcon: 'sc_images/index/sc_icon_me_admin.svg', onTap: () { SCNavigatorUtils.push( context, - "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.adminUrl)}&showTitle=false", + "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(SCGlobalConfig.adminUrl)}&showTitle=false&safeTop=true", ); }, ), @@ -956,7 +1005,7 @@ class _MePage2State extends State with WidgetsBindingObserver { items.add( _MenuRowData( title: SCAppLocalizations.of(context)!.managerCenter, - assetIcon: 'sc_images/index/sc_icon_admin_center.png', + assetIcon: 'sc_images/index/sc_icon_me_manager_center.svg', onTap: () { SCNavigatorUtils.push( context, @@ -970,58 +1019,73 @@ class _MePage2State extends State with WidgetsBindingObserver { '[MePage2] hide Manager Center because yumiManager=$isYumiManager', ); } - return _buildMenuCard(items); + return items; } - Widget _buildMenuCard(List<_MenuRowData> items) { - // 没有任何项时,不显示整个卡片 + Widget _buildMenuGridCard(List<_MenuRowData> items) { if (items.isEmpty) return const SizedBox.shrink(); return _buildGlassCard( - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 6.w), - radius: 4.w, + padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 20.w), + radius: 14.w, + child: LayoutBuilder( + builder: (context, constraints) { + final itemWidth = constraints.maxWidth / 4; + return Wrap( + alignment: WrapAlignment.start, + runSpacing: 18.w, + children: + items.map((item) { + return SizedBox( + width: itemWidth, + child: _buildMenuGridItem(item), + ); + }).toList(), + ); + }, + ), + ); + } + + Widget _buildMenuGridItem(_MenuRowData item) { + return SCDebounceWidget( + onTap: item.onTap, child: Column( + mainAxisSize: MainAxisSize.min, children: [ - for (int i = 0; i < items.length; i++) ...[_buildMenuRow(items[i])], + _buildMenuGridIcon(item.assetIcon!), + SizedBox(height: 16.w), + Text( + item.title, + maxLines: 1, + overflow: TextOverflow.ellipsis, + textAlign: TextAlign.center, + style: TextStyle( + color: Colors.white, + fontSize: 10.sp, + fontWeight: FontWeight.w600, + height: 1, + ), + ), ], ), ); } - Widget _buildMenuRow(_MenuRowData item) { - return SCDebounceWidget( - onTap: item.onTap, - child: SizedBox( - height: 46.w, - child: Row( - children: [ - Image.asset( - item.assetIcon!, - width: 24.w, - height: 24.w, - color: Colors.white, - ), - - SizedBox(width: 12.w), - Expanded( - child: Text( - item.title, - style: TextStyle( - color: Colors.white, - fontSize: 15.sp, - fontWeight: FontWeight.w600, - ), - ), - ), - Icon( - SCGlobalConfig.lang == 'ar' - ? Icons.keyboard_arrow_left - : Icons.keyboard_arrow_right, - color: Colors.white, - size: 18.w, - ), - ], - ), - ), + Widget _buildMenuGridIcon(String assetIcon) { + if (assetIcon.endsWith('.svg')) { + return SvgPicture.asset( + assetIcon, + width: 28.w, + height: 28.w, + fit: BoxFit.contain, + ); + } + return Image.asset( + assetIcon, + width: 28.w, + height: 28.w, + color: Colors.white, + fit: BoxFit.contain, ); } @@ -1037,13 +1101,8 @@ class _MePage2State extends State with WidgetsBindingObserver { child: SCDebounceWidget( onTap: onTap, child: Container( - height: 110.w, - decoration: BoxDecoration( - image: const DecorationImage( - image: AssetImage('sc_images/person/sc_icon_me_menu_1_bg.png'), - fit: BoxFit.fill, - ), - ), + height: 88.w, + color: Colors.transparent, child: Stack( children: [ Center( @@ -1052,8 +1111,8 @@ class _MePage2State extends State with WidgetsBindingObserver { children: [ Image.asset( iconPath, - width: (iconWidth ?? 54).w, - height: (iconHeight ?? 54).w, + width: (iconWidth ?? 50).w, + height: (iconHeight ?? 50).w, fit: BoxFit.contain, ), SizedBox(height: 4.w), @@ -1064,7 +1123,8 @@ class _MePage2State extends State with WidgetsBindingObserver { style: TextStyle( color: Colors.white, fontSize: 15.sp, - fontWeight: FontWeight.w700, + fontWeight: FontWeight.w600, + height: 1.2, ), ), ], @@ -1116,26 +1176,29 @@ class _MePage2State extends State with WidgetsBindingObserver { child: SCDebounceWidget( onTap: onTap, child: Column( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Text( - value, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Colors.white, - fontSize: 16.sp, - fontWeight: FontWeight.w700, - ), - ), - SizedBox(height: 1.w), Text( label, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - color: Colors.white, + color: scHomeShellAccentColor.withValues(alpha: 0.7), fontSize: 12.sp, fontWeight: FontWeight.w500, + height: 1.5, + ), + ), + SizedBox(height: 1.w), + Text( + value, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: scHomeShellAccentColor, + fontSize: 16.sp, + fontWeight: FontWeight.w700, + height: 1.5, ), ), ], @@ -1148,7 +1211,7 @@ class _MePage2State extends State with WidgetsBindingObserver { return Container( width: 0.5.w, height: 16.w, - color: const Color(0xFFE6E6E6).withValues(alpha: 0.8), + color: Colors.white.withValues(alpha: 0.32), margin: EdgeInsets.symmetric(horizontal: 6.w), ); } @@ -1163,13 +1226,16 @@ class _MePage2State extends State with WidgetsBindingObserver { padding: padding, decoration: BoxDecoration( borderRadius: BorderRadius.circular(radius), - border: Border.all(color: const Color(0xFFB4FCCE), width: 1.w), + border: Border.all( + color: scHomeShellAccentColor.withValues(alpha: 0.2), + width: 1.w, + ), gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ - const Color(0xFF0A7D49).withValues(alpha: 0.20), - const Color(0xFF031513).withValues(alpha: 0.35), + const Color(0xFF111A1B).withValues(alpha: 0.62), + const Color(0xFF2C4D42).withValues(alpha: 0.44), ], ), ), diff --git a/lib/modules/user/task/task_page.dart b/lib/modules/user/task/task_page.dart index b4f4193..c05a6da 100644 --- a/lib/modules/user/task/task_page.dart +++ b/lib/modules/user/task/task_page.dart @@ -10,6 +10,7 @@ import 'package:yumi/shared/business_logic/models/res/sc_task_list_res.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/tools/sc_entry_popup_coordinator.dart'; +import 'package:yumi/ui_kit/widgets/sc_home_shell_background.dart'; class TaskPage extends StatefulWidget { const TaskPage({ @@ -27,7 +28,11 @@ class TaskPage extends StatefulWidget { class _TaskPageState extends State with WidgetsBindingObserver, RouteAware { + static const String _taskMicAsset = 'sc_images/index/sc_icon_task_mic.png'; + static const String _taskGameAsset = 'sc_images/index/sc_icon_task_game.png'; static const String _taskGiftAsset = 'sc_images/index/sc_icon_task_gift.png'; + static const String _taskRechargeAsset = + 'sc_images/index/sc_icon_task_recharge.png'; static const Duration _taskStatusCacheRefreshDelay = Duration(seconds: 65); final SCAccountRepository _repository = SCAccountRepository(); @@ -94,9 +99,6 @@ class _TaskPageState extends State if (!mounted) return; final sortedTasks = tasks..sort((a, b) => (a.sortOrder ?? 0).compareTo(b.sortOrder ?? 0)); - final dailyCount = - sortedTasks.where((task) => (task.taskType ?? 0).toInt() == 0).length; - final exclusiveCount = sortedTasks.length - dailyCount; setState(() { _tasks = sortedTasks; _loading = false; @@ -133,88 +135,90 @@ class _TaskPageState extends State final newcomerTasks = _sectionTasks(isNewcomer: true); return Scaffold( - backgroundColor: const Color(0xFF00221D), - body: SafeArea( - bottom: false, - child: Stack( - children: [ - Column( + backgroundColor: scHomeShellBackgroundColor, + body: Stack( + children: [ + const Positioned.fill(child: SCHomeShellBackground()), + SafeArea( + bottom: false, + child: Stack( children: [ - _buildTopBar(), - Expanded( - child: RefreshIndicator( - color: const Color(0xFF16DBB2), - backgroundColor: const Color(0xFF06342A), - onRefresh: _handleManualRefresh, - child: SingleChildScrollView( - physics: const AlwaysScrollableScrollPhysics( - parent: BouncingScrollPhysics(), - ), - padding: EdgeInsets.fromLTRB(10.w, 18.w, 10.w, 28.w), - child: Column( - children: [ - if (_loading) - Padding( - padding: EdgeInsets.only(top: 120.w), - child: SizedBox( - width: 24.w, - height: 24.w, - child: const CircularProgressIndicator( - strokeWidth: 2, - color: Color(0xFF16DBB2), + Column( + children: [ + _buildTopBar(), + Expanded( + child: RefreshIndicator( + color: const Color(0xFF16DBB2), + backgroundColor: const Color(0xFF06342A), + onRefresh: _handleManualRefresh, + child: SingleChildScrollView( + physics: const AlwaysScrollableScrollPhysics( + parent: BouncingScrollPhysics(), + ), + padding: EdgeInsets.fromLTRB(10.w, 10.w, 10.w, 28.w), + child: Column( + children: [ + if (_loading) + Padding( + padding: EdgeInsets.only(top: 120.w), + child: SizedBox( + width: 24.w, + height: 24.w, + child: const CircularProgressIndicator( + strokeWidth: 2, + color: Color(0xFF16DBB2), + ), + ), + ) + else + ..._buildTaskSections( + dailyTasks, + newcomerTasks, ), - ), - ) - else - ..._buildTaskSections(dailyTasks, newcomerTasks), - ], + ], + ), + ), ), ), - ), + ], ), + if (_toastMessage != null) _buildToast(), ], ), - if (_toastMessage != null) _buildToast(), - ], - ), + ), + ], ), ); } Widget _buildTopBar() { return SizedBox( - height: 44.w, - child: Stack( - alignment: Alignment.center, + height: 48.w, + child: Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Align( - alignment: AlignmentDirectional.centerStart, - child: - widget.showBackButton - ? GestureDetector( - behavior: HitTestBehavior.opaque, - onTap: () => SCNavigatorUtils.goBack(context), - child: SizedBox( - width: 44.w, - height: 44.w, - child: Icon( - SCGlobalConfig.lang == 'ar' - ? Icons.keyboard_arrow_right - : Icons.keyboard_arrow_left, - color: Colors.white, - size: 28.w, - ), - ), - ) - : SizedBox(width: 44.w, height: 44.w), - ), - Text( + if (widget.showBackButton) + GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () => SCNavigatorUtils.goBack(context), + child: SizedBox( + width: 44.w, + height: 48.w, + child: Icon( + SCGlobalConfig.lang == 'ar' + ? Icons.keyboard_arrow_right + : Icons.keyboard_arrow_left, + color: Colors.white, + size: 28.w, + ), + ), + ) + else + SizedBox(width: 10.w), + SCHomeShellGradientText( SCAppLocalizations.of(context)!.task, - style: TextStyle( - color: Colors.white, - fontSize: 20.sp, - fontWeight: FontWeight.w500, - ), + textAlign: TextAlign.start, + style: scHomeShellTitleStyle(fontSize: 28.sp), ), ], ), @@ -517,7 +521,18 @@ class _TaskPageState extends State } String _iconForTask(SCTaskListRes task) { - return _taskGiftAsset; + switch (task.conditionType?.trim().toUpperCase()) { + case 'MIC_DURATION_SECONDS': + return _taskMicAsset; + case 'GAME_CONSUME_GOLD': + return _taskGameAsset; + case 'GIFT_CONSUME_GOLD': + return _taskGiftAsset; + case 'RECHARGE_GOLD': + return _taskRechargeAsset; + default: + return _taskGiftAsset; + } } String _taskProgressText( @@ -688,15 +703,16 @@ class _TaskSection extends StatelessWidget { return Container( width: double.infinity, decoration: BoxDecoration( - color: const Color(0xFF052E25), - borderRadius: BorderRadius.circular(7.w), - border: Border.all(color: const Color(0xFFB4FCCE), width: 1.w), + color: const Color(0xFF08251E).withValues(alpha: 0.56), + borderRadius: BorderRadius.circular(8.w), + border: Border.all(color: const Color(0xFF1FA87C), width: 0.5.w), ), child: Column( children: [ Padding( - padding: EdgeInsets.fromLTRB(12.w, 24.w, 12.w, 12.w), + padding: EdgeInsets.fromLTRB(12.w, 12.w, 12.w, 8.w), child: Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded(child: _GradientTaskTitle(title)), SizedBox(width: 8.w), @@ -705,10 +721,10 @@ class _TaskSection extends StatelessWidget { maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( - color: Colors.white, - fontSize: 12.sp, + color: Colors.white.withValues(alpha: 0.72), + fontSize: 10.sp, fontWeight: FontWeight.w400, - height: 1, + height: 1.2, ), ), ], @@ -726,7 +742,7 @@ class _TaskSection extends StatelessWidget { child: Divider( height: 1.w, thickness: 0.5.w, - color: const Color(0xFF295346).withValues(alpha: 0.8), + color: Colors.white.withValues(alpha: 0.06), ), ), ], @@ -745,73 +761,41 @@ class _GradientTaskTitle extends StatelessWidget { Widget build(BuildContext context) { final style = TextStyle( fontSize: 16.sp, - fontWeight: FontWeight.w900, + fontWeight: FontWeight.w600, height: 1, ); - return LayoutBuilder( - builder: (context, constraints) { - return SizedBox( - width: constraints.maxWidth, - height: 23.w, - child: Stack( - clipBehavior: Clip.none, - children: [ - PositionedDirectional( - top: 3.w, - start: 0, - end: 0, - child: Text( - text, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: style.copyWith(color: const Color(0xFF157D10)), - ), - ), - PositionedDirectional( - start: 0, - end: 0, - child: Text( - text, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: style.copyWith( - foreground: - Paint() - ..style = PaintingStyle.stroke - ..strokeWidth = 1.w - ..color = const Color(0xFF157D10), - ), - ), - ), - PositionedDirectional( - start: 0, - end: 0, - child: ShaderMask( - blendMode: BlendMode.srcIn, - shaderCallback: - (bounds) => const LinearGradient( - begin: Alignment.centerRight, - end: Alignment.centerLeft, - colors: [ - Color(0xFFFFFFFF), - Color(0xFFBEFAE8), - Color(0xFFFFFFFF), - ], - stops: [0.224, 0.4907, 0.7224], - ).createShader(bounds), - child: Text( - text, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: style.copyWith(color: Colors.white), - ), - ), - ), - ], + return Align( + alignment: AlignmentDirectional.centerStart, + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + _TaskTitleSparkle(), + SizedBox(width: 4.w), + Flexible( + child: SCHomeShellGradientText( + text, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: style, + ), ), - ); - }, + SizedBox(width: 4.w), + _TaskTitleSparkle(), + ], + ), + ); + } +} + +class _TaskTitleSparkle extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Image.asset( + 'sc_images/index/sc_task_title_sparkle.png', + width: 10.w, + height: 10.w, + fit: BoxFit.contain, ); } } @@ -834,17 +818,8 @@ class _TaskRow extends StatelessWidget { child: Row( children: [ SizedBox(width: 12.w), - Container( - width: 42.w, - height: 42.w, - decoration: const BoxDecoration( - color: Color(0x30BEF9E8), - shape: BoxShape.circle, - ), - alignment: Alignment.center, - child: _TaskIcon(task: task), - ), - SizedBox(width: 20.w), + SizedBox(width: 42.w, height: 42.w, child: _TaskIcon(task: task)), + SizedBox(width: 8.w), Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, @@ -861,36 +836,43 @@ class _TaskRow extends StatelessWidget { height: 1.15, ), ), - SizedBox(height: 3.w), - if (task.requirementText.isNotEmpty) ...[ - Text( - task.requirementText, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Colors.white.withValues(alpha: 0.72), - fontSize: 10.sp, - fontWeight: FontWeight.w400, - height: 1, - ), - ), - SizedBox(height: 3.w), - ], - if (task.progressText.isNotEmpty) ...[ - Text( - task.progressText, - maxLines: 1, - overflow: TextOverflow.ellipsis, - style: TextStyle( - color: Colors.white.withValues(alpha: 0.62), - fontSize: 10.sp, - fontWeight: FontWeight.w400, - height: 1, - ), - ), - SizedBox(height: 5.w), - ] else - SizedBox(height: 6.w), + SizedBox(height: 4.w), + Row( + children: [ + if (task.requirementText.isNotEmpty) + Flexible( + child: Text( + task.requirementText, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: Colors.white.withValues(alpha: 0.6), + fontSize: 10.sp, + fontWeight: FontWeight.w400, + height: 1, + ), + ), + ), + if (task.requirementText.isNotEmpty && + task.progressText.isNotEmpty) + SizedBox(width: 10.w), + if (task.progressText.isNotEmpty) + Flexible( + child: Text( + task.progressText, + maxLines: 1, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: const Color(0xFF28E883), + fontSize: 10.sp, + fontWeight: FontWeight.w400, + height: 1, + ), + ), + ), + ], + ), + SizedBox(height: 7.w), Row( children: [ Image.asset( @@ -921,7 +903,7 @@ class _TaskRow extends StatelessWidget { claiming: claiming, onTap: () => onAction(task), ), - SizedBox(width: 12.w), + SizedBox(width: 14.w), ], ), ); @@ -950,16 +932,26 @@ class _TaskActionButton extends StatelessWidget { onTap: claiming ? null : onTap, child: Container( width: config.width.w, - height: 20.w, + height: 24.w, alignment: Alignment.center, decoration: BoxDecoration( - borderRadius: BorderRadius.circular(10.w), + borderRadius: BorderRadius.circular(999.w), + image: + config.assetPath == null + ? null + : DecorationImage( + image: AssetImage(config.assetPath!), + fit: BoxFit.fill, + ), border: - config.borderColor == null + config.assetPath != null || config.borderColor == null ? null : Border.all(color: config.borderColor!, width: 1.w), - gradient: config.gradient, - color: config.gradient == null ? config.backgroundColor : null, + gradient: config.assetPath == null ? config.gradient : null, + color: + config.assetPath == null && config.gradient == null + ? config.backgroundColor + : null, ), child: claiming @@ -977,7 +969,7 @@ class _TaskActionButton extends StatelessWidget { overflow: TextOverflow.ellipsis, style: TextStyle( color: config.textColor, - fontSize: 13.sp, + fontSize: 12.sp, fontWeight: FontWeight.w400, height: 1, ), @@ -1000,8 +992,8 @@ class _TaskIcon extends StatelessWidget { } return Image.network( iconUrl, - width: 29.4.w, - height: 29.4.w, + width: 42.w, + height: 42.w, fit: BoxFit.contain, errorBuilder: (_, __, ___) => _buildAssetIcon(), loadingBuilder: (context, child, loadingProgress) { @@ -1014,8 +1006,8 @@ class _TaskIcon extends StatelessWidget { Widget _buildAssetIcon() { return Image.asset( task.iconAsset, - width: 29.4.w, - height: 29.4.w, + width: 42.w, + height: 42.w, fit: BoxFit.contain, ); } @@ -1029,6 +1021,7 @@ class _TaskButtonConfig { this.backgroundColor, this.borderColor, this.gradient, + this.assetPath, }); final String label; @@ -1037,6 +1030,7 @@ class _TaskButtonConfig { final Color? backgroundColor; final Color? borderColor; final Gradient? gradient; + final String? assetPath; factory _TaskButtonConfig.fromStatus( _TaskActionStatus status, @@ -1046,8 +1040,9 @@ class _TaskButtonConfig { case _TaskActionStatus.claim: return _TaskButtonConfig( label: l10n.claim, - textColor: Color(0xFF2B1500), - width: 53, + textColor: Color(0xFF221901), + width: 66, + assetPath: 'sc_images/index/sc_task_action_claim_bg.png', gradient: const LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, @@ -1058,7 +1053,8 @@ class _TaskButtonConfig { return _TaskButtonConfig( label: l10n.claimed, textColor: Colors.white, - width: 58, + width: 66, + assetPath: 'sc_images/index/sc_task_action_claimed_bg.png', backgroundColor: const Color(0xFF062E28), borderColor: Colors.white.withValues(alpha: 0.56), ); @@ -1066,7 +1062,8 @@ class _TaskButtonConfig { return _TaskButtonConfig( label: l10n.go, textColor: Colors.white, - width: 53, + width: 66, + assetPath: 'sc_images/index/sc_task_action_go_bg.png', backgroundColor: const Color(0xFF062E28), borderColor: const Color(0xFF98E4C2), ); diff --git a/lib/modules/webview/webview_page.dart b/lib/modules/webview/webview_page.dart index e634901..0e83c8a 100644 --- a/lib/modules/webview/webview_page.dart +++ b/lib/modules/webview/webview_page.dart @@ -27,11 +27,13 @@ class WebViewPage extends StatefulWidget { final String title; final String url; final String showTitle; + final bool safeTop; const WebViewPage({ Key? key, this.title = "", this.showTitle = "true", + this.safeTop = false, required this.url, }) : super(key: key); @@ -293,7 +295,7 @@ class _WebViewPageState extends State { ) : null, body: SafeArea( - top: false, + top: widget.safeTop, child: Stack( children: [ WebViewWidget(controller: _controller), diff --git a/lib/services/audio/rtc_manager.dart b/lib/services/audio/rtc_manager.dart index 8867afb..d98fbab 100644 --- a/lib/services/audio/rtc_manager.dart +++ b/lib/services/audio/rtc_manager.dart @@ -2557,14 +2557,41 @@ class RealTimeCommunicationManager extends ChangeNotifier { } Future releaseRtcEngineForAppTermination() async { + final roomId = (currenRoom?.roomProfile?.roomProfile?.id ?? "").trim(); + final shouldQuitRoom = !_currentRoomIsEntryPreview && roomId.isNotEmpty; final adapter = _roomRtcEngineAdapter; _roomRtcEngineAdapter = null; _rtcEnginePrewarmTask = null; + SCHeartbeatUtils.cancelTimer(); _resetRoomRtcTracking(); - try { - await adapter?.release(); - } catch (e) {} + + final rtcReleaseTask = () async { + try { + await adapter?.release(); + } catch (e) {} + }(); + final remoteCleanupTask = () async { + if (!shouldQuitRoom) { + return; + } + await _retryExitNetworkRequest( + 'quit room on app termination $roomId', + () async { + final didQuit = await SCAccountRepository().quitRoom( + roomId, + silentErrorToast: true, + ); + if (!didQuit) { + throw StateError('quitRoom returned false'); + } + await _clearPersistedRoomMarkerIfMatches(roomId); + }, + ); + }(); + + await rtcReleaseTask; await SCVoiceRoomForegroundService.stop(); + await remoteCleanupTask; } void _handleRoomRtcVoiceVolume( @@ -4172,7 +4199,7 @@ class RealTimeCommunicationManager extends ChangeNotifier { final currentPercent = _roomRocketStatusPercent(currentStatus); if (currentStatus.currentEnergy == 0 && currentPercent <= 0 && - currentLevel >= launch.safeLevel) { + currentLevel > launch.safeLevel) { return; } final launchedLevel = math.max(currentLevel, launch.safeLevel); diff --git a/lib/services/audio/rtm_manager.dart b/lib/services/audio/rtm_manager.dart index e01ff20..72410b9 100644 --- a/lib/services/audio/rtm_manager.dart +++ b/lib/services/audio/rtm_manager.dart @@ -17,6 +17,7 @@ import 'package:yumi/shared/tools/sc_room_utils.dart'; import 'package:yumi/shared/tools/sc_cp_gift_relation_utils.dart'; import 'package:yumi/shared/tools/sc_cp_relation_broadcast_assets.dart'; import 'package:yumi/shared/tools/sc_cp_relation_notice_utils.dart'; +import 'package:yumi/shared/tools/sc_chat_bubble_message_data.dart'; import 'package:yumi/shared/tools/sc_room_rocket_reward_popup_ack.dart'; import 'package:yumi/shared/tools/sc_user_id_utils.dart'; import 'package:yumi/shared/data_sources/sources/local/floating_screen_manager.dart'; @@ -24,6 +25,7 @@ import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; +import 'package:yumi/services/room/rc_room_manager.dart'; import 'package:provider/provider.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart'; import 'package:tencent_cloud_chat_sdk/enum/V2TimConversationListener.dart'; @@ -95,6 +97,159 @@ typedef OnNewGroupMessageListener = typedef OnMessageRecvC2CReadListener = Function(List messageIDList); typedef RtmProvider = RealTimeMessagingManager; +@visibleForTesting +bool shouldRefreshRoomContributionForGiftMessage({ + required String? messageType, + required String? messageRoomId, + required String? messageGroupId, + required String currentRoomId, + required String currentRoomGroupId, +}) { + if (messageType != SCRoomMsgType.gift && + messageType != SCRoomMsgType.luckGiftAnimOther) { + return false; + } + final normalizedRoomId = currentRoomId.trim(); + if (normalizedRoomId.isEmpty) { + return false; + } + final normalizedCurrentGroupId = currentRoomGroupId.trim(); + final normalizedMessageGroupId = messageGroupId?.trim() ?? ''; + if (normalizedCurrentGroupId.isNotEmpty && + normalizedMessageGroupId.isNotEmpty && + normalizedMessageGroupId != normalizedCurrentGroupId) { + return false; + } + if (messageType == SCRoomMsgType.gift) { + final normalizedMessageRoomId = messageRoomId?.trim() ?? ''; + if (normalizedMessageRoomId.isNotEmpty && + normalizedMessageRoomId != normalizedRoomId) { + return false; + } + } + return true; +} + +@visibleForTesting +bool shouldSuppressRoomCpRelationNotice({ + required String? messageType, + required String? noticeAction, +}) { + return messageType == SCRoomMsgType.cpSystemNotice && + noticeAction == "RELATION_ESTABLISHED"; +} + +@visibleForTesting +SCFloatingMessage? buildCpRelationBroadcastFloatingMessage(dynamic rawPayload) { + Map payloadMap(dynamic value) { + if (value is Map) { + return value; + } + if (value is Map) { + return value.map((key, item) => MapEntry(key.toString(), item)); + } + if (value is String && value.trim().isNotEmpty) { + try { + return payloadMap(json.decode(value)); + } catch (_) { + return const {}; + } + } + return const {}; + } + + String firstText(Iterable values) { + for (final value in values) { + final text = value?.toString().trim() ?? ''; + if (text.isNotEmpty && text.toLowerCase() != 'null') { + return text; + } + } + return ''; + } + + final root = payloadMap(rawPayload); + final nested = payloadMap(root['data']); + final payload = nested.isEmpty ? root : nested; + if (payload.isEmpty) { + return null; + } + + final user = payloadMap(payload['user']); + final cpUser = payloadMap(payload['cpUser']); + final relationType = scNormalizeCpRelationType( + firstText([payload['relationType'], payload['role']]), + ); + final userId = firstText([ + user['userId'], + user['id'], + payload['userId'], + payload['sendUserId'], + payload['senderUserId'], + ]); + final cpUserId = firstText([ + cpUser['userId'], + cpUser['id'], + payload['cpUserId'], + payload['acceptUserId'], + payload['toUserId'], + ]); + final userName = firstText([ + user['userNickname'], + user['nickname'], + user['account'], + payload['userNickname'], + payload['nickname'], + payload['account'], + userId, + ]); + final cpUserName = firstText([ + cpUser['userNickname'], + cpUser['nickname'], + cpUser['account'], + payload['cpUserNickname'], + payload['acceptNickname'], + payload['toUserName'], + payload['cpUserAccount'], + cpUserId, + ]); + if (userId.isEmpty && + cpUserId.isEmpty && + userName.isEmpty && + cpUserName.isEmpty) { + return null; + } + + return SCFloatingMessage( + type: scCpRelationBroadcastFloatingType, + priority: 970, + roomId: firstText([payload['roomId'], payload['groupId']]), + userId: userId, + toUserId: cpUserId, + userAvatarUrl: firstText([ + user['userAvatar'], + user['avatar'], + payload['userAvatar'], + ]), + toUserAvatarUrl: firstText([ + cpUser['userAvatar'], + cpUser['avatar'], + payload['cpUserAvatar'], + payload['acceptUserAvatar'], + payload['toUserAvatarUrl'], + ]), + userName: userName, + toUserName: cpUserName, + giftUrl: scCpRelationBroadcastAsset(relationType), + giftId: "RELATION_ESTABLISHED", + giftTab: relationType, + gameId: firstText([payload['applyId'], payload['eventId']]), + displayText: firstText([payload['msg']]), + durationSeconds: 5, + broadcastScope: SCFloatingMessage.broadcastScopeRegion, + ); +} + enum _CpInviteProcessResult { accepted, rejected, expired } class _LuckGiftPushQueueEntry { @@ -217,6 +372,9 @@ class RealTimeMessagingManager extends ChangeNotifier { static const int _luckyGiftBurstRecentEventTtlMs = 5000; static const int _luckyGiftBurstPlaybackWatchdogMs = 8000; static const int _cpRelationGiftRefreshMinIntervalMs = 800; + static const Duration _roomContributionGiftRefreshDebounce = Duration( + milliseconds: 500, + ); static const List _cpRelationGiftRefreshDelays = [ Duration(milliseconds: 300), Duration(milliseconds: 1500), @@ -358,6 +516,7 @@ class RealTimeMessagingManager extends ChangeNotifier { final Set _shownCpInviteRejectedDialogKeys = {}; final Map _recentCpRelationNoticeTimes = {}; int _lastCpRelationGiftRefreshAt = 0; + Timer? _roomContributionGiftRefreshTimer; int get currentLuckGiftBurstPlaybackToken => _luckGiftPushPlaybackToken; String? roomRedPacketBroadcastGroupId; String? roomRedPacketBroadcastRegionCode; @@ -1472,15 +1631,6 @@ class RealTimeMessagingManager extends ChangeNotifier { return true; } if (result == _CpInviteProcessResult.accepted) { - if (isSender) { - _dispatchCpRelationEstablishedRoomNotice( - groupId: _currentVisibleVoiceRoomGroupId(context), - applyId: applyId, - data: data, - invite: invite, - currentProfile: currentProfile, - ); - } return true; } if (result == _CpInviteProcessResult.expired) { @@ -1793,15 +1943,7 @@ class RealTimeMessagingManager extends ChangeNotifier { ); SmartDialog.dismiss(tag: RoomCpInviteDialog.dialogTag); unawaited(profileManager.refreshLoadedCpProfiles()); - if (agree) { - _dispatchCpRelationEstablishedRoomNotice( - groupId: voiceRoomGroupId, - applyId: applyId, - data: data, - invite: invite, - currentProfile: AccountStorage().getCurrentUser()?.userProfile, - ); - } else { + if (!agree) { _dispatchCpInviteRejectedRoomNotice( groupId: voiceRoomGroupId, applyId: applyId, @@ -1823,66 +1965,6 @@ class RealTimeMessagingManager extends ChangeNotifier { ); } - void _dispatchCpRelationEstablishedRoomNotice({ - required String groupId, - required String applyId, - required SCSystemInvitMessageRes invite, - required SocialChatUserProfile? currentProfile, - Map? data, - }) { - if (currentProfile == null) { - return; - } - if (groupId.isEmpty) { - _cpInviteLog( - 'skip room established notice reason=no_visible_voice_room ' - 'applyId=$applyId', - ); - return; - } - final isSender = _cpInviteSenderMatchesCurrent( - invite, - currentProfile, - data: data, - ); - final inviter = isSender ? currentProfile : _cpInviteInviterProfile(invite); - final receiver = isSender ? _cpInviteReceiverProfile(data) : currentProfile; - final relationType = scNormalizeCpRelationType( - _firstCpInviteValue([ - invite.relationType, - data == null ? null : data["relationType"]?.toString(), - data == null ? null : data["relation_type"]?.toString(), - ]) ?? - "", - ); - final targetUserIds = _compactCpNoticeTargetIds([inviter, receiver]); - _cpInviteLog( - 'dispatch room established notice applyId=$applyId ' - 'relationType=$relationType groupId=$groupId ' - 'isSender=$isSender targets=${targetUserIds.join(",")}', - ); - unawaited( - dispatchMessage( - Msg( - groupId: groupId, - msg: scBuildCpRelationEstablishedNotice( - userName1: _roomMsgUserDisplayName(inviter), - userName2: _roomMsgUserDisplayName(receiver), - relationType: relationType, - ), - type: SCRoomMsgType.cpSystemNotice, - noticeAction: "RELATION_ESTABLISHED", - user: receiver, - toUser: inviter, - targetUserIds: targetUserIds, - giftBatchId: applyId, - role: relationType, - ), - addLocal: true, - ), - ); - } - void _dispatchCpInviteRejectedRoomNotice({ required String groupId, required String applyId, @@ -1988,27 +2070,6 @@ class RealTimeMessagingManager extends ChangeNotifier { ); } - SocialChatUserProfile _cpInviteReceiverProfile(Map? data) { - final receiverData = - data == null - ? const {} - : Map.from(data); - final receiver = _cpInviteReceiverFromMessageData(receiverData); - final userId = _cpInviteReceiverIdFromMessageData(receiverData); - return SocialChatUserProfile( - id: userId, - account: - _firstCpInviteValue([ - receiverData["acceptAccount"]?.toString(), - receiverData["receiverAccount"]?.toString(), - userId, - ]) ?? - userId, - userNickname: receiver.name, - userAvatar: receiver.avatarUrl, - ); - } - List _compactCpNoticeTargetIds( Iterable profiles, ) { @@ -2606,6 +2667,9 @@ class RealTimeMessagingManager extends ChangeNotifier { String msg, V2TimConversation toConversation, ) async { + final chatBubbleCloudData = scEncodeChatBubbleMessageSnapshot( + AccountStorage().getCurrentUser()?.userProfile?.getChatBox(), + ); // 创建文本消息 V2TimValueCallback createTextMessageRes = await TencentImSDKPlugin.v2TIMManager @@ -2628,6 +2692,7 @@ class RealTimeMessagingManager extends ChangeNotifier { id: id, // 创建的messageid receiver: toConversation.userID!, // 接收人id needReadReceipt: true, + cloudCustomData: chatBubbleCloudData, groupID: '', // 是否需要已读回执 ); if (sendMessageRes.code == 0) { @@ -2973,6 +3038,7 @@ class RealTimeMessagingManager extends ChangeNotifier { addMsg(Msg msg) { _scheduleRoomRocketStatusRefreshForGiftMessage(msg); _scheduleCpRelationRefreshForGiftMessage(msg); + _scheduleRoomContributionRefreshForGiftMessage(msg); final mergedGiftMsg = _mergeGiftMessageIfNeeded(msg); if (mergedGiftMsg != null) { msgAllListener?.call(mergedGiftMsg); @@ -2997,6 +3063,12 @@ class RealTimeMessagingManager extends ChangeNotifier { if (SCRoomMsgType.isRocketRewardUserType(msg.type)) { return; } + if (shouldSuppressRoomCpRelationNotice( + messageType: msg.type, + noticeAction: msg.noticeAction, + )) { + return; + } if (msg.type == SCRoomMsgType.rocketLaunchNotice && _hasRoomRocketNoticeMessage(msg)) { return; @@ -3111,6 +3183,7 @@ class RealTimeMessagingManager extends ChangeNotifier { giftTab: relationType, displayText: msg.msg ?? "", durationSeconds: 5, + gameId: msg.giftBatchId, broadcastScope: isRegionBroadcast ? SCFloatingMessage.broadcastScopeRegion : '', ), @@ -3209,6 +3282,35 @@ class RealTimeMessagingManager extends ChangeNotifier { ); } + void _showCpRelationFormedDialogFromBroadcast(SCFloatingMessage message) { + final inviter = SocialChatUserProfile( + id: message.userId, + userNickname: message.userName, + userAvatar: message.userAvatarUrl, + ); + final receiver = SocialChatUserProfile( + id: message.toUserId, + userNickname: message.toUserName, + userAvatar: message.toUserAvatarUrl, + ); + _showCpRelationFormedDialogIfNeeded( + Msg( + groupId: '', + msg: message.displayText, + type: SCRoomMsgType.cpSystemNotice, + noticeAction: 'RELATION_ESTABLISHED', + user: receiver, + toUser: inviter, + targetUserIds: [ + if ((message.userId ?? '').trim().isNotEmpty) message.userId!, + if ((message.toUserId ?? '').trim().isNotEmpty) message.toUserId!, + ], + giftBatchId: message.gameId, + role: message.giftTab, + ), + ); + } + void _showCpInviteRejectedDialogIfNeeded(Msg msg) { final currentProfile = AccountStorage().getCurrentUser()?.userProfile; if (currentProfile == null || @@ -3355,6 +3457,43 @@ class RealTimeMessagingManager extends ChangeNotifier { rtcProvider.scheduleRoomRocketStatusRefreshForGift(roomId: currentRoomId); } + void _scheduleRoomContributionRefreshForGiftMessage(Msg msg) { + final currentContext = context; + if (currentContext == null || !currentContext.mounted) { + return; + } + final rtcProvider = Provider.of( + currentContext, + listen: false, + ); + final currentRoomId = + (rtcProvider.currenRoom?.roomProfile?.roomProfile?.id ?? '').trim(); + final currentRoomGroupId = + (rtcProvider.currenRoom?.roomProfile?.roomProfile?.roomAccount ?? '') + .trim(); + if (!shouldRefreshRoomContributionForGiftMessage( + messageType: msg.type, + messageRoomId: msg.msg, + messageGroupId: msg.groupId, + currentRoomId: currentRoomId, + currentRoomGroupId: currentRoomGroupId, + )) { + return; + } + _roomContributionGiftRefreshTimer?.cancel(); + _roomContributionGiftRefreshTimer = Timer( + _roomContributionGiftRefreshDebounce, + () { + final latestRoomId = + (rtcProvider.currenRoom?.roomProfile?.roomProfile?.id ?? '').trim(); + if (latestRoomId != currentRoomId) { + return; + } + socialChatRoomManager.fetchContributionLevelData(currentRoomId); + }, + ); + } + void _scheduleCpRelationRefreshForGiftMessage(Msg msg) { if (!_isCpRelationGiftMessage(msg)) { return; @@ -4196,7 +4335,8 @@ class RealTimeMessagingManager extends ChangeNotifier { try { final decoded = json.decode(customData); final payload = _broadcastPayloadMap(decoded); - return payload['type'] == SCRoomMsgType.roomRedPacket; + return payload['type'] == SCRoomMsgType.roomRedPacket || + payload['type'] == SCRoomMsgType.cpRelationBroadcast; } catch (_) { return false; } @@ -6077,34 +6217,14 @@ class RealTimeMessagingManager extends ChangeNotifier { if (isRegionBroadcastGroup) { _handleRegionGiftBroadcast(data["data"]); } - } else if (type == SCRoomMsgType.cpSystemNotice) { - final payload = data["data"] ?? data; - final payloadMap = _broadcastPayloadMap(payload); - if (payloadMap.isEmpty) { - return; - } - final msg = Msg.fromJson(payloadMap); - msg.type ??= SCRoomMsgType.cpSystemNotice; - msg.groupId = _firstNonBlank([ - msg.groupId, - _payloadText(payloadMap["groupId"]), - _payloadText(payloadMap["roomId"]), - _payloadText(data["groupId"]), - _payloadText(data["roomId"]), - ]); - msg.noticeAction ??= data["noticeAction"]?.toString(); - if ((msg.role ?? "").trim().isEmpty) { - msg.role = _firstNonBlank([ - _payloadText(payloadMap["role"]), - _payloadText(payloadMap["relationType"]), - _payloadText(data["role"]), - _payloadText(data["relationType"]), - ]); - } - _enqueueCpRelationBroadcastFloatingIfNeeded( - msg, - isRegionBroadcast: isRegionBroadcastGroup, + } else if (type == SCRoomMsgType.cpRelationBroadcast) { + final floatingMessage = buildCpRelationBroadcastFloatingMessage( + data["data"] ?? data, ); + if (floatingMessage != null) { + OverlayManager().addMessage(floatingMessage); + _showCpRelationFormedDialogFromBroadcast(floatingMessage); + } } else if (type == SCRoomMsgType.inviteRoom) { ///邀请进入房间 var fdata = data["data"]; @@ -6820,6 +6940,8 @@ class RealTimeMessagingManager extends ChangeNotifier { _hiddenCurrentRoomRocketLaunchKeys.clear(); _roomRocketRewardPopupRetryTimer?.cancel(); _roomRocketRewardPopupRetryTimer = null; + _roomContributionGiftRefreshTimer?.cancel(); + _roomContributionGiftRefreshTimer = null; for (final timer in _roomRocketRewardHoldTimers.values) { timer.cancel(); } diff --git a/lib/services/general/sc_app_general_manager.dart b/lib/services/general/sc_app_general_manager.dart index 27d6b07..3dcb835 100644 --- a/lib/services/general/sc_app_general_manager.dart +++ b/lib/services/general/sc_app_general_manager.dart @@ -25,6 +25,7 @@ class SCAppGeneralManager extends ChangeNotifier { List countryModeList = []; final Map> _countryMap = {}; final Map _countryByNameMap = {}; + final Map _countryByCodeMap = {}; bool _isFetchingCountryList = false; ///礼物 @@ -114,6 +115,7 @@ class SCAppGeneralManager extends ChangeNotifier { final result = await SCConfigRepositoryImp().loadCountry(); _countryMap.clear(); _countryByNameMap.clear(); + _countryByCodeMap.clear(); countryModeList.clear(); for (final c in result.openCountry ?? const []) { @@ -126,6 +128,10 @@ class SCAppGeneralManager extends ChangeNotifier { if ((c.countryName ?? "").isNotEmpty) { _countryByNameMap[c.countryName!] = c; } + final countryCode = c.alphaTwo?.trim().toUpperCase() ?? ""; + if (countryCode.isNotEmpty) { + _countryByCodeMap[countryCode] = c; + } } _countryMap.forEach((k, v) { @@ -147,6 +153,10 @@ class SCAppGeneralManager extends ChangeNotifier { return _countryByNameMap[countryName]; } + Country? findCountryByCode(String countryCode) { + return _countryByCodeMap[countryCode.trim().toUpperCase()]; + } + ///选择国家 Country? chooseCountry(int subIndex, int cIndex) { var selectCm = countryModeList[subIndex].prefixCountrys[cIndex]; @@ -468,14 +478,41 @@ class SCAppGeneralManager extends ChangeNotifier { } Map> emojiByTab = {}; + List roomEmojiGroups = []; + bool _isFetchingRoomEmojis = false; + bool _hasRoomEmojisLoaded = false; + + bool get isFetchingRoomEmojis => _isFetchingRoomEmojis; + + bool get hasRoomEmojisLoaded => _hasRoomEmojisLoaded; ///emoji表情 - void emojiAll() async { - var roomEmojis = await SCChatRoomRepository().emojiAll(); - for (var value in roomEmojis) { - emojiByTab[value.groupName!] = value.emojis ?? []; + Future emojiAll() async { + if (_isFetchingRoomEmojis || _hasRoomEmojisLoaded) { + return; + } + + _isFetchingRoomEmojis = true; + try { + final roomEmojis = await SCChatRoomRepository().emojiAll(); + roomEmojiGroups = + roomEmojis + .where((group) => (group.emojis ?? const []).isNotEmpty,) + .toList(); + emojiByTab.clear(); + for (final value in roomEmojiGroups) { + final groupName = value.groupName?.trim() ?? ""; + if (groupName.isNotEmpty) { + emojiByTab[groupName] = value.emojis ?? []; + } + } + _hasRoomEmojisLoaded = true; + } catch (_) { + return; + } finally { + _isFetchingRoomEmojis = false; + notifyListeners(); } - notifyListeners(); } ///加载等级资源 diff --git a/lib/shared/business_logic/models/res/sc_room_emoji_res.dart b/lib/shared/business_logic/models/res/sc_room_emoji_res.dart index 92775f4..befe5e4 100644 --- a/lib/shared/business_logic/models/res/sc_room_emoji_res.dart +++ b/lib/shared/business_logic/models/res/sc_room_emoji_res.dart @@ -1,146 +1,178 @@ -/// id : 0 -/// sysOrigin : "" -/// groupCode : "" -/// groupName : "" -/// cover : "" -/// have : false -/// amount : 0.0 -/// emojis : [{"sourceUrl":"","sourceType":0,"coverUrl":"","type":""}] - -class SCRoomEmojiRes { - SCRoomEmojiRes({ - String? id, - String? sysOrigin, - String? groupCode, - String? groupName, - String? cover, - bool? have, - num? amount, - List? emojis,}){ - _id = id; - _sysOrigin = sysOrigin; - _groupCode = groupCode; - _groupName = groupName; - _cover = cover; - _have = have; - _amount = amount; - _emojis = emojis; -} - - SCRoomEmojiRes.fromJson(dynamic json) { - _id = json['id']; - _sysOrigin = json['sysOrigin']; - _groupCode = json['groupCode']; - _groupName = json['groupName']; - _cover = json['cover']; - _have = json['have']; - _amount = json['amount']; - if (json['emojis'] != null) { - _emojis = []; - json['emojis'].forEach((v) { - _emojis?.add(Emojis.fromJson(v)); - }); - } - } - String? _id; - String? _sysOrigin; - String? _groupCode; - String? _groupName; - String? _cover; - bool? _have; - num? _amount; - List? _emojis; -SCRoomEmojiRes copyWith({ String? id, - String? sysOrigin, - String? groupCode, - String? groupName, - String? cover, - bool? have, - num? amount, - List? emojis, -}) => SCRoomEmojiRes( id: id ?? _id, - sysOrigin: sysOrigin ?? _sysOrigin, - groupCode: groupCode ?? _groupCode, - groupName: groupName ?? _groupName, - cover: cover ?? _cover, - have: have ?? _have, - amount: amount ?? _amount, - emojis: emojis ?? _emojis, -); - String? get id => _id; - String? get sysOrigin => _sysOrigin; - String? get groupCode => _groupCode; - String? get groupName => _groupName; - String? get cover => _cover; - bool? get have => _have; - num? get amount => _amount; - List? get emojis => _emojis; - - Map toJson() { - final map = {}; - map['id'] = _id; - map['sysOrigin'] = _sysOrigin; - map['groupCode'] = _groupCode; - map['groupName'] = _groupName; - map['cover'] = _cover; - map['have'] = _have; - map['amount'] = _amount; - if (_emojis != null) { - map['emojis'] = _emojis?.map((v) => v.toJson()).toList(); - } - return map; - } - -} - -/// sourceUrl : "" -/// sourceType : 0 -/// coverUrl : "" -/// type : "" - -class Emojis { - Emojis({ - String? sourceUrl, - num? sourceType, - String? coverUrl, - String? type,}){ - _sourceUrl = sourceUrl; - _sourceType = sourceType; - _coverUrl = coverUrl; - _type = type; -} - - Emojis.fromJson(dynamic json) { - _sourceUrl = json['sourceUrl']; - _sourceType = json['sourceType']; - _coverUrl = json['coverUrl']; - _type = json['type']; - } - String? _sourceUrl; - num? _sourceType; - String? _coverUrl; - String? _type; -Emojis copyWith({ String? sourceUrl, - num? sourceType, - String? coverUrl, - String? type, -}) => Emojis( sourceUrl: sourceUrl ?? _sourceUrl, - sourceType: sourceType ?? _sourceType, - coverUrl: coverUrl ?? _coverUrl, - type: type ?? _type, -); - String? get sourceUrl => _sourceUrl; - num? get sourceType => _sourceType; - String? get coverUrl => _coverUrl; - String? get type => _type; - - Map toJson() { - final map = {}; - map['sourceUrl'] = _sourceUrl; - map['sourceType'] = _sourceType; - map['coverUrl'] = _coverUrl; - map['type'] = _type; - return map; - } - -} \ No newline at end of file +// id : 0 +// sysOrigin : "" +// groupCode : "" +// groupName : "" +// cover : "" +// have : false +// amount : 0.0 +// emojis : [{"sourceUrl":"","sourceType":0,"coverUrl":"","type":""}] + +class SCRoomEmojiRes { + SCRoomEmojiRes({ + String? id, + String? sysOrigin, + String? groupCode, + String? groupName, + String? cover, + bool? have, + num? amount, + List? emojis,}){ + _id = id; + _sysOrigin = sysOrigin; + _groupCode = groupCode; + _groupName = groupName; + _cover = cover; + _have = have; + _amount = amount; + _emojis = emojis; +} + + SCRoomEmojiRes.fromJson(dynamic json) { + final map = json is Map ? json : const {}; + _id = _stringOrNull(map['id']); + _sysOrigin = _stringOrNull(map['sysOrigin']); + _groupCode = _stringOrNull(map['groupCode']); + _groupName = _stringOrNull(map['groupName']); + _cover = _stringOrNull(map['cover']); + _have = _boolOrNull(map['have']); + _amount = _numOrNull(map['amount']); + if (map['emojis'] is List) { + _emojis = []; + map['emojis'].forEach((v) { + _emojis?.add(Emojis.fromJson(v)); + }); + } + } + String? _id; + String? _sysOrigin; + String? _groupCode; + String? _groupName; + String? _cover; + bool? _have; + num? _amount; + List? _emojis; +SCRoomEmojiRes copyWith({ String? id, + String? sysOrigin, + String? groupCode, + String? groupName, + String? cover, + bool? have, + num? amount, + List? emojis, +}) => SCRoomEmojiRes( id: id ?? _id, + sysOrigin: sysOrigin ?? _sysOrigin, + groupCode: groupCode ?? _groupCode, + groupName: groupName ?? _groupName, + cover: cover ?? _cover, + have: have ?? _have, + amount: amount ?? _amount, + emojis: emojis ?? _emojis, +); + String? get id => _id; + String? get sysOrigin => _sysOrigin; + String? get groupCode => _groupCode; + String? get groupName => _groupName; + String? get cover => _cover; + bool? get have => _have; + num? get amount => _amount; + List? get emojis => _emojis; + + Map toJson() { + final map = {}; + map['id'] = _id; + map['sysOrigin'] = _sysOrigin; + map['groupCode'] = _groupCode; + map['groupName'] = _groupName; + map['cover'] = _cover; + map['have'] = _have; + map['amount'] = _amount; + if (_emojis != null) { + map['emojis'] = _emojis?.map((v) => v.toJson()).toList(); + } + return map; + } + +} + +/// sourceUrl : "" +/// sourceType : 0 +/// coverUrl : "" +/// type : "" + +class Emojis { + Emojis({ + String? sourceUrl, + num? sourceType, + String? coverUrl, + String? type,}){ + _sourceUrl = sourceUrl; + _sourceType = sourceType; + _coverUrl = coverUrl; + _type = type; +} + + Emojis.fromJson(dynamic json) { + final map = json is Map ? json : const {}; + _sourceUrl = _stringOrNull(map['sourceUrl']); + _sourceType = _numOrNull(map['sourceType']); + _coverUrl = _stringOrNull(map['coverUrl']); + _type = _stringOrNull(map['type']); + } + String? _sourceUrl; + num? _sourceType; + String? _coverUrl; + String? _type; +Emojis copyWith({ String? sourceUrl, + num? sourceType, + String? coverUrl, + String? type, +}) => Emojis( sourceUrl: sourceUrl ?? _sourceUrl, + sourceType: sourceType ?? _sourceType, + coverUrl: coverUrl ?? _coverUrl, + type: type ?? _type, +); + String? get sourceUrl => _sourceUrl; + num? get sourceType => _sourceType; + String? get coverUrl => _coverUrl; + String? get type => _type; + + Map toJson() { + final map = {}; + map['sourceUrl'] = _sourceUrl; + map['sourceType'] = _sourceType; + map['coverUrl'] = _coverUrl; + map['type'] = _type; + return map; + } + +} +String? _stringOrNull(dynamic value) { + if (value == null) { + return null; + } + return value.toString(); +} + +num? _numOrNull(dynamic value) { + if (value is num) { + return value; + } + return num.tryParse(value?.toString() ?? ""); +} + +bool? _boolOrNull(dynamic value) { + if (value is bool) { + return value; + } + if (value is num) { + return value != 0; + } + final normalized = value?.toString().trim().toLowerCase(); + if (normalized == "true" || normalized == "1") { + return true; + } + if (normalized == "false" || normalized == "0") { + return false; + } + return null; +} diff --git a/lib/shared/data_sources/sources/local/floating_screen_manager.dart b/lib/shared/data_sources/sources/local/floating_screen_manager.dart index c2f36f5..ffe9898 100644 --- a/lib/shared/data_sources/sources/local/floating_screen_manager.dart +++ b/lib/shared/data_sources/sources/local/floating_screen_manager.dart @@ -25,6 +25,61 @@ import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart'; typedef FloatingScreenManager = OverlayManager; +@visibleForTesting +bool isFloatingAllowedRouteName( + String? routeName, { + required bool rootTabAllowed, +}) { + final normalizedRoute = (routeName ?? '').split('?').first.trim(); + if (normalizedRoute.isEmpty || normalizedRoute == '/') { + return rootTabAllowed; + } + return normalizedRoute == '/main/messagePage' || + normalizedRoute == '/chat' || + normalizedRoute == '/systemChat' || + normalizedRoute == '/room'; +} + +@visibleForTesting +bool shouldDismissFloatingForLeftSwipe( + double dragOffset, { + double threshold = 72, +}) { + return dragOffset <= -threshold; +} + +class SCFloatingScreenRouteObserver extends NavigatorObserver { + void _update(Route? route) { + if (route is PageRoute) { + OverlayManager().setCurrentPageRouteName(route.settings.name); + } + } + + @override + void didPush(Route route, Route? previousRoute) { + super.didPush(route, previousRoute); + _update(route); + } + + @override + void didPop(Route route, Route? previousRoute) { + super.didPop(route, previousRoute); + _update(previousRoute); + } + + @override + void didReplace({Route? newRoute, Route? oldRoute}) { + super.didReplace(newRoute: newRoute, oldRoute: oldRoute); + _update(newRoute); + } + + @override + void didRemove(Route route, Route? previousRoute) { + super.didRemove(route, previousRoute); + _update(previousRoute); + } +} + class OverlayManager { static const int _maxDeferredRegionRedPacketCount = 12; static const Duration _redPacketFloatingDedupWindow = Duration(minutes: 30); @@ -48,6 +103,8 @@ class OverlayManager { OverlayEntry? _currentOverlayEntry; SCFloatingMessage? _currentMessage; bool _homeRootTabsVisible = false; + String? _currentPageRouteName; + bool _allowedPageRefreshScheduled = false; int _suppressedCount = 0; bool _isProcessing = false; @@ -184,6 +241,10 @@ class OverlayManager { return 'global_lucky_gift_win_fallback|$roomId|$userId|$toUserId|$giftId|$coins|$multiple'; } if (message.type == 6) { + final eventId = message.gameId?.trim() ?? ''; + if (eventId.isNotEmpty) { + return 'cp_relation_event|$eventId'; + } final roomId = message.roomId?.trim() ?? ''; final action = message.giftId?.trim() ?? ''; final relationType = message.giftTab?.trim() ?? ''; @@ -435,58 +496,68 @@ class OverlayManager { SCFloatingMessage message, VoidCallback onComplete, ) { + final Widget child; switch (message.type) { case 0: - return FloatingLuckGiftScreenWidget( + child = FloatingLuckGiftScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 1: //房间礼物 - return FloatingGiftScreenWidget( + child = FloatingGiftScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 2: //游戏中奖 - return FloatingGameScreenWidget( + child = FloatingGameScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case FloatingLuckyGiftGlobalScreenWidget.floatingType: // Global lucky gift win. - return FloatingLuckyGiftGlobalScreenWidget( + child = FloatingLuckyGiftGlobalScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 3: //火箭 - return FloatingRoomRocketScreenWidget( + child = FloatingRoomRocketScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 4: //红包 - return FloatingRoomRedenvelopeScreenWidget( + child = FloatingRoomRedenvelopeScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 5: //VIP进房飘窗 - return FloatingVipEntryScreenWidget( + child = FloatingVipEntryScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; case 6: //CP / 挚友关系飘窗 - return FloatingCpRelationScreenWidget( + child = FloatingCpRelationScreenWidget( message: message, onAnimationCompleted: onComplete, ); + break; default: onComplete(); - return Container(); + child = const SizedBox.shrink(); } + return _SwipeToDismissFloating(onDismiss: onComplete, child: child); } int? _stackSlotKeyFor(SCFloatingMessage message) { @@ -616,9 +687,39 @@ class OverlayManager { return; } _homeRootTabsVisible = visible; - if (!visible) { - _removeActiveRegionBroadcastMessage(); - _removeRegionBroadcastMessages(); + _scheduleAllowedPageVisibilityRefresh(); + } + + void setCurrentPageRouteName(String? routeName) { + if (_currentPageRouteName == routeName) { + return; + } + _currentPageRouteName = routeName; + _scheduleAllowedPageVisibilityRefresh(); + } + + void _scheduleAllowedPageVisibilityRefresh() { + if (_allowedPageRefreshScheduled) { + return; + } + _allowedPageRefreshScheduled = true; + WidgetsBinding.instance.addPostFrameCallback((_) { + _allowedPageRefreshScheduled = false; + if (!_isDisposed) { + _refreshAllowedPageVisibility(); + } + }); + } + + bool get _isAllowedPageVisible => isFloatingAllowedRouteName( + _currentPageRouteName, + rootTabAllowed: _homeRootTabsVisible, + ); + + void _refreshAllowedPageVisibility() { + if (!_isAllowedPageVisible) { + _removeActiveMessage(scheduleNext: false); + _removeAllStackedMessages(); return; } _restoreDeferredRegionRedPacketMessages(); @@ -672,6 +773,8 @@ class OverlayManager { void dispose() { _isDisposed = true; _homeRootTabsVisible = false; + _currentPageRouteName = null; + _allowedPageRefreshScheduled = false; _suppressedCount = 0; _currentOverlayEntry?.remove(); _currentOverlayEntry = null; @@ -846,6 +949,9 @@ class OverlayManager { if (SCGlobalConfig.isFloatingBroadcastClosed) { return false; } + if (!_isAllowedPageVisible) { + return false; + } if (message.isRegionBroadcast) { return _shouldDisplayRegionBroadcastMessage(context, message); } @@ -897,6 +1003,9 @@ class OverlayManager { if (SCGlobalConfig.isFloatingBroadcastClosed) { return false; } + if (!_isAllowedPageVisible) { + return false; + } final rtcProvider = Provider.of( context, listen: false, @@ -937,13 +1046,13 @@ class OverlayManager { if (rtcProvider.shouldShowRoomVisualEffects) { return true; } - return SCGlobalConfig.isFloatingBroadcastAll && _homeRootTabsVisible; + return SCGlobalConfig.isFloatingBroadcastAll && _isAllowedPageVisible; } if (isGlobalStackedBroadcast && rtcProvider.shouldShowRoomVisualEffects) { return true; } if (isGlobalStackedBroadcast) { - return _homeRootTabsVisible; + return _isAllowedPageVisible; } if (SCGlobalConfig.isFloatingBroadcastRoomOnly) { return false; @@ -951,37 +1060,7 @@ class OverlayManager { if (rtcProvider.shouldShowRoomVisualEffects) { return false; } - return SCGlobalConfig.isFloatingBroadcastAll && _homeRootTabsVisible; - } - - void _removeRegionBroadcastMessages() { - final newQueue = SCPriorityQueue( - (a, b) => b.priority.compareTo(a.priority), - ); - - while (_messageQueue.isNotEmpty) { - final message = _messageQueue.removeFirst(); - if (!message.isRegionBroadcast || - _isCrossRoomRegionFloatingMessage(message)) { - newQueue.add(message); - } - } - - while (newQueue.isNotEmpty) { - _messageQueue.add(newQueue.removeFirst()); - } - } - - void _removeActiveRegionBroadcastMessage() { - final activeMessage = _currentMessage; - if (activeMessage != null && activeMessage.isRegionBroadcast) { - _currentOverlayEntry?.remove(); - _currentOverlayEntry = null; - _currentMessage = null; - _isPlaying = false; - } - _removeStackedMessagesWhere((message) => message.isRegionBroadcast); - _safeScheduleNext(); + return SCGlobalConfig.isFloatingBroadcastAll && _isAllowedPageVisible; } void _removeActiveRoomMessage({ @@ -1065,3 +1144,57 @@ class OverlayManager { _markStackedEntriesNeedsBuild(); } } + +class _SwipeToDismissFloating extends StatefulWidget { + const _SwipeToDismissFloating({required this.child, required this.onDismiss}); + + final Widget child; + final VoidCallback onDismiss; + + @override + State<_SwipeToDismissFloating> createState() => + _SwipeToDismissFloatingState(); +} + +class _SwipeToDismissFloatingState extends State<_SwipeToDismissFloating> { + double _dragOffset = 0; + + void _handleDragUpdate(DragUpdateDetails details) { + final nextOffset = _dragOffset + details.delta.dx; + if (nextOffset > 0) { + if (_dragOffset != 0) { + setState(() => _dragOffset = 0); + } + return; + } + setState(() => _dragOffset = nextOffset); + } + + void _handleDragEnd(DragEndDetails details) { + if (shouldDismissFloatingForLeftSwipe(_dragOffset)) { + widget.onDismiss(); + return; + } + if (_dragOffset != 0) { + setState(() => _dragOffset = 0); + } + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onHorizontalDragUpdate: _handleDragUpdate, + onHorizontalDragEnd: _handleDragEnd, + onHorizontalDragCancel: () { + if (_dragOffset != 0) { + setState(() => _dragOffset = 0); + } + }, + child: Transform.translate( + offset: Offset(_dragOffset, 0), + child: widget.child, + ), + ); + } +} diff --git a/lib/shared/tools/sc_chat_bubble_message_data.dart b/lib/shared/tools/sc_chat_bubble_message_data.dart new file mode 100644 index 0000000..b6b6faf --- /dev/null +++ b/lib/shared/tools/sc_chat_bubble_message_data.dart @@ -0,0 +1,83 @@ +import 'dart:convert'; + +import 'package:yumi/shared/business_logic/models/res/login_res.dart'; + +const String _chatBubbleSnapshotKey = 'yumiChatBubbleV1'; + +class SCChatBubbleMessageSnapshot { + final bool hasSnapshot; + final String imageUrl; + + const SCChatBubbleMessageSnapshot({ + required this.hasSnapshot, + required this.imageUrl, + }); +} + +String scResolveChatBubbleImageUrl(PropsResources? resource) { + final candidates = [ + resource?.imSendCoverUrl, + resource?.imOpenedUrl, + resource?.imOpenedUrlTwo, + resource?.imNotOpenedUrl, + resource?.roomSendCoverUrl, + resource?.roomOpenedUrl, + resource?.roomNotOpenedUrl, + resource?.cover, + resource?.expand, + resource?.sourceUrl, + ]; + return _firstNonBlank([...candidates.where(_isSvgaResource), ...candidates]); +} + +String scEncodeChatBubbleMessageSnapshot(PropsResources? resource) { + return jsonEncode({ + _chatBubbleSnapshotKey: scResolveChatBubbleImageUrl(resource), + }); +} + +SCChatBubbleMessageSnapshot scDecodeChatBubbleMessageSnapshot( + String? cloudCustomData, +) { + final data = cloudCustomData?.trim() ?? ''; + if (data.isEmpty) { + return const SCChatBubbleMessageSnapshot(hasSnapshot: false, imageUrl: ''); + } + try { + final decoded = jsonDecode(data); + if (decoded is! Map || !decoded.containsKey(_chatBubbleSnapshotKey)) { + return const SCChatBubbleMessageSnapshot( + hasSnapshot: false, + imageUrl: '', + ); + } + final imageUrl = decoded[_chatBubbleSnapshotKey]; + if (imageUrl is! String) { + return const SCChatBubbleMessageSnapshot( + hasSnapshot: false, + imageUrl: '', + ); + } + return SCChatBubbleMessageSnapshot( + hasSnapshot: true, + imageUrl: imageUrl.trim(), + ); + } catch (_) { + return const SCChatBubbleMessageSnapshot(hasSnapshot: false, imageUrl: ''); + } +} + +bool _isSvgaResource(String? resource) { + final lower = resource?.trim().toLowerCase() ?? ''; + return lower.endsWith('.svga') || lower.contains('.svga?'); +} + +String _firstNonBlank(Iterable values) { + for (final value in values) { + final text = value?.trim(); + if (text != null && text.isNotEmpty) { + return text; + } + } + return ''; +} diff --git a/lib/shared/tools/sc_conversation_time_formatter.dart b/lib/shared/tools/sc_conversation_time_formatter.dart new file mode 100644 index 0000000..e18ab86 --- /dev/null +++ b/lib/shared/tools/sc_conversation_time_formatter.dart @@ -0,0 +1,18 @@ +class SCConversationTimeFormatter { + const SCConversationTimeFormatter._(); + + static String format(DateTime date, {DateTime? now}) { + final current = now ?? DateTime.now(); + if (date.year != current.year) { + return '${date.year}-${_twoDigits(date.month)}-${_twoDigits(date.day)}'; + } + + final time = '${_twoDigits(date.hour)}.${_twoDigits(date.minute)}'; + if (date.month != current.month || date.day != current.day) { + return '${_twoDigits(date.month)}-${_twoDigits(date.day)} $time'; + } + return time; + } + + static String _twoDigits(int value) => value.toString().padLeft(2, '0'); +} diff --git a/lib/shared/tools/sc_google_auth_utils.dart b/lib/shared/tools/sc_google_auth_utils.dart index 942e67d..f9e3dc0 100644 --- a/lib/shared/tools/sc_google_auth_utils.dart +++ b/lib/shared/tools/sc_google_auth_utils.dart @@ -24,6 +24,9 @@ class SCGoogleAuthService { static Future signInWithGoogle() async { try { await initialize(); + // 主动登录前清理上次账号,确保重新显示账号选择器 + await _g.signOut(); + await FirebaseAuth.instance.signOut(); // 触发谷歌登录 final GoogleSignInAccount? googleAccount = await _g.signIn(); if (googleAccount == null) return null; diff --git a/lib/ui_kit/widgets/msg/message_conversation_list_page.dart b/lib/ui_kit/widgets/msg/message_conversation_list_page.dart index d6218fc..0cfadcc 100644 --- a/lib/ui_kit/widgets/msg/message_conversation_list_page.dart +++ b/lib/ui_kit/widgets/msg/message_conversation_list_page.dart @@ -1,7 +1,6 @@ import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; -import 'package:flutter_smart_dialog/flutter_smart_dialog.dart'; import 'package:yumi/ui_kit/components/sc_debounce_widget.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:provider/provider.dart'; @@ -13,13 +12,12 @@ import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart'; import 'package:tencent_cloud_chat_sdk/models/v2_tim_text_elem.dart'; import 'package:yumi/app_localizations.dart'; -import 'package:yumi/ui_kit/components/dialog/dialog_base.dart'; import 'package:yumi/ui_kit/components/sc_compontent.dart'; import 'package:yumi/ui_kit/components/text/sc_text.dart'; import 'package:yumi/app/constants/sc_global_config.dart'; import 'package:yumi/app/routes/sc_fluro_navigator.dart'; import 'package:yumi/shared/data_sources/models/enum/sc_sysytem_message_type.dart'; -import 'package:yumi/shared/tools/sc_date_utils.dart'; +import 'package:yumi/shared/tools/sc_conversation_time_formatter.dart'; import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart'; import 'package:yumi/shared/business_logic/models/res/login_res.dart'; import 'package:yumi/shared/tools/sc_user_id_utils.dart'; @@ -46,6 +44,7 @@ class _MessageConversationListPageState extends State { final Map _conversationUserCache = {}; final Set _loadingConversationUserIds = {}; + String? _deleteActionConversationId; @override void initState() { @@ -69,177 +68,199 @@ class _MessageConversationListPageState if (searchQuery.isNotEmpty) { _loadSearchUserInfo(provider.conversationList); } - return Column( - children: [ - Expanded( - child: CustomScrollView( - shrinkWrap: true, - slivers: [ - SliverToBoxAdapter( - child: - searchQuery.isEmpty && - provider.customerInfo != null && - provider.customerInfo?.id != - AccountStorage() - .getCurrentUser() - ?.userProfile - ?.id - ? Stack( - children: [ - Container( - margin: EdgeInsets.symmetric( - horizontal: 15.w, - ), - child: Row( - children: [ - Image.asset( - "sc_images/general/sc_icon_logo.png", - height: 48.w, - ), - SizedBox(width: 10.w), - Expanded( - child: Column( - crossAxisAlignment: - CrossAxisAlignment.start, - children: [ - text( + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: _dismissDeleteAction, + child: Column( + children: [ + Expanded( + child: CustomScrollView( + shrinkWrap: true, + slivers: [ + SliverToBoxAdapter( + child: + searchQuery.isEmpty && + provider.customerInfo != null && + provider.customerInfo?.id != + AccountStorage() + .getCurrentUser() + ?.userProfile + ?.id + ? Stack( + children: [ + Container( + margin: EdgeInsets.symmetric( + horizontal: 15.w, + ), + child: Row( + children: [ + Image.asset( + "sc_images/general/sc_icon_logo.png", + height: 48.w, + ), + SizedBox(width: 10.w), + Expanded( + child: Column( + crossAxisAlignment: + CrossAxisAlignment.start, + children: [ + text( + SCAppLocalizations.of( + context, + )!.contactUs, + fontWeight: FontWeight.w600, + textColor: + widget.isRoom + ? Colors.white + : Colors.black, + fontSize: 15.sp, + ), + Row( + children: [ + Expanded( + child: Text( + "[${SCAppLocalizations.of(context)!.newMessage}]", + maxLines: 1, + overflow: + TextOverflow.ellipsis, + style: TextStyle( + fontSize: ScreenUtil() + .setSp(13), + color: + widget.isRoom + ? Colors.white54 + : Color( + 0xFF666666, + ), + ), + ), + ), + SizedBox(width: 5.w), + ], + ), + ], + ), + ), + SCDebounceWidget( + child: Container( + alignment: Alignment.center, + width: 88.w, + height: 26.w, + decoration: BoxDecoration( + borderRadius: + BorderRadius.circular(18.w), + gradient: LinearGradient( + colors: [ + Color(0xff963EFB), + Color(0xffDCAEF6), + ], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + ), + child: text( SCAppLocalizations.of( context, )!.contactUs, fontWeight: FontWeight.w600, - textColor: - widget.isRoom - ? Colors.white - : Colors.black, - fontSize: 15.sp, - ), - Row( - children: [ - Expanded( - child: Text( - "[${SCAppLocalizations.of(context)!.newMessage}]", - maxLines: 1, - overflow: - TextOverflow.ellipsis, - style: TextStyle( - fontSize: ScreenUtil() - .setSp(13), - color: - widget.isRoom - ? Colors.white54 - : Color( - 0xFF666666, - ), - ), - ), - ), - SizedBox(width: 5.w), - ], - ), - ], - ), - ), - SCDebounceWidget( - child: Container( - alignment: Alignment.center, - width: 88.w, - height: 26.w, - decoration: BoxDecoration( - borderRadius: BorderRadius.circular( - 18.w, - ), - gradient: LinearGradient( - colors: [ - Color(0xff963EFB), - Color(0xffDCAEF6), - ], - begin: Alignment.topLeft, - end: Alignment.bottomRight, + textColor: Colors.white, + fontSize: 13.sp, ), ), - child: text( - SCAppLocalizations.of( + onTap: () async { + if (_dismissDeleteAction()) { + return; + } + var conversation = + V2TimConversation( + type: + ConversationType + .V2TIM_C2C, + userID: + provider.customerInfo?.id, + conversationID: '', + ); + provider.updateCustomerCount(0); + var bool = + await Provider.of( + context, + listen: false, + ).startConversation( + conversation, + ); + if (!bool) return; + var json = jsonEncode( + conversation.toJson(), + ); + SCNavigatorUtils.push( context, - )!.contactUs, - fontWeight: FontWeight.w600, - textColor: Colors.white, - fontSize: 13.sp, - ), + "${SCChatRouter.chat}?conversation=${Uri.encodeComponent(json)}", + ); + }, ), - onTap: () async { - var conversation = V2TimConversation( - type: ConversationType.V2TIM_C2C, - userID: provider.customerInfo?.id, - conversationID: '', - ); - provider.updateCustomerCount(0); - var bool = - await Provider.of( - context, - listen: false, - ).startConversation(conversation); - if (!bool) return; - var json = jsonEncode( - conversation.toJson(), - ); - SCNavigatorUtils.push( - context, - "${SCChatRouter.chat}?conversation=${Uri.encodeComponent(json)}", - ); - }, - ), - ], + ], + ), ), - ), - // 未读数量 - PositionedDirectional( - bottom: 0, - end: 10.w, - child: Visibility( - visible: provider.customerUnReadCount > 0, - child: Container( - padding: EdgeInsets.symmetric( - horizontal: 6.w, - ), - alignment: Alignment.center, - height: 16.w, - decoration: BoxDecoration( - //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]), - color: Colors.red, - shape: BoxShape.circle, - //borderRadius: BorderRadius.all(Radius.circular(7.w)), - ), - child: Text( - "${provider.customerUnReadCount > 99 ? '99+' : provider.customerUnReadCount}", - style: TextStyle( - fontSize: 10.sp, - color: Color(0xffffffff), - fontWeight: FontWeight.w400, - decoration: TextDecoration.none, + // 未读数量 + PositionedDirectional( + bottom: 0, + end: 10.w, + child: Visibility( + visible: provider.customerUnReadCount > 0, + child: Container( + padding: EdgeInsets.symmetric( + horizontal: 6.w, + ), + alignment: Alignment.center, + height: 16.w, + decoration: BoxDecoration( + //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]), + color: Colors.red, + shape: BoxShape.circle, + //borderRadius: BorderRadius.all(Radius.circular(7.w)), + ), + child: Text( + "${provider.customerUnReadCount > 99 ? '99+' : provider.customerUnReadCount}", + style: TextStyle( + fontSize: 10.sp, + color: Color(0xffffffff), + fontWeight: FontWeight.w400, + decoration: TextDecoration.none, + ), ), ), ), ), - ), - ], - ) - : Container(), - ), - SliverToBoxAdapter( - child: _msgListView( - conversationList, - isRoom: widget.isRoom, + ], + ) + : Container(), ), - ), - ], + SliverToBoxAdapter( + child: _msgListView( + conversationList, + isRoom: widget.isRoom, + ), + ), + ], + ), ), - ), - ], + ], + ), ); }, ); } + bool _dismissDeleteAction() { + if (_deleteActionConversationId == null) { + return false; + } + setState(() { + _deleteActionConversationId = null; + }); + return true; + } + Widget _msgListView( List chatList, { EdgeInsetsGeometry? margin, @@ -269,9 +290,9 @@ class _MessageConversationListPageState ), separatorBuilder: (_, index) => Divider( - color: Colors.black12, - indent: 65.w, - endIndent: 15.w, + color: const Color(0xFF0E5B42).withValues(alpha: 0.7), + indent: 64.w, + endIndent: 0, height: 0.5.w, thickness: 0.5.w, ), @@ -291,6 +312,28 @@ class _MessageConversationListPageState index: index, isRoom: isRoom, initialUser: _cachedConversationUser(conversation), + isDeleteActionVisible: + _deleteActionConversationId == conversation.conversationID, + isAnyDeleteActionVisible: _deleteActionConversationId != null, + onDismissDeleteAction: _dismissDeleteAction, + onLongPress: () { + setState(() { + _deleteActionConversationId = conversation.conversationID; + }); + }, + onDelete: () async { + await Provider.of( + context, + listen: false, + ).deleteConversationById(conversation.conversationID); + if (!mounted || + _deleteActionConversationId != conversation.conversationID) { + return; + } + setState(() { + _deleteActionConversationId = null; + }); + }, key: Key(conversation.conversationID), ); } @@ -384,6 +427,11 @@ class ConversationItem extends StatefulWidget { final int index; final bool isRoom; final SocialChatUserProfile? initialUser; + final bool isDeleteActionVisible; + final bool isAnyDeleteActionVisible; + final VoidCallback onDismissDeleteAction; + final VoidCallback onLongPress; + final Future Function() onDelete; const ConversationItem({ super.key, @@ -391,6 +439,11 @@ class ConversationItem extends StatefulWidget { required this.index, required this.isRoom, this.initialUser, + required this.isDeleteActionVisible, + required this.isAnyDeleteActionVisible, + required this.onDismissDeleteAction, + required this.onLongPress, + required this.onDelete, }); @override @@ -526,6 +579,10 @@ class _ConversationItemState extends State { }*/ return GestureDetector( onTap: () async { + if (widget.isAnyDeleteActionVisible) { + widget.onDismissDeleteAction(); + return; + } if (_isC2CConversation && _effectiveUserId.isEmpty) { return; } @@ -551,9 +608,7 @@ class _ConversationItemState extends State { "$route?conversation=${Uri.encodeComponent(json)}", ); }, - onLongPress: () { - showDeleteConfirm(); - }, + onLongPress: widget.onLongPress, child: Container( decoration: BoxDecoration( //color: Colors.white, @@ -562,15 +617,19 @@ class _ConversationItemState extends State { children: [ Container( width: ScreenUtil().screenWidth, - padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w), + height: 76.w, + padding: EdgeInsets.symmetric(horizontal: 0.w, vertical: 10.w), decoration: BoxDecoration( - //color: Colors.white, + color: + widget.isDeleteActionVisible + ? Colors.white.withValues(alpha: 0.06) + : Colors.transparent, ), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - head(url: _displayAvatar, width: 45.w), - SizedBox(width: 6.w), + head(url: _displayAvatar, width: 56.w), + SizedBox(width: 8.w), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, @@ -585,11 +644,8 @@ class _ConversationItemState extends State { maxWidth: 152.w, _displayName, fontSize: 14.sp, - fontWeight: FontWeight.w500, - textColor: - widget.isRoom - ? Colors.black - : Colors.white, + fontWeight: FontWeight.w700, + textColor: Colors.white, type: _isC2CConversation ? user?.getVIP()?.name ?? "" @@ -602,8 +658,7 @@ class _ConversationItemState extends State { ), SizedBox(width: 6.w), Text( - SCMDateUtils.formatMessageTime( - context, + SCConversationTimeFormatter.format( DateTime.fromMillisecondsSinceEpoch( (conversation.lastMessage!.timestamp ?? 0) * 1000, @@ -611,10 +666,7 @@ class _ConversationItemState extends State { ), style: TextStyle( fontSize: 13.sp, - color: - widget.isRoom - ? Colors.white54 - : Color(0xff8d8d8d), + color: Colors.white.withValues(alpha: 0.5), fontWeight: FontWeight.w400, decoration: TextDecoration.none, height: 1, @@ -632,10 +684,7 @@ class _ConversationItemState extends State { overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: ScreenUtil().setSp(13), - color: - widget.isRoom - ? Colors.white54 - : Color(0xFF666666), + color: Colors.white.withValues(alpha: 0.5), ), ), ), @@ -669,6 +718,21 @@ class _ConversationItemState extends State { ], ), ), + if (widget.isDeleteActionVisible) + SCDebounceWidget( + onTap: widget.onDelete, + child: SizedBox( + width: 50.w, + height: 50.w, + child: Center( + child: Image.asset( + "sc_images/msg/sc_icon_msg_menu_delete.png", + width: 28.w, + height: 28.w, + ), + ), + ), + ), ], ), ), @@ -678,28 +742,6 @@ class _ConversationItemState extends State { ); } - void showDeleteConfirm() { - SmartDialog.show( - tag: "showConfirmDialog", - alignment: Alignment.center, - debounce: true, - animationType: SmartAnimationType.fade, - builder: (_) { - return MsgDialog( - title: SCAppLocalizations.of(context)!.tips, - msg: SCAppLocalizations.of(context)!.deleteConversationTips, - btnText: SCAppLocalizations.of(context)!.confirm, - onEnsure: () async { - Provider.of( - context, - listen: false, - ).clearC2CHistoryMessage(conversation.conversationID, true); - }, - ); - }, - ); - } - void loadUserInfo() { if (!_shouldLoadUserInfo) return; final userId = _effectiveUserId; diff --git a/lib/ui_kit/widgets/room/cp/room_cp_invite_dialog.dart b/lib/ui_kit/widgets/room/cp/room_cp_invite_dialog.dart index cb91f2c..6f96640 100644 --- a/lib/ui_kit/widgets/room/cp/room_cp_invite_dialog.dart +++ b/lib/ui_kit/widgets/room/cp/room_cp_invite_dialog.dart @@ -368,11 +368,13 @@ class _RoomCpInviteDialogState extends State { fit: BoxFit.contain, ), ), - Positioned( - left: 65.w, - top: 74.w, - child: _CountdownRow(text: _countdownText), - ), + if (widget.actionState != RoomCpInviteActionState.accepted && + widget.actionState != RoomCpInviteActionState.rejected) + Positioned( + left: 65.w, + top: 74.w, + child: _CountdownRow(text: _countdownText), + ), ], ), ), diff --git a/lib/ui_kit/widgets/room/rocket/room_rocket_floating_entry.dart b/lib/ui_kit/widgets/room/rocket/room_rocket_floating_entry.dart index 7a4f0fa..64b70f2 100644 --- a/lib/ui_kit/widgets/room/rocket/room_rocket_floating_entry.dart +++ b/lib/ui_kit/widgets/room/rocket/room_rocket_floating_entry.dart @@ -32,9 +32,11 @@ class RoomRocketFloatingEntry extends StatelessWidget { @override Widget build(BuildContext context) { - return Selector( - selector: (_, provider) => provider.roomRocketStatus, - builder: (context, status, child) { + final provider = context.read(); + return AnimatedBuilder( + animation: provider, + builder: (context, child) { + final status = provider.roomRocketStatus; if (status == null || !status.isEnabled) { return const SizedBox.shrink(); } diff --git a/lib/ui_kit/widgets/room/room_bottom_widget.dart b/lib/ui_kit/widgets/room/room_bottom_widget.dart index a04f178..a55095e 100644 --- a/lib/ui_kit/widgets/room/room_bottom_widget.dart +++ b/lib/ui_kit/widgets/room/room_bottom_widget.dart @@ -38,9 +38,11 @@ class RoomGiftComboFloatingLayer extends StatelessWidget { @override Widget build(BuildContext context) { - return Selector( - selector: (context, provider) => _shouldShowRoomBottomMic(provider), - builder: (context, showMic, child) { + final provider = context.read(); + return AnimatedBuilder( + animation: provider, + builder: (context, child) { + final showMic = _shouldShowRoomBottomMic(provider); return LayoutBuilder( builder: (context, constraints) { final inputWidth = _resolveRoomBottomInputWidth( @@ -81,15 +83,16 @@ class _RoomBottomWidgetState extends State { @override Widget build(BuildContext context) { + final provider = context.read(); return SizedBox( height: _floatingButtonHostHeight.w, - child: Selector( - selector: - (context, provider) => _RoomBottomSnapshot( - showMic: _shouldShowRoomBottomMic(provider), - isMic: provider.isMic, - ), - builder: (context, bottomSnapshot, child) { + child: AnimatedBuilder( + animation: provider, + builder: (context, child) { + final bottomSnapshot = _RoomBottomSnapshot( + showMic: _shouldShowRoomBottomMic(provider), + isMic: provider.isMic, + ); return LayoutBuilder( builder: (context, constraints) { final inputWidth = _resolveRoomBottomInputWidth( diff --git a/lib/ui_kit/widgets/room/room_emoji_asset_image.dart b/lib/ui_kit/widgets/room/room_emoji_asset_image.dart index 885cdaf..ca610f2 100644 --- a/lib/ui_kit/widgets/room/room_emoji_asset_image.dart +++ b/lib/ui_kit/widgets/room/room_emoji_asset_image.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:yumi/ui_kit/components/sc_compontent.dart'; +import 'package:yumi/ui_kit/widgets/svga/sc_network_svga_widget.dart'; class RoomEmojiAssetImage extends StatefulWidget { const RoomEmojiAssetImage({ @@ -20,12 +22,12 @@ class RoomEmojiAssetImage extends StatefulWidget { class _RoomEmojiAssetImageState extends State with AutomaticKeepAliveClientMixin { - late AssetImage _imageProvider; + AssetImage? _imageProvider; @override void initState() { super.initState(); - _imageProvider = AssetImage(widget.asset); + _syncImageProvider(); } @override @@ -38,7 +40,7 @@ class _RoomEmojiAssetImageState extends State void didUpdateWidget(covariant RoomEmojiAssetImage oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.asset != widget.asset) { - _imageProvider = AssetImage(widget.asset); + _syncImageProvider(); _precache(); } } @@ -46,9 +48,42 @@ class _RoomEmojiAssetImageState extends State @override Widget build(BuildContext context) { super.build(context); + final resource = widget.asset.trim(); + if (resource.isEmpty) { + return SizedBox(width: widget.width, height: widget.height); + } + if (SCNetworkSvgaWidget.isSvga(resource)) { + return RepaintBoundary( + child: SCNetworkSvgaWidget( + resource: resource, + width: widget.width, + height: widget.height, + loop: true, + fit: widget.fit, + ), + ); + } + if (!_isLocalAsset(resource)) { + return RepaintBoundary( + child: netImage( + url: resource, + width: widget.width, + height: widget.height, + fit: widget.fit, + gifFit: widget.fit, + noDefaultImg: true, + loadingWidget: SizedBox(width: widget.width, height: widget.height), + errorWidget: SizedBox(width: widget.width, height: widget.height), + ), + ); + } + final imageProvider = _imageProvider; + if (imageProvider == null) { + return SizedBox(width: widget.width, height: widget.height); + } return RepaintBoundary( child: Image( - image: _imageProvider, + image: imageProvider, width: widget.width, height: widget.height, fit: widget.fit, @@ -59,7 +94,19 @@ class _RoomEmojiAssetImageState extends State } void _precache() { - precacheImage(_imageProvider, context); + final imageProvider = _imageProvider; + if (imageProvider != null) { + precacheImage(imageProvider, context); + } + } + + void _syncImageProvider() { + final resource = widget.asset.trim(); + _imageProvider = _isLocalAsset(resource) ? AssetImage(resource) : null; + } + + bool _isLocalAsset(String resource) { + return resource.startsWith("assets/") || resource.startsWith("sc_images/"); } @override diff --git a/lib/ui_kit/widgets/room/room_msg_input.dart b/lib/ui_kit/widgets/room/room_msg_input.dart index cfc999d..a32a375 100644 --- a/lib/ui_kit/widgets/room/room_msg_input.dart +++ b/lib/ui_kit/widgets/room/room_msg_input.dart @@ -9,6 +9,8 @@ import 'package:yumi/app/constants/sc_screen.dart'; import 'package:yumi/app_localizations.dart'; import 'package:yumi/services/audio/rtc_manager.dart'; import 'package:yumi/services/audio/rtm_manager.dart'; +import 'package:yumi/services/general/sc_app_general_manager.dart'; +import 'package:yumi/shared/business_logic/models/res/sc_room_emoji_res.dart'; import 'package:yumi/shared/business_logic/usecases/sc_case.dart'; import 'package:yumi/shared/data_sources/sources/local/user_manager.dart'; import 'package:yumi/shared/tools/sc_keybord_util.dart'; @@ -34,34 +36,34 @@ class _RoomMsgInputState extends State { static const List<_RoomEmojiCategory> _roomEmojiCategories = [ _RoomEmojiCategory( id: "fluent", - iconAsset: "sc_images/room/emoji/fluent_emoji_01.webp", - assets: [ - "sc_images/room/emoji/fluent_emoji_01.webp", - "sc_images/room/emoji/fluent_emoji_02.webp", - "sc_images/room/emoji/fluent_emoji_03.webp", - "sc_images/room/emoji/fluent_emoji_04.webp", - "sc_images/room/emoji/fluent_emoji_05.webp", - "sc_images/room/emoji/fluent_emoji_06.webp", - "sc_images/room/emoji/fluent_emoji_07.webp", - "sc_images/room/emoji/fluent_emoji_08.webp", - "sc_images/room/emoji/fluent_emoji_09.webp", - "sc_images/room/emoji/fluent_emoji_10.webp", + iconResource: "sc_images/room/emoji/fluent_emoji_01.webp", + items: [ + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_01.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_02.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_03.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_04.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_05.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_06.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_07.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_08.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_09.webp"), + _RoomEmojiItem.local("sc_images/room/emoji/fluent_emoji_10.webp"), ], ), _RoomEmojiCategory( id: "monkey", - iconAsset: "sc_images/room/emoji/monkey_1.gif", - assets: [ - "sc_images/room/emoji/monkey_1.gif", - "sc_images/room/emoji/monkey_2.gif", - "sc_images/room/emoji/monkey_3.gif", - "sc_images/room/emoji/monkey_4.gif", - "sc_images/room/emoji/monkey_5.gif", - "sc_images/room/emoji/monkey_6.gif", - "sc_images/room/emoji/monkey_7.gif", - "sc_images/room/emoji/monkey_8.gif", - "sc_images/room/emoji/monkey_9.gif", - "sc_images/room/emoji/monkey_10.gif", + iconResource: "sc_images/room/emoji/monkey_1.gif", + items: [ + _RoomEmojiItem.local("sc_images/room/emoji/monkey_1.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_2.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_3.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_4.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_5.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_6.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_7.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_8.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_9.gif"), + _RoomEmojiItem.local("sc_images/room/emoji/monkey_10.gif"), ], ), ]; @@ -99,6 +101,7 @@ class _RoomMsgInputState extends State { super.didChangeDependencies(); if (showEmoji) { _precacheRoomEmojis(); + _loadRemoteRoomEmojis(); } } @@ -247,7 +250,12 @@ class _RoomMsgInputState extends State { } Widget _buildEmojiPanel() { - final selectedCategory = _roomEmojiCategories[_selectedEmojiCategoryIndex]; + final categories = _resolveRoomEmojiCategories(); + final selectedIndex = _selectedEmojiCategoryIndex.clamp( + 0, + categories.length - 1, + ); + final selectedCategory = categories[selectedIndex]; return Container( height: 220.w, decoration: BoxDecoration( @@ -265,18 +273,18 @@ class _RoomMsgInputState extends State { crossAxisSpacing: 18.w, mainAxisSpacing: 12.w, ), - itemCount: selectedCategory.assets.length, + itemCount: selectedCategory.items.length, itemBuilder: (context, index) { - final emojiAsset = selectedCategory.assets[index]; + final emojiItem = selectedCategory.items[index]; return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { - _sendRoomEmoji(emojiAsset); + _sendRoomEmoji(emojiItem.sendResource); }, child: Center( child: RoomEmojiAssetImage( - key: ValueKey(emojiAsset), - asset: emojiAsset, + key: ValueKey(emojiItem.displayResource), + asset: emojiItem.displayResource, width: 42.w, height: 42.w, ), @@ -285,13 +293,16 @@ class _RoomMsgInputState extends State { }, ), ), - _buildEmojiCategoryBar(), + _buildEmojiCategoryBar(categories, selectedIndex), ], ), ); } - Widget _buildEmojiCategoryBar() { + Widget _buildEmojiCategoryBar( + List<_RoomEmojiCategory> categories, + int selectedIndex, + ) { return Container( height: 50.w, padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 7.w), @@ -303,11 +314,11 @@ class _RoomMsgInputState extends State { ), child: ListView.separated( scrollDirection: Axis.horizontal, - itemCount: _roomEmojiCategories.length, + itemCount: categories.length, separatorBuilder: (_, __) => SizedBox(width: 10.w), itemBuilder: (context, index) { - final category = _roomEmojiCategories[index]; - final selected = index == _selectedEmojiCategoryIndex; + final category = categories[index]; + final selected = index == selectedIndex; return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { @@ -340,7 +351,7 @@ class _RoomMsgInputState extends State { child: Center( child: RoomEmojiAssetImage( key: ValueKey("emoji_category_${category.id}"), - asset: category.iconAsset, + asset: category.iconResource, width: 26.w, height: 26.w, ), @@ -363,6 +374,7 @@ class _RoomMsgInputState extends State { SCKeybordUtil.hide(context); _precacheRoomEmojis(); + _loadRemoteRoomEmojis(); setState(() { showEmoji = true; }); @@ -374,13 +386,28 @@ class _RoomMsgInputState extends State { } _emojiAssetsPrecached = true; for (final category in _roomEmojiCategories) { - precacheImage(AssetImage(category.iconAsset), context); - for (final asset in category.assets) { - precacheImage(AssetImage(asset), context); + precacheImage(AssetImage(category.iconResource), context); + for (final item in category.items) { + precacheImage(AssetImage(item.displayResource), context); } } } + void _loadRemoteRoomEmojis() { + Provider.of(context, listen: false).emojiAll(); + } + + List<_RoomEmojiCategory> _resolveRoomEmojiCategories() { + final remoteGroups = + Provider.of(context).roomEmojiGroups; + return [ + ..._roomEmojiCategories, + ...remoteGroups + .map(_RoomEmojiCategory.fromRemote) + .where((category) => category.items.isNotEmpty), + ]; + } + void _sendRoomEmoji(String emojiAsset) { final rtcProvider = Provider.of(context, listen: false); final currenRoom = rtcProvider.currenRoom; @@ -435,13 +462,54 @@ class _RoomMsgInputState extends State { class _RoomEmojiCategory { const _RoomEmojiCategory({ required this.id, - required this.iconAsset, - required this.assets, + required this.iconResource, + required this.items, }); + factory _RoomEmojiCategory.fromRemote(SCRoomEmojiRes group) { + final items = + (group.emojis ?? const []) + .map(_RoomEmojiItem.fromRemote) + .where((item) => item.sendResource.isNotEmpty) + .toList(); + final firstPreview = + items.isEmpty ? "" : items.first.displayResource.trim(); + final cover = group.cover?.trim() ?? ""; + final remoteId = + (group.id ?? group.groupCode ?? group.groupName ?? firstPreview).trim(); + return _RoomEmojiCategory( + id: "remote_${remoteId.isEmpty ? firstPreview : remoteId}", + iconResource: cover.isNotEmpty ? cover : firstPreview, + items: items, + ); + } + final String id; - final String iconAsset; - final List assets; + final String iconResource; + final List<_RoomEmojiItem> items; +} + +class _RoomEmojiItem { + const _RoomEmojiItem({ + required this.displayResource, + required this.sendResource, + }); + + const _RoomEmojiItem.local(String resource) + : displayResource = resource, + sendResource = resource; + + factory _RoomEmojiItem.fromRemote(Emojis emoji) { + final cover = emoji.coverUrl?.trim() ?? ""; + final source = emoji.sourceUrl?.trim() ?? ""; + return _RoomEmojiItem( + displayResource: cover.isNotEmpty ? cover : source, + sendResource: source.isNotEmpty ? source : cover, + ); + } + + final String displayResource; + final String sendResource; } class PopRoute extends PopupRoute { diff --git a/lib/ui_kit/widgets/room/room_msg_item.dart b/lib/ui_kit/widgets/room/room_msg_item.dart index 9b46207..945853f 100644 --- a/lib/ui_kit/widgets/room/room_msg_item.dart +++ b/lib/ui_kit/widgets/room/room_msg_item.dart @@ -408,8 +408,8 @@ class _MsgItemState extends State { final imageUrl = _resolveRoomChatBubbleImageUrl(resource); final multilineMaxBubbleWidth = math.min(maxBubbleWidth, 300.w); final multilineMaxTextWidth = math.max( - 82.w, - multilineMaxBubbleWidth - 64.w, + 60.w, + multilineMaxBubbleWidth - 44.w, ); final multilineTextPainter = TextPainter( text: TextSpan(text: messageText, style: textStyle), @@ -443,15 +443,15 @@ class _MsgItemState extends State { required double maxBubbleWidth, required double startMargin, }) { - final leftPadding = 22.w; - final rightPadding = 42.w; - final topPadding = 16.w; - final bottomPadding = 24.w; + final leftPadding = 18.w; + final rightPadding = 26.w; + final topPadding = 10.w; + final bottomPadding = 12.w; final bubbleWidth = math - .max(126.w, textSize.width + leftPadding + rightPadding) - .clamp(126.w, maxBubbleWidth); + .max(92.w, textSize.width + leftPadding + rightPadding) + .clamp(92.w, maxBubbleWidth); final textMaxWidth = math.max( - 64.w, + 48.w, bubbleWidth - leftPadding - rightPadding, ); final textPainter = TextPainter( @@ -460,7 +460,7 @@ class _MsgItemState extends State { )..layout(maxWidth: textMaxWidth); final textBoxHeight = textPainter.size.height + 2.w; final bubbleHeight = math.max( - 76.w, + 52.w, textBoxHeight + topPadding + bottomPadding, ); @@ -502,13 +502,13 @@ class _MsgItemState extends State { required double maxBubbleWidth, required double startMargin, }) { - final leftPadding = 22.w; - final rightPadding = 24.w; - final topPadding = 12.w; - final bottomPadding = 16.w; - final minSkinWidth = 96.w; - final minSkinHeight = 58.w; - final textWidthSafety = 10.w; + final leftPadding = 16.w; + final rightPadding = 18.w; + final topPadding = 8.w; + final bottomPadding = 10.w; + final minSkinWidth = 56.w; + final minSkinHeight = 52.w; + final textWidthSafety = 4.w; final maxTextWidth = math.max( 1.0, maxBubbleWidth - leftPadding - rightPadding, @@ -1183,78 +1183,107 @@ class _MsgItemState extends State { alignment: AlignmentDirectional.topStart, padding: EdgeInsets.symmetric(horizontal: width(5.w), vertical: width(4)), margin: EdgeInsets.symmetric(horizontal: width(10)).copyWith(bottom: 8.w), - child: Column( - children: [ - _buildUserInfoLine(context), - SizedBox(height: 6.w), - Row( + child: _buildGiftMessageItem(context), + ); + } + + Widget _buildGiftMessageItem(BuildContext context) { + final userId = widget.msg.user?.id; + _clearStaleUserInfoIfNeeded(userId); + if (userId == null || userId.isEmpty) { + return _buildGiftMessageItemWithUser(context, widget.msg.user); + } + final cachedUser = SCRoomUtils.roomUsersMap[userId]; + if (cachedUser != null) { + return _buildGiftMessageItemWithUser(context, cachedUser); + } + return FutureBuilder( + future: _loadRoomUserInfoSilently(userId), + builder: (ct, AsyncSnapshot snapshot) { + if (snapshot.connectionState == ConnectionState.done && + snapshot.hasData) { + final user = snapshot.data!; + SCRoomUtils.roomUsersMap[user.id ?? ""] = user; + return _buildGiftMessageItemWithUser(context, user); + } + return _buildGiftMessageItemWithUser(context, widget.msg.user); + }, + ); + } + + Widget _buildGiftMessageItemWithUser( + BuildContext context, + SocialChatUserProfile? user, + ) { + final badges = _activeWearBadges(user); + return Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + _buildMessageUserAvatar(context, user), + SizedBox(width: 8.w), + Flexible( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Flexible( - // 使用Flexible替代Expanded - child: Container( - constraints: BoxConstraints( - maxWidth: ScreenUtil().screenWidth * 0.7, // 最大宽度约束 - ), - decoration: BoxDecoration( - color: Colors.black38, - borderRadius: BorderRadius.only( - topRight: Radius.circular(15.w), - bottomLeft: Radius.circular(15.w), - bottomRight: Radius.circular(15.w), - ), - ), - padding: EdgeInsets.symmetric( - horizontal: 10.w, - vertical: 4.w, - ), - margin: EdgeInsetsDirectional.only( - start: 54.w, - ).copyWith(bottom: 8.w), - child: Text.rich( - TextSpan( - children: [ - TextSpan( - text: SCAppLocalizations.of(context)!.sendTo, - style: TextStyle( - fontSize: 13.sp, - color: Colors.white, - ), - ), - TextSpan(text: " "), - TextSpan( - text: _giftTargetName(context), - style: TextStyle( - fontSize: 13.sp, - color: SocialChatTheme.primaryColor, - ), - recognizer: TapGestureRecognizer()..onTap = () {}, - ), - TextSpan(text: " "), - WidgetSpan( - child: netImage( - url: widget.msg.gift?.giftPhoto ?? "", - width: 22.w, - height: 22.w, - ), - ), - TextSpan(text: " "), - TextSpan( - text: "x${widget.msg.number}", - style: TextStyle( - fontSize: 13.sp, - color: Colors.white, - ), - recognizer: TapGestureRecognizer()..onTap = () {}, - ), - ], - ), - textAlign: TextAlign.left, - ), - ), - ), + _buildUserNameAndLevels(user), + _buildLongMedals(userId: user?.id, fallbackBadges: badges), + _buildMedals(userId: user?.id, fallbackBadges: badges), + SizedBox(height: 2.w), + _buildGiftMessageBubble(context), ], ), - ], + ), + ], + ); + } + + Widget _buildGiftMessageBubble(BuildContext context) { + return Container( + constraints: BoxConstraints(maxWidth: ScreenUtil().screenWidth * 0.7), + decoration: BoxDecoration( + color: Colors.black38, + borderRadius: BorderRadius.only( + topRight: Radius.circular(15.w), + bottomLeft: Radius.circular(15.w), + bottomRight: Radius.circular(15.w), + ), + ), + padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 4.w), + margin: EdgeInsetsDirectional.only(start: 0).copyWith(bottom: 8.w), + child: Text.rich( + TextSpan( + children: [ + TextSpan( + text: SCAppLocalizations.of(context)!.sendTo, + style: TextStyle(fontSize: 13.sp, color: Colors.white), + ), + TextSpan(text: " "), + TextSpan( + text: _giftTargetName(context), + style: TextStyle( + fontSize: 13.sp, + color: SocialChatTheme.primaryColor, + ), + recognizer: TapGestureRecognizer()..onTap = () {}, + ), + TextSpan(text: " "), + WidgetSpan( + child: netImage( + url: widget.msg.gift?.giftPhoto ?? "", + width: 22.w, + height: 22.w, + ), + ), + TextSpan(text: " "), + TextSpan( + text: "x${widget.msg.number}", + style: TextStyle(fontSize: 13.sp, color: Colors.white), + recognizer: TapGestureRecognizer()..onTap = () {}, + ), + ], + ), + textAlign: TextAlign.left, ), ); } @@ -1625,19 +1654,12 @@ class _MsgItemState extends State { if (path.isEmpty) { return SizedBox(width: width, height: height); } - if (_isLocalAsset(path)) { - return RoomEmojiAssetImage( - key: ValueKey(path), - asset: path, - width: width, - height: height, - ); - } - return netImage(url: path, width: width, height: height); - } - - bool _isLocalAsset(String path) { - return path.startsWith("assets/") || path.startsWith("sc_images/"); + return RoomEmojiAssetImage( + key: ValueKey(path), + asset: path, + width: width, + height: height, + ); } Widget _buildDiceMsg(BuildContext context) { diff --git a/lib/ui_kit/widgets/sc_home_shell_background.dart b/lib/ui_kit/widgets/sc_home_shell_background.dart new file mode 100644 index 0000000..d3510c3 --- /dev/null +++ b/lib/ui_kit/widgets/sc_home_shell_background.dart @@ -0,0 +1,94 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_screenutil/flutter_screenutil.dart'; + +const Color scHomeShellBackgroundColor = Color(0xFF051711); +const Color scHomeShellAccentColor = Color(0xFF18F2B1); +const Color scHomeShellGoldColor = Color(0xFFE9B455); +const LinearGradient scHomeShellGoldTextGradient = LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [Color(0xFFFCFBD9), Color(0xFFDC9D3A)], +); +const String scHomeShellBackgroundAsset = + 'sc_images/index/sc_home_shell_bg.png'; + +class SCHomeShellBackground extends StatelessWidget { + const SCHomeShellBackground({super.key}); + + @override + Widget build(BuildContext context) { + return DecoratedBox( + decoration: const BoxDecoration(color: scHomeShellBackgroundColor), + child: Image.asset( + scHomeShellBackgroundAsset, + width: double.infinity, + height: double.infinity, + fit: BoxFit.cover, + alignment: Alignment.topCenter, + errorBuilder: + (context, error, stackTrace) => + const ColoredBox(color: scHomeShellBackgroundColor), + ), + ); + } +} + +class SCHomeShellGradientText extends StatelessWidget { + const SCHomeShellGradientText( + this.text, { + super.key, + required this.style, + this.maxLines, + this.overflow, + this.textAlign, + }); + + final String text; + final TextStyle style; + final int? maxLines; + final TextOverflow? overflow; + final TextAlign? textAlign; + + @override + Widget build(BuildContext context) { + final gradientText = ShaderMask( + blendMode: BlendMode.srcIn, + shaderCallback: scHomeShellGoldTextGradient.createShader, + child: _buildText(style.copyWith(color: Colors.white, shadows: null)), + ); + if (style.shadows == null || style.shadows!.isEmpty) { + return gradientText; + } + return Stack( + clipBehavior: Clip.none, + children: [ + ExcludeSemantics( + child: _buildText(style.copyWith(color: Colors.transparent)), + ), + gradientText, + ], + ); + } + + Widget _buildText(TextStyle textStyle) { + return Text( + text, + maxLines: maxLines, + overflow: overflow, + textAlign: textAlign, + style: textStyle, + ); + } +} + +TextStyle scHomeShellTitleStyle({double? fontSize}) { + return TextStyle( + color: scHomeShellGoldColor, + fontSize: (fontSize ?? 28).sp, + fontWeight: FontWeight.w900, + fontStyle: FontStyle.italic, + shadows: const [ + Shadow(color: Color(0xB3000000), offset: Offset(0, 1), blurRadius: 1), + ], + ); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/CHANGELOG.md b/local_packages/extended_text_field-16.0.2-patched/CHANGELOG.md new file mode 100644 index 0000000..170aa38 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/CHANGELOG.md @@ -0,0 +1,319 @@ +## 16.0.2 + +* Fix issue that the caret offset is not right after pinyin(composing) is completed on windows desktop(#255) + +## 16.0.1 + +* Fix issue that context menu click didn't work on desktop(#250) + +## 16.0.0 + +* Migrate to Flutter 3.24.0 + +## 15.0.0 + +* Migrate to Flutter 3.22.0 + +## 14.0.0 + +* Migrate to Flutter 3.19.0 +* Fix wrong postion of Magnifier + +## 13.0.1 + +* Update readme about HarmonyOS + +## 13.0.0 + +* Migrate to Flutter 3.16.0 (#229) +* Fix wrong caret position (#224,#226) + +## 12.1.0 + +* Migrate to Flutter 3.13.0 + +## 12.0.1 + +* Fix issue that wrong cursor position on macos. (https://github.com/fluttercandies/extended_text_field/issues/210) + +## 12.0.0 + +* Migrate to Flutter 3.10.0 +* Refactoring codes and sync codes from 3.10.0 +* Breaking change: + Remove [ExtendedText.textSelectionGestureDetectorBuilder],[ExtendedText.shouldShowSelectionHandles] +* Add ExtendedSelectableText + +## 11.0.1 + +* fix issue on ios after flutter version 3.7.0. #191 #198 + +## 11.0.0 + +* Migrate to 3.7.0 + +## 10.2.0 + +* Add TextInputBindingMixin to prevent system keyboard show. +* Add No SystemKeyboard demo + +## 10.1.1 + +* Fix issue selection not right #172 + +## 10.1.0 + +* Migrate to 3.0.0 +* Support Scribble Handwriting for iPads + +## 10.0.1 + +* Public ExtendedTextFieldState and add bringIntoView method to support jump to caret when insert text with TextEditingController + +## 10.0.0 + +* Migrate to 2.10.0. +* Add shouldShowSelectionHandles and textSelectionGestureDetectorBuilder call back to define the behavior of handles and toolbar. +* Shortcut support for web and desktop. + +## 9.0.3 + +* Fix hittest is not right #131 + +## 9.0.2 + +* Fix selectionWidthStyle and selectionHeightStyle are not working. + +## 9.0.1 + +* Support to use keyboard move cursor for SpecialInlineSpan. #135 +* Fix issue that backspace delete two chars. #141 + +## 9.0.0 + +* Migrate to 2.8 + +## 8.0.0 + +* Add [SpecialTextSpan.mouseCursor], [SpecialTextSpan.onEnter] and [SpecialTextSpan.onExit]. +* merge code from 2.2.0 + +## 7.0.1 + +* Fix issue that composing is not updated.#122 + +## 7.0.0 + +* Breaking change: [SpecialText.getContent] is not include endflag now.(please check if you call getContent and your endflag length is more than 1) +* Fix demo manualDelete error #120 + +## 6.0.1 + +* Fix issue that toolbar is not shown when double tap +* Fix throw exception when selectWordAtOffset + +## 6.0.0 + +* Support null-safety + +## 5.0.4 + +* Fix toolbar is not show after some behaviour #107 + +## 5.0.3 + +* Fix miss TextStyle for specialTextSpanBuilder #89 + +## 5.0.2 + +* Fix wrong position of caret + +## 5.0.1 + +* change handleSpecialText to hasSpecialInlineSpanBase(extended_text_library) +* add hasPlaceholderSpan(extended_text_library) + +## 5.0.0 + +* Merge from Flutter v1.22 +* Support cursorHeight, onAppPrivateCommand, restorationId + +## 4.0.0 + +* Merge from Flutter v1.20 +* Support Autofill + +## 3.0.1 + +* Fix issue that text is clipped when maxLine is 1 and width is more than maxWidth.(#67,#76) +* Fix issue that handles are not shown when the height of TextStyle is big than 1.0.(#49) + +## 3.0.0 + +* Breaking change: fix typos OverflowWidget. + +## 2.0.0 + +* Breaking change: extended_text_library has changed to support OverFlowWidget ExtendedText +* Fix textSelectionControls is not working. + +## 1.0.1 + +* Fix wrong calculation about selection handles. + +## 1.0.0 + +* Merge code from 1.17.0 +* Fix analysis_options + +## 0.5.0 + +* Fix error caret offset on ios. + +## 0.4.9 + +* Fix error about TargetPlatform.macOS + +## 0.4.8 + +* Fix issue that the cursor returns to the top when deleting quickly in Multi-line text +* Fix issue that toolbar will not show if autofocus is true when longpress + +## 0.4.7 + +* Codes base on 1.12.13+hotfix.5 +* Set limitation of flutter sdk >=1.12.13 <1.12.16 +* Add demo that how to delete text with code +* Fix issue that not showing text while entering text from keyboard + +## 0.4.6 + +* Remove TargetPlatform.macOS + +## 0.4.5 + +* Fix build error for flutter sdk 1.12 + +## 0.4.4 + +* Fix wrong caret hegiht and postion +* Make Ios/Android caret the same height + +## 0.4.3 + +* Fix kMinInteractiveSize is missing in high version of flutter + +## 0.4.2 + +* Support custom selection toolbar and handles +* Improve codes about selection overlay +* Select all SpecialTextSpan(which deleteAll is true) when double tap or long tap +* Support WidgetSpan hitTest + +## 0.4.1 + +* Fix issue that type 'ImageSpan' is not a subtype of type 'textSpan'(https://github.com/fluttercandies/extended_text_field/issues/13) + +## 0.4.0 + +* Fix issue tgat WidgetSpan wrong offset(https://github.com/fluttercandies/extended_text_field/issues/11) +* Fix wrong caret offset + +## 0.3.9 + +* Improve codes base on v1.7.8 +* Support WidgetSpan (ExtendedWidgetSpan) + +## 0.3.7 + +* Update extended_text_library + +## 0.3.4 + +* Remove un-used codes in extended_text_selection + +## 0.3.3 + +* Update extended_text_library + +## 0.3.2 + +* Update path_provider 1.1.0 + +## 0.3.0 + +* Uncomment getFullHeightForCaret method for 1.5.4-hotfix.2 +* Corret selection handles visibility for _updateSelectionExtentsVisibility method + +## 0.2.8 + +* Corret selection handles position for image textspan +* StrutStyle strutStyle is obsoleted, it will lead to bugs for image span size. + +## 0.2.7 + +* Fix selection handles blinking + +## 0.2.6 + +* Take care when TextSpan children is null + +## 0.2.5 + +* Update extended_text_library +1.Remove caretIn parameter(SpecialTextSpan) +2.DeleteAll parameter has the same effect as caretIn parameter(SpecialTextSpan) + +## 0.2.4 + +* Fix caret position about image span +* Add caretIn parameter(whether caret can move into special text for SpecialTextSpan(like a image span or @xxxx)) for SpecialTextSpan + +## 0.2.3 + +* Disabled informationCollector to keep backwards compatibility for now (ExtendedNetworkImageProvider) + +## 0.2.2 + +* Fix caret position for last one image span +* Add image text demo +* Fix position for specialTex + +## 0.2.1 + +* Fix caret position for image span + +## 0.2.0 + +* Only iterate textSpan.children to find SpecialTextSpan + +## 0.1.9 + +* Add BackgroundTextSpan, support to paint custom background + +## 0.1.8 + +* Handle TextEditingValue's composing + +## 0.1.6 + +* Improve codes to avoid unnecessary computation + +## 0.1.5 + +* Override compareTo method in SpecialTextSpan and ImageSpan to + Fix issue that image span or special text span was error rendering + +## 0.1.4 + +* Update limitation +* Improve codes + +## 0.1.3 + +* Update limitation +* Improve codes + +## 0.1.1 + +* Support special text amd inline image diff --git a/local_packages/extended_text_field-16.0.2-patched/CODEOWNERS b/local_packages/extended_text_field-16.0.2-patched/CODEOWNERS new file mode 100644 index 0000000..b0e8c47 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/CODEOWNERS @@ -0,0 +1 @@ +* @zmtzawqlp diff --git a/local_packages/extended_text_field-16.0.2-patched/LICENSE b/local_packages/extended_text_field-16.0.2-patched/LICENSE new file mode 100644 index 0000000..5e61798 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019 zmtzawqlp + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/local_packages/extended_text_field-16.0.2-patched/README-ZH.md b/local_packages/extended_text_field-16.0.2-patched/README-ZH.md new file mode 100644 index 0000000..91c0b73 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/README-ZH.md @@ -0,0 +1,616 @@ +# extended_text_field + +[![pub package](https://img.shields.io/pub/v/extended_text_field.svg)](https://pub.dartlang.org/packages/extended_text_field) [![GitHub stars](https://img.shields.io/github/stars/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/stargazers) [![GitHub forks](https://img.shields.io/github/forks/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/network) [![GitHub license](https://img.shields.io/github/license/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/issues) flutter-candies + +文档语言: [English](README.md) | 中文简体 + +官方输入框的扩展组件,支持图片,@某人,自定义文字背景。也支持自定义菜单和选择器。 + +[ExtendedTextField 在线 Demo](https://fluttercandies.github.io/extended_text_field/) + +ExtendedTextField 是 Flutter 官方 TextField 的三方扩展库,主要扩展功能如下: + +| 功能 | ExtendedTextField | TextField | +|-----------------------------------------|---------------------------------------------------------|----------------------------------------------------------| +| 图文混合 | 支持,可以实现图文混合显示 | 仅支持显示文本,但在选择文本时会出现问题 | +| 支持复制真实值 | 支持,可以复制出文本的真实值 | 不支持 | +| 根据文本格式快速构建富文本 | 支持,可以根据文本格式快速构建富文本 | 不支持 | + +> 已支持 `HarmonyOS`. 请使用最新的带有 `ohos` 标志的版本. 你可以在 `Versions` 签查找. + +```yaml +dependencies: + extended_text_field: 11.0.1-ohos +``` + + +- [extended\_text\_field](#extended_text_field) + - [限制](#限制) + - [特殊文本](#特殊文本) + - [创建特殊文本](#创建特殊文本) + - [特殊文本Builder](#特殊文本builder) + - [图片](#图片) + - [ImageSpan](#imagespan) + - [缓存图片](#缓存图片) + - [文本选择控制器](#文本选择控制器) + - [WidgetSpan](#widgetspan) + - [阻止系统键盘](#阻止系统键盘) + - [TextInputBindingMixin](#textinputbindingmixin) + - [TextInputFocusNode](#textinputfocusnode) + - [CustomKeyboard](#customkeyboard) + - [☕️Buy me a coffee](#️buy-me-a-coffee) + +## 限制 + +- 不支持TextDirection.rtl,从右向左. + +- 不支持obscureText为true. + +## 特殊文本 + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/extended_text_field.gif) + +### 创建特殊文本 + +extended_text 帮助将字符串文本快速转换为特殊的TextSpan + +下面的例子告诉你怎么创建一个@xxx + +具体思路是对字符串进行进栈遍历,通过判断flag来判定是否是一个特殊字符。 +例子:@zmtzawqlp ,以@开头并且以空格结束,我们就认为它是一个@的特殊文本 + +```dart +class AtText extends SpecialText { + static const String flag = "@"; + final int start; + + /// whether show background for @somebody + final bool showAtBackground; + + AtText(TextStyle textStyle, SpecialTextGestureTapCallback onTap, + {this.showAtBackground: false, this.start}) + : super( + flag, + " ", + textStyle, + ); + + @override + InlineSpan finishText() { + TextStyle textStyle = + this.textStyle?.copyWith(color: Colors.blue, fontSize: 16.0); + + final String atText = toString(); + + return showAtBackground + ? BackgroundTextSpan( + background: Paint()..color = Colors.blue.withOpacity(0.15), + text: atText, + actualText: atText, + start: start, + + ///caret can move into special text + deleteAll: true, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) onTap(atText); + })) + : SpecialTextSpan( + text: atText, + actualText: atText, + start: start, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) onTap(atText); + })); + } +} + +``` + +### 特殊文本Builder + +创建属于你自己规则的Builder,上面说了你可以继承SpecialText来定义各种各样的特殊文本。 +- build 方法中,是通过具体思路是对字符串进行进栈遍历,通过判断flag来判定是否是一个特殊文本。 + 感兴趣的,可以看一下SpecialTextSpanBuilder里面build方法的实现,当然你也可以写出属于自己的build逻辑 +- createSpecialText 通过判断flag来判定是否是一个特殊文本 + +```dart +class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder { + /// whether show background for @somebody + final bool showAtBackground; + final BuilderType type; + MySpecialTextSpanBuilder( + {this.showAtBackground: false, this.type: BuilderType.extendedText}); + + @override + TextSpan build(String data, {TextStyle textStyle, onTap}) { + var textSpan = super.build(data, textStyle: textStyle, onTap: onTap); + return textSpan; + } + + @override + SpecialText createSpecialText(String flag, + {TextStyle textStyle, SpecialTextGestureTapCallback onTap, int index}) { + if (flag == null || flag == "") return null; + + ///index is end index of start flag, so text start index should be index-(flag.length-1) + if (isStart(flag, AtText.flag)) { + return AtText(textStyle, onTap, + start: index - (AtText.flag.length - 1), + showAtBackground: showAtBackground, + type: type); + } else if (isStart(flag, EmojiText.flag)) { + return EmojiText(textStyle, start: index - (EmojiText.flag.length - 1)); + } else if (isStart(flag, DollarText.flag)) { + return DollarText(textStyle, onTap, + start: index - (DollarText.flag.length - 1), type: type); + } + return null; + } +} +``` +其实你也不是一定要用这套代码将字符串转换为TextSpan,你可以有自己的方法,给最后的TextSpan就可以了。 + +## 图片 + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/extended_text_field_image.gif) + +### ImageSpan + +使用ImageSpan 展示图片 + +```dart +ImageSpan( + ImageProvider image, { + Key key, + @required double imageWidth, + @required double imageHeight, + EdgeInsets margin, + int start: 0, + ui.PlaceholderAlignment alignment = ui.PlaceholderAlignment.bottom, + String actualText, + TextBaseline baseline, + TextStyle style, + BoxFit fit: BoxFit.scaleDown, + ImageLoadingBuilder loadingBuilder, + ImageFrameBuilder frameBuilder, + String semanticLabel, + bool excludeFromSemantics = false, + Color color, + BlendMode colorBlendMode, + AlignmentGeometry imageAlignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + FilterQuality filterQuality = FilterQuality.low, + }) + +ImageSpan(AssetImage("xxx.jpg"), + imageWidth: size, + imageHeight: size, + margin: EdgeInsets.only(left: 2.0, bottom: 0.0, right: 2.0)); + } +``` + +| 参数 | 描述 | 默认 | +| ----------- | ----------------------------------------------------------------- | ---------------- | +| image | 图片展示的Provider(ImageProvider) | - | +| imageWidth | 宽度,不包括 margin | 必填 | +| imageHeight | 高度,不包括 margin | 必填 | +| margin | 图片的margin | - | +| actualText | 真实的文本,当你开启文本选择功能的时候,必须设置,比如图片"\[love\] | 空占位符'\uFFFC' | +| start | 在文本字符串中的开始位置,当你开启文本选择功能的时候,必须设置 | 0 | + +### 缓存图片 + +你可以用ExtendedNetworkImageProvider来缓存文本中的图片,使用clearDiskCachedImages方法来清掉本地缓存 + +引入 extended_image_library + +```dart +dependencies: + extended_image_library: ^0.1.4 +``` + +```dart +ExtendedNetworkImageProvider( + this.url, { + this.scale = 1.0, + this.headers, + this.cache: false, + this.retries = 3, + this.timeLimit, + this.timeRetry = const Duration(milliseconds: 100), + CancellationToken cancelToken, +}) : assert(url != null), + assert(scale != null), + cancelToken = cancelToken ?? CancellationToken(); +``` + +| 参数 | 描述 | 默认 | +| ----------- | ------------------- | ------------------- | +| url | 网络请求地址 | required | +| scale | ImageInfo中的scale | 1.0 | +| headers | HttpClient的headers | - | +| cache | 是否缓存到本地 | false | +| retries | 请求尝试次数 | 3 | +| timeLimit | 请求超时 | - | +| timeRetry | 请求重试间隔 | milliseconds: 100 | +| cancelToken | 用于取消请求的Token | CancellationToken() | + +```dart +/// Clear the disk cache directory then return if it succeed. +/// timespan to compute whether file has expired or not +Future clearDiskCachedImages({Duration duration}) async +``` + +## 文本选择控制器 + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/custom_toolbar.gif) + +提供了默认的控制器MaterialExtendedTextSelectionControls/CupertinoExtendedTextSelectionControls + +通过重写 [ExtendedTextField.extendedContextMenuBuilder] 和 [TextSelectionControls] 来自定义菜单和选择器。 + +```dart +const double _kHandleSize = 22.0; + +/// Android Material styled text selection controls. +class MyTextSelectionControls extends TextSelectionControls + with TextSelectionHandleControls { + static Widget defaultContextMenuBuilder( + BuildContext context, ExtendedEditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.buttonItems( + buttonItems: [ + ...editableTextState.contextMenuButtonItems, + ContextMenuButtonItem( + onPressed: () { + launchUrl( + Uri.parse( + 'mailto:zmtzawqlp@live.com?subject=extended_text_share&body=${editableTextState.textEditingValue.text}', + ), + ); + editableTextState.hideToolbar(true); + editableTextState.textEditingValue + .copyWith(selection: const TextSelection.collapsed(offset: 0)); + }, + type: ContextMenuButtonType.custom, + label: 'like', + ), + ], + anchors: editableTextState.contextMenuAnchors, + ); + // return AdaptiveTextSelectionToolbar.editableText( + // editableTextState: editableTextState, + // ); + } + + /// Returns the size of the Material handle. + @override + Size getHandleSize(double textLineHeight) => + const Size(_kHandleSize, _kHandleSize); + + /// Builder for material-style text selection handles. + @override + Widget buildHandle( + BuildContext context, TextSelectionHandleType type, double textLineHeight, + [VoidCallback? onTap, double? startGlyphHeight, double? endGlyphHeight]) { + final Widget handle = SizedBox( + width: _kHandleSize, + height: _kHandleSize, + child: Image.asset( + 'assets/40.png', + ), + ); + + // [handle] is a circle, with a rectangle in the top left quadrant of that + // circle (an onion pointing to 10:30). We rotate [handle] to point + // straight up or up-right depending on the handle type. + switch (type) { + case TextSelectionHandleType.left: // points up-right + return Transform.rotate( + angle: math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.right: // points up-left + return Transform.rotate( + angle: -math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.collapsed: // points up + return handle; + } + } + + /// Gets anchor for material-style text selection handles. + /// + /// See [TextSelectionControls.getHandleAnchor]. + @override + Offset getHandleAnchor(TextSelectionHandleType type, double textLineHeight, + [double? startGlyphHeight, double? endGlyphHeight]) { + switch (type) { + case TextSelectionHandleType.left: + return const Offset(_kHandleSize, 0); + case TextSelectionHandleType.right: + return Offset.zero; + default: + return const Offset(_kHandleSize / 2, -4); + } + } + + @override + bool canSelectAll(TextSelectionDelegate delegate) { + // Android allows SelectAll when selection is not collapsed, unless + // everything has already been selected. + final TextEditingValue value = delegate.textEditingValue; + return delegate.selectAllEnabled && + value.text.isNotEmpty && + !(value.selection.start == 0 && + value.selection.end == value.text.length); + } +} + +``` + +## WidgetSpan + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/widget_span.gif) + +ExtendedWidgetSpan 支持选择以及hitTest, 所以你可以在输入框中加入任何的widget。 + +```dart +class EmailText extends SpecialText { + final TextEditingController controller; + final int start; + final BuildContext context; + EmailText(TextStyle textStyle, SpecialTextGestureTapCallback onTap, + {this.start, this.controller, this.context, String startFlag}) + : super(startFlag, " ", textStyle, onTap: onTap); + + @override + bool isEnd(String value) { + var index = value.indexOf("@"); + var index1 = value.indexOf("."); + + return index >= 0 && + index1 >= 0 && + index1 > index + 1 && + super.isEnd(value); + } + + @override + InlineSpan finishText() { + final String text = toString(); + + return ExtendedWidgetSpan( + actualText: text, + start: start, + alignment: ui.PlaceholderAlignment.middle, + child: GestureDetector( + child: Padding( + padding: EdgeInsets.only(right: 5.0, top: 2.0, bottom: 2.0), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5.0)), + child: Container( + padding: EdgeInsets.all(5.0), + color: Colors.orange, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + text.trim(), + //style: textStyle?.copyWith(color: Colors.orange), + ), + SizedBox( + width: 5.0, + ), + InkWell( + child: Icon( + Icons.close, + size: 15.0, + ), + onTap: () { + controller.value = controller.value.copyWith( + text: controller.text + .replaceRange(start, start + text.length, ""), + selection: TextSelection.fromPosition( + TextPosition(offset: start))); + }, + ) + ], + ), + )), + ), + onTap: () { + showDialog( + context: context, + barrierDismissible: true, + builder: (c) { + TextEditingController textEditingController = + TextEditingController()..text = text.trim(); + return Column( + children: [ + Expanded( + child: Container(), + ), + Material( + child: Padding( + padding: EdgeInsets.all(10.0), + child: TextField( + controller: textEditingController, + decoration: InputDecoration( + suffixIcon: FlatButton( + child: Text("OK"), + onPressed: () { + controller.value = controller.value.copyWith( + text: controller.text.replaceRange( + start, + start + text.length, + textEditingController.text + " "), + selection: TextSelection.fromPosition( + TextPosition( + offset: start + + (textEditingController.text + " ") + .length))); + + Navigator.pop(context); + }, + )), + ), + )), + Expanded( + child: Container(), + ) + ], + ); + }); + }, + ), + deleteAll: true, + ); + } +} +``` + +## 阻止系统键盘 + +我们不需要代码侵入到 [ExtendedTextField] 或者 [TextField] 当中, 就可以阻止系统键盘弹出, + +### TextInputBindingMixin + +我们通过阻止 Flutter Framework 发送 `TextInput.show` 到 Flutter 引擎来阻止系统键盘弹出 + +你可以直接使用 [TextInputBinding]. + +``` dart +void main() { + TextInputBinding(); + runApp(const MyApp()); +} +``` + +或者你如果有其他的 `binding`,你可以这样。 + +``` dart + class YourBinding extends WidgetsFlutterBinding with TextInputBindingMixin,YourBindingMixin { + } + + void main() { + YourBinding(); + runApp(const MyApp()); + } +``` + +或者你需要重载 `ignoreTextInputShow` 方法,你可以这样。 + +``` dart + class YourBinding extends TextInputBinding { + @override + // ignore: unnecessary_overrides + bool ignoreTextInputShow() { + // you can override it base on your case + // if NoKeyboardFocusNode is not enough + return super.ignoreTextInputShow(); + } + } + + void main() { + YourBinding(); + runApp(const MyApp()); + } +``` + +### TextInputFocusNode + +把 [TextInputFocusNode] 传递给 [ExtendedTextField] 或者 [TextField]。 + + +``` dart +final TextInputFocusNode _focusNode = TextInputFocusNode(); + + @override + Widget build(BuildContext context) { + return ExtendedTextField( + // request keyboard if need + focusNode: _focusNode..debugLabel = 'ExtendedTextField', + ); + } + + @override + Widget build(BuildContext context) { + return TextField( + // request keyboard if need + focusNode: _focusNode..debugLabel = 'CustomTextField', + ); + } +``` + +我们通过当前的 `FocusNode` 是否是 [TextInputFocusNode],来决定是否阻止系统键盘弹出的。 + +``` dart + final FocusNode? focus = FocusManager.instance.primaryFocus; + if (focus != null && + focus is TextInputFocusNode && + focus.ignoreSystemKeyboardShow) { + return true; + } +``` +### CustomKeyboard + +你可以通过当前焦点的变化的时候,来显示或者隐藏自定义的键盘。 + +当你的自定义键盘可以关闭而不让焦点失去,你应该在 [ExtendedTextField] 或者 [TextField] +的 `onTap` 事件中,再次判断键盘是否显示。 + +``` dart + @override + void initState() { + super.initState(); + _focusNode.addListener(_handleFocusChanged); + } + + void _onTextFiledTap() { + if (_bottomSheetController == null) { + _handleFocusChanged(); + } + } + + void _handleFocusChanged() { + if (_focusNode.hasFocus) { + // just demo, you can define your custom keyboard as you want + _bottomSheetController = showBottomSheet( + context: FocusManager.instance.primaryFocus!.context!, + // set false, if don't want to drag to close custom keyboard + enableDrag: true, + builder: (BuildContext b) { + // your custom keyboard + return Container(); + }); + // maybe drag close + _bottomSheetController?.closed.whenComplete(() { + _bottomSheetController = null; + }); + } else { + _bottomSheetController?.close(); + _bottomSheetController = null; + } + } + + @override + void dispose() { + _focusNode.removeListener(_handleFocusChanged); + super.dispose(); + } +``` + + +查看 [完整的例子](https://github.com/fluttercandies/extended_text_field/tree/master/example/lib/pages/simple/no_keyboard.dart) + +## ☕️Buy me a coffee + +![img](http://zmtzawqlp.gitee.io/my_images/images/qrcode.png) diff --git a/local_packages/extended_text_field-16.0.2-patched/README.md b/local_packages/extended_text_field-16.0.2-patched/README.md new file mode 100644 index 0000000..8c67e2f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/README.md @@ -0,0 +1,605 @@ +# extended_text_field + +[![pub package](https://img.shields.io/pub/v/extended_text_field.svg)](https://pub.dartlang.org/packages/extended_text_field) [![GitHub stars](https://img.shields.io/github/stars/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/stargazers) [![GitHub forks](https://img.shields.io/github/forks/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/network) [![GitHub license](https://img.shields.io/github/license/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/blob/master/LICENSE) [![GitHub issues](https://img.shields.io/github/issues/fluttercandies/extended_text_field)](https://github.com/fluttercandies/extended_text_field/issues) flutter-candies + +Language: English | [中文简体](README-ZH.md) + +Extended official text field to build special text like inline image, @somebody, custom background etc quickly.It also support to build custom seleciton toolbar and handles. + +[Web demo for ExtendedTextField](https://fluttercandies.github.io/extended_text_field/) + +ExtendedTextField is a third-party extension library for Flutter's official TextField component. The main extended features are as follows: + +| Feature | ExtendedTextField | TextField | +|---------------------------------------|------------------------------------------------------|----------------------------------------------------| +| Inline images and text mixture | Supported, allows displaying inline images and mixed text | Only supports displaying text, but have issues with text selection | +| Copying the actual value | Supported, enables copying the actual value of the text | Not supported | +| Quick construction of rich text | Supported, enables quick construction of rich text based on text format | Not supported | + +> `HarmonyOS` is supported. Please use the latest version which contains `ohos` tag. You can check it in `Versions` tab. + +```yaml +dependencies: + extended_text_field: 11.0.1-ohos +``` + + +Please note that the translation provided above is based on the information you provided in the original text. + +- [extended\_text\_field](#extended_text_field) + - [Limitation](#limitation) + - [Special Text](#special-text) + - [Create Special Text](#create-special-text) + - [SpecialTextSpanBuilder](#specialtextspanbuilder) + - [Image](#image) + - [ImageSpan](#imagespan) + - [Cache Image](#cache-image) + - [TextSelectionControls](#textselectioncontrols) + - [WidgetSpan](#widgetspan) + - [NoSystemKeyboard](#nosystemkeyboard) + - [TextInputBindingMixin](#textinputbindingmixin) + - [TextInputFocusNode](#textinputfocusnode) + +## Limitation + +- Not support: it won't handle special text when TextDirection.rtl. + + Image position calculated by TextPainter is strange. + +- Not support:it won't handle special text when obscureText is true. + +## Special Text + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/extended_text_field.gif) + +### Create Special Text + +extended text helps to convert your text to special textSpan quickly. + +for example, follwing code show how to create @xxxx special textSpan. + +```dart +class AtText extends SpecialText { + static const String flag = "@"; + final int start; + + /// whether show background for @somebody + final bool showAtBackground; + + AtText(TextStyle textStyle, SpecialTextGestureTapCallback onTap, + {this.showAtBackground: false, this.start}) + : super( + flag, + " ", + textStyle, + ); + + @override + InlineSpan finishText() { + TextStyle textStyle = + this.textStyle?.copyWith(color: Colors.blue, fontSize: 16.0); + + final String atText = toString(); + + return showAtBackground + ? BackgroundTextSpan( + background: Paint()..color = Colors.blue.withOpacity(0.15), + text: atText, + actualText: atText, + start: start, + + ///caret can move into special text + deleteAll: true, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) onTap(atText); + })) + : SpecialTextSpan( + text: atText, + actualText: atText, + start: start, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) onTap(atText); + })); + } +} + +``` + +### SpecialTextSpanBuilder + +create your SpecialTextSpanBuilder + +```dart +class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder { + /// whether show background for @somebody + final bool showAtBackground; + final BuilderType type; + MySpecialTextSpanBuilder( + {this.showAtBackground: false, this.type: BuilderType.extendedText}); + + @override + TextSpan build(String data, {TextStyle textStyle, onTap}) { + var textSpan = super.build(data, textStyle: textStyle, onTap: onTap); + return textSpan; + } + + @override + SpecialText createSpecialText(String flag, + {TextStyle textStyle, SpecialTextGestureTapCallback onTap, int index}) { + if (flag == null || flag == "") return null; + + ///index is end index of start flag, so text start index should be index-(flag.length-1) + if (isStart(flag, AtText.flag)) { + return AtText(textStyle, onTap, + start: index - (AtText.flag.length - 1), + showAtBackground: showAtBackground, + type: type); + } else if (isStart(flag, EmojiText.flag)) { + return EmojiText(textStyle, start: index - (EmojiText.flag.length - 1)); + } else if (isStart(flag, DollarText.flag)) { + return DollarText(textStyle, onTap, + start: index - (DollarText.flag.length - 1), type: type); + } + return null; + } +} +``` + +## Image + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/extended_text_field_image.gif) + +### ImageSpan + +show inline image by using ImageSpan. + +```dart +ImageSpan( + ImageProvider image, { + Key key, + @required double imageWidth, + @required double imageHeight, + EdgeInsets margin, + int start: 0, + ui.PlaceholderAlignment alignment = ui.PlaceholderAlignment.bottom, + String actualText, + TextBaseline baseline, + TextStyle style, + BoxFit fit: BoxFit.scaleDown, + ImageLoadingBuilder loadingBuilder, + ImageFrameBuilder frameBuilder, + String semanticLabel, + bool excludeFromSemantics = false, + Color color, + BlendMode colorBlendMode, + AlignmentGeometry imageAlignment = Alignment.center, + ImageRepeat repeat = ImageRepeat.noRepeat, + Rect centerSlice, + bool matchTextDirection = false, + bool gaplessPlayback = false, + FilterQuality filterQuality = FilterQuality.low, + }) + +ImageSpan(AssetImage("xxx.jpg"), + imageWidth: size, + imageHeight: size, + margin: EdgeInsets.only(left: 2.0, bottom: 0.0, right: 2.0)); + } +``` + +| parameter | description | default | +| ----------- | ----------------------------------------------------------------------------- | -------- | +| image | The image to display(ImageProvider). | - | +| imageWidth | The width of image(not include margin) | required | +| imageHeight | The height of image(not include margin) | required | +| margin | The margin of image | - | +| actualText | Actual text, take care of it when enable selection,something likes "\[love\]" | '\uFFFC' | +| start | Start index of text,take care of it when enable selection. | 0 | + +### Cache Image + +if you want cache the network image, you can use ExtendedNetworkImageProvider and clear them with clearDiskCachedImages + +import extended_image_library + +```dart +dependencies: + extended_image_library: ^0.1.4 +``` + +```dart +ExtendedNetworkImageProvider( + this.url, { + this.scale = 1.0, + this.headers, + this.cache: false, + this.retries = 3, + this.timeLimit, + this.timeRetry = const Duration(milliseconds: 100), + CancellationToken cancelToken, +}) : assert(url != null), + assert(scale != null), + cancelToken = cancelToken ?? CancellationToken(); +``` + +| parameter | description | default | +| ----------- | ------------------------------------------------------------------------------------- | ------------------- | +| url | The URL from which the image will be fetched. | required | +| scale | The scale to place in the [ImageInfo] object of the image. | 1.0 | +| headers | The HTTP headers that will be used with [HttpClient.get] to fetch image from network. | - | +| cache | whether cache image to local | false | +| retries | the time to retry to request | 3 | +| timeLimit | time limit to request image | - | +| timeRetry | the time duration to retry to request | milliseconds: 100 | +| cancelToken | token to cancel network request | CancellationToken() | + +```dart +/// Clear the disk cache directory then return if it succeed. +/// timespan to compute whether file has expired or not +Future clearDiskCachedImages({Duration duration}) async +``` + +## TextSelectionControls + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/custom_toolbar.gif) + + +override [ExtendedTextField.extendedContextMenuBuilder] and [TextSelectionControls] to custom your toolbar widget or handle widget + +```dart +const double _kHandleSize = 22.0; + +/// Android Material styled text selection controls. +class MyTextSelectionControls extends TextSelectionControls + with TextSelectionHandleControls { + static Widget defaultContextMenuBuilder( + BuildContext context, ExtendedEditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.buttonItems( + buttonItems: [ + ...editableTextState.contextMenuButtonItems, + ContextMenuButtonItem( + onPressed: () { + launchUrl( + Uri.parse( + 'mailto:zmtzawqlp@live.com?subject=extended_text_share&body=${editableTextState.textEditingValue.text}', + ), + ); + editableTextState.hideToolbar(true); + editableTextState.textEditingValue + .copyWith(selection: const TextSelection.collapsed(offset: 0)); + }, + type: ContextMenuButtonType.custom, + label: 'like', + ), + ], + anchors: editableTextState.contextMenuAnchors, + ); + // return AdaptiveTextSelectionToolbar.editableText( + // editableTextState: editableTextState, + // ); + } + + /// Returns the size of the Material handle. + @override + Size getHandleSize(double textLineHeight) => + const Size(_kHandleSize, _kHandleSize); + + /// Builder for material-style text selection handles. + @override + Widget buildHandle( + BuildContext context, TextSelectionHandleType type, double textLineHeight, + [VoidCallback? onTap, double? startGlyphHeight, double? endGlyphHeight]) { + final Widget handle = SizedBox( + width: _kHandleSize, + height: _kHandleSize, + child: Image.asset( + 'assets/40.png', + ), + ); + + // [handle] is a circle, with a rectangle in the top left quadrant of that + // circle (an onion pointing to 10:30). We rotate [handle] to point + // straight up or up-right depending on the handle type. + switch (type) { + case TextSelectionHandleType.left: // points up-right + return Transform.rotate( + angle: math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.right: // points up-left + return Transform.rotate( + angle: -math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.collapsed: // points up + return handle; + } + } + + /// Gets anchor for material-style text selection handles. + /// + /// See [TextSelectionControls.getHandleAnchor]. + @override + Offset getHandleAnchor(TextSelectionHandleType type, double textLineHeight, + [double? startGlyphHeight, double? endGlyphHeight]) { + switch (type) { + case TextSelectionHandleType.left: + return const Offset(_kHandleSize, 0); + case TextSelectionHandleType.right: + return Offset.zero; + default: + return const Offset(_kHandleSize / 2, -4); + } + } + + @override + bool canSelectAll(TextSelectionDelegate delegate) { + // Android allows SelectAll when selection is not collapsed, unless + // everything has already been selected. + final TextEditingValue value = delegate.textEditingValue; + return delegate.selectAllEnabled && + value.text.isNotEmpty && + !(value.selection.start == 0 && + value.selection.end == value.text.length); + } +} + +``` + +## WidgetSpan + +![](https://github.com/fluttercandies/Flutter_Candies/blob/master/gif/extended_text_field/widget_span.gif) + +support to select and hitTest ExtendedWidgetSpan, you can create any widget in ExtendedTextField. + +```dart +class EmailText extends SpecialText { + final TextEditingController controller; + final int start; + final BuildContext context; + EmailText(TextStyle textStyle, SpecialTextGestureTapCallback onTap, + {this.start, this.controller, this.context, String startFlag}) + : super(startFlag, " ", textStyle, onTap: onTap); + + @override + bool isEnd(String value) { + var index = value.indexOf("@"); + var index1 = value.indexOf("."); + + return index >= 0 && + index1 >= 0 && + index1 > index + 1 && + super.isEnd(value); + } + + @override + InlineSpan finishText() { + final String text = toString(); + + return ExtendedWidgetSpan( + actualText: text, + start: start, + alignment: ui.PlaceholderAlignment.middle, + child: GestureDetector( + child: Padding( + padding: EdgeInsets.only(right: 5.0, top: 2.0, bottom: 2.0), + child: ClipRRect( + borderRadius: BorderRadius.all(Radius.circular(5.0)), + child: Container( + padding: EdgeInsets.all(5.0), + color: Colors.orange, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + text.trim(), + //style: textStyle?.copyWith(color: Colors.orange), + ), + SizedBox( + width: 5.0, + ), + InkWell( + child: Icon( + Icons.close, + size: 15.0, + ), + onTap: () { + controller.value = controller.value.copyWith( + text: controller.text + .replaceRange(start, start + text.length, ""), + selection: TextSelection.fromPosition( + TextPosition(offset: start))); + }, + ) + ], + ), + )), + ), + onTap: () { + showDialog( + context: context, + barrierDismissible: true, + builder: (c) { + TextEditingController textEditingController = + TextEditingController()..text = text.trim(); + return Column( + children: [ + Expanded( + child: Container(), + ), + Material( + child: Padding( + padding: EdgeInsets.all(10.0), + child: TextField( + controller: textEditingController, + decoration: InputDecoration( + suffixIcon: FlatButton( + child: Text("OK"), + onPressed: () { + controller.value = controller.value.copyWith( + text: controller.text.replaceRange( + start, + start + text.length, + textEditingController.text + " "), + selection: TextSelection.fromPosition( + TextPosition( + offset: start + + (textEditingController.text + " ") + .length))); + + Navigator.pop(context); + }, + )), + ), + )), + Expanded( + child: Container(), + ) + ], + ); + }); + }, + ), + deleteAll: true, + ); + } +} +``` + +## NoSystemKeyboard + +support to prevent system keyboard show without any code intrusion for [ExtendedTextField] or [TextField]. + +### TextInputBindingMixin + +we prevent system keyboard show by stop Flutter Framework send `TextInput.show` message to Flutter Engine. + +you can use [TextInputBinding] directly. + +``` dart +void main() { + TextInputBinding(); + runApp(const MyApp()); +} +``` + +or if you have other `binding` you can do as following. + +``` dart + class YourBinding extends WidgetsFlutterBinding with TextInputBindingMixin,YourBindingMixin { + } + + void main() { + YourBinding(); + runApp(const MyApp()); + } +``` + +or you need to override `ignoreTextInputShow`, you can do as following. + +``` dart + class YourBinding extends TextInputBinding { + @override + // ignore: unnecessary_overrides + bool ignoreTextInputShow() { + // you can override it base on your case + // if NoKeyboardFocusNode is not enough + return super.ignoreTextInputShow(); + } + } + + void main() { + YourBinding(); + runApp(const MyApp()); + } +``` + +### TextInputFocusNode + +you should pass the [TextInputFocusNode] into [ExtendedTextField] or [TextField]. + +``` dart +final TextInputFocusNode _focusNode = TextInputFocusNode(); + + @override + Widget build(BuildContext context) { + return ExtendedTextField( + // request keyboard if need + focusNode: _focusNode..debugLabel = 'ExtendedTextField', + ); + } + + @override + Widget build(BuildContext context) { + return TextField( + // request keyboard if need + focusNode: _focusNode..debugLabel = 'CustomTextField', + ); + } +``` + +we prevent system keyboard show base on current focus is [TextInputFocusNode] and `ignoreSystemKeyboardShow` is true。 + +``` dart + final FocusNode? focus = FocusManager.instance.primaryFocus; + if (focus != null && + focus is TextInputFocusNode && + focus.ignoreSystemKeyboardShow) { + return true; + } + +### CustomKeyboard + +show/hide your custom keyboard on [TextInputFocusNode] focus is changed. + +if your custom keyboard can be close without unFocus, you need also handle +show custom keyboard when [ExtendedTextField] or [TextField] `onTap`. + +``` dart + @override + void initState() { + super.initState(); + _focusNode.addListener(_handleFocusChanged); + } + + void _onTextFiledTap() { + if (_bottomSheetController == null) { + _handleFocusChanged(); + } + } + + void _handleFocusChanged() { + if (_focusNode.hasFocus) { + // just demo, you can define your custom keyboard as you want + _bottomSheetController = showBottomSheet( + context: FocusManager.instance.primaryFocus!.context!, + // set false, if don't want to drag to close custom keyboard + enableDrag: true, + builder: (BuildContext b) { + // your custom keyboard + return Container(); + }); + // maybe drag close + _bottomSheetController?.closed.whenComplete(() { + _bottomSheetController = null; + }); + } else { + _bottomSheetController?.close(); + _bottomSheetController = null; + } + } + + @override + void dispose() { + _focusNode.removeListener(_handleFocusChanged); + super.dispose(); + } +``` + + +see [Full Demo](https://github.com/fluttercandies/extended_text_field/tree/master/example/lib/pages/simple/no_keyboard.dart) \ No newline at end of file diff --git a/local_packages/extended_text_field-16.0.2-patched/analysis_options.yaml b/local_packages/extended_text_field-16.0.2-patched/analysis_options.yaml new file mode 100644 index 0000000..47879b9 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/analysis_options.yaml @@ -0,0 +1,203 @@ +# Specify analysis options. +# +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# There are other similar analysis options files in the flutter repos, +# which should be kept in sync with this file: +# +# - analysis_options.yaml (this file) +# - packages/flutter/lib/analysis_options_user.yaml +# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml +# - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# +# This file contains the analysis options used by Flutter tools, such as IntelliJ, +# Android Studio, and the `flutter analyze` command. + +analyzer: + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # Ignore analyzer hints for updating pubspecs when using Future or + # Stream and not importing dart:async + # Please see https://github.com/flutter/flutter/pull/24528 for details. + # sdk_version_async_exported_from_core: ignore + # exclude: + # - "bin/cache/**" + # # the following two are relative to the stocks example and the flutter package respectively + # # see https://github.com/dart-lang/sdk/issues/28463 + # - "lib/i18n/messages_*.dart" + # - "lib/src/http/**" + +linter: + rules: + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + # - always_require_non_null_named_parameters + - always_specify_types + - annotate_overrides + # - avoid_annotating_with_dynamic # conflicts with always_specify_types + # - avoid_as # required for implicit-casts: true + - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses # we do this commonly + # - avoid_catching_errors # we do this commonly + - avoid_classes_with_only_static_members + # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_empty_else + # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + # - avoid_implementing_value_types # not yet tested + - avoid_init_to_null + # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # not yet tested + # - avoid_print # not yet tested + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + # - avoid_redundant_argument_values # not yet tested + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + # - avoid_returning_null # there are plenty of valid reasons to return null + # - avoid_returning_null_for_future # not yet tested + - avoid_returning_null_for_void + # - avoid_returning_this # there are plenty of valid reasons to return this + # - avoid_setters_without_getters # not yet tested + # - avoid_shadowing_type_parameters # not yet tested + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters # conflicts with always_specify_types + # - avoid_unnecessary_containers # not yet tested + - avoid_unused_constructor_parameters + - avoid_void_async + # - avoid_web_libraries_in_flutter # not yet tested + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # not yet tested + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not yet tested + # - diagnostic_describe_all_properties # not yet tested + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + # - file_names # not yet tested + - flutter_style_todos + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + # - iterable_contains_unrelated_type + # - join_return_with_assignment # not yet tested + - library_names + - library_prefixes + # - lines_longer_than_80_chars # not yet tested + # - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + # - missing_whitespace_between_adjacent_strings # not yet tested + - no_adjacent_strings_in_list + - no_duplicate_case_values + # - no_logic_in_create_state # not yet tested + # - no_runtimeType_toString # not yet tested + - non_constant_identifier_names + # - null_closures # not yet tested + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_asserts_with_message # not yet tested + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # not yet tested + - prefer_contains + # - prefer_double_quotes # opposite of prefer_single_quotes + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + # - prefer_function_declarations_over_variables # not yet tested + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals # not yet tested + # - prefer_interpolation_to_compose_strings # not yet tested + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 + # - prefer_relative_imports # not yet tested + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + # - provide_deprecation_message # not yet tested + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + - slash_for_doc_comments + # - sort_child_properties_last # not yet tested + - sort_constructors_first + # - sort_pub_dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives + # - unnecessary_await_in_return # not yet tested + - unnecessary_brace_in_string_interps + - unnecessary_const + # - unnecessary_final # conflicts with prefer_final_locals + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_in_if_null_operators + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - unsafe_html # not yet tested + - use_full_hex_values_for_flutter_colors + # - use_function_type_syntax_for_parameters # not yet tested + # - use_key_in_widget_constructors # not yet tested + - use_rethrow_when_possible + # - use_setters_to_change_properties # not yet tested + # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + - void_checks diff --git a/local_packages/extended_text_field-16.0.2-patched/example/README.md b/local_packages/extended_text_field-16.0.2-patched/example/README.md new file mode 100644 index 0000000..99ce5c8 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter application. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) + +For help getting started with Flutter, view our +[online documentation](https://flutter.dev/docs), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/local_packages/extended_text_field-16.0.2-patched/example/analysis_options.yaml b/local_packages/extended_text_field-16.0.2-patched/example/analysis_options.yaml new file mode 100644 index 0000000..04e68ba --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/analysis_options.yaml @@ -0,0 +1,203 @@ +# Specify analysis options. +# +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# There are other similar analysis options files in the flutter repos, +# which should be kept in sync with this file: +# +# - analysis_options.yaml (this file) +# - packages/flutter/lib/analysis_options_user.yaml +# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml +# - https://github.com/flutter/engine/blob/master/analysis_options.yaml +# +# This file contains the analysis options used by Flutter tools, such as IntelliJ, +# Android Studio, and the `flutter analyze` command. + +analyzer: + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # Ignore analyzer hints for updating pubspecs when using Future or + # Stream and not importing dart:async + # Please see https://github.com/flutter/flutter/pull/24528 for details. + # sdk_version_async_exported_from_core: ignore + # exclude: + # - "bin/cache/**" + # # the following two are relative to the stocks example and the flutter package respectively + # # see https://github.com/dart-lang/sdk/issues/28463 + # - "lib/i18n/messages_*.dart" + # - "lib/src/http/**" + +linter: + rules: + # these rules are documented on and in the same order as + # the Dart Lint rules page to make maintenance easier + # https://github.com/dart-lang/linter/blob/master/example/all.yaml + - always_declare_return_types + - always_put_control_body_on_new_line + # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219 + # - always_require_non_null_named_parameters + - always_specify_types + - annotate_overrides + # - avoid_annotating_with_dynamic # conflicts with always_specify_types + # - avoid_as # required for implicit-casts: true + - avoid_bool_literals_in_conditional_expressions + # - avoid_catches_without_on_clauses # we do this commonly + # - avoid_catching_errors # we do this commonly + - avoid_classes_with_only_static_members + # - avoid_double_and_int_checks # only useful when targeting JS runtime + - avoid_empty_else + # - avoid_equals_and_hash_code_on_mutable_classes # not yet tested + - avoid_field_initializers_in_const_classes + - avoid_function_literals_in_foreach_calls + # - avoid_implementing_value_types # not yet tested + - avoid_init_to_null + # - avoid_js_rounded_ints # only useful when targeting JS runtime + - avoid_null_checks_in_equality_operators + # - avoid_positional_boolean_parameters # not yet tested + # - avoid_print # not yet tested + # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356) + # - avoid_redundant_argument_values # not yet tested + - avoid_relative_lib_imports + - avoid_renaming_method_parameters + - avoid_return_types_on_setters + # - avoid_returning_null # there are plenty of valid reasons to return null + # - avoid_returning_null_for_future # not yet tested + - avoid_returning_null_for_void + # - avoid_returning_this # there are plenty of valid reasons to return this + # - avoid_setters_without_getters # not yet tested + # - avoid_shadowing_type_parameters # not yet tested + - avoid_single_cascade_in_expression_statements + - avoid_slow_async_io + - avoid_types_as_parameter_names + # - avoid_types_on_closure_parameters # conflicts with always_specify_types + # - avoid_unnecessary_containers # not yet tested + - avoid_unused_constructor_parameters + - avoid_void_async + # - avoid_web_libraries_in_flutter # not yet tested + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + # - cascade_invocations # not yet tested + # - close_sinks # not reliable enough + # - comment_references # blocked on https://github.com/flutter/flutter/issues/20765 + # - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204 + - control_flow_in_finally + # - curly_braces_in_flow_control_structures # not yet tested + # - diagnostic_describe_all_properties # not yet tested + - directives_ordering + - empty_catches + - empty_constructor_bodies + - empty_statements + # - file_names # not yet tested + - flutter_style_todos + - hash_and_equals + - implementation_imports + # - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811 + # - iterable_contains_unrelated_type + # - join_return_with_assignment # not yet tested + - library_names + - library_prefixes + # - lines_longer_than_80_chars # not yet tested + # - list_remove_unrelated_type + # - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181 + # - missing_whitespace_between_adjacent_strings # not yet tested + - no_adjacent_strings_in_list + - no_duplicate_case_values + # - no_logic_in_create_state # not yet tested + # - no_runtimeType_toString # not yet tested + - non_constant_identifier_names + # - null_closures # not yet tested + # - omit_local_variable_types # opposite of always_specify_types + # - one_member_abstracts # too many false positives + # - only_throw_errors # https://github.com/flutter/flutter/issues/5792 + - overridden_fields + - package_api_docs + - package_names + - package_prefixed_library_names + # - parameter_assignments # we do this commonly + - prefer_adjacent_string_concatenation + - prefer_asserts_in_initializer_lists + # - prefer_asserts_with_message # not yet tested + - prefer_collection_literals + - prefer_conditional_assignment + - prefer_const_constructors + - prefer_const_constructors_in_immutables + - prefer_const_declarations + - prefer_const_literals_to_create_immutables + # - prefer_constructors_over_static_methods # not yet tested + - prefer_contains + # - prefer_double_quotes # opposite of prefer_single_quotes + # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods + - prefer_final_fields + - prefer_final_in_for_each + - prefer_final_locals + - prefer_for_elements_to_map_fromIterable + - prefer_foreach + # - prefer_function_declarations_over_variables # not yet tested + - prefer_generic_function_type_aliases + - prefer_if_elements_to_conditional_expressions + - prefer_if_null_operators + - prefer_initializing_formals + - prefer_inlined_adds + # - prefer_int_literals # not yet tested + # - prefer_interpolation_to_compose_strings # not yet tested + - prefer_is_empty + - prefer_is_not_empty + - prefer_is_not_operator + - prefer_iterable_whereType + # - prefer_mixin # https://github.com/dart-lang/language/issues/32 + # - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932 + # - prefer_relative_imports # not yet tested + - prefer_single_quotes + - prefer_spread_collections + - prefer_typing_uninitialized_variables + - prefer_void_to_null + # - provide_deprecation_message # not yet tested + # - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml + - recursive_getters + - slash_for_doc_comments + #- sort_child_properties_last # not yet tested + - sort_constructors_first + #- sort_pub_dependencies + - sort_unnamed_constructors_first + - test_types_in_equals + - throw_in_finally + # - type_annotate_public_apis # subset of always_specify_types + - type_init_formals + # - unawaited_futures # too many false positives + # - unnecessary_await_in_return # not yet tested + - unnecessary_brace_in_string_interps + - unnecessary_const + # - unnecessary_final # conflicts with prefer_final_locals + - unnecessary_getters_setters + # - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498 + - unnecessary_new + - unnecessary_null_aware_assignments + - unnecessary_null_in_if_null_operators + - unnecessary_overrides + - unnecessary_parenthesis + - unnecessary_statements + - unnecessary_string_interpolations + - unnecessary_this + - unrelated_type_equality_checks + # - unsafe_html # not yet tested + - use_full_hex_values_for_flutter_colors + # - use_function_type_syntax_for_parameters # not yet tested + # - use_key_in_widget_constructors # not yet tested + - use_rethrow_when_possible + # - use_setters_to_change_properties # not yet tested + # - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182 + # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review + - valid_regexps + - void_checks diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/build.gradle b/local_packages/extended_text_field-16.0.2-patched/example/android/app/build.gradle new file mode 100644 index 0000000..118ee1d --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/build.gradle @@ -0,0 +1,67 @@ +plugins { + id "com.android.application" + id "kotlin-android" + id "dev.flutter.flutter-gradle-plugin" +} + +def localProperties = new Properties() +def localPropertiesFile = rootProject.file('local.properties') +if (localPropertiesFile.exists()) { + localPropertiesFile.withReader('UTF-8') { reader -> + localProperties.load(reader) + } +} + +def flutterVersionCode = localProperties.getProperty('flutter.versionCode') +if (flutterVersionCode == null) { + flutterVersionCode = '1' +} + +def flutterVersionName = localProperties.getProperty('flutter.versionName') +if (flutterVersionName == null) { + flutterVersionName = '1.0' +} + +android { + namespace "com.example.example" + compileSdkVersion flutter.compileSdkVersion + ndkVersion flutter.ndkVersion + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + kotlinOptions { + jvmTarget = '1.8' + } + + sourceSets { + main.java.srcDirs += 'src/main/kotlin' + } + + defaultConfig { + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). + applicationId "com.example.example" + // You can update the following values to match your application needs. + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. + minSdkVersion flutter.minSdkVersion + targetSdkVersion flutter.targetSdkVersion + versionCode flutterVersionCode.toInteger() + versionName flutterVersionName + } + + buildTypes { + release { + // TODO: Add your own signing config for the release build. + // Signing with the debug keys for now, so `flutter run --release` works. + signingConfig signingConfigs.debug + } + } +} + +flutter { + source '../..' +} + +dependencies {} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/debug/AndroidManifest.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/debug/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/debug/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/AndroidManifest.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..19b862e --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt new file mode 100644 index 0000000..e793a00 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt @@ -0,0 +1,6 @@ +package com.example.example + +import io.flutter.embedding.android.FlutterActivity + +class MainActivity: FlutterActivity() { +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable-v21/launch_background.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable-v21/launch_background.xml new file mode 100644 index 0000000..f74085f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable-v21/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable/launch_background.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable/launch_background.xml new file mode 100644 index 0000000..304732f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/drawable/launch_background.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..db77bb4b7b0906d62b1847e87f15cdcacf6a4f29 GIT binary patch literal 544 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY3?!3`olAj~WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8bpbvhu0Wd6uZuB!w&u2PAxD2eNXD>P5D~Wn-+_Wa#27Xc zC?Zj|6r#X(-D3u$NCt}(Ms06KgJ4FxJVv{GM)!I~&n8Bnc94O7-Hd)cjDZswgC;Qs zO=b+9!WcT8F?0rF7!Uys2bs@gozCP?z~o%U|N3vA*22NaGQG zlg@K`O_XuxvZ&Ks^m&R!`&1=spLvfx7oGDKDwpwW`#iqdw@AL`7MR}m`rwr|mZgU`8P7SBkL78fFf!WnuYWm$5Z0 zNXhDbCv&49sM544K|?c)WrFfiZvCi9h0O)B3Pgg&ebxsLQ05GG~ AQ2+n{ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..17987b79bb8a35cc66c3c1fd44f5a5526c1b78be GIT binary patch literal 442 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5Xx&nMcT!A!W`0S9QKQy;}1Cl^CgaH=;G9cpY;r$Q>i*pfB zP2drbID<_#qf;rPZx^FqH)F_D#*k@@q03KywUtLX8Ua?`H+NMzkczFPK3lFz@i_kW%1NOn0|D2I9n9wzH8m|-tHjsw|9>@K=iMBhxvkv6m8Y-l zytQ?X=U+MF$@3 zt`~i=@j|6y)RWMK--}M|=T`o&^Ni>IoWKHEbBXz7?A@mgWoL>!*SXo`SZH-*HSdS+ yn*9;$7;m`l>wYBC5bq;=U}IMqLzqbYCidGC!)_gkIk_C@Uy!y&wkt5C($~2D>~)O*cj@FGjOCM)M>_ixfudOh)?xMu#Fs z#}Y=@YDTwOM)x{K_j*Q;dPdJ?Mz0n|pLRx{4n|)f>SXlmV)XB04CrSJn#dS5nK2lM zrZ9#~WelCp7&e13Y$jvaEXHskn$2V!!DN-nWS__6T*l;H&Fopn?A6HZ-6WRLFP=R` zqG+CE#d4|IbyAI+rJJ`&x9*T`+a=p|0O(+s{UBcyZdkhj=yS1>AirP+0R;mf2uMgM zC}@~JfByORAh4SyRgi&!(cja>F(l*O+nd+@4m$|6K6KDn_&uvCpV23&>G9HJp{xgg zoq1^2_p9@|WEo z*X_Uko@K)qYYv~>43eQGMdbiGbo>E~Q& zrYBH{QP^@Sti!`2)uG{irBBq@y*$B zi#&(U-*=fp74j)RyIw49+0MRPMRU)+a2r*PJ$L5roHt2$UjExCTZSbq%V!HeS7J$N zdG@vOZB4v_lF7Plrx+hxo7(fCV&}fHq)$ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d5f1c8d34e7a88e3f88bea192c3a370d44689c3c GIT binary patch literal 1031 zcmeAS@N?(olHy`uVBq!ia0vp^6F``Q8Ax83A=Cw=BuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrIztFa`(sgt!6~Yi|1%a`XoT0ojZ}lNrNjb9xjc(B0U1_% zz5^97Xt*%oq$rQy4?0GKNfJ44uvxI)gC`h-NZ|&0-7(qS@?b!5r36oQ}zyZrNO3 zMO=Or+<~>+A&uN&E!^Sl+>xE!QC-|oJv`ApDhqC^EWD|@=#J`=d#Xzxs4ah}w&Jnc z$|q_opQ^2TrnVZ0o~wh<3t%W&flvYGe#$xqda2bR_R zvPYgMcHgjZ5nSA^lJr%;<&0do;O^tDDh~=pIxA#coaCY>&N%M2^tq^U%3DB@ynvKo}b?yu-bFc-u0JHzced$sg7S3zqI(2 z#Km{dPr7I=pQ5>FuK#)QwK?Y`E`B?nP+}U)I#c1+FM*1kNvWG|a(TpksZQ3B@sD~b zpQ2)*V*TdwjFOtHvV|;OsiDqHi=6%)o4b!)x$)%9pGTsE z-JL={-Ffv+T87W(Xpooq<`r*VzWQcgBN$$`u}f>-ZQI1BB8ykN*=e4rIsJx9>z}*o zo~|9I;xof literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4d6372eebdb28e45604e46eeda8dd24651419bc0 GIT binary patch literal 1443 zcmb`G{WsKk6vsdJTdFg%tJav9_E4vzrOaqkWF|A724Nly!y+?N9`YV6wZ}5(X(D_N(?!*n3`|_r0Hc?=PQw&*vnU?QTFY zB_MsH|!j$PP;I}?dppoE_gA(4uc!jV&0!l7_;&p2^pxNo>PEcNJv za5_RT$o2Mf!<+r?&EbHH6nMoTsDOa;mN(wv8RNsHpG)`^ymG-S5By8=l9iVXzN_eG%Xg2@Xeq76tTZ*dGh~Lo9vl;Zfs+W#BydUw zCkZ$o1LqWQO$FC9aKlLl*7x9^0q%0}$OMlp@Kk_jHXOjofdePND+j!A{q!8~Jn+s3 z?~~w@4?egS02}8NuulUA=L~QQfm;MzCGd)XhiftT;+zFO&JVyp2mBww?;QByS_1w! zrQlx%{^cMj0|Bo1FjwY@Q8?Hx0cIPF*@-ZRFpPc#bBw{5@tD(5%sClzIfl8WU~V#u zm5Q;_F!wa$BSpqhN>W@2De?TKWR*!ujY;Yylk_X5#~V!L*Gw~;$%4Q8~Mad z@`-kG?yb$a9cHIApZDVZ^U6Xkp<*4rU82O7%}0jjHlK{id@?-wpN*fCHXyXh(bLt* zPc}H-x0e4E&nQ>y%B-(EL=9}RyC%MyX=upHuFhAk&MLbsF0LP-q`XnH78@fT+pKPW zu72MW`|?8ht^tz$iC}ZwLp4tB;Q49K!QCF3@!iB1qOI=?w z7In!}F~ij(18UYUjnbmC!qKhPo%24?8U1x{7o(+?^Zu0Hx81|FuS?bJ0jgBhEMzf< zCgUq7r2OCB(`XkKcN-TL>u5y#dD6D!)5W?`O5)V^>jb)P)GBdy%t$uUMpf$SNV31$ zb||OojAbvMP?T@$h_ZiFLFVHDmbyMhJF|-_)HX3%m=CDI+ID$0^C>kzxprBW)hw(v zr!Gmda);ICoQyhV_oP5+C%?jcG8v+D@9f?Dk*!BxY}dazmrT@64UrP3hlslANK)bq z$67n83eh}OeW&SV@HG95P|bjfqJ7gw$e+`Hxo!4cx`jdK1bJ>YDSpGKLPZ^1cv$ek zIB?0S<#tX?SJCLWdMd{-ME?$hc7A$zBOdIJ)4!KcAwb=VMov)nK;9z>x~rfT1>dS+ zZ6#`2v@`jgbqq)P22H)Tx2CpmM^o1$B+xT6`(v%5xJ(?j#>Q$+rx_R|7TzDZe{J6q zG1*EcU%tE?!kO%^M;3aM6JN*LAKUVb^xz8-Pxo#jR5(-KBeLJvA@-gxNHx0M-ZJLl z;#JwQoh~9V?`UVo#}{6ka@II>++D@%KqGpMdlQ}?9E*wFcf5(#XQnP$Dk5~%iX^>f z%$y;?M0BLp{O3a(-4A?ewryHrrD%cx#Q^%KY1H zNre$ve+vceSLZcNY4U(RBX&)oZn*Py()h)XkE?PL$!bNb{N5FVI2Y%LKEm%yvpyTP z(1P?z~7YxD~Rf<(a@_y` literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values-night/styles.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 0000000..06952be --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values/styles.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..cb1ef88 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/main/res/values/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/profile/AndroidManifest.xml b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/profile/AndroidManifest.xml new file mode 100644 index 0000000..399f698 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/app/src/profile/AndroidManifest.xml @@ -0,0 +1,7 @@ + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/build.gradle b/local_packages/extended_text_field-16.0.2-patched/example/android/build.gradle new file mode 100644 index 0000000..e83fb5d --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/build.gradle @@ -0,0 +1,30 @@ +buildscript { + ext.kotlin_version = '1.7.10' + repositories { + google() + mavenCentral() + } + + dependencies { + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + } +} + +allprojects { + repositories { + google() + mavenCentral() + } +} + +rootProject.buildDir = '../build' +subprojects { + project.buildDir = "${rootProject.buildDir}/${project.name}" +} +subprojects { + project.evaluationDependsOn(':app') +} + +tasks.register("clean", Delete) { + delete rootProject.buildDir +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/gradle.properties b/local_packages/extended_text_field-16.0.2-patched/example/android/gradle.properties new file mode 100644 index 0000000..598d13f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/gradle.properties @@ -0,0 +1,3 @@ +org.gradle.jvmargs=-Xmx4G +android.useAndroidX=true +android.enableJetifier=true diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/gradle/wrapper/gradle-wrapper.properties b/local_packages/extended_text_field-16.0.2-patched/example/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..3c472b9 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/local_packages/extended_text_field-16.0.2-patched/example/android/settings.gradle b/local_packages/extended_text_field-16.0.2-patched/example/android/settings.gradle new file mode 100644 index 0000000..7cd7128 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/android/settings.gradle @@ -0,0 +1,29 @@ +pluginManagement { + def flutterSdkPath = { + def properties = new Properties() + file("local.properties").withInputStream { properties.load(it) } + def flutterSdkPath = properties.getProperty("flutter.sdk") + assert flutterSdkPath != null, "flutter.sdk not set in local.properties" + return flutterSdkPath + } + settings.ext.flutterSdkPath = flutterSdkPath() + + includeBuild("${settings.ext.flutterSdkPath}/packages/flutter_tools/gradle") + + repositories { + google() + mavenCentral() + gradlePluginPortal() + } + + plugins { + id "dev.flutter.flutter-gradle-plugin" version "1.0.0" apply false + } +} + +plugins { + id "dev.flutter.flutter-plugin-loader" version "1.0.0" + id "com.android.application" version "7.3.0" apply false +} + +include ":app" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/1.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/1.png new file mode 100644 index 0000000000000000000000000000000000000000..7781b8095b4546ddfa42b494e41923806812067c GIT binary patch literal 6890 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 KtAA3pkNH1zXWm-? literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/10.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/10.png new file mode 100644 index 0000000000000000000000000000000000000000..abce71457c84e8ccf48fb86e32cfdfac5a91020b GIT binary patch literal 8188 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 T4O%4s004Pu6{&iOuVMcWmvyC{ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/11.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/11.png new file mode 100644 index 0000000000000000000000000000000000000000..23bd18e1e0f9981ed4702ac9090efbda67c89c58 GIT binary patch literal 10136 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 BQB42< literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/12.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/12.png new file mode 100644 index 0000000000000000000000000000000000000000..e27a414415d83ebf59d1cf506e9bc2069994295d GIT binary patch literal 9039 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/13.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/13.png new file mode 100644 index 0000000000000000000000000000000000000000..a64a750898c96db28439a622f115032f50fa9118 GIT binary patch literal 7408 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 MuP#^l+Wf=+009y?v;Y7A literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/15.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/15.png new file mode 100644 index 0000000000000000000000000000000000000000..65b942cbd01006d0875e097459183ec40a663a8a GIT binary patch literal 9840 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 RH17bwyAeR9R>~y!e*n;mAmIQ2 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/16.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/16.png new file mode 100644 index 0000000000000000000000000000000000000000..d94736e8b79fad71db04ce786e178df2d5046728 GIT binary patch literal 7282 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/18.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/18.png new file mode 100644 index 0000000000000000000000000000000000000000..5d6890089d186745af467a9fe409bca3f19b7299 GIT binary patch literal 7863 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/19.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/19.png new file mode 100644 index 0000000000000000000000000000000000000000..c051967b8529420922ce4381a620d343dc5b7991 GIT binary patch literal 6870 zcmZ{pbx<5#m&OMj+{57RIs*gz z{i=4iYOAaJRG+@*{?n)XKF{w)tE#-k#vsE0007wU4Irv7ZenfRrU3+sIUdk*w~Ww&lC9Y*wRLe7{qlVpz0>CbJ586 zvQpD<8Ap|B*E1)F6x zY-9lMfj{z&o9gvy3^ityM;|h%>jUz2O89lHQ(;9a&2Qe`(!RYNW`!DD%qN;=jW$Nu z3aIm{SH?@!DSWBN{c4%_b40B4&2|jcR2qac&G@Mo4M`3~6=-P;8tD=?!Ek+NLDuJn zJ!{nlYm|l9AaeRDyI?JThcF6l&kL`78fwfsd}7J74S~bgGt7l2;U7;p;Yzb`eh6g( z?bJPe+=n6x*HZewn~KD<9Hpm9%-aCLbvLO5|8yjVW5s!m(u~~&ov*b7ga&EpSrVN- zOwbJ@*0j8pc#ICTz{U|Zk`17-|7y+EvI|z$xYpkP*3QP zr~PA;5L94ULZ2)MIk(C>YnNrkI$fmH(k0fO+@#)z0Xlqv)qa^`p!YD_%W+@Vc;1HY z=BCf+-(=1M-61M8q?-GoG9O?QGwG=cI+9tlF@Mz(&L7+6aNTPqL7CJs;%Z_}!m5

d%&U}vKOwY5i6YpycPejnN%*p}MV~E(E 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/2.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/2.png new file mode 100644 index 0000000000000000000000000000000000000000..73101eb57cf25fba633dad7e84f472f466f90608 GIT binary patch literal 7854 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/21.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/21.png new file mode 100644 index 0000000000000000000000000000000000000000..1c708126392d8cc0e342bb48934965e92d3248b8 GIT binary patch literal 7814 zcmV;19(m!3P)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00007 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 YFfckWFe0$_R{#J207*qoM6N<$g0E8HmjD0& literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/22.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/22.png new file mode 100644 index 0000000000000000000000000000000000000000..d8773edfc3ec35d32b2e096bb4ea3aeb5235ee04 GIT binary patch literal 7559 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 L>Z(*J*@gWdgmPBZ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/23.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/23.png new file mode 100644 index 0000000000000000000000000000000000000000..3645445a092b5460961c473647d001f7bd4849f6 GIT binary patch literal 7803 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/26.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/26.png new file mode 100644 index 0000000000000000000000000000000000000000..a27eab47aa144cb8a48b06912f8110ede204130a GIT binary patch literal 6077 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 Cb&XX3 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/28.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/28.png new file mode 100644 index 0000000000000000000000000000000000000000..bf0d182962cbb6481029953e3b9b6926dd6f227f GIT binary patch literal 7023 zcmZ`;bxa&ius+~$io4t4?q1v}?heHdDDLj=?(VLoxb@26P+UrJ_d>Bge#!gi{qeHd zne0x!*<^N;{bnXc?UURG6k-$r0PsOUURvW_C;vB*5Z>jX?CDh&^6CE^qOf3xV6ojKxd@>RoV+ zybIXH+(p_I2%}Ae&Y=Hr5X%@Cawg!a{2|1>FIxMHGJ zDv#`O3qp;Ov#QzR{fH2W6VOg-)2MlN)9_ERSMXCz#uGQkF3O!kl zEsyk|Iga;LhkYa|+7UJibGRmniw+mln-N&oU%QLgWf|wHY344V{aHH9So4Y2s(gHY z@WP||XkOM`)tuYFQ%ULR@TIf;bdJaO`G>o2kQG8ek5F2_ULGiT;F_p^gtr_2J*w*8 zBa8@6lr2hk$R((kXX5wc!E!5NeY9LopZy()%?VvNwW~cA2#FWl*rtfq)A=^HGsTR4 z#ssdUO9l1k%4wylwpabqO7EsI9X{vAST1X%_&SYIbU}N;+11SW;lQuc4xeTX)0!>i z4|gT^iD3I&JCdyFI6C(ozxQp+~-anth6ClJJmZj3FhMfe|X z=uY9b69nI}`}T=$k(oIJ+d)>%JKOH5yuj5BOI`m*82=I5cv6U`tv^_sQ~Z{mr>rZ} zvwYiR`qhskOah;#JhlAQ(T}aKgQei2C|$X)%|QdUYZXZSI+{IFZJHAuCN(}C&l*C? ztyP09+mJgtJ6iI=4sl?AAe3h)-&{GrMEpvZ{7gJeKhS+-SUYwRR zCEi@Csd}#l+P%HqAQFyu=v-R%1c);DnAF^X|e>5TeAic>I{R4j1LpX zR2sagQTUhi!KP*cOeUAKxfmL_maq9{O%m2NuWIOebe(6YrjsWSl-0Sb;k;N|np_op z%^tK>ZT+FlM`=U(tQ^d|4z!aUMt9okwqER2=MAzc>muBo5cZk2@^`x1sne~K)V-^d zyJSqid0eAk!0*I0Z2w5$#Z)K1EEwK;I{m zIqYW6X2yCx<8TQlz$#g~S-3|rG2z^XJo&IV1reN1D1#c8dfatBU0=peLbf$01Acaa zoJQq9GCWPE**^O_>(-^v6vQNpoS5B?bubf0=Eti&KR78`-!zAgKk!NS8J zMOe3Rr305tR);KZh%^Gw;jGZDq1|+=e7^b1mWf5zKGI|fRz3ao#pEDk?uCcN54{kFXppIt*a%Wi20O9CYv9dRgq{G zqfs-S!d*A%bFdPI%Ftho*t#kwB@c+D%^72{&4q1+JvnOC*j7j?qL}OqBdhV@V%fHr zkW$uW7FYInld}Hwoq85NOxO>zxE8lO&bTU<^^h;tMXs&suU=LN9k%s*=PubU>XdCW zLU@k18!l5!k!hwN>bV!>AGHQ2AKs=V)rj9py~663T-qrD4X5X|8#7y-|E=b@uKiS_ znr(VxAix5hDFk@!a_n%Puo&;V;Ts5*Rn(H)EB-*z~GYszJGi! zm$!qMWHZ?ID~IJFYPZFZlUdsXKews2z-iQ5wMmk6HXw?D=v%|7yZc=!<5W#hpd*$T zdf=|D+)gnq*0-w_62798Zb#eQIt-8EIRX%J7pVwbVMUOHqk%}rS8rLU34#*_DM?Se zZfXQ(-nSN%5Vi&PQ17TH2Wqh-D~yQ;A2&NWA!eE(htb%l4w?v+W=9Wo4a6|L1P=#U zZ+`?4!>&8;r{!HT)^kGvCZ;n8CR#vt?A1#>ISCfgSK_I?!k_xZd|v;C`bzJ@zc~!4v~jjm z(zNQL?w&~;snfJ`-+;#EDvWiYqe6Yz_+*7T6W!?yjG-UB9tc8nK+8-_t8TPJtO z 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/29.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/29.png new file mode 100644 index 0000000000000000000000000000000000000000..2f05e7f04935a005ceb225a52941438cc1f78cb1 GIT binary patch literal 5710 zcmV-U7P0AxP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00007 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/30.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/30.png new file mode 100644 index 0000000000000000000000000000000000000000..27b31454bebe7661408a9d952cb52425c55fff08 GIT binary patch literal 7751 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

7Em0amYANd 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 Bi%0+f literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/38.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/38.png new file mode 100644 index 0000000000000000000000000000000000000000..efaaad0eca0fe9a9ebe095c89d4578fbe70ae20d GIT binary patch literal 4358 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 F{s+wg5DowU literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/39.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/39.png new file mode 100644 index 0000000000000000000000000000000000000000..5f5ee126ca3a8f53c92ed9d2206cb3c605d01c21 GIT binary patch literal 10638 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/4.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/4.png new file mode 100644 index 0000000000000000000000000000000000000000..3262ca981f3a38b1d49658ef114e83708522508a GIT binary patch literal 7796 zcmV-)9*g0LP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00007 zbV*G`2jU6=6dw;Go_9_F000JJOGiWi{{a60|De66lK=o6cu7P-RCwC$T?cqoMHas4 z9YT7600|}3^qwHD2qK7LLC{su1zl0Ffa_veu&#(AE3hoCVg+;&#Ra33P(_k}AP9mO z5ClRmX@rvG>^b+%TS827=azYS$-DD?|0gDS_syI6-UhF;1(M*Rkq75PeF%t0) zL@we-Mu190O)Y}xMGbrAarPd$>^(;z5)lDxPUf)V;em)n+=qAvQHVHIN0QhY)oc!% z*_`f2bVGQW+hrevHX5% z(lmDLonT}d$v%^L%n3fCvJh_~b|Wq|L((*a%ZNRQ8HjB2h%QSJc5sSEnd%b9zil}QJ6N7VqtQs#RRzFAIA5_q^dgTJ3E z1pB)|Sb#f32D?MMP!AdOZ~7Vij{b)JmR@5cBGDRrg&1faZOY1VD&iyNurr(_ULMX6 z5#$a@vA%HYwLviP?zZs8_-OcON>})LMo-9pHy(cYI1zsOBngT>OM!z+Qf1J;>1Xsi z`WyONdJVmno^cyKi=G*QM5Ff*M6MFVd_KW`W4-q9O|^$Uh+ z<2u5Mw|c^!Pm|&FiVV2)Z8kt*4#4Iq?#0`jbM)+^&n@`6~zZ8FX<)IF+{$IV}=vQfQd1Lm~ z1SvpLNjT<;S8Rkz~&x{K_w8x5T^km?Od1yqXvb7FRqCO68(x8(j1j*n(!S=u~YS-dw24Ig)hd! z`Sn>Asgs}M*uXWY+>iyIz8nkjU3|2V=m?9aH5>1>i)6{wIj-h|db&HK)CqxKK1*?& z<4UD|v~O_=j2av&ua!y?QQpygY;Wvd@(_7Wsri6yLp)&C#26@FYf2p@X;iT;OE&u{ z$g3euWR$%hXSX4asrg`JVXd3fTlR^VQio3((OQusG7T*?l_WaOQe^CMP+aCWZu8vP z35NC!g1w(5n^H%kG%CU)?e;$e$!n?7;W*gd$U|wEMZ6!v1JCfshDXAw6&WUZbdu=w z$_zQ2qf#&0&)h3^F}ffMcqi}e=?s%cN6BZod1M)Lq>;t?!UOHW$5WN5PrkX>rY292 zWT}kcnl$Ccy!J>(xIno$CV31c(M4QSN^ooCql!ddvRtet8I)c*gEu@uvWS zlRTnGbQ#xn_LH5|kcdi)W=c&|oAv;2V3dxnsVI3&^4Nw%6#h|hoKXOFtgXpI`8)@> z6lOPz&SM^1wmr^BCsLtUll7cw%lzdPJQH(9^OCGBQ(Toy0SD> zu2SNmeFNbnnd&BanuJ7T;*+09g+4S*bdL1^iL*MCJj_2YGM$7??I-$Waf+P5$w{I! z%poi+qi{8EY-{bD-X?kMghUkfh~kf(trcb3|CPsNCol8Ni81D}brrH3fbEX6Ie+QI zt5nk-KVx*zHHkOQHS)$#OH{qU!3nb|(}H}e#OM$3{Sbhyw<2!Cf8PSIWe~2>wO9T& zKT9Zq$dI}JrZ6?}vJ|7p_{RK{5BV$Y$rff1pw3l*Qlwo5R1sR=P6u6lvtYtNTkhuV9_hxc++F4 zXtBRu@=%S@=UhkEpirn>?|?@aZ8RN8hyIO{A{i--aBnC* z_D}pr8O6$c^$=*N#L=6lQ(I5iu^`F8q))a*zuEI7N}OG^^I+(>TncdXQwuqblt#Em zyFN*RE>T?79ulL1C((?@ zV|cyPxmu+VISosd-XOKR9~4vFR)GVNhpZ}6eycBmO~&~H06#ryoTY|)b?obO$mrFI zhd^aooQu>Y>|^C}V<)*{)Nzh3CV7e%SQKAdj>o9h`-d=OQ%8DE}EPy}OJd5$@T!yiB-0wGD4YN46RQz0Mtm*Cf?4@lH8xip>&_${-xW;Q(avR zmoHz2ni`$HBJyOD)6xi~8uyS26*(+2YKA_NM|obX#7622cHqlY2Ql4oleXQ7me4^> zdwuxuVOX?i5lomc0frAB4!7KL3ydB;8m3R54x2Y`h6@)iXd}_#_YJeie*15#+z^!0 zvDj$-bZ^8_r3XDRBGTq53BT)(+87E9)_o|ZrE-*(mcpDlb097*4&2<_>S+k-1c8Bp zFly8&*uH(cHYv1im@!fa*XzkYw&ksCO=yfjW0kTEDdT?)<@$(Lo>@bI3mdXw@1kT_ z`bH1A;^5^!cYrCQ+rwmp<-bwz{FwG~8(%U@H@+Pw>t;39o`kx6J_A+jKF5zAm!*um zyE|9NpljEzux!~fmAX(hz`j>m@KwJuy?$<-+(eyYzT+E(J;98h0o>UO4n-uU+?a=G`jxVRXS zl9Dvf)y2gHX3d(#PoS#v%sZWFh}7TuVFJ(ES2bjf%~tw=*Cq)%z8HC)y)R0>YeEum zX-QmXA1Ig?uZ~28*IR;_oMXw7CE(%Vp=+M~`t^hI@^XGX=$9$R5QrUP{ZjpT<~g@6 zd0I=BTZkKdAsq)Iq)+vx9J%aS6nU(m;9(JW#w0lpZvv<&;wI3fNt1NXF+4mRcJ125 zFNF@gWekCs6e1&qW1jg4|JnrVrPPv+8eitk>SetCgOgtIRxkOE3z6ip;_d+kI4Ft>Y&UC9)YsAlzH3rlCFt3iG5mX?$%0jZo5mx<+}y zp{1$D9$)yZlDtf~F*Cqs7rD_F;q$58Ilc(l76p~^m^leVjzYcj^YZe7yu3UW1bWvv z0^xoXFH4gh#T=Cz_tYlPG@dF`s<}2gM|b`Uv09o&>H=NNLXqgkzYHw?MY%YfW8AoL zy5|-U5CB`YY~d%+!G9V@AjGAO*>DG6HS6@+;fp0oFL?Q(4u46G^-W zhlayTcqY?zNow)*sCFRbd@u{KNgPE)09-OoghM#WejIq6RG>mxgM?0|@f2wenvng(5MLo{-*Cjh{x{qEN%7j^UQ~qDx%JVRrm$r7uO6CF0F#%3B9nQJp(?Rz)6) zpPf6Wvcf}7=`g+kk&LBVt_kF62Q!HX^rq4W9Ct^Akl-nKwGS^%gChv~FWpd6^_`fe z1LQ8a`n}RQ-wVln{7co@76k?)9sDmKbGk$o*g%{lkAh-Pv)H=j&B0uLC%> zT6+d+WhE3970F~-zka=(Kz8E93EBCmX;2V#&tHtSzUmO@z2~~f?i2-Xd`kq{)#&-` z;si@x>+aYDA}K^s?@On_E(SGWAX1C^ytvoP-sl1Du8KabJw%{GO8uSb?sJDGkX08t z{DJ=F3AzgmQK8>)pBUYz7J~t-q-$&$3~+W+(~*ac zuA-O3cQ>Qlpbrutu(e`N-JQ_AL1KefLq)DJ!BqHBpw9EM@tw+yBT$Wbgy|&_^)sZDii&;4S!mQ>@#HraYs;3zsda?yQE`NsO0@2l zz9fxqx75!QkyHdC zn?fMi+Iug}4 z885iTk`lY~0f4>FT3WJ@grX#PYErfD6@cB3SsF&k3UXG{NgVBt#3N=X!xqPzwQGI7 z$Z8rrM}a`pi@=RDl(9z1RC{|;XOlpV1l()teaR6_-9Q9d&}8WxChV3#oar2kBvzi$ zc%rwUgfbKMds*G1cXB0^y+s6?sFcz=C`&*}s|mZs#SPhTb04mhR=NUAx>d=U*ek|| zBY)ULOOZY&m#0H~XCEa3Q6a`KiPbnaUe?pbO=Ei$6V364!(9uLAdIi9C&^k^xK-)u zZZhj^qDX5kBy<$mVEuF7?8#GZz8w*6Ep7fnNnv{N!S-S$5NovX=Ht=uw?9S6{SQrC z!DL*MHy?|JbE0nsKmt)|IEMoLUxcT%K7Ojw3rMLV;?3s$Z!J)+9^)pkB_$bJKERiho4E729O-<3#V5IJi>5qslh47 zm6#`3Px1ecR;^s2047xMgW#2|iE`Ve%bfJg#;@=~mvLZX*IyOBV&f#)>f zL}nYjzhWHOpujrCILB|*p zbNk1M5E|fS5~v>OzeQk^cRIfMrEnczi`lgp^^OOXE?c2e=e*gygmvp6a%RW1G6_@% zX+8bm%t}EP7;Ep_+L!CHm4_RB>t=b)=Y;sPmY*hs7)R=yMnXQ92DZ02ifq&YTz{Ut`K~<>fs*ccxP7)*qEV zR7!V0aXCWxOlrex637C&O;FT2Q}~E3Q0AD&E_NX^*H8?uQpW!Kf9oPhtoDKL-ihOB zFVf-(6wt~QHq4C^v(ETTy1Kn?t7V?xsnSSe@eW1L^eI8H8R`^z&%h9eC(vC3g2kj0 zd%T+Se5Qyyj4|t@IT=G*W=G(FQpS|VESVtugnbpDq*oBtT9Zu;pzoBa` z8yo!)B}xxZiuHxVf)qUZ=Kb-85Qinui0gyp0J8|`Q~XsLq;}`heW?C@fTUq~^IXE> zj20Qy5Q(x7=$66AU=N2Q5Ov1*?j1pKM>O4EA0I7;M>yuP6yYOj979+evqs;9y3KDB z)WL%smUL61lau2R$cd%S)CdZi?wFq_-wePpmvY2VNyqT!aV*L=0p7rS6QDM6t0uhB z+zCWia|%%l@OkI)NWAyPP~N#L)+2qaqc3aY(de6bdpOG`p%{^C$&`x-a&PejqH-Ep zaTc_W3to(svr9SVat84S$$;U;Zt3Onm{MmeQ66f#*W80+BbqCL+})hzlnPNt*WS-k zmPVjEt_y+_%f*F;DBk74cZ|{=KP3qmfru46 z45rq=t7nTl$4SAYh7T=;KsRKxv6M^+S})4=;cVGU$U_84g2r{stqnX5M!FMK)S?_% zk}6+{R-bv_TnI#SACeO&x6~E2PCqY7mIL3M8Lv`+gEY@-~IK~f);Po~WzCi>_HX3wW z?>??iy&-5(_zG@Rri3p-V^ z@wiW^F_jh6D&(aH+rvdsi&m?m<4&~DdicA;Pf0=cL!g8ph-u{}&yD6NtSk!Gme!cM zYj}BZlZP5bjggvQPSvBtUrr6wNHh>g6HrsIrsB3ZF66tkGs%j}Rq%LUbR6S3F`TEOqwcMU6o8eZ_`9^eh4(Q9n=_6*G^U@>W(uf z#Hdd5WqU$x>74AHK+cRr#cDnvl`>N*$j{b%q5>V?&{dgGc3TvjOSc08;T+0_w}+ZF zS-L(GtqEN{O5qO=^$Ge%8F`$gW-^H7HzN+HtwiVqaTx+}l%AVPX+tpw!FJtW+-civQiXB&nm!`=fi4NhOT5IYH z5m{0T8Pq;+5l=>=R8MO+y7*(xQ=Q-xW$bO{Ad*#)zNMXJMcNQB1)9qOE3j1KQmOdd zzjlU%F1~8b^V;DFx_O|p)WSvpi=9dL2Mo0dRyeBm6F zJjwJqsME=N&vt>F_|`mEO*R%7ogp%#u&IY9i{kIsxIpsalJDsC@f~5`;uNUflvBS{ z!vC-OJXM!JNU!uMxgip&7N`DRhhx&F8vjk%h!g-NpN#sLmzQ}(D%B!W<>YQnc6?PngVJZy)w&IV`atH*>ILJ5MaWl3xH#(~ z4z1yGme1oPInbae@C&>-){?^24lIYF1`K`CT0}`-C+6 zeuhOs4eDVu2O>@B>P#q{7Z0zE>j-@lTg%N#^?q)a!~C)>GYRc&P>wZKKdzJ%nw;~1 zlGLdoQy8GD&9|o@)}0b8q8tjNJtGKVaUCbB@EVV9GT?}V<8qJZPnoFF)msy)q>EBg>}BrOD{X9UUb zN$IN^{WnUE!KYfXqO8YzO%<^3NS3;6Ll>SdJGnc=3yM-KS0ETp9(?8@B+tVU-r(ls zWHf24wd(UEOU0OFXJ3;neXK7Uv0=Wr`F;J}VQNP|SQi%{E83?ruIM$T zOkbj(9Y_sS`#Oo|}=wWWRSY?}1|)kU$R@6Xp$%M*7I0e-8=tghc#Zkejn&dl?lmE6SOos+PMDk&fmFv=^z= z9q|Ao)2~MOlLX>23po&J=w_rIrnIpyGR3fO^DN172kfyXCR7!h1C>3^mMmF;olI-0 zc^q@C*f*SxI=Z@nQXICjBd8A4TiJWP#@@Rpn~QloHS05UK!I4vppnF*q$TFfA}KR5CC+GcY004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00007 zbV*G`2jU6=4>l4Mt;p>F000JJOGiWi000000Qp0^e*gd*j7da6RCwC$T?u$pMYg_4 zAcO$fAtCHL2}{DhZ(#{w0%1+Uz6JthA>9cGIx4siAR;2pIEad%qYt-H1Vxcy89)R< z5HO=Yp8Awolu=B zLq~?m3~N=QoMreY!%r0m;x7Kf@DGMF3~w>4X2@k|&k$h}DsUv2A%S58!zzXY3>R+L zO}qs>^Bac!3=c4*GsLU!Xo{anv`U%{>hW^P2ZYhXj|?9&Jfe~*%3L1m6As)Sa`pIyO^0NSvVz+f;>> zDjELHu$5u3NhITss-6r_t5t^v&i5jFPQeG2`&F@3I7xSt%VzZcj*}`l^iRid`7bD zP2;Km;=a^sa7&766v>_)Y@`Wbi+bxc#fgM5OlK%}n>3*zRJU~;b;?bpF^`O<1$*XE z+36Bm_G#JGg}=4Dly3dRAh6G}lMBzlvlhIYM_CV#qSWjZifb9miEIFo&ZrjdP?Ij# zOGAc7Rr`oblN%HiM78VHrsT{dMw(Gna9{!5dam>uVLmDKD(r+>dd^A(`|~MlZ6+m+ zY)iH3)*>ayEfW2UVU22WH$}Z|>~+UPwXD!a~0*1f2a#Y2(h~<-C$c`!K9DzU_heTpn zv@f3qmiDKZrqQk*ZMg2wWvE_N$WxQyc31SB@R)GwHLnNdGX>TDO%62TINOotzdeV# z&+JMyqrzO(i%P441seff_sL$-gR2Eo^Zw1a4F*bSAnrIKM1ol%XY&MV(yOs6#!6iE z@2t%BB9P}HMKX{J7T`f;18DKlLZ*mTKH}U6DBHzH7E%A=zHG;>DNCY%E4J99@XB~> zVdwdejIPtLO9PtpO!n2AOl2oe#akOp5HNZsrqq|!jsC6fM3v?^gTj29%&`TdTgt?a zT*0ggyN>hSsEoT(I*e(@k8#Q4tgJF9*1_s+OITs95mAE%l=LI(iQ-DB>$svDS&kP` z--6y0T02x$v7Q&`SA5ucE{F~qmgLM;x7d7CoL&%@a-XNa{rh9YG9|gzs#1pm_0Th$_v9^qcVbSd%<1l4#sxSya2O zuugQ5A;;gz(@8X*CoCe2Mz6^*bsjg5Gh8~t*v(atM5h^&{gpfjL;a(uooAq>KX*%* zL~swdu_Dq^B4BN^YS{HVnJH>4Or6-#X6G??A47H_>&as3l#?QAvHnqwYV<2p>AwwZk_$F=1uF~!aPr5y(Y|Z5t z6G0N)=Py?39;(GtHzXr%=|FR_J#1_ovOG;R8w4rUo&CX4x>55Zg6CSQep^i~nLkoEk2>}9q z%Fx=I1S%8RebVn7!j(F6L46mXkIEwgiHq>o7kZ04C=U5&UEQa394-2@X>s=TE(8m8 zy`*{~yAVns*YO5{hKq!2pv;MRboqxaG|<{#G~8p5r^y3F>k*MSpSf?$G@@eKv#KgQ`c5C!_q`HZg}juEz%KL~Pmu?WOZMr#K|_;=Xrpwa;%1bW5jB*X@KdG5F(BIVZ9fBahy%Go@TSL@dy5US(XHIhJG6J6iTQ8OHT54q*Mm@{Ke9oj9)Z45FHMHYctxi)9YQw{^K57ZcoT*P-6LjNAjAVz z&N7W8P^sRznViv{%m)rt-0x4+Jl zJK0)1?a#lu!};SC8h@g6an{3`)G0TGH;Y002JWA7Yd#d-R4?C+$-HmKM=b)EJOky>y@J%dM{yTGhrzfdh4ClW!hq}+|DpNJXEwmZdn#xXJix zwlrq=U(FckggU&%qcZ~G=je}xQog$1qHuOBB_>ki#*HZ^CWeB8gIy*PvSM$!e*~3& zwAib=5uR0gaxvFy(3;B8@q}?ALji*Xx4AT+Wo&3EK*Hf=vy(lEawQV1rl+imC zx`#JNWM80^2^}1UkYXGd55|S@VVoE*#*OjE$H%)xpoqi>&5#;<+H*vr_XyNb&0N&X z!oarZDuKFm=|X$9IXDY=f$2+|_;{7oWJvn&rAT@8^++zfq$MiC^mC*UD zj~MECI=#j_BT#5)C~exbiA3d#FTS8|-MYE8#WzSz)K>UiBoA(W3GJO9 zKX`Avzo@KRx6Y+wTZBM@*Z9LmUE>ieX&5nz#+} zq7Md;$lmu9N2Jy>SFKtlHO}+r&r?!TlHmm6hQw{T6k1Eykob;bE8Xn2gsGAG8Xc5_ zY{B%O$q^_oFOPox^;fBhJ#gRvMMg%tMIam}=uhf)@*}&dfeNy9u zJ~VmqWaA0M)@c0WV@3Lpy=qkXJM{c|&K+l}GXmXl#~maqXU?3V`t|F(y$j(RnDy`| zw?c3+u8app@SC32vv9-2d&`Q&V)4ih1Xqy2XZ_yDaE^!c9@sOlhqMx1T3RYSsV7dH zpt^PI8e%hnE5X$YBK$VQ6G`dy3?!mfRaW! z4=8g+pp1+Rx_tSv)TF-r^2=1CMh(L(x0p;+4vao&ocByfG|NZwgXwV?T z2?V!F$8qgN>IKa)l0exEKf4;z>Wo0x+7BN-EIg?{|NJw}nKQ>w(|=6UXiXcIQ-9LV z*%Z}KTo=Q80A*ml%c`NuZu;;=N|ON@s>TEj!SZDO32j zO+(ev4;DP29@@gBT#u64=s^-29B{^yLJhU^Ww#eG;Z8D!|g!!V>haiF7Z(~ z-q5Z-O&I>F=v1P2me$N2cyBv4USWG*zI?eZi4Gk)L>)VJ^oRozLFS0f5s4?V7b-|- zC+~7dNlD@3(2^g1_<_$y_3G7K8VefuIn(Q~Hj|#t=4Kb2&pBq4CtfPC5ITV~<}chk z->EYdB+AXr>`f7wHOrl zOzUj(>FMd*R~Ign7iZit~C-m|f61`fsk5cj5U+nMr;-@gTomMSc72OTZE7 zGobODv!fT$iUMiPpEI=ZRDr1j`UR#sIh}k|ZuQrRuTi@OP5a|yO+Co2gjUmE1fK!z zo*Z6e*bW3^ufS*QP(0WYQ`aJmxMT#k-*^V|Z@?eMi`41!36SQ(Q+zNQ^hAd{KfC|} zLG-`_iWekP^_A#1nJd5f8Vr9~)80)2lR#`SkPYgO@7`iSbFzF`eAArcIO|_5v}^uL z@j|Nudx+~1UEfd3SRVcFXcro_CPSoJs7WA+%oB%tr@h%qTOkAGUNw!~E3#ZS>JROn z?izYiz}7N#7eW(WlR(A*#Z4XUJ{Svf(-1K#@Hr)l7p1*oYa6W_u;utlUq+L+cNzBOIuzj+-b(eSu6E|$6c)2*#(AviXRBH_xnXA0Yw;4pHC|R z5rJo@gXoKx8$4If7baLD*YK-4dR$;`v=Rm<{BEpF1-P}I2wQbknkhO380Y7 z{fL|X;uLB-qK()5W(emP{ZOVZfl%YooeCkcvD$6YThp``CSNx<&H~+>RR(c@v);D* zh{!Y%9~t-7k4|RS&qB>C2pGnY!!&;57-}`RCDo`?!=sCZI3}$kSrtp8pf8$dgWE!> zWm*f~=M;0Gm41zPDmt`~|GwboqaWA;#SaCU8&8XV+o4PF-eNj2$oSS+&&BX)2H;Ljq zga{CTg&rRWQL|R*wh@ z81Qcp_~vSH1^inqy67|cbN4Uc&&50A-R*>tE|ks)l=0vQ3X2d{nlCfVR{}s_8$x@` zUquF1C%z6%`29HdianL9Z3A3@A?*rWd2YFTMXiwBC{XLUA~q==>c;E|L2bP^LOBf@}OLA z4<$fl1jCmyJ|5mO!6cDmchBqEg*+9hLq^r#@w!BsI62|LE6ZZ zqBbH-T-T|cZT=uhn++Cj-Up?Wvc*D?t4pZn10_^%T?zGj$-)U`*e;=d4hYl#B`bdh zo`q+oZne<-WAe|zSmC1RF{isoJ?DyrF=6Y8Rw}um2i1$>aWEk~NfAA;L`j4N%V!JP z=rIc^ca_+%!uDqn`!jZ}h0b90$+p^`b?XJn*v(xh;*Vhf9UAz-Zf0sbYe7 zl>MTUgxqgb!`JNz%251KDJ49jL7*FmgyRNB-Pm`n{CKmTv619jkh<+>IF81?W4(GT zY7(cyGve91;GLEUkZ9z6!znC6Ds<&NhL%bd6;wStE;?C=w##^Mq;7}UL< z$wR3Ut?tD5rVo4FO2I2#Sa5@ZV-C8~G7a*eRTdn|668V6?tvz4u9vZjKz4^6(M_Xi z>b6|R=`9Q;Y!^y-R#k9)0k-o5vp?HE&GesBj`bhBJ7T|4$wY!YUod2tbaCuAo1)lK zZG}s^&3t*9L+2}YAuL>%Z5FC_kBi5T8{`SQzl8d3xALRQk?wy9^@JUDt?{u--z$-mu!P?ByD5 z!S~MRh0P_%gSjYH{3wsh-vwc@C}MS4bdr(Q!fO#}kO(MXSNzPktdz9bb}he-Op@1r z>}a(fETPt$ER?a!=4-S2#GH|*@GlFg%`mCHAE=6ZyE-SPNJyCKRTlQ(BQ2WuiO|aJ zQmx5lXKmKx(QjL++w&HF?7&_VdM_i!%A2qBAPa0j;fydaQnr7_LL+uqx#P6-jEEK6 zR?eown0BJ6#{hb?J*arF@ONbwc$L>GI?e7XI$u+>JMw-OVy&BO3y;5BKel=8r|h?K zQo+9k=V(8ML9beAlv|*3p;bF~yH_xB^AcV&Qj+ zPNNs4Lee5SGNW;dD<1siI?y_zw49@;#wJlT0-p6}6c5*Iu1bQ5+@c7EfgsVYZ$WQc z-c`AeqYBwh1s|TIbMz&K`sT75D+%hv3Ku3wTRMdG$ z%}6{+B9Le98#AdvYN8BzK35Fx(Qb;kOi*kNMzM~@&0~1AFHdB?a_8vlGkFVf3GyKN zAj@1v-w7Ox$iBQNx@hr9^=QWSsX{HjWypiPezbOwAP2PuWYdoG71OisHv+#ID#iXJqgbQ57o3|Y&Ml)G;dcRa zc}CeiiOQ(x>_wvC5avOpTjMIJ`^Bd z-Bxk3wHo0VUa3^VwByPmF^Vno^%q65#BWriNJ`F3;`Iu1Hcz10uTAF_Spl?S$a!)C z@2QGn-w}xsu5@lj+A$o%wajJmZ$U@JXJkpFRH&GWL`Kwa#4!ip?{2m$hY#-w#fu#Q zP4Oj(j0MQEO?@X*0!ZQ*9+y$9Jpd3GwX^G)%MrMW_1!XdA_IXq=7$tBrYGP9*X0~V z!gpo>koY%C@q<=MrWhv(lR${*KRrmC?^I05UK!I4vsa60003~!qSaf7zbY(hiZ)9m^c>ppnF*q$TFfA}K iR53L=H8eUfG%GMLIxsMGyAkRD0000OJq%OH_8laa2beMw5 z2lPK!NJQwOP7=NeFH>mdN^&xQ=l@DUXITmWK=VUEMpD~*`PdlUTN`ryMO(2a93LZG z6(eL?=@lDMJ(nKIQB_s>;lT;}Vm(83FasT(ii^jOP#hVsCGiI&C=wfckRpKolAE=2 z>tX7266bZwNXPwJ$ITAT_+!@vpYqx-x0BOVzmwLo7NZQ=n2+p3seP#D-H z3xk2i5GdX(J={XsCQE)s|8|xBc3k$B^1<`ew^tnOt*UoC+Gf%AVjGQPx z;G)HMJ37~)XsL<9&xCFMlBA6ZhC;b!EAUZNps;Kx^{hO+KL{D?bD3_2824XB%ysIC>k|-gvl9|3 zU=kNsC`!GCD8-dhK+G$2+{h*W#hsqL1BKcArOXLNq46J?6YBU5#U9dEK2?gy+oxmG zWlq*iHm^`A#)55bD_m~n3GIJhyV`$z+P~~hQh|=Fa6#wMYoHTDj<%br%Ivx6Oc-DO zQa?r7oN)$*trsQav~bU5^?{`+NkR^JXWzm-&CJ>@D@HFtv$(T>e(idHBC9zLwPq9j zh{)?oxdu6*QjafAsri3N-7t-ZUQ6TfmL37OLVJtZ`eCq-q~I- zIfW^`f%5e5(828JjR7L*)O}J7PW%yp%#OLt=hf@6HQcGOd2;2E<_=FC&*v7K>gM}LW%v*^1{>Ql%;hK4| z4=0jIhCh#oCFvt7_uMreKQV=s9_N?f<##pm#kVTlx%nS#GGG`_iWV+b?0>pp=>B(0H<0@asgq=UmRA1bXJC%F ze+7YY@3|oW9QvV$lC(HDkNebrl47ZnUx0lk$kbN8J0OMHw<>-Tvfu3705xBaOr0+& zLev~r&ru3>>GjMe?aMJbYd=z0-O3x8=9W-#tmri|{6=~AkaRa!U@cl)g;0b~7UJd~ zW(LlS{cCa4fO$1r-dSndvl}e`o&l(`fejutDBE_IEh~FKe1M_}<#*vlF7deQ45(tp zVNPpw3E~vf(Fqe%9(6z^pwaRGNaRVHJAl8O;JX8v4T_A|R)E2>FA4LPE?spj{P#H|hsVG4YCh6a)>F zVRJatFRNyB=wcY-03jNK1#iTu1ET2`$9I&j{$f%%(=6-z3oHvkx6Y)5pld|loXI)Y zN#5JoMD-HVMdSLXaMilQMn7~bUd1vhO2hrcjK;@O z#=j7iF{WoApcbkwoNIpiu$)BvD5iG0N}l6`bF#2?UIfDRh*)4L?B!BpbL?PEpQ zzp=qT&V^Vsmyc%|D6P4=y+f2ubvnPp{J%@$wm3eaU-xG0XXlAV{4D@ltNn@qOT zhA_Or=w+pdW$3a#Z$$V&uf}Z3IkBBEuS^x3OP9Z zkd}IdocrUm)jRKxQw<*!J|?)1fn=L&2-llSuO6&PkcV;>UZY1JL=r`#c#Bu@m;g*I z`tH?=B~{@KKYPy+L~$mx2~< z`9#%UHfFOD7@w%bI4O%u$t#mNToWhLptK1Gw}Yt44jQF3;)Q4o?>BlgZ&YjT9}0Rv zLj<(G4Ake->Q#=_b*^l_QBwUKfo{QyQq^FAnXE#B<<}DE3^t=OZ9R;vQq^5Zd4gFt zl;UGVB)PG4Kvv?ubbX@0GT&yQoA@1OR!p&(k=872-lkl`X>B9|HGJk#1-cn*nmA&M z!NuM%a9VuJb$Lyom+;TZ;zt2?IZxXxIf*R0%4Ga1d{r|$=h_BvNzk@yOuhNIH9O_{ z-YghWK1e0ud|hf!Iqz4SznZ+-e86m<^(pbZ5QU+5gAW$|6M&D)e`9Q_G8Lc?*WZY- z@--|qBLkUDeg6|!#X0~c!tjpeYdR$6xLH6h^hCH!s9C)?ECeCY!#3fpgsJAI(7Am&DN1y4HR5GU zxez%gE8fJ%oI9P!_HS4rfbu9MdSSJ&Y^(iUyp=`k?BCk>q7)z+!=>kdUy&3GI_K9S zqcC^6swq!!-^!&&yh#4P)AX%P4|vhNAF*f@3EtdXQ`w6kOs~53$ zm{EHm`&d5^?lxk*Tn6FupT`T#p@xk~SL0aUW~+z(n);s!{(mdSVnOirj|?Lh{hU z8*PGoiCHN|hA_vh{O!empf<_yl~ca$y%IR;hRHcYsBAaD2KD5UYcV(R+RGB}%_ZRE{oVT?3{^rD=Udf3_=h zoSJYst2m2UTH$T*I;b&FzFNFA)VACiy9dW&ObHwO?D0DbXLIzv=`$5Y=zm9zAF784 zV_YQ-K7m0|?o}0|3#|wZBT6LN0f0X_;3r+$$O&)e;G^<5B z6Tn{=cjnm(cxaCewfoA?)-ZvCi=Ww-w7@qhtkO+Q%#>Gj?Quc zcqk8sGU>GAkFt5?l#b&Rh=F9je|Fd)K@SseO24Z@Uv@yYzJE;;XL0tu2T87IM@;KE z-p~2xCm?B~R*f5H&EvqU6+7!E#^zF^X&t+XZ;g+i09D#L$jfHT2l+fQ9$BMs%H`VdKay1hHXFEYu6!rKNX9qiBro8QE zJ3oWb4>Kq09!;CebZ|JzQQ%T2{y()0#7}?jGR?%$x~T*e4@#`|*cigmHnu$BI1{Y( zZ~LV$dXA2Qk-~w?zCM2DW6usQ7FsMM;$Ev_5boYOgmt%z(l4Y+|L@z3RO1bRX$-EA zil1C;JJ=B*TZ|^F4yvck&7y%DI4|ll1g-ey8uD6Opo!ceG3Z1udFdUj{AjW$(;2tU zy5Z|l9jGE5<5wpKI-=3r9GM6vI6CrqUORp@K|3w)CZ!ZYJ9!x{Oy zgB5m|d#0Ry=EOxnA~H!$@=wM!&@1nXAxg|4!#^JLd@BDr3&y$uysn>)iFWAXDcFP_ zvp8N|I9C{wNWRJTrZw|R5~q^-4!PjJ_|9zpX$~+A1lZ>2_}grWHWTrH@l z={02+B(BuJLeEC&95uG?$du~+)sWp0#5MD0+@`~yz@Sw3%w8#?t1xlsQ_8+iJhFwf zubTHggN+?D|INQAp#jF>=94x{)SCvk4!9%!jBktxZy-ANwJSDKc=4IgF$dJzad1mw zvAAuTIN;9BBKyt`t@GYontnj)OjR`w@!DJb?}txD^{uKR26m|bWNBSr9X;Ow`@WM| z^yta{^?U^1*h%f8m8k@I7^S7rHK}kQq1ZnH^ZD2~^)c*_V^oe{E55iE)xA-g)|yDSFK1MP!Syob%nYh*N}ty4ptt_jHss%Y zli|X5B}!v)jHQa4j$aweNY#4c3RTKw)ATwO=2CmySJEKWHzmZcJcL(WJs@d>aZY{V zfeFa*^UOjWoz71nEtwU_UItolvcs$CH(tzL3x%g{ z;h3-gk?vu;yda~-t>g4-@(V7HDoLWIuY|p%MM`4>L!m<9Rv2j-zz~$QXD;2hF@O~t z5-*GdVy5PpCem|PvX!!;*)>#_8hC}Pzf_HLkhL5JBE_Hz0}&M#6nA4UxhVO|uKU)3 z!g#2R(~^B~HLKYl$$Ch@7SOcT44?kxI+2&+Wl~A@S&uBn#wA(Cv@>y!jIgiz<4RA= z8>|IKff7vDuEziq?u5VD1?yE6^403%u{-g2MH~&<)kyd)VmU%Z713=^{LXmlfAJ2D z6UF~|wTWbbuSLpO+zNVucW9C{0eJ%fk>><2<}QFlGBFOa_HXITa_P*t&@chWCHO76EWN|Hk?&Hu^c)9|IDk?muarwii z*7Yjdw+1(jDk<5!PS}pzxGMR1553K4rFgr2EU~lX{~*kLtYd=r;t0D^#adZK=AXHc_3NrYW3~C`NL%zk{GSN3m zZVN?rT*orfZ#I#;y#^A&>Zrfjw{&P& z0IcCU3@vP{uvSf%h>(1QsMAmWLtDM7T;3H}HJ$PD=q3>$qEB(a9oy?v)iA2XzCj(+O zI$?J(b+?r2!yYB8q4l(*=IMA#-4K79;?ptKggIXD%YBEKH!Ya@S`L{arYbvVP0zRm z?BzhLRx`_i(VQi?*7RTE1=tiv8q)OCJB7O?jT(q8%`@jQIs3}7fUD+@U{>@l5f7fG zHygk?q1G#F`E8SgDiyC13NVCh237NxNE^aF6#z*QRuHqOh6FLK* zocm-=7H=xN0&{#b2M%YC#Q()bp}V*Dh8X+s$-l#)XI+1Z1y%Ia#{AtvO8xpEK}p0L zNEe>|V3Wj8BicX&}i%OP7Z`eET}M;&<^!kcrKuNu5m*NM#-2 z6`RpR2RV$&7VD-Ltld8CBcpBz0LJzf4H{x|r&Bf4Hb^X8d`Z*%T;%X{`qxR zep=z%dvML{pj81K=GYLsWb%fzB?j1#WpT)sWf58b+`OYS$f)C0e+`gd6MB`kp>|OX zsZAmvdk_vy8C9IXpz%3j^sBcEB&aj!#>GZvo&M$%o|Ca#``+zwOa>$;p=PI2A(U#) zD~UVlimEyTfMfD`;B3{N~6%{Q;Bi%xRXx$t1LF zgUh?)0qy2{)D0>Z%JXgOe~B+h-h#JUyG=2Z;kIwFf0n%KTTn9=<_63a&+b(D26}jT z>eP!@c`G0nt$OTbsu7N4sU9u9xkK-bnIGC*hDS)fD${5KL}agl&@;aLB>wx$U!)+( znoeE8uw+cPhe?wHA1aK6E+f-asNakHL`|{wvsDN zj@Zb^lAvT&?NG@O< zjzq)&xVxNHV*?t@KKX>eL~vT@!iU(q|AtlSl+IV_M*X+Jpvi%piJ93B$reZJ8#$no zJ0L{SvD#_1tZE63rFQyIGK>rMZB5ym#N(mW<-|ug8JMucqB?5@mHtK?i-V;@EaBs( zhm0H+)d_iiS(IrwllLl)6h>AwCXWSr(W`s_vmOt0g)Q z_7EflW4ftbuDHZg2-)_AqE7xHtG-^4uupu@>f783FV?HKMKDzAH^4^^keSSx8l1Oi zb@@<-CnrgK(S}mjZ(;u|-sQOKx)_eNy`eVwP4=SK*AO@Nv7EV?S@OO<;unHk$(Ev}70 z&rch!CmVPjZ;S{_#zplaYMFt&JhuH3E*pS&S_zY@>(0!(c23UkrJ)KH0`>Lv=1P9s zX}aZKzfPN+&@ZTdl^%*=d|Z!CSg|jRu`lfnL)TJOO~^#1-ssJl9Au)Y2=jN0Ix@*>y=B|D$cNj*PD9 z&_n)vznQg8KQ6Q>J}>VUraUU5u-4)g)Z1|lrKm3Fb@5({2#dD5U#2`&D2euXh7@ zm0D#9_-=?B@Mt=hVY%~qmv*PG2P6L!0i586Xm_YS{*O%>2zAm;`a+AV#ld>F#N*2q zg&i&OF%9N{d^8suU(<@`8ZYe)p)1lpKNM`##V&}fw>-J`jq_E8X`SB?ti&L=tBd>!VTKE`P>F#y*bEW>d&7|3Y=K7*(;SE#YmDJ72>W@XZN)Gd2ET6^E29h_Q)hH1K z??=Fk%TcKoL2KfeMuNYy^n_z%AY+&OtAd2W?ik7ZhlYl<+}ytLcA~VfLn_}MB~(XO zQqW(R&_x5AdP>5{6jkF&Q`wzfQesivzsW(AW*XtTaRh@VWCDY@G{K};vS;kVlg1O# zO=fb?GOK7>X2bn5@a6+babxNU_``3^*AyW)>jK~1B5W0sBx4gISY|zelb7%@>Km~V zY==s}%E&0p6gCu}U6YafPw*1H&dJ7E^PN1`vjKzEcQVP8+vlS;zI?>FGt0x9Pb8fN z4)L8dSM-i7{5-hk*%OWP+ml~OIeT(b12VbpVHvp_6U+(JS9JLQMBq)HYc{Bq@_I=$ z*4b7rMQVzJ6E3aAQ5!WEuhD`5h0)auc@S^b!ax0c@f{@@vL%It!PJm zE;$qvsAUglx1HnS0&=#Dd7wvL3V`>oN-nmIehfg=r3QT6syGxpEU7Z|tx zT6H6cS6oN_1mC)IP~f2tAao zMJs|kbrbgOMF-#09Mh(CEVBB9rR@a5t+{ElQjWQw@rJ-DG+Vb7OD|vCOt24nFiSI- z70|-X>V*LKdHF=R_;|T^`Ly|YfxPd4f_xmjFCAXCHq6lf!{F#_3AOh5{~7dl>&0If O016*eWoo59hW-!3`HLd} literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/42.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/42.png new file mode 100644 index 0000000000000000000000000000000000000000..09acb706bf466c546f0b5c87dc0f6b4270b6f062 GIT binary patch literal 6184 zcmV+@7}w{CP)004R>004l5008;`004mK004C`008P>0026e000+ooVrmw00007 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 N1~-jSwL14={s$L@<6Hm$ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/44.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/44.png new file mode 100644 index 0000000000000000000000000000000000000000..0797d3e10ed7f3b9b182fff931b30e457a6d12cb GIT binary patch literal 4036 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Ν(B#BsW=mG>W+LM0m)OcL`}+m?_TwP|2>|zwU!2Qvo$_IN$Cg zf7o?l`1{3SlfBoFUv$#YY&1&bBu)HPcNXK`82j42D$UbJ1ob#YMpE1W2mS1}SG<&- z^^2hFglt08YNOHWySU}Pi?boXCv(zZ;3(@5R`bL4ez{BW4k5x^a&w}`Fk8$o=GMYl!VAxl{? zTTj)Ez@n_gxPfjFw>>#Lp#XN#7d!FAeEP9NMFU8Mq~7@8+tnFOQC6u`=$;=HnzNbW zu~!RnG|3;~L))S=VO19utOZ5Qb%=2!oW6VNp4Ds z_IUmim%}qlu}iTM`|smNOH_&d|NH(w+<%;hND zmV+XoDys7GstQmkIXP81InNJ{(*Kp(u>Il1-6^uTFTO~TvS^V4rD$=N(&7%Ki%Zes?ogy?v86!q#dU$=UL1p$<)`|vWEIk_iua&L0)%_K9CuQinLacFP=0KivKhHC%A`2YMF=D)b3xc=iGpxer+ z%K^amFSz&S82{Fcmde`d0N~3C0KuOD;O6Nc?g4-Y7y$Oo06-!Q04QA&O?wsp1<1&v`bT29tEekrt>d7ONsx;YnoRwpFfCpwL4l|LEU%+92>|F_RG@Ni zycZ6$vD2RGru6^$n`1JWeKZOehOx4+eF8qYhoA`(kWwJ2y)dCfWJFq8N*G#J3F^d9 zivD-hc$pwjK|x3v8gq0W3SBbQGxWsvxvC8+b)UfF-y!|=roVM`o0lhjuI@%Dm0MRT zTmRP7KaREJ%<0F@=*L>WO;T$)Xq0p}(c*r|r<# z1SL4r9b%i`h)~4ps}N=DRIWYBfixu=7O`SapC>^zNPVO*R>_7b3TI4`UelsD0bAhGN-{xm-QUHCZG(T;=~OdqdC#=XvgWC$_u;Xp4ga<>RpV0cSQ`11`wr{D zh*INh3|Z3uv;!9nDhTFW_xeVRbd>tc9>1ty6GfN1?lq6D^wb>z?};BIQM#>;D~aj+ z0<7;p_dSM0-28$dm5p@EYz8)f0k${l$;5JwaFb z?gw=hS(RL+^xz7}p)K^6F0oVbstk&?%M|g`@F50glA-2Z-;`n~Q;r;-mPYzS$9G5v zNPRAyh5cH(Pw zcT!~L2#IFPe0+vNLQsf14ulzyl+$qoEhft^;VvCMV1HXir!zwVQW>PrPZ=FR#58NB z#BSy9>vZFp1g*N^v~S0J`(t-P21={gFu%u5Ptpf$iQHYSjrtjS?}bfFjog{78q&Kg zBQ4jYJ`^d3T4n)n??sJFaWXtI`O#@>?P4m{BA*EjFj9BO0i?G6eGg$`sGge?FYHo6zkslN2}n*@ zd3%$Mf3`!p^Y_+mVFupAmhceGwO`pV*RJ*xZM-mqz3skOS9ImONE*?yK6l>*<&B(y`}e7@OXBU-gsOU_4wSR0)<2H&Su`ERmidH4 z#N7G6L7Z7y+!kJ|T?a=w`n|PEZJm(n1#VN);`1YbZkHA3O~9X%VNtQGW>8c-;*5p0c+ts2n|{m6P6^MovsK?eJUt#whKS$DAvRcV~RB2C9qUYt1sC%wPw`jxW;=j+YDlUcW-ogg!AvG=;eS zEEBZawv}P0VYaY0Q!_xWGQkH1)3IiiTI0$bAJu~%Mp zkuJ?Q|MK_XMo@Y_DG?*y0(3*DD<+V^PP0Y&ryjS~hbOYvQs3R{X1rFff;#(?{ksLQ zz02}QnH;J!9dBEM&29XIgHBGm;{4&<2PQd*0rNeN1@A?FwJu<3)|%6ti|G0TbT*CW z_Gho`;)6(pUgM2Z2(bGNt`ILT_+!D3Nm1L=k|XcEve`RpM2xOO+!hLz3WXLk9-d4{ z0%fi}TqydDPJMDKa8KIp;H^egtk^g(EmwxCV~O2PPgf;73Qzs}OhzI4%h!?aHVq>E zsN9%q7&fipF^b21>j(2bPN$cGAa-B7eaB0;c^#M(5woBmuN-hmWa8 za#>7sE_Z66w1>MzW|`?_itJfDI#0+86*bl|knP8!PT?9o9Y23Y0`JS3d0`l2}AtCTB-DkFs=rY_mD=|PerxgPxmk5YP& z(LM$yVzv3qOd)AqGMQ)FU5cSC3T;PAGwUpK7dWT65q$MbD_63Q(iy^`x_>3)hWX!n zq0_5hH1@zKp5UyWQ@x$_oC{LgEr|n`OtcJk!|&RRX1)dIa!lg0kZWcmw_={4k<2_C z&r}ub-PueU?cklwi5W_y0c)Gt{P{I(nrNjvWrKrdjMME-+nA;{TP)ek>ah+zweK9Y zNp)sR-=Km4WmXjT+S1)YPi*?w8xWGbBq|yO$_f`@Doj{m_Yrd#%x|}kdJ+Ee4}P2j z6;;do%d=-#bY+vUEoO4ean{R`k?Z4(Jp!qwUEKF$wqCos;<;W!v{HptgV@o;N)mXo zPLG2)s_1KQ=Ni=3a@_tF{k&soo6}FmsL$5NvzrJdtn!#$*jx#^NGSreL~Cba>cS}9 z%wm?*#PgdSrb!~T@ETdqtLuVg#-*_c8zeC_e+u~uS{f5RS-=~B3j#Z;ykpyMjq|Y50 zU_%c=!`(gC42MfKYvRu1fL)yZbG|#dG%TY;-q*2Y``{OyD?OvqJhpIU8tM0^0jQVj z7E1XpjK`FRiDa_uD!cFfCX^}d{L6prMc{u`6JFJgKggX1?3yrT2@Qc{p@i|%Iv=8i zq_mnZ1Rje$p2Q1of^lNGV``{*8a^Ci2167}v~OnjoYl*Lh!Vhv6YZr@(u>_6rjFh8 z-^m4PGEJ9Z7^_V7VX93t0o@2nVpvrM;_3y52IFYKpOMn__uNo8JBv%`(`hHg3NK|n zOF_!3ZH$sX%~AySZ?YfC>Tc=UG^QY0V?1K59uG_;Ud#ES(igeQo?~WP?sXZHP=daL?=Dw=vuOos+5|wbW zc8}|H{Cb&_WYtdrfiL+bvLgiA`V_S5p+9q# ztvsv`KY8s-p~zW6zrjk^=D8nJJ-_W3((RA#Q3(I)UO>59t z-*8Mwapic2ut>4kwX9c2(0jj9X|K~d$3gKogUTaLefmTM;V&mwyA@c_^Z+IImr`GI z`!-*92ialDPb1Be$ za&bljSffe=r}2$$KW#4m(NU!bg%j*b2qv>#2=i~R$AtA4nA~$3o{L}t-i*n7PTSGq z!S)LLb}5UzGj2b%jxd0EbEMZ}&OMQRoN%>iPZ^#n)q^LgYWShFiiBWTM>j_cZwlBH zt;%zqobXs?yC~J)$c!logIHgjFFtmJ>XRZ(CYse$uyK!q1gWaCyW(U{Ei!C7!HqZ| z^oGB^!#w3G&o#Tjh)E61YmSY0dFbql!GB7D}@Vd^8C%*@{spEbmw8wk#~Cf1CDY=ZsNBXTI%yL1;H1& z?htwL+kN>qBrRxAnsAry`f4`irojIsqS#;7yPc)@o>1faHi|Jt!DFeRtE_$4i5m5U z@bh-1)Zly<+d+qv`oDBDZ3Rs3c^en#OEG)iV;W*p{iX3K&B+|!SzYm}? z`+nyhD-Y`Y%i@e5NAzq9cDZ*=^j!vX{av(zxR%TjJI|vJ277W1=07({e-j3#o%(w1 zwn6Js+?brQE0F4H1mzj#t7l)_@Rc}X@3EQJ(teox0Xv4>F1*3p;^;&V$C?}sGF!Rk zzrCexKzK9i7v#@EUo5K0SpS720{gn>hlm#lZe3p^Tp^zdFhfLm$4}y5-{c;)YcHy= zL)9s-q?E!>-?H3t z)Zw16;;RF%;6K;3EBx*ym-UBAHU`;YAaD{HUR0jr#f|g*+UHJk0PTrt2B>_%&DL_2j!RTUg7NfZ+=uM&JR?`5Hc}%7jW;-h|$}fd+*?j?Ctvu#82nv9)q3A*bgRDv{?~ z^!w*Mm)|{9l=8rr8bZ80%EpS%uZ5Mml-Llqw@PdweVfqU(qtX2Gq=Ph-7yv4u3F8G z));s}vS5Tn(_Vz>5My*e)%u4d7PMS5a(|zk4$j2ZOg4sJk6N9#pGl-b2P+fen%XDb zywjpa{XJSlOmoE9r{5}BycvWGAR|6R*fsl@dshqvnJIhOB0dV>q0Jy*EG>E(g*J$9 zifn&mWWLG7hpKtQ(9G#64OX@9-bmd>CCU$;=i7SqyGpCHz93!uR`-tN%|rg%d)0|_ z9IzQ!8#Y2_4^BfV9XlAJ{L*M!iitd%+uM>dh9kWxbUe~(I2aRZplCeo}jV?}sp%7mFMXj-EY;k%lZ?l8s;n*@{8)pFGf zT^^SPvNvceo3EcUN#zQm;5mY>2~9r;Z~B$Hg6;AQqBY~=1f{{i15*CC7G~~~hE=)a zVWFUDbs>L^mGrqouQFs5UTYo3N1y_8WVWgR8_1^8&F6$Em> zI?U-KFF`pu-l==%=M@%kV=XbK(C%YL&2u9y?`u5ERX?$`kr72EP`M6+98OnG-J)Th(&_{4Xj< zUrNtON=oqG+b5t+p=$P))6(P+T+B3Rn2)B{rYiO|bm{QKY%t3We&8``AP>g;6sJ1* z(c8i(%aD=fyO=L0U-R}b@ghO)Hp+RQ1jZL}_tdOGSjo_*er}q)&=pKZ4qJ3B3xJ}U zaAd&5qT<<@3idB4PMQ(;;g->_)+-Cqe#Z#*)-ducE55dArJj!dAC= z;%S$@{exYDb{zv`o)HW`GiLp%^LI0U#LG-5y)OewdfEmiR3YZkFt2dL$4T1yqD(6# zLLLzM*I(#kGKu1BS{?^Ycoy+RY!GFCd#QN6Nbn9NsOEyJ!C}@vc194b>eHQl+3(uvH_0JbrMKfYgz|E@M+~#G9kFl|Ecp0$+VmRMW6G zs67_0o&?6a%sG3v|3n!wj=Zhf9Hepj2 zq8pu#bpBRWs==4tv6rS?M_olx6I^K93TDXw2%JPa^1-#5(uQ?o`-n0LM+Vz8MtR@Y z2U{6e_M>(1EUOzX?%WA>xg=yBTR2;06ZuCi9`B5^OZu-Jv= z;mMI*-40^J6Cvd^97m>g6Wx;rTKF1Y?@|^RRuv-Y(rO%n|81uKK{0(ZbVV*Mg2HP1 zY&>Z;ky?y3eFT)+hMJJ#Mu(YKG>t!fw^nfJB9J#&{4B%brxSPwY8C>i$b89S*2RE= zNIx~b-#SS?m%_3VQP^-EK3Mf((VQmuIew2UCLq80*>bVo z!!DKM%q?M01-KB$AH#5+lDGL~h}fJ-lV`6dXvFj2Ipc)1`HQ~G3K(pKG-KXm4ydRA z?nQcO%I~Z6g;+>j$*`8_DS3T#x9MW|{*0G_$2SoljwC7n?tDR*h?l<@JE;`26=N(Q zo=_M1&4Ooa_Df(SX^AorUcX;Zaa_uoNJRBomi!GF^dRbg&fTUw@aW=<9pV zZOF@IS7+leKeFyldUME`sRm0f*UEV2As#H}OpuE^#6_yZlrO;e2`#|B3a$&1p}Wn? zjrFsdM@wL0c0O4X4Py~_6}pn|nExpsSLVPe5)t@d>tA z^|d(^tuuVcD(_vhocIw@k{3y=L42XB;S|<7wDuFQkWUxv*XL27obd@|1A+VkNC0)R zmVBDbFBIK)u@uhB%Gh=qB;$FLl>(l{!dn1w&KcS{g#c^nC~q)KF3b2>!VPM}2{HZz zs>q8>o^q6l7p5^PiyWA&eUie{#@Nh^Hw5tiUHYdhM80bpt%D&QMyOBzWUkTUnS_3m zqWDWPWAdweY)X}0J?grI=y2KCLnDxpu#6_$UeU-chjU)bd|Wtv&-NM@lIsKs4x@XT zrgEQk%07ij>&pS(A++c8ho2ebo6=TRdM+$vbfdG$-@qsMph<6r1}V)$au}3~>dmxY zxKWYcok^!+yj6sou+;Ib_xQ{*`n)AxJhjCBxvSPggstVsEaSdK(Bbn)v|v32DQJiz z50+g~XyeM-ooji2p1;{S4eX<|O>Ssc^U|6K3QZNnq-l8H!AzUu!^ph(;MLKf*b+ zUh|@{{fQ{1V$r3xmuJ%dZpsnWYu_j-MBrREU;=UxSibEa$-S4+sVVV&f{0cP1N$+m zkR7Nytn%VR0)t^=9=~Q!8O0h;441a*%i-J*h_M|W`evGTcc6qG%A+&x-FY(2nF8H8 z^e7@Vgk%KCil+d(3$GRZu5kEj`KTCNEPeEHBa6eebl}`RgWsQemu-3<@)WXxR-xj^ zTl^h!@7X<3@M$fzC&qa&+7aaIr#*+{$TIe$skyIW^>!NDG#`(!iqrVyRfmPhgmV5A zac=*C83G!a1CAZtJn#|wkTB)gCCmro&Uod$7Hj^5oqBTgAv@yKh&aOQk#YS&E_q^e zD%4^IRpRNb0mVXAff|utz>hio_=;-j1YBW}#vggp#!g&Y^11^sy)LJ09o*Hf)7x@f zC5XDZjv9oSreIbPf@ik6@cP){w**I3kN|mze5G?!h=*~qU1gS!s{GVulpP~f@g#3B zb#+&e%7L5a2G=e}RAkUnUAl&C7Cphm@qGwMcNh7%a0>`T9*Fp_XWy^M{ULlGhSkyg zq3#1VMBO%44}y0Tn9zprc#;X4i}aV-@UpgxrrE%R3IQtcgfLHufo7Y=4YaA zrNn&5$ir46y#8&qc(>QvWOT)Y-YgvHcnEJOd88~H9fJucrWOVe5VMK)w^=@XVD^~-K8y!2bAYzUE`9z1OYUe;26cnPZZC8>&=? z{`%`BN^kl1ZFr>gH$p;nn0QZlm{en(U>?$fZiOMEXaU~0=IkKVx?rHRh|mwk2ozmf zUW6|5)@7!4`w+!$z1OWOg+r&l30bG;bf5~fuiej1Na$NxrUwcrU7-!-gmW2kiR=e5esD~8GXLU0+N6jJ+rPVUbK?Vw4k=e zeD005q<3Rv%1CjPf$VLXpJO6#r90?k2AQw{*A zOTf9eL4RH|zE#oF1ONir0f5kO0O0mn6}k%m`0xV&`_=#eC=&pnaR1zB4m;e$0B0>pA%6qDYMdx zIKreT!f=XS#d57E))WWKb^i54^!tx2xE*?~;_(jn=4UCCAjF|7g zN(PZIV?oGxnYV{V0P<+C>R!!$^QcJqzgl2MV+x9sb8l2pV+tM>u>O$i+B#gP;{+eIrs~R?LnnbvL?DR!j2y^Y# z=qecPHTpw5*5yTT1rj7c+972zoxCeql+PcQLi{sTN>xuZlnZp+Cs0>dQ>i1Ar!aF?=clg4Xm;|<4{$1!126%%)r?`pT zAQmqf)#^M{E>s0n$S*BQ2t=U@F6t&Pll2d!;EOg=i8O&SfhayvThv03Q$GQm$5~Ef z0UD|oDlwEN-d^49Bz{fX zgdB4>tBp-WGO#L$R1@N#rs2YN+7GhD(6FhCb?|sT@9e)X)VruEho_`&lrQ2qbE-E& zRLHvYX8W0hs&`PeeKlshcVC-ZfRS%Zy}uG@2eIP>nxu0NC61ZybmITbD^tYyx_q&) z8vtaHVT<+4Sg}MR0>4q5#?c4TE!4E~2_}CLxUH)+^*9@q zH~fa9R+U~BxoDyKw<-!rPDn@JFq8SR##b;16)R&1>0O2K;wUdzyeAx)z9J`W)ROM| zd5`8_V-CV$5U#00x?A%AZ|5?^N(=l}=Ss@Hq{GpmM?V2KRqM>!1qqnm8U*m6+{woa zy2EAjDROc~Gj{hcm~ljn-x^e|rHpICRPg^f^o{m{C~XggV?DY?O)@vVP+mPfx5f=6SjjK5|U$3SQwVe%i|E`%@oh{dt0j?U{x)}0Lvq~5O9qJ z0=dL{^Tmh!Bm!a`V+2+4J7c|k&vaA4Vp z>R(C=X-vj<*OuAlGJX2)dN_*a%*|D(#1_!%MB#U+f>y+h7k__qoEt3Iq~f%dbyiXy zn$m!4rG%O7MRqF{4i_XT??w;;wBt7|0^CMS?-_2bnNhwGtCMnuk1NbD z1*7jG1f9Q2pSv59?kBe;j|$x|*CqrS<&LtUgk(yek_43|3KTbB5~s80T! zFX-R*H1!OV9E~lE<{Lj(iB5$Zl0IwMH~LX{c$;zk9Za?P6HcG_hTCG>7Kb*0aA@if zjtEYR>J;OBLABl36LHjLIauz7Gq1>!ec;anZE-cCI#IvUpB59Z|Mjocc^=!+)dsI)j=tYhJay32^r zIxEt*%{HLkeIH_hS4kdERp@{9-qV|5cQ$u*zyi*<#$AU9d6X>+{NX+LXqzd<`nEld~` z&y5$D&z&i-F3{?JR6Q?vb^M25EJxJXH9sSRV)U~($-9*fC*KDew~j(XJ_wrKt;noI zfL_3Q&=ljVS1<8t#jH!0po`6NVHkL=$8vp&cBsLPfh9K1ZX1ocN2fiNTlW7-9pdPv zvfG2FVxIS!Kcw$|yyZe55RSRc4{>=x%%7l-bJ-Ndnfd%5_?pkP$`&Z~lO+%lJ)1-c z-F$7r{I|JL)-^7r;md*gWg^e*Dna!v!fq&a_yIq%_3#<$Zw(+dq@D6ODMHImTf{*r%O`8!1^X{GSOMoVw3(fM&@@g>~)o@{j0Up&REds8^ z@>;5I<|I(NOoT@?>Kw*D!F!~9Kp#H&QAkOBk%pVWM^wA7x1;{ zmK=PKgn|Wbo4&PzZuS#TO2h>l3_eu^jhJp1P5P z7xMJk%#RFD+3^IpgSCSyv@w?`x&ez%U85QmaC|!3NuMT+Y^fk$Hk60qST`Ej>$NT2 zAMTGW8~?qm3MfM-NoP*Qp}#{w6Ix|Qn06bY-d}*J%Q;U~n4IKNw!pz3UUN|{o4F*O zCef9Zs;pKmjFJYDhG|3#m3UD@l+Y^!j$+$ZWLPkccbvGV4|Q{X@nZFBKYMDNUZM?5 zqS5#&J{ASelG+My6@uqy3q=~_303G|v8+Yd^&W*weWtlvGjNs2{S$JU-JPv*Y#Gy( zbQUZ`o~#ma98hI7j_1~>viL0t=ebq+px<~TEOx2p&5}B^Bu&R{|bV#hI=D$ z3|si5q&n5^f6ug#&x08k-W9IzdUJCO4tpm_y__=E6B|n)Z`_{GOx74)Y=vMibp?-b zP*P%|Zc)a8TI<=^yKe9sJ_J}D;FH+9HAay=bsjvoIGy5hej_NnJ*~x&YV@XY4NUs;LfD>zw!_3j97{`Ap%R_rdry*3vgm{X>!+ve z^UwEP3ym?ZNX|K{XvtYNg(i!3Rjz*163wZVu}KrPdi$(=|5`Tvfu86-xB=BRM#x_3 zu)-!)xs9|*+NOLK*jzess_YeN2-$K4^YMEs>2z^HwS1ETx-(w({-+2 zFbgktB9(;;%Y?fe8E80C2K%_XJ{6A!^WSmAMmK$UF=j~QhY#H(&DIGGp0}iwi=CYo zS;bc|z|2zd=Lc$ep>Mc;=<8OBPqpThh%-x*&rb8$Nl&F6e`li%?hijI9h}Y5H7*dV z?AXU`sv&p!;NPooSkq7Sy03&D|n-njpUM*cOq89hv}y$As-qY9JNxnO!(34RxrM ze7a?<-KRF@IQj)q%2Smp4Uwcerk6?k1ZfMe5#L5e7I&bIXc7Ufit?;M6>=!P^7ukA zF{`J+sqQaM5s)7f>jt>albxN-rx9EjaAWnA?i1hrlfWg*;k z!`ZU-qW!bvFk9+&oq1YAY`mFTxXgv~Oro9IcnE*W4>{w^-0aU#AMCnNP-dQyrU;{X zq9%JPf}f^D3BzPk;UVg$0W*Q&gGJRqw`%n?=fQ3atf({G$O2oahSNv?{&3q83u9zB0y4A{P6(q%FYDnV<&|A! z59UBmA2qrW(%<6dvMS~9Kgv!q-7p7=qsB#n-(k(Chsm~7;Yb(v{`qrC`mu;&cJYQd zI7yaw!RV~g=i)gGjeQ3Qj>>z_H7lc%hV6G{g#C-LF^a$jJs#+-RPf@9?KCLN2iuto zk0wweA}N`1*PlnrYL{v9?z@GS&T#Cqs&M>%$|;r z=d=qN^m&2^=kF?fj3IR0Gv@bwypFU|4DDm%rpJl>y^fb!^k$8B>UXTm2MsRx z#&qw1oO}SBn54VYptQ9A)-#5#ExB$b4Jx=&;@fkz1|nkUaX_^$70TCuHR-GT`q!_E%%{_EL#GMJPh% zwMm83502-a?9Fw(FGMUk{IoXaR|;}*M&`-9Nfz2Y!YzGoJsnk77KE9sD2yGqkMI;a z!mQ)1f=%`qhGb<32L1^Dcsj51>`7h#o680s2gjln$>-7*9>>*XJU;iI{GEM8MJ{c8lAKW^I2wFf%_%>^V93E1KGxbw>NT z<=0)LTqc(lC7NO4>_Kl~$@#%6Qq#3%PUkeb8D{}GBoS@*Fe@`UvOvNlPw)~41= zjeYQ?*5}mI*Z6KpHR;`YW=v%S$Rw1%u_VOt1@}^5#vjEkO`PP06s*)Myj=qxl7NR? zyGNo}NsekX%e#+OV%OhVXLeDWL6Fr`~O?ZGRMu z67xp!D(G-%RrKF04n6e?FIaw%QfiJU2*jPg3?zgc~6V_-uZ)Lgt5 z6Y?gbdP7ChpIhu z#}Yq%Je<9+VwE)~8vN{@eR0nGek29RUn@6lg)GKXd34-dsBfYfu+yc^gyC+q5nOb( z)b%C*EJx^m@v_$SWp|CyiU_lbtdQW#(s;TeeA7;Md}?dN9y<^OYI}2Q`-_VH=hmH0 z+zIhyq7l%m8|ES|T|_UbM#e!ac9~&F>H=3V&!P42G9~ZGOUE~Vt7oGP!DgAN(>XNM zC_T6ke29Ncc-&UMUlcvbt`DlWW+jFn2_s>ba?OVcBAW47+m@6M8skiF#^~2{w=sfj#19f3nk1BquQ5xR3duJiy}w6sP14>09yGd(pNhK+yM;Svl6+)E zSkEBfh%@rH1=Bkr(DM_#rX zeZIl$9VHuq$49>p9HW0|7Rm;THZuR7bS4SH$o|OZOdz7}&B%fR%Lvic>?})}-<_mbdLoIGXZ-u^3>4+1ii5pS&(+DD%Ha)`W{FYifD_f?lNt&4!ik|6-DFtT8xd&o4V+`t_+Pv=8Qb zOH`CAY!^JO5^C|or}K+20^J*ib0+P`r_MFn#PsMXeowLaQGp_rndaHBc=itTLy#|> zMc^>d{=HAtY|Mhq5R)q97v7O;VE=cN?LuVQyP=7a2qwtbIg(be&`1i|U-R zV>CoSlBy)yZ|v3|gp#4M%_kGgfenSg>$3)?be2A_$weqKP-e#@i0` z*3<4;0ABM8i17&U^Y9B82nd6O#6bdLT>ShXetwD18KeIT0Cj^n*$4dp0JR=I_h$e= MRZ$CEBX9ljKZ_Z52mk;8 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/47.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/47.png new file mode 100644 index 0000000000000000000000000000000000000000..da7f13cc052ff4f3a023153dcfbdf2bd8c70ea1c GIT binary patch literal 6272 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 DSj6U& literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/48.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/48.png new file mode 100644 index 0000000000000000000000000000000000000000..497fc384e4367c607e4b5c558ece3e33dfc115dc GIT binary patch literal 4614 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 PN`=bu8gft>^N{}mg#j;K literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/7.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/7.png new file mode 100644 index 0000000000000000000000000000000000000000..e19d8c72029002aa9da68db83b1e5a63166ce37a GIT binary patch literal 8209 zcmZ`;MN}L>7989I1RpFRI1CJ~!5xAVoZvRNOK=PB8iLC(xVt+Efx+F~9Rdj~d)&jm ze%?s{CA_HzMlIsTP?4EY$g6l8~~_|$NFo6 z@_K(~Ca3-h0Pvv)00Kh+fXCNT-~j;O4h8^@i~#__3;=+{DZ5Qg`1JwJP5zTK+7>3l zTXcj$#sd4-5~``9tQ6qozbmh^G#LP(CX$yD*YsLCHN@~Dl)lT&7L$16fR2HOh>XsP zoP;OW7hAA_F!DZ~rsf$%O#pfBRziG6>rziAmE|3C!2v3IY0Zlk5(Xb8dhm$fx-37U z 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/8.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/8.png new file mode 100644 index 0000000000000000000000000000000000000000..c5a0b438dc4f0a68e53c0c90565ca616b89a6f44 GIT binary patch literal 7875 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 D zo!ReRx}E>Gzsb( z>Qh7~+l~-;F(3{b91)W=7bnPD>X+eBs?jlKvI%DROZ2S~P)3xMmE~LnKVgA|vdCdp z5~&9-^Ezctj}2cdi`hlG(Z2fhHmkcp0X|1g#+L>Nzmy@~){Izh4it^CXya6D=IEne z%8mF7DWdm1R1b`5nRXj*emfuYC^Ra>XQ67Nvl!Zg8SIYWgwgnw$q*y?6K(wu9{paw zKKj!Z>0f0sMl%Al-i}Hut5H{XWf93{18FEMm^4zR2Mubs@A=bI$q=6}TiCd|GLOUE z3GFkmP$%-IV;&sf7N@>7rLQc19h%}u(yDRtWc=WKI=n(=!pdFPOGtdE;U;Wd47w;) zZaMISCweR5CzD``srwKGQY#^U15rsr{NwZX(?Y?X+?H`Ta6q6HLt$Q z88W-sBy+tf{(}bf88u@Q?^sC3Xg16n*}q5r%NRdVA`dpy{f+oKym6tw3v~fjk>~X` z@X@yQ67()lKGo@Rs=>}konei@&5H00@l`@@Jc=x79ngETR>F;qFQer_;su!L`sL*p z=SKFfW;&*V^l?pUm;&f|{j_Yx>iGyvdLee*DM++woJNvj6<3V^ZpYEA%FDH~ZftaO zv*{dlyn(*e1n0#Xy!lV?keYb(pKCmYEw+UpW1D3SL~;G$WbBhpm|P74FXHsu;#x` zi(g2b&RGU0qpHxnuD@8L2`G%%Ev%{YX=E;fNayxDskdhj0@iT03fPiVCv7%5)`!J) zcOv1jtFQ{T)G>O-dp573>%h=4gxp4k#jS|b6FJu)jhSwV_V$Bj)svnh{Hrw2pvu|A zFVyp+TjJh(ZS*mk-}5jFF(zP4P6tFZm3Qr(3lA0^1tMAg(sDO%1#81)B}j`DL9_ zg&p#}?8uvqPZ7T-0v>_opJba7vqSP`KX4qJ7ZJL+X_;^^EWnpbx6h3jRn?M#yO^|t zdbhr5)rXa+OHzJjTRqx41qusRb7J1NtSJ(L`l<+vBmfdyKaL^9bQ)Bwgpo_}R$R^> z*q9$^+0aLw{d`x4`kwr66ruO@}l zsOUvjjZ3iUBgR;lT@4;wyL`i-HOuXMXe;8b2wqr%RG(XTNZ#S4p-5fY?SB1#1do!C zgzqhQAHDSu5b?V0dWX5u>wSrt*O~VqSOZMlwU)c=>X#0m{KwOm2P|8ml?`WWX>lD% z^b($p%VO({KEyU-G72-38KE!z6Y5s5)51wfjrRZ9EXkMgiC9q|h1v&B49b6Oip%rr z2ABSm!5pmWsF}ScglEJWMC2W=BN~XdO}5(5Wm34mHci^gcx;$>nX4t)@z?Y?9rG^;E*r() zeGOkI@I){oZ$|rZTeufaF@>cbL=fou&T@@o=!|{OqOL@Cy@&Z5uVE)kDGEbOdPl?o z8_mEOy)ejg0^91#rXa&xND;%E-dqua)L?)%6eeTXo~a7TvuI}F%4gn~U3yO$Jx?oh zPitXIck4F*aC34AvT<>;adK&M2?=xZ3iI-_aB>QBaz3pW{znx5kAkzSmA#Gc|E`b_ SP8RZ}08o%o1yxI#h5a9feJwKp literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/9.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/9.png new file mode 100644 index 0000000000000000000000000000000000000000..dea81b3214d8439091ac125a9298a3f79acde656 GIT binary patch literal 7640 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/assets/flutter_candies_logo.png b/local_packages/extended_text_field-16.0.2-patched/example/assets/flutter_candies_logo.png new file mode 100644 index 0000000000000000000000000000000000000000..53ace5af554a5d69dfad011a5fa8c22eb525520d GIT binary patch literal 131155 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%0AO}A8C~p0 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 + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + App + CFBundleIdentifier + io.flutter.flutter.app + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + App + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + MinimumOSVersion + 11.0 + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Debug.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 0000000..e8efba1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Release.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Release.xcconfig new file mode 100644 index 0000000..399e934 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile b/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile new file mode 100644 index 0000000..88359b2 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile @@ -0,0 +1,41 @@ +# Uncomment this line to define a global platform for your project +# platform :ios, '11.0' + +# 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', '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 Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + use_modular_headers! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile.lock b/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile.lock new file mode 100644 index 0000000..377a985 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - Flutter (1.0.0) + - url_launcher_ios (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + +SPEC CHECKSUMS: + Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 + url_launcher_ios: ae1517e5e344f5544fb090b079e11f399dfbe4d2 + +PODFILE CHECKSUM: ef19549a9bc3046e7bb7d2fab4d021637c0c58a3 + +COCOAPODS: 1.11.2 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.pbxproj b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..f5c19d1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,566 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + objects = { + +/* Begin PBXBuildFile section */ + 12DF17661E7D053967D9F0A5 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 077B3BB1790B19B0B9B3DA35 /* Pods_Runner.framework */; }; + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 077B3BB1790B19B0B9B3DA35 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B3394F8EB42DB1DE0424DE03 /* 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 = ""; }; + D70E638480C55D8480B56A38 /* 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 = ""; }; + FC67FABFE76D4AE404256943 /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 12DF17661E7D053967D9F0A5 /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 32D6548EE3BBF9FC104A3D3B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 077B3BB1790B19B0B9B3DA35 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 53FC81DD4D77A1C70BDD5FBD /* Pods */ = { + isa = PBXGroup; + children = ( + FC67FABFE76D4AE404256943 /* Pods-Runner.debug.xcconfig */, + D70E638480C55D8480B56A38 /* Pods-Runner.release.xcconfig */, + B3394F8EB42DB1DE0424DE03 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 53FC81DD4D77A1C70BDD5FBD /* Pods */, + 32D6548EE3BBF9FC104A3D3B /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 075D337C84B38FC7530C1FEC /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + B5C945045794C5F8A8418301 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1300; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 075D337C84B38FC7530C1FEC /* [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; + }; + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + B5C945045794C5F8A8418301 /* [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; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + 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_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + 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_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + 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_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + 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_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + 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_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Flutter", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..3db53b6 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..f9b0d7c --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,8 @@ + + + + + PreviewsEnabled + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/AppDelegate.swift b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/AppDelegate.swift new file mode 100644 index 0000000..70693e4 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/AppDelegate.swift @@ -0,0 +1,13 @@ +import UIKit +import Flutter + +@UIApplicationMain +@objc class AppDelegate: FlutterAppDelegate { + override func application( + _ application: UIApplication, + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? + ) -> Bool { + GeneratedPluginRegistrant.register(with: self) + return super.application(application, didFinishLaunchingWithOptions: launchOptions) + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d36b1fa --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,122 @@ +{ + "images" : [ + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-App-20x20@3x.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-App-29x29@3x.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-App-40x40@3x.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@2x.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-App-60x60@3x.png", + "scale" : "3x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@1x.png", + "scale" : "1x" + }, + { + "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-App-20x20@2x.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@1x.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-App-29x29@2x.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@1x.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-App-40x40@2x.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@1x.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-App-76x76@2x.png", + "scale" : "2x" + }, + { + "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-App-83.5x83.5@2x.png", + "scale" : "2x" + }, + { + "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-App-1024x1024@1x.png", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..dc9ada4725e9b0ddb1deab583e5b5102493aa332 GIT binary patch literal 10932 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f091b6b0bca859a3f474b03065bef75ba58a9e4c GIT binary patch literal 1588 zcmV-42Fv-0P)C1SqPt}wig>|5Crh^=oyX$BK<}M8eLU3e2hGT;=G|!_SP)7zNI6fqUMB=)y zRAZ>eDe#*r`yDAVgB_R*LB*MAc)8(b{g{9McCXW!lq7r(btRoB9!8B-#AI6JMb~YFBEvdsV)`mEQO^&#eRKx@b&x- z5lZm*!WfD8oCLzfHGz#u7sT0^VLMI1MqGxF^v+`4YYnVYgk*=kU?HsSz{v({E3lb9 z>+xILjBN)t6`=g~IBOelGQ(O990@BfXf(DRI5I$qN$0Gkz-FSc$3a+2fX$AedL4u{ z4V+5Ong(9LiGcIKW?_352sR;LtDPmPJXI{YtT=O8=76o9;*n%_m|xo!i>7$IrZ-{l z-x3`7M}qzHsPV@$v#>H-TpjDh2UE$9g6sysUREDy_R(a)>=eHw-WAyfIN z*qb!_hW>G)Tu8nSw9yn#3wFMiLcfc4pY0ek1}8(NqkBR@t4{~oC>ryc-h_ByH(Cg5 z>ao-}771+xE3um9lWAY1FeQFxowa1(!J(;Jg*wrg!=6FdRX+t_<%z&d&?|Bn){>zm zZQj(aA_HeBY&OC^jj*)N`8fa^ePOU72VpInJoI1?`ty#lvlNzs(&MZX+R%2xS~5Kh zX*|AU4QE#~SgPzOXe9>tRj>hjU@c1k5Y_mW*Jp3fI;)1&g3j|zDgC+}2Q_v%YfDax z!?umcN^n}KYQ|a$Lr+51Nf9dkkYFSjZZjkma$0KOj+;aQ&721~t7QUKx61J3(P4P1 zstI~7-wOACnWP4=8oGOwz%vNDqD8w&Q`qcNGGrbbf&0s9L0De{4{mRS?o0MU+nR_! zrvshUau0G^DeMhM_v{5BuLjb#Hh@r23lDAk8oF(C+P0rsBpv85EP>4CVMx#04MOfG z;P%vktHcXwTj~+IE(~px)3*MY77e}p#|c>TD?sMatC0Tu4iKKJ0(X8jxQY*gYtxsC z(zYC$g|@+I+kY;dg_dE>scBf&bP1Nc@Hz<3R)V`=AGkc;8CXqdi=B4l2k|g;2%#m& z*jfX^%b!A8#bI!j9-0Fi0bOXl(-c^AB9|nQaE`*)Hw+o&jS9@7&Gov#HbD~#d{twV zXd^Tr^mWLfFh$@Dr$e;PBEz4(-2q1FF0}c;~B5sA}+Q>TOoP+t>wf)V9Iy=5ruQa;z)y zI9C9*oUga6=hxw6QasLPnee@3^Rr*M{CdaL5=R41nLs(AHk_=Y+A9$2&H(B7!_pURs&8aNw7?`&Z&xY_Ye z)~D5Bog^td-^QbUtkTirdyK^mTHAOuptDflut!#^lnKqU md>ggs(5nOWAqO?umG&QVYK#ibz}*4>0000U6E9hRK9^#O7(mu>ETqrXGsduA8$)?`v2seloOCza43C{NQ$$gAOH**MCn0Q?+L7dl7qnbRdqZ8LSVp1ItDxhxD?t@5_yHg6A8yI zC*%Wgg22K|8E#!~cTNYR~@Y9KepMPrrB8cABapAFa=`H+UGhkXUZV1GnwR1*lPyZ;*K(i~2gp|@bzp8}og7e*#% zEnr|^CWdVV!-4*Y_7rFvlww2Ze+>j*!Z!pQ?2l->4q#nqRu9`ELo6RMS5=br47g_X zRw}P9a7RRYQ%2Vsd0Me{_(EggTnuN6j=-?uFS6j^u69elMypu?t>op*wBx<=Wx8?( ztpe^(fwM6jJX7M-l*k3kEpWOl_Vk3@(_w4oc}4YF4|Rt=2V^XU?#Yz`8(e?aZ@#li0n*=g^qOcVpd-Wbok=@b#Yw zqn8u9a)z>l(1kEaPYZ6hwubN6i<8QHgsu0oE) ziJ(p;Wxm>sf!K+cw>R-(^Y2_bahB+&KI9y^);#0qt}t-$C|Bo71lHi{_+lg#f%RFy z0um=e3$K3i6K{U_4K!EX?F&rExl^W|G8Z8;`5z-k}OGNZ0#WVb$WCpQu-_YsiqKP?BB# vzVHS-CTUF4Ozn5G+mq_~Qqto~ahA+K`|lyv3(-e}00000NkvXXu0mjfd`9t{ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..d0ef06e7edb86cdfe0d15b4b0d98334a86163658 GIT binary patch literal 1716 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..c8f9ed8f5cee1c98386d13b17e89f719e83555b2 GIT binary patch literal 1895 zcmV-t2blPYP)FQtfgmafE#=YDCq`qUBt#QpG%*H6QHY765~R=q zZ6iudfM}q!Pz#~9JgOi8QJ|DSu?1-*(kSi1K4#~5?#|rh?sS)(-JQqX*}ciXJ56_H zdw=^s_srbAdqxlvGyrgGet#6T7_|j;95sL%MtM;q86vOxKM$f#puR)Bjv9Zvz9-di zXOTSsZkM83)E9PYBXC<$6(|>lNLVBb&&6y{NByFCp%6+^ALR@NCTse_wqvNmSWI-m z!$%KlHFH2omF!>#%1l3LTZg(s7eof$7*xB)ZQ0h?ejh?Ta9fDv59+u#MokW+1t8Zb zgHv%K(u9G^Lv`lh#f3<6!JVTL3(dCpxHbnbA;kKqQyd1~^Xe0VIaYBSWm6nsr;dFj z4;G-RyL?cYgsN1{L4ZFFNa;8)Rv0fM0C(~Tkit94 zz#~A)59?QjD&pAPSEQ)p8gP|DS{ng)j=2ux)_EzzJ773GmQ_Cic%3JJhC0t2cx>|v zJcVusIB!%F90{+}8hG3QU4KNeKmK%T>mN57NnCZ^56=0?&3@!j>a>B43pi{!u z7JyDj7`6d)qVp^R=%j>UIY6f+3`+qzIc!Y_=+uN^3BYV|o+$vGo-j-Wm<10%A=(Yk^beI{t%ld@yhKjq0iNjqN4XMGgQtbKubPM$JWBz}YA65k%dm*awtC^+f;a-x4+ddbH^7iDWGg&N0n#MW{kA|=8iMUiFYvMoDY@sPC#t$55gn6ykUTPAr`a@!(;np824>2xJthS z*ZdmT`g5-`BuJs`0LVhz+D9NNa3<=6m;cQLaF?tCv8)zcRSh66*Z|vXhG@$I%U~2l z?`Q zykI#*+rQ=z6Jm=Bui-SfpDYLA=|vzGE(dYm=OC8XM&MDo7ux4UF1~0J1+i%aCUpRe zt3L_uNyQ*cE(38Uy03H%I*)*Bh=Lb^Xj3?I^Hnbeq72(EOK^Y93CNp*uAA{5Lc=ky zx=~RKa4{iTm{_>_vSCm?$Ej=i6@=m%@VvAITnigVg{&@!7CDgs908761meDK5azA} z4?=NOH|PdvabgJ&fW2{Mo$Q0CcD8Qc84%{JPYt5EiG{MdLIAeX%T=D7NIP4%Hw}p9 zg)==!2Lbp#j{u_}hMiao9=!VSyx0gHbeCS`;q&vzeq|fs`y&^X-lso(Ls@-706qmA z7u*T5PMo_w3{se1t2`zWeO^hOvTsohG_;>J0wVqVe+n)AbQCx)yh9;w+J6?NF5Lmo zecS@ieAKL8%bVd@+-KT{yI|S}O>pYckUFs;ry9Ow$CD@ztz5K-*D$^{i(_1llhSh^ zEkL$}tsQt5>QA^;QgjgIfBDmcOgi5YDyu?t6vSnbp=1+@6D& z5MJ}B8q;bRlVoxasyhcUF1+)o`&3r0colr}QJ3hcSdLu;9;td>kf@Tcn<@9sIx&=m z;AD;SCh95=&p;$r{Xz3iWCO^MX83AGJ(yH&eTXgv|0=34#-&WAmw{)U7OU9!Wz^!7 zZ%jZFi@JR;>Mhi7S>V7wQ176|FdW2m?&`qa(ScO^CFPR80HucLHOTy%5s*HR0^8)i h0WYBP*#0Ks^FNSabJA*5${_#%002ovPDHLkV1oKhTl@e3 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..a6d6b8609df07bf62e5100a53a01510388bd2b22 GIT binary patch literal 2665 zcmV-v3YPVWP)oFh3q0MFesq&64WThn3$;G69TfjsAv=f2G9}p zgSx99+!YV6qME!>9MD13x)k(+XE7W?_O4LoLb5ND8 zaV{9+P@>42xDfRiYBMSgD$0!vssptcb;&?u9u(LLBKmkZ>RMD=kvD3h`sk6!QYtBa ztlZI#nu$8lJ^q2Z79UTgZe>BU73(Aospiq+?SdMt8lDZ;*?@tyWVZVS_Q7S&*tJaiRlJ z+aSMOmbg3@h5}v;A*c8SbqM3icg-`Cnwl;7Ts%A1RkNIp+Txl-Ckkvg4oxrqGA5ewEgYqwtECD<_3Egu)xGllKt&J8g&+=ac@Jq4-?w6M3b*>w5 z69N3O%=I^6&UL5gZ!}trC7bUj*12xLdkNs~Bz4QdJJ*UDZox2UGR}SNg@lmOvhCc~ z*f_UeXv(=#I#*7>VZx2ObEN~UoGUTl=-@)E;YtCRZ>SVp$p9yG5hEFZ!`wI!spd)n zSk+vK0Vin7FL{7f&6OB%f;SH22dtbcF<|9fi2Fp%q4kxL!b1#l^)8dUwJ zwEf{(wJj@8iYDVnKB`eSU+;ml-t2`@%_)0jDM`+a46xhDbBj2+&Ih>1A>6aky#(-SYyE{R3f#y57wfLs z6w1p~$bp;6!9DX$M+J~S@D6vJAaElETnsX4h9a5tvPhC3L@qB~bOzkL@^z0k_hS{T4PF*TDrgdXp+dzsE? z>V|VR035Pl9n5&-RePFdS{7KAr2vPOqR9=M$vXA1Yy5>w;EsF`;OK{2pkn-kpp9Pw z)r;5JfJKKaT$4qCb{TaXHjb$QA{y0EYy*+b1XI;6Ah- zw13P)xT`>~eFoJC!>{2XL(a_#upp3gaR1#5+L(Jmzp4TBnx{~WHedpJ1ch8JFk~Sw z>F+gN+i+VD?gMXwcIhn8rz`>e>J^TI3E-MW>f}6R-pL}>WMOa0k#jN+`RyUVUC;#D zg|~oS^$6%wpF{^Qr+}X>0PKcr3Fc&>Z>uv@C);pwDs@2bZWhYP!rvGx?_|q{d`t<*XEb#=aOb=N+L@CVBGqImZf&+a zCQEa3$~@#kC);pasdG=f6tuIi0PO-y&tvX%>Mv=oY3U$nD zJ#gMegnQ46pq+3r=;zmgcG+zRc9D~c>z+jo9&D+`E6$LmyFqlmCYw;-Zooma{sR@~ z)_^|YL1&&@|GXo*pivH7k!msl+$Sew3%XJnxajt0K%3M6Bd&YFNy9}tWG^aovK2eX z1aL1%7;KRDrA@eG-Wr6w+;*H_VD~qLiVI`{_;>o)k`{8xa3EJT1O_>#iy_?va0eR? zDV=N%;Zjb%Z2s$@O>w@iqt!I}tLjGk!=p`D23I}N4Be@$(|iSA zf3Ih7b<{zqpDB4WF_5X1(peKe+rASze%u8eKLn#KKXt;UZ+Adf$_TO+vTqshLLJ5c z52HucO=lrNVae5XWOLm!V@n-ObU11!b+DN<$RuU+YsrBq*lYT;?AwJpmNKniF0Q1< zJCo>Q$=v$@&y=sj6{r!Y&y&`0$-I}S!H_~pI&2H8Z1C|BX4VgZ^-! zje3-;x0PBD!M`v*J_)rL^+$<1VJhH*2Fi~aA7s&@_rUHYJ9zD=M%4AFQ`}k8OC$9s XsPq=LnkwKG00000NkvXXu0mjfhAk5^ literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..75b2d164a5a98e212cca15ea7bf2ab5de5108680 GIT binary patch literal 3831 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..c4df70d39da7941ef3f6dcb7f06a192d8dcb308d GIT binary patch literal 1888 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 iW8Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 GIT binary patch literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx0wlM}@Gt=>Zci7-kcv6Uzs@r-FtIZ-&5|)J Q1PU{Fy85}Sb4q9e0B4a5jsO4v literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md new file mode 100644 index 0000000..89c2725 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md @@ -0,0 +1,5 @@ +# Launch Screen Assets + +You can customize the launch screen with your own desired assets by replacing the image files in this directory. + +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. \ No newline at end of file diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/LaunchScreen.storyboard b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..f2e259c --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/Main.storyboard b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/Main.storyboard new file mode 100644 index 0000000..f3c2851 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Base.lproj/Main.storyboard @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Info.plist b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Info.plist new file mode 100644 index 0000000..4f68a2c --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Info.plist @@ -0,0 +1,49 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Runner-Bridging-Header.h b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Runner-Bridging-Header.h new file mode 100644 index 0000000..308a2a5 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/ios/Runner/Runner-Bridging-Header.h @@ -0,0 +1 @@ +#import "GeneratedPluginRegistrant.h" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/common/button.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/common/button.dart new file mode 100644 index 0000000..69e021b --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/common/button.dart @@ -0,0 +1,70 @@ +import 'package:flutter/material.dart'; + +class NumberButton extends StatelessWidget { + const NumberButton({ + Key? key, + required this.number, + required this.insertText, + }) : super(key: key); + final int number; + final Function(String text) insertText; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + insertText('$number'); + }, + child: Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 4, + offset: Offset(0, 2), + ), + ], + ), + child: Text( + '$number', + ), + ), + ); + } +} + +class CustomButton extends StatelessWidget { + const CustomButton({ + Key? key, + required this.child, + required this.onTap, + }) : super(key: key); + final Widget child; + final GestureTapCallback onTap; + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(10), + boxShadow: const [ + BoxShadow( + color: Colors.black12, + blurRadius: 4, + offset: Offset(0, 2), + ), + ], + ), + child: child, + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/common/toggle_button.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/common/toggle_button.dart new file mode 100644 index 0000000..737b9de --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/common/toggle_button.dart @@ -0,0 +1,49 @@ +import 'package:flutter/material.dart'; + +class ToggleButton extends StatefulWidget { + const ToggleButton({ + this.activeChanged, + this.active = false, + super.key, + required this.builder, + }); + + final bool active; + final ValueChanged? activeChanged; + final Widget Function(bool active) builder; + @override + State createState() => _ToggleButtonState(); +} + +class _ToggleButtonState extends State { + bool _active = false; + + @override + void initState() { + _active = widget.active; + super.initState(); + } + + @override + void didUpdateWidget(ToggleButton oldWidget) { + _active = widget.active; + super.didUpdateWidget(oldWidget); + } + + @override + Widget build(BuildContext context) { + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + setState(() { + _active = !_active; + widget.activeChanged?.call(_active); + }); + }, + child: Padding( + padding: const EdgeInsets.only(left: 20.0, top: 10.0, bottom: 10.0), + child: widget.builder(_active), + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/data/mock_data.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/mock_data.dart new file mode 100644 index 0000000..8c2ff10 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/mock_data.dart @@ -0,0 +1,50395 @@ +// ignore_for_file: always_specify_types + +import 'tu_chong_source.dart'; + +// ignore_for_file: implicit_dynamic_list_literal,implicit_dynamic_map_literal +Map _mock = { + 'counts': 316, + 'feedList': [ + { + 'author_id': '2789905', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '归期/\n\n摄影:给给Eru\n出镜:一折', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '深圳小清新摄影小组', + '人像爱好者', + '古装摄影圈子', + '人像写真摄影约拍', + '我要上开屏', + '分享神仙颜值', + '冷色调人像', + '驚鴻·一眸' + ], + 'excerpt': '归期/\n\n摄影:给给Eru\n出镜:一折', + 'favorite_list_prefix': [], + 'favorites': 42, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 302304041, + 'img_id_str': '302304041', + 'title': '001', + 'user_id': 2789905, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 627230197, + 'img_id_str': '627230197', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 129943371, + 'img_id_str': '129943371', + 'title': '001', + 'user_id': 2789905, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 629983027, + 'img_id_str': '629983027', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 480954067, + 'img_id_str': '480954067', + 'title': '001', + 'user_id': 2789905, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 614450970, + 'img_id_str': '614450970', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 154781482, + 'img_id_str': '154781482', + 'title': '001', + 'user_id': 2789905, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 524928648, + 'img_id_str': '524928648', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 423413281, + 'img_id_str': '423413281', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3508, + 'img_id': 462931952, + 'img_id_str': '462931952', + 'title': '001', + 'user_id': 2789905, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 628147833, + 'img_id_str': '628147833', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 400082871, + 'img_id_str': '400082871', + 'title': '001', + 'user_id': 2789905, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月19日', + 'post_id': 61835188, + 'published_at': '2020-01-19 12:01:24', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 3, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 616, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2789905_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '给给Eru', + 'site_id': '2789905', + 'type': 'user', + 'url': 'https://tuchong.com/2789905/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2789905', + 'sites': [], + 'tags': ['深圳小清新摄影小组', '人像爱好者', '古装摄影圈子', '人像写真摄影约拍', '我要上开屏', '分享神仙颜值'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2789905/61835188/', + 'views': 1330 + }, + { + 'author_id': '999799', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 37, + 'content': + '出镜:@鳗鱼霏儿 (https://www.weibo.com/u/1728752564)\n摄影:@歌罢海西流 (https://www.weibo.com/u/2281254862)\n游戏官博:@明日方舟Arknights \n漫展主办方:@中国国际漫画节动漫游戏展', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '出镜:@鳗鱼霏儿 (https://www.weibo.com/u/1728752564)\n摄影:@歌罢海西流 (https://www.weibo.com/u/2281254862)\n游戏官博:@明日方舟Arknights \n漫展主办方:@中国国际漫画节动漫游戏展', + 'favorite_list_prefix': [], + 'favorites': 1285, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 180335429, + 'img_id_str': '180335429', + 'title': '', + 'user_id': 999799, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 653047009, + 'img_id_str': '653047009', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 398898247, + 'img_id_str': '398898247', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5395, + 'img_id': 244823034, + 'img_id_str': '244823034', + 'title': '', + 'user_id': 999799, + 'width': 3602 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5650, + 'img_id': 389854263, + 'img_id_str': '389854263', + 'title': '', + 'user_id': 999799, + 'width': 3772 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5780, + 'img_id': 306360893, + 'img_id_str': '306360893', + 'title': '', + 'user_id': 999799, + 'width': 3858 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5491, + 'img_id': 45462366, + 'img_id_str': '45462366', + 'title': '', + 'user_id': 999799, + 'width': 3666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5831, + 'img_id': 84063617, + 'img_id_str': '84063617', + 'title': '', + 'user_id': 999799, + 'width': 3892 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5665, + 'img_id': 436843148, + 'img_id_str': '436843148', + 'title': '', + 'user_id': 999799, + 'width': 3782 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年10月16日', + 'post_id': 56053420, + 'published_at': '2019-10-16 16:01:59', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 33, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 6436, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_999799_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '歌罢', + 'site_id': '999799', + 'type': 'user', + 'url': 'https://tuchong.com/999799/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '999799', + 'sites': [], + 'tags': ['Cosplay', '人像', '少女', '85mm', '美腿', '尼康'], + 'title': '明日方舟cosplay', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/999799/56053420/', + 'views': 69556 + }, + { + 'author_id': '1030747', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 279, + 'content': + '历时5个月,以奇特的拍摄和处理手法展现了株洲的网红地标,恍如进入了「盗梦空间」,谨以此组照片献给我热爱的祖国,我热爱的城市!', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['寻找「城市秘境」', '第三届京东摄影金像奖', '2019你最满意的照片'], + 'excerpt': + '历时5个月,以奇特的拍摄和处理手法展现了株洲的网红地标,恍如进入了「盗梦空间」,谨以此组照片献给我热爱的祖国,我热爱的城市!', + 'favorite_list_prefix': [], + 'favorites': 3494, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 55290291, + 'img_id_str': '55290291', + 'title': '', + 'user_id': 1030747, + 'width': 1217 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 127248519, + 'img_id_str': '127248519', + 'title': '', + 'user_id': 1030747, + 'width': 1245 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 424585238, + 'img_id_str': '424585238', + 'title': '', + 'user_id': 1030747, + 'width': 1304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 469674195, + 'img_id_str': '469674195', + 'title': '', + 'user_id': 1030747, + 'width': 1260 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 311863407, + 'img_id_str': '311863407', + 'title': '', + 'user_id': 1030747, + 'width': 1282 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 514697201, + 'img_id_str': '514697201', + 'title': '', + 'user_id': 1030747, + 'width': 1206 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 277325761, + 'img_id_str': '277325761', + 'title': '', + 'user_id': 1030747, + 'width': 1271 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 461875423, + 'img_id_str': '461875423', + 'title': '', + 'user_id': 1030747, + 'width': 1259 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 203794226, + 'img_id_str': '203794226', + 'title': '', + 'user_id': 1030747, + 'width': 1310 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '252', + 'passed_time': '2019年09月26日', + 'post_id': 53655560, + 'published_at': '2019-09-26 22:05:01', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '13', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 247, + 'site': { + 'description': '资深建筑摄影师', + 'domain': '', + 'followers': 4732, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1030747_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '石彦科-YANKEE', + 'site_id': '1030747', + 'type': 'user', + 'url': 'https://tuchong.com/1030747/', + 'verification_list': [ + {'verification_reason': '资深建筑摄影师', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1030747', + 'sites': [], + 'tags': ['寻找「城市秘境」', '第三届京东摄影金像奖', '2019你最满意的照片', '株洲', 'JD看城市', '北京汽车'], + 'title': '盗梦之城——株洲', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1030747/53655560/', + 'views': 144209 + }, + { + 'author_id': '3229117', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '我能看见大海的颜色\n我看不清心事', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '极简主义,少即是多', + '最美肖像照', + '有温度的人像', + '济南约拍圈', + '人像写真摄影约拍', + '咔了个图', + '高颜值女神聚集地', + '人像爱好者', + '驚鴻·一眸', + '分享神仙颜值' + ], + 'excerpt': '我能看见大海的颜色\n我看不清心事', + 'favorite_list_prefix': [], + 'favorites': 213, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 132171098, + 'img_id_str': '132171098', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 496813711, + 'img_id_str': '496813711', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 55625060, + 'img_id_str': '55625060', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 295224561, + 'img_id_str': '295224561', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 44353101, + 'img_id_str': '44353101', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 584369944, + 'img_id_str': '584369944', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 478921963, + 'img_id_str': '478921963', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 598001081, + 'img_id_str': '598001081', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 95405724, + 'img_id_str': '95405724', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '01月07日', + 'post_id': 61478978, + 'published_at': '2020-01-07 10:24:35', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 7, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3071, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3229117_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '黑猫阿姨', + 'site_id': '3229117', + 'type': 'user', + 'url': 'https://tuchong.com/3229117/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3229117', + 'sites': [], + 'tags': ['极简主义,少即是多', '最美肖像照', '有温度的人像', '济南约拍圈', '人像写真摄影约拍', '咔了个图'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3229117/61478978/', + 'views': 8240 + }, + { + 'author_id': '389785', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 26, + 'content': '', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 731, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5168, + 'img_id': 114930137, + 'img_id_str': '114930137', + 'title': '001', + 'user_id': 389785, + 'width': 3448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5168, + 'img_id': 529051556, + 'img_id_str': '529051556', + 'title': '001', + 'user_id': 389785, + 'width': 3448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 253144912, + 'img_id_str': '253144912', + 'title': '001', + 'user_id': 389785, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 23851, + 'img_id': 394965265, + 'img_id_str': '394965265', + 'title': '001', + 'user_id': 389785, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 464236295, + 'img_id_str': '464236295', + 'title': '001', + 'user_id': 389785, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 10928, + 'img_id': 87208312, + 'img_id_str': '87208312', + 'title': '001', + 'user_id': 389785, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 10046, + 'img_id': 124170215, + 'img_id_str': '124170215', + 'title': '001', + 'user_id': 389785, + 'width': 3359 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5168, + 'img_id': 201437355, + 'img_id_str': '201437355', + 'title': '001', + 'user_id': 389785, + 'width': 7144 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5063, + 'img_id': 154447940, + 'img_id_str': '154447940', + 'title': '001', + 'user_id': 389785, + 'width': 3378 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '26', + 'passed_time': '2019年10月09日', + 'post_id': 55406969, + 'published_at': '2019-10-09 22:21:47', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 29, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4329, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_389785_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '阿怪小天使', + 'site_id': '389785', + 'type': 'user', + 'url': 'https://tuchong.com/389785/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '389785', + 'sites': [], + 'tags': ['色彩', '人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/389785/55406969/', + 'views': 28368 + }, + { + 'author_id': '1590219', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 40, + 'content': '萤火虫DAY1 \n出镜:清水由乃\n\n拍个场照跟打仗一样...', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '萤火虫DAY1 \n出镜:清水由乃\n\n拍个场照跟打仗一样...', + 'favorite_list_prefix': [], + 'favorites': 1034, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6181, + 'img_id': 355828066, + 'img_id_str': '355828066', + 'title': '', + 'user_id': 1590219, + 'width': 4120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 399933769, + 'img_id_str': '399933769', + 'title': '', + 'user_id': 1590219, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 254968217, + 'img_id_str': '254968217', + 'title': '', + 'user_id': 1590219, + 'width': 6240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 549683596, + 'img_id_str': '549683596', + 'title': '', + 'user_id': 1590219, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 380731607, + 'img_id_str': '380731607', + 'title': '', + 'user_id': 1590219, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 198934547, + 'img_id_str': '198934547', + 'title': '', + 'user_id': 1590219, + 'width': 7396 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5824, + 'img_id': 94601483, + 'img_id_str': '94601483', + 'title': '', + 'user_id': 1590219, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3815, + 'img_id': 370835750, + 'img_id_str': '370835750', + 'title': '', + 'user_id': 1590219, + 'width': 6783 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5824, + 'img_id': 652771493, + 'img_id_str': '652771493', + 'title': '', + 'user_id': 1590219, + 'width': 4160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '29', + 'passed_time': '2019年07月29日', + 'post_id': 46827805, + 'published_at': '2019-07-29 22:25:47', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 23, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'tuopiandidai.tuchong.com', + 'followers': 10737, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1590219_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '故乡の缘风景', + 'site_id': '1590219', + 'type': 'user', + 'url': 'https://tuopiandidai.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1590219', + 'sites': [], + 'tags': ['人像', '小清新', '美女', '少女', '富士', '女孩'], + 'title': '练习', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuopiandidai.tuchong.com/46827805/', + 'views': 52188 + }, + { + 'author_id': '488929', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 35, + 'content': '阳光明媚的早晨 牛奶 面包 和你☁️', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['日系集'], + 'excerpt': '阳光明媚的早晨 牛奶 面包 和你☁️', + 'favorite_list_prefix': [], + 'favorites': 1030, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 514754687, + 'img_id_str': '514754687', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 468879705, + 'img_id_str': '468879705', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 204704390, + 'img_id_str': '204704390', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 528123867, + 'img_id_str': '528123867', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 156731674, + 'img_id_str': '156731674', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 232425720, + 'img_id_str': '232425720', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 497584269, + 'img_id_str': '497584269', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 442402907, + 'img_id_str': '442402907', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 70158973, + 'img_id_str': '70158973', + 'title': '001', + 'user_id': 488929, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '33', + 'passed_time': '2019年08月06日', + 'post_id': 47993130, + 'published_at': '2019-08-06 23:06:53', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 27, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4045, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_488929_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '苏蓝sherry', + 'site_id': '488929', + 'type': 'user', + 'url': 'https://tuchong.com/488929/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '488929', + 'sites': [], + 'tags': ['日系集', '少女', '日系少女', '少女写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/488929/47993130/', + 'views': 50477 + }, + { + 'author_id': '490904', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': '秋凉。', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '分享神仙颜值', + '暖色调人像', + '驚鴻·一眸', + '约拍馆摄影作品投稿', + '糖水人像小组', + '人像爱好者', + '我们都爱日系摄影', + '河北摄影圈', + '高颜值女神聚集地', + '日系集' + ], + 'excerpt': '秋凉。', + 'favorite_list_prefix': [], + 'favorites': 1033, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 643873860, + 'img_id_str': '643873860', + 'title': '52892', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 598784501, + 'img_id_str': '598784501', + 'title': '52887', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 90487758, + 'img_id_str': '90487758', + 'title': '52886', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 413252113, + 'img_id_str': '413252113', + 'title': '52888', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 49920432, + 'img_id_str': '49920432', + 'title': '52890', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 319732118, + 'img_id_str': '319732118', + 'title': '52893', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 552254016, + 'img_id_str': '552254016', + 'title': '52889', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 294173479, + 'img_id_str': '294173479', + 'title': '52891', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 560511953, + 'img_id_str': '560511953', + 'title': '52546', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 72459318, + 'img_id_str': '72459318', + 'title': '52027', + 'user_id': 490904, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '2019年11月03日', + 'post_id': 57691196, + 'published_at': '2019-11-03 16:32:20', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 34, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12649, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_490904_8', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师CAT', + 'site_id': '490904', + 'type': 'user', + 'url': 'https://tuchong.com/490904/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '490904', + 'sites': [], + 'tags': ['分享神仙颜值', '暖色调人像', '驚鴻·一眸', '约拍馆摄影作品投稿', '糖水人像小组', '人像爱好者'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/490904/57691196/', + 'views': 28932 + }, + { + 'author_id': '1718084', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 16, + 'content': + '出镜: \nWeibo :\n-浅域- \nhttps://weibo.com/u/5486388616\n\n摄影:@Cchua华仔\nWeibo:\n@Cchua华-仔\nhttps://weibo.com/vipcchua', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '出镜: \nWeibo :\n-浅域- \nhttps://weibo.com/u/5486388616\n\n摄影:@Cchua华仔\nWeibo:\n@Cchua华-仔\nhttps://weibo.com/vipcchua', + 'favorite_list_prefix': [], + 'favorites': 762, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 219519810, + 'img_id_str': '219519810', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 48142938, + 'img_id_str': '48142938', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 570399487, + 'img_id_str': '570399487', + 'title': '', + 'user_id': 1718084, + 'width': 3538 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 549035080, + 'img_id_str': '549035080', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 57973561, + 'img_id_str': '57973561', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 128490403, + 'img_id_str': '128490403', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 609327692, + 'img_id_str': '609327692', + 'title': '', + 'user_id': 1718084, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 371235416, + 'img_id_str': '371235416', + 'title': '', + 'user_id': 1718084, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8351, + 'img_id': 303078135, + 'img_id_str': '303078135', + 'title': '', + 'user_id': 1718084, + 'width': 5571 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '13', + 'passed_time': '2019年08月28日', + 'post_id': 50900424, + 'published_at': '2019-08-28 14:08:44', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 23, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'cchua.tuchong.com', + 'followers': 4650, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1718084_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Cchua华仔', + 'site_id': '1718084', + 'type': 'user', + 'url': 'https://cchua.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1718084', + 'sites': [], + 'tags': ['人像', 'JK'], + 'title': 'JK - Hot Summer', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://cchua.tuchong.com/50900424/', + 'views': 30474 + }, + { + 'author_id': '1413882', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 33, + 'content': 'Kitty and Beauty', + 'created_at': '', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '驚鴻·一眸', + '写真人像摄影', + '成都约拍圈子', + '成都人像爱好者', + '高颜值女神聚集地', + '日系集', + '分享神仙颜值' + ], + 'excerpt': 'Kitty and Beauty', + 'favorite_list_prefix': [], + 'favorites': 674, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4969, + 'img_id': 305643973, + 'img_id_str': '305643973', + 'title': '001', + 'user_id': 1413882, + 'width': 3313 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 326353053, + 'img_id_str': '326353053', + 'title': '001', + 'user_id': 1413882, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 49988311, + 'img_id_str': '49988311', + 'title': '001', + 'user_id': 1413882, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5212, + 'img_id': 129614118, + 'img_id_str': '129614118', + 'title': '001', + 'user_id': 1413882, + 'width': 3475 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3803, + 'img_id': 236896802, + 'img_id_str': '236896802', + 'title': '001', + 'user_id': 1413882, + 'width': 5705 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5788, + 'img_id': 220643714, + 'img_id_str': '220643714', + 'title': '001', + 'user_id': 1413882, + 'width': 3859 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3753, + 'img_id': 434356864, + 'img_id_str': '434356864', + 'title': '001', + 'user_id': 1413882, + 'width': 5630 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5392, + 'img_id': 512607079, + 'img_id_str': '512607079', + 'title': '001', + 'user_id': 1413882, + 'width': 3595 + } + ], + 'is_favorite': false, + 'last_read': true, + 'parent_comments': '32', + 'passed_time': '2019年12月06日', + 'post_id': 59959066, + 'published_at': '2019-12-06 09:31:29', + 'recommend': true, + 'recom_type': '热门', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '7f35fa915780a55900b9d37f03996a40', + 'shares': 29, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2548, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1413882_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Batkid', + 'site_id': '1413882', + 'type': 'user', + 'url': 'https://tuchong.com/1413882/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1413882', + 'sites': [], + 'tags': ['驚鴻·一眸', '写真人像摄影', '成都约拍圈子', '成都人像爱好者', '高颜值女神聚集地', '日系集'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1413882/59959066/', + 'views': 63307 + }, + { + 'author_id': '8564826', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 11, + 'content': '赛车娘冲鸭', + 'created_at': '2020-01-04 08:15:47', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上开屏', 'Cosplay摄影集中地', '分享神仙颜值', '高颜值女神聚集地'], + 'excerpt': '赛车娘冲鸭', + 'favorite_list_prefix': [], + 'favorites': 227, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5982, + 'img_id': 599901817, + 'img_id_str': '599901817', + 'title': '1764398', + 'user_id': 8564826, + 'width': 3988 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6368, + 'img_id': 298108304, + 'img_id_str': '298108304', + 'title': '1764399', + 'user_id': 8564826, + 'width': 4246 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6272, + 'img_id': 178636322, + 'img_id_str': '178636322', + 'title': '1764406', + 'user_id': 8564826, + 'width': 4182 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4324, + 'img_id': 422823864, + 'img_id_str': '422823864', + 'title': '1764401', + 'user_id': 8564826, + 'width': 2882 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5258, + 'img_id': 164349529, + 'img_id_str': '164349529', + 'title': '1764402', + 'user_id': 8564826, + 'width': 3506 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4976, + 'img_id': 267044509, + 'img_id_str': '267044509', + 'title': '1764405', + 'user_id': 8564826, + 'width': 3317 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2789, + 'img_id': 611829156, + 'img_id_str': '611829156', + 'title': '1764404', + 'user_id': 8564826, + 'width': 6508 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '01月04日', + 'post_id': 61377798, + 'published_at': '2020-01-04 08:15:47', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4460, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_8564826_15', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '南廷Osimple', + 'site_id': '8564826', + 'type': 'user', + 'url': 'https://tuchong.com/8564826/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '8564826', + 'sites': [], + 'tags': ['我要上开屏', 'Cosplay摄影集中地', '分享神仙颜值', '高颜值女神聚集地'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8564826/61377798/', + 'views': 15640 + }, + { + 'author_id': '2600543', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 23, + 'content': '出镜:@妍子坚不可摧', + 'created_at': '2019-12-25 16:12:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Cosplay摄影集中地', '让摄影穿破次元壁', '高颜值女神聚集地', '图虫约拍圈子', '悦拍评片会'], + 'excerpt': '出镜:@妍子坚不可摧', + 'favorite_list_prefix': [], + 'favorites': 545, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 536332429, + 'img_id_str': '536332429', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 644335113, + 'img_id_str': '644335113', + 'title': '', + 'user_id': 2600543, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 581617094, + 'img_id_str': '581617094', + 'title': '', + 'user_id': 2600543, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 440256264, + 'img_id_str': '440256264', + 'title': '', + 'user_id': 2600543, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 49464774, + 'img_id_str': '49464774', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 150783459, + 'img_id_str': '150783459', + 'title': '', + 'user_id': 2600543, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 489538300, + 'img_id_str': '489538300', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 52872239, + 'img_id_str': '52872239', + 'title': '', + 'user_id': 2600543, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 230606434, + 'img_id_str': '230606434', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 642433959, + 'img_id_str': '642433959', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 369083520, + 'img_id_str': '369083520', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 482198929, + 'img_id_str': '482198929', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 482198929, + 'img_id_str': '482198929', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年12月25日', + 'post_id': 60962192, + 'published_at': '2019-12-25 16:12:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 9, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'sanyue015.tuchong.com', + 'followers': 13818, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2600543_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '叁月life', + 'site_id': '2600543', + 'type': 'user', + 'url': 'https://sanyue015.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2600543', + 'sites': [], + 'tags': ['Cosplay摄影集中地', '让摄影穿破次元壁', '高颜值女神聚集地', '图虫约拍圈子', '悦拍评片会', '人像'], + 'title': '#爱宕兔女郎 #写真 #约拍', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sanyue015.tuchong.com/60962192/', + 'views': 38814 + }, + { + 'author_id': '6656530', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 86, + 'content': '', + 'created_at': '2020-01-03 15:40:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '摄影机位探索', + '最满意的风光照', + '每人推荐一个旅行目的地', + '图虫旅行摄影圈子', + '极致风光摄影', + '光影者的风光摄影', + '中山大学摄影圈', + '一个风光摄影圈', + '直到世界的尽头', + '清华大学摄影圈' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1172, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 223003837, + 'img_id_str': '223003837', + 'title': '001', + 'user_id': 6656530, + 'width': 1250 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '74', + 'passed_time': '01月03日', + 'post_id': 61357000, + 'published_at': '2020-01-03 15:40:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 29, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 4861, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_6656530_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '远海视界', + 'site_id': '6656530', + 'type': 'user', + 'url': 'https://tuchong.com/6656530/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '6656530', + 'sites': [], + 'tags': [ + '摄影机位探索', + '最满意的风光照', + '每人推荐一个旅行目的地', + '图虫旅行摄影圈子', + '极致风光摄影', + '光影者的风光摄影' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/6656530/61357000/', + 'views': 21083 + }, + { + 'author_id': '2981258', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '上海音乐学院', + 'created_at': '2020-01-16 00:17:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '极致风光摄影', + '我要上开屏', + '风光摄影集', + '图虫城市建筑', + '带我看看,你的城市', + '华东理工大学摄影圈', + '绝不停止记录的2019', + '我要上“首页推荐位”', + '摄影机位探索' + ], + 'excerpt': '上海音乐学院', + 'favorite_list_prefix': [], + 'favorites': 31, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4024, + 'img_id': 307284082, + 'img_id_str': '307284082', + 'title': '001', + 'user_id': 2981258, + 'width': 6048 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月16日', + 'post_id': 61744600, + 'published_at': '2020-01-16 00:17:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 7097, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2981258_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'MaxWell_Z', + 'site_id': '2981258', + 'type': 'user', + 'url': 'https://tuchong.com/2981258/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2981258', + 'sites': [], + 'tags': ['极致风光摄影', '我要上开屏', '风光摄影集', '图虫城市建筑', '带我看看,你的城市', '华东理工大学摄影圈'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2981258/61744600/', + 'views': 776 + }, + { + 'author_id': '1366156', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': '', + 'created_at': '2019-12-04 19:01:28', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1188, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 563986825, + 'img_id_str': '563986825', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 458604479, + 'img_id_str': '458604479', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5093, + 'img_id': 385794641, + 'img_id_str': '385794641', + 'title': '001', + 'user_id': 1366156, + 'width': 3395 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 643941143, + 'img_id_str': '643941143', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 196198688, + 'img_id_str': '196198688', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 382320981, + 'img_id_str': '382320981', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 185319905, + 'img_id_str': '185319905', + 'title': '001', + 'user_id': 1366156, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '40', + 'passed_time': '2019年12月04日', + 'post_id': 59879188, + 'published_at': '2019-12-04 19:01:28', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 48, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1200, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1366156_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄影师辰子姐姐', + 'site_id': '1366156', + 'type': 'user', + 'url': 'https://tuchong.com/1366156/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1366156', + 'sites': [], + 'tags': [], + 'title': '疲倦的生活里,总有一些温柔的梦想', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1366156/59879188/', + 'views': 50196 + }, + { + 'author_id': '3557775', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': '对情绪的掌控仍然生涩的像一个新手/', + 'created_at': '2019-10-08 19:14:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我们都在孤独星球'], + 'excerpt': '对情绪的掌控仍然生涩的像一个新手/', + 'favorite_list_prefix': [], + 'favorites': 971, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2812, + 'img_id': 642559665, + 'img_id_str': '642559665', + 'title': '001', + 'user_id': 3557775, + 'width': 4680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 610119686, + 'img_id_str': '610119686', + 'title': '001', + 'user_id': 3557775, + 'width': 3179 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2847, + 'img_id': 502771888, + 'img_id_str': '502771888', + 'title': '001', + 'user_id': 3557775, + 'width': 4672 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 330674472, + 'img_id_str': '330674472', + 'title': '001', + 'user_id': 3557775, + 'width': 4680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 172797671, + 'img_id_str': '172797671', + 'title': '001', + 'user_id': 3557775, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 644395161, + 'img_id_str': '644395161', + 'title': '001', + 'user_id': 3557775, + 'width': 4680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 280146106, + 'img_id_str': '280146106', + 'title': '001', + 'user_id': 3557775, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2756, + 'img_id': 39366552, + 'img_id_str': '39366552', + 'title': '001', + 'user_id': 3557775, + 'width': 4680 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '33', + 'passed_time': '2019年10月08日', + 'post_id': 55260698, + 'published_at': '2019-10-08 19:14:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15706, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3557775_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '阮儿', + 'site_id': '3557775', + 'type': 'user', + 'url': 'https://tuchong.com/3557775/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3557775', + 'sites': [], + 'tags': ['我们都在孤独星球', '在室内', '房间', '女孩', '复古人像', '优雅'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3557775/55260698/', + 'views': 45489 + }, + { + 'author_id': '6698986', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 21, + 'content': '努力会上瘾,尤其在尝到了甜头之后。', + 'created_at': '2020-01-07 16:09:18', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '私密人像写真馆', + '有温度的人像', + '好色之图', + '暖色调人像', + '高颜值女神聚集地', + '人像爱好者', + '唯美人像摄影', + '写真人像摄影', + '分享神仙颜值' + ], + 'excerpt': '努力会上瘾,尤其在尝到了甜头之后。', + 'favorite_list_prefix': [], + 'favorites': 427, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 368885122, + 'img_id_str': '368885122', + 'title': '2563457', + 'user_id': 6698986, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3766, + 'img_id': 334872163, + 'img_id_str': '334872163', + 'title': '2563456', + 'user_id': 6698986, + 'width': 5660 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3622, + 'img_id': 399228775, + 'img_id_str': '399228775', + 'title': '2563454', + 'user_id': 6698986, + 'width': 5355 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3686, + 'img_id': 49135390, + 'img_id_str': '49135390', + 'title': '2569205', + 'user_id': 6698986, + 'width': 5529 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3407, + 'img_id': 541376283, + 'img_id_str': '541376283', + 'title': '2569207', + 'user_id': 6698986, + 'width': 5443 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '01月07日', + 'post_id': 61487820, + 'published_at': '2020-01-07 16:09:18', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '7', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12498, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_6698986_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '柠檬的宁', + 'site_id': '6698986', + 'type': 'user', + 'url': 'https://tuchong.com/6698986/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '6698986', + 'sites': [], + 'tags': ['私密人像写真馆', '有温度的人像', '好色之图', '暖色调人像', '高颜值女神聚集地', '人像爱好者'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/6698986/61487820/', + 'views': 46774 + }, + { + 'author_id': '998297', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 18, + 'content': '摄影/后期:@霂青衣', + 'created_at': '2019-09-18 22:30:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '摄影/后期:@霂青衣', + 'favorite_list_prefix': [], + 'favorites': 541, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 43689466, + 'img_id_str': '43689466', + 'title': '', + 'user_id': 998297, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 262055143, + 'img_id_str': '262055143', + 'title': '', + 'user_id': 998297, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 320578417, + 'img_id_str': '320578417', + 'title': '', + 'user_id': 998297, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 405710123, + 'img_id_str': '405710123', + 'title': '', + 'user_id': 998297, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 401712838, + 'img_id_str': '401712838', + 'title': '', + 'user_id': 998297, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 218867131, + 'img_id_str': '218867131', + 'title': '', + 'user_id': 998297, + 'width': 1067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 370255164, + 'img_id_str': '370255164', + 'title': '', + 'user_id': 998297, + 'width': 1067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 55485282, + 'img_id_str': '55485282', + 'title': '', + 'user_id': 998297, + 'width': 1067 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '17', + 'passed_time': '2019年09月18日', + 'post_id': 52953741, + 'published_at': '2019-09-18 22:30:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 43, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 9709, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_998297_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '霂青衣', + 'site_id': '998297', + 'type': 'user', + 'url': 'https://tuchong.com/998297/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '998297', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '形象照', 'OL'], + 'title': '形象照', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/998297/52953741/', + 'views': 19278 + }, + { + 'author_id': '14392565', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': '没有一朵花,从一开始就是花。\n也没有一朵花,最后以花结束。', + 'created_at': '2019-10-14 10:54:09', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地', '晒晒旅行打卡照', '暖色调人像', '日系集', '第三届京东摄影金像奖'], + 'excerpt': '没有一朵花,从一开始就是花。\n也没有一朵花,最后以花结束。', + 'favorite_list_prefix': [], + 'favorites': 1227, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4954, + 'img_id': 586003362, + 'img_id_str': '586003362', + 'title': '', + 'user_id': 14392565, + 'width': 3303 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 109228765, + 'img_id_str': '109228765', + 'title': '', + 'user_id': 14392565, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 142062116, + 'img_id_str': '142062116', + 'title': '', + 'user_id': 14392565, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2981, + 'img_id': 202813899, + 'img_id_str': '202813899', + 'title': '', + 'user_id': 14392565, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 585872667, + 'img_id_str': '585872667', + 'title': '', + 'user_id': 14392565, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 85701830, + 'img_id_str': '85701830', + 'title': '', + 'user_id': 14392565, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 263893259, + 'img_id_str': '263893259', + 'title': '', + 'user_id': 14392565, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5238, + 'img_id': 333951770, + 'img_id_str': '333951770', + 'title': '', + 'user_id': 14392565, + 'width': 3492 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5389, + 'img_id': 620605720, + 'img_id_str': '620605720', + 'title': '', + 'user_id': 14392565, + 'width': 3593 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4889, + 'img_id': 438940508, + 'img_id_str': '438940508', + 'title': '', + 'user_id': 14392565, + 'width': 3259 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 537506508, + 'img_id_str': '537506508', + 'title': '', + 'user_id': 14392565, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4916, + 'img_id': 217756215, + 'img_id_str': '217756215', + 'title': '', + 'user_id': 14392565, + 'width': 3277 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5351, + 'img_id': 351711606, + 'img_id_str': '351711606', + 'title': '', + 'user_id': 14392565, + 'width': 3568 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5260, + 'img_id': 332641393, + 'img_id_str': '332641393', + 'title': '', + 'user_id': 14392565, + 'width': 3506 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '39', + 'passed_time': '2019年10月14日', + 'post_id': 55860620, + 'published_at': '2019-10-14 10:54:09', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 50, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3268, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_14392565_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '是小汤圆喔', + 'site_id': '14392565', + 'type': 'user', + 'url': 'https://tuchong.com/14392565/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '14392565', + 'sites': [], + 'tags': ['高颜值女神聚集地', '晒晒旅行打卡照', '暖色调人像', '日系集', '第三届京东摄影金像奖', '人像'], + 'title': '「 解语 · 花 」', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/14392565/55860620/', + 'views': 37245 + }, + { + 'author_id': '5351023', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 45, + 'content': + '初冻的Minnewanka Lake — Banff 的Minnewanka 湖总是比其他的湖冻得晚些。初冻的湖边有很多的冰花和薄薄的冰层,湖水随风飘荡,冲击着时瘾时现的薄冰,晚霞后的蓝沁人心扉,让这寂静的湖畔充满了梦幻般的气息……', + 'created_at': '2019-12-28 11:16:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '天津摄影论坛', + '我们都爱黑白摄影', + '成都爬楼集团圈子', + '中国星空摄影圈子', + '星空小分队圈子', + '杭州风光圈子', + '清华大学摄影圈', + '重庆印象圈', + '神奇的慢门世界', + '光环摄影美学' + ], + 'excerpt': + '初冻的Minnewanka Lake — Banff 的Minnewanka 湖总是比其他的湖冻得晚些。初冻的湖边有很多的冰花和薄薄的冰层,湖水随风飘荡,冲击着时瘾时现的薄冰,晚霞后的蓝沁人心扉,让这寂静的湖畔充满了梦幻般的气息……', + 'favorite_list_prefix': [], + 'favorites': 184, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 853, + 'img_id': 48022540, + 'img_id_str': '48022540', + 'title': '001', + 'user_id': 5351023, + 'width': 1280 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年12月28日', + 'post_id': 61084424, + 'published_at': '2019-12-28 11:16:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 5, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 1015, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5351023_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '落基山逐光者', + 'site_id': '5351023', + 'type': 'user', + 'url': 'https://tuchong.com/5351023/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5351023', + 'sites': [], + 'tags': [ + '天津摄影论坛', + '我们都爱黑白摄影', + '成都爬楼集团圈子', + '中国星空摄影圈子', + '星空小分队圈子', + '杭州风光圈子' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5351023/61084424/', + 'views': 2931 + }, + { + 'author_id': '400799', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '', + 'created_at': '2020-01-06 18:13:16', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 39, + 'image_count': 82, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3776, + 'img_id': 397199144, + 'img_id_str': '397199144', + 'title': '', + 'user_id': 400799, + 'width': 3021 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3492, + 'img_id': 458278443, + 'img_id_str': '458278443', + 'title': '', + 'user_id': 400799, + 'width': 2794 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3645, + 'img_id': 441174212, + 'img_id_str': '441174212', + 'title': '', + 'user_id': 400799, + 'width': 2603 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3588, + 'img_id': 384485277, + 'img_id_str': '384485277', + 'title': '', + 'user_id': 400799, + 'width': 2870 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2419, + 'img_id': 476693913, + 'img_id_str': '476693913', + 'title': '', + 'user_id': 400799, + 'width': 1935 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1798, + 'img_id': 444254015, + 'img_id_str': '444254015', + 'title': '', + 'user_id': 400799, + 'width': 2517 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2483, + 'img_id': 309708369, + 'img_id_str': '309708369', + 'title': '', + 'user_id': 400799, + 'width': 1774 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 587318925, + 'img_id_str': '587318925', + 'title': '', + 'user_id': 400799, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2454, + 'img_id': 338086060, + 'img_id_str': '338086060', + 'title': '', + 'user_id': 400799, + 'width': 1753 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2526, + 'img_id': 291948293, + 'img_id_str': '291948293', + 'title': '', + 'user_id': 400799, + 'width': 1804 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2656, + 'img_id': 592364900, + 'img_id_str': '592364900', + 'title': '', + 'user_id': 400799, + 'width': 1897 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2367, + 'img_id': 443205086, + 'img_id_str': '443205086', + 'title': '', + 'user_id': 400799, + 'width': 1894 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2362, + 'img_id': 418826226, + 'img_id_str': '418826226', + 'title': '', + 'user_id': 400799, + 'width': 1687 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 464963283, + 'img_id_str': '464963283', + 'title': '', + 'user_id': 400799, + 'width': 1786 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2030, + 'img_id': 547342041, + 'img_id_str': '547342041', + 'title': '', + 'user_id': 400799, + 'width': 1624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2691, + 'img_id': 150717796, + 'img_id_str': '150717796', + 'title': '', + 'user_id': 400799, + 'width': 1922 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2450, + 'img_id': 607110833, + 'img_id_str': '607110833', + 'title': '', + 'user_id': 400799, + 'width': 1749 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3581, + 'img_id': 512476461, + 'img_id_str': '512476461', + 'title': '', + 'user_id': 400799, + 'width': 2865 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3673, + 'img_id': 488359038, + 'img_id_str': '488359038', + 'title': '', + 'user_id': 400799, + 'width': 2938 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2665, + 'img_id': 207996420, + 'img_id_str': '207996420', + 'title': '', + 'user_id': 400799, + 'width': 1904 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2697, + 'img_id': 403425583, + 'img_id_str': '403425583', + 'title': '', + 'user_id': 400799, + 'width': 1926 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2674, + 'img_id': 221038384, + 'img_id_str': '221038384', + 'title': '', + 'user_id': 400799, + 'width': 1909 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2722, + 'img_id': 297649340, + 'img_id_str': '297649340', + 'title': '', + 'user_id': 400799, + 'width': 1944 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2682, + 'img_id': 236504635, + 'img_id_str': '236504635', + 'title': '', + 'user_id': 400799, + 'width': 1915 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2683, + 'img_id': 610453101, + 'img_id_str': '610453101', + 'title': '', + 'user_id': 400799, + 'width': 1917 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2691, + 'img_id': 250856860, + 'img_id_str': '250856860', + 'title': '', + 'user_id': 400799, + 'width': 1922 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2681, + 'img_id': 112051243, + 'img_id_str': '112051243', + 'title': '', + 'user_id': 400799, + 'width': 1915 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1820, + 'img_id': 626312748, + 'img_id_str': '626312748', + 'title': '', + 'user_id': 400799, + 'width': 2548 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2701, + 'img_id': 172803161, + 'img_id_str': '172803161', + 'title': '', + 'user_id': 400799, + 'width': 1929 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2621, + 'img_id': 292800531, + 'img_id_str': '292800531', + 'title': '', + 'user_id': 400799, + 'width': 1872 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2657, + 'img_id': 612681155, + 'img_id_str': '612681155', + 'title': '', + 'user_id': 400799, + 'width': 1898 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1810, + 'img_id': 647349529, + 'img_id_str': '647349529', + 'title': '', + 'user_id': 400799, + 'width': 2534 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2596, + 'img_id': 400410407, + 'img_id_str': '400410407', + 'title': '', + 'user_id': 400799, + 'width': 1854 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2651, + 'img_id': 389335136, + 'img_id_str': '389335136', + 'title': '', + 'user_id': 400799, + 'width': 1894 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2716, + 'img_id': 227788200, + 'img_id_str': '227788200', + 'title': '', + 'user_id': 400799, + 'width': 1940 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1816, + 'img_id': 509855541, + 'img_id_str': '509855541', + 'title': '', + 'user_id': 400799, + 'width': 2542 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3788, + 'img_id': 633849652, + 'img_id_str': '633849652', + 'title': '', + 'user_id': 400799, + 'width': 3030 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1759, + 'img_id': 483378938, + 'img_id_str': '483378938', + 'title': '', + 'user_id': 400799, + 'width': 2462 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2701, + 'img_id': 197379815, + 'img_id_str': '197379815', + 'title': '', + 'user_id': 400799, + 'width': 1929 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2421, + 'img_id': 184338254, + 'img_id_str': '184338254', + 'title': '', + 'user_id': 400799, + 'width': 1937 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2701, + 'img_id': 455001108, + 'img_id_str': '455001108', + 'title': '', + 'user_id': 400799, + 'width': 1929 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1786, + 'img_id': 323471379, + 'img_id_str': '323471379', + 'title': '', + 'user_id': 400799, + 'width': 2500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2446, + 'img_id': 385664587, + 'img_id_str': '385664587', + 'title': '', + 'user_id': 400799, + 'width': 1747 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2630, + 'img_id': 644007516, + 'img_id_str': '644007516', + 'title': '', + 'user_id': 400799, + 'width': 1879 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2656, + 'img_id': 337299116, + 'img_id_str': '337299116', + 'title': '', + 'user_id': 400799, + 'width': 1897 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2750, + 'img_id': 135121161, + 'img_id_str': '135121161', + 'title': '', + 'user_id': 400799, + 'width': 1964 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2484, + 'img_id': 124241118, + 'img_id_str': '124241118', + 'title': '', + 'user_id': 400799, + 'width': 1774 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1841, + 'img_id': 210683644, + 'img_id_str': '210683644', + 'title': '', + 'user_id': 400799, + 'width': 2301 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2683, + 'img_id': 341165926, + 'img_id_str': '341165926', + 'title': '', + 'user_id': 400799, + 'width': 1915 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2609, + 'img_id': 111527452, + 'img_id_str': '111527452', + 'title': '', + 'user_id': 400799, + 'width': 1863 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2316, + 'img_id': 352241235, + 'img_id_str': '352241235', + 'title': '', + 'user_id': 400799, + 'width': 1853 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2739, + 'img_id': 551339662, + 'img_id_str': '551339662', + 'title': '', + 'user_id': 400799, + 'width': 1956 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2568, + 'img_id': 354404030, + 'img_id_str': '354404030', + 'title': '', + 'user_id': 400799, + 'width': 1834 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2422, + 'img_id': 636602071, + 'img_id_str': '636602071', + 'title': '', + 'user_id': 400799, + 'width': 1938 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1795, + 'img_id': 558811077, + 'img_id_str': '558811077', + 'title': '', + 'user_id': 400799, + 'width': 2513 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3591, + 'img_id': 130139852, + 'img_id_str': '130139852', + 'title': '', + 'user_id': 400799, + 'width': 2873 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3474, + 'img_id': 40224230, + 'img_id_str': '40224230', + 'title': '', + 'user_id': 400799, + 'width': 2779 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3591, + 'img_id': 242009839, + 'img_id_str': '242009839', + 'title': '', + 'user_id': 400799, + 'width': 2873 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2710, + 'img_id': 470992412, + 'img_id_str': '470992412', + 'title': '', + 'user_id': 400799, + 'width': 1936 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2722, + 'img_id': 62638022, + 'img_id_str': '62638022', + 'title': '', + 'user_id': 400799, + 'width': 1945 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1870, + 'img_id': 191939971, + 'img_id_str': '191939971', + 'title': '', + 'user_id': 400799, + 'width': 2618 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2685, + 'img_id': 538035809, + 'img_id_str': '538035809', + 'title': '', + 'user_id': 400799, + 'width': 1918 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2627, + 'img_id': 628344420, + 'img_id_str': '628344420', + 'title': '', + 'user_id': 400799, + 'width': 1876 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2664, + 'img_id': 56215276, + 'img_id_str': '56215276', + 'title': '', + 'user_id': 400799, + 'width': 1903 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2637, + 'img_id': 538232464, + 'img_id_str': '538232464', + 'title': '', + 'user_id': 400799, + 'width': 1884 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2651, + 'img_id': 395167512, + 'img_id_str': '395167512', + 'title': '', + 'user_id': 400799, + 'width': 1894 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2498, + 'img_id': 481478082, + 'img_id_str': '481478082', + 'title': '', + 'user_id': 400799, + 'width': 1784 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2653, + 'img_id': 628802784, + 'img_id_str': '628802784', + 'title': '', + 'user_id': 400799, + 'width': 1895 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2614, + 'img_id': 401393601, + 'img_id_str': '401393601', + 'title': '', + 'user_id': 400799, + 'width': 1867 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2687, + 'img_id': 74761691, + 'img_id_str': '74761691', + 'title': '', + 'user_id': 400799, + 'width': 1919 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2560, + 'img_id': 451003804, + 'img_id_str': '451003804', + 'title': '', + 'user_id': 400799, + 'width': 1829 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1781, + 'img_id': 424724213, + 'img_id_str': '424724213', + 'title': '', + 'user_id': 400799, + 'width': 2493 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2554, + 'img_id': 525059563, + 'img_id_str': '525059563', + 'title': '', + 'user_id': 400799, + 'width': 1825 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2650, + 'img_id': 644728507, + 'img_id_str': '644728507', + 'title': '', + 'user_id': 400799, + 'width': 1893 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2666, + 'img_id': 312002246, + 'img_id_str': '312002246', + 'title': '', + 'user_id': 400799, + 'width': 1904 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2649, + 'img_id': 129811994, + 'img_id_str': '129811994', + 'title': '', + 'user_id': 400799, + 'width': 1892 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2656, + 'img_id': 468567689, + 'img_id_str': '468567689', + 'title': '', + 'user_id': 400799, + 'width': 1897 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1923, + 'img_id': 605406847, + 'img_id_str': '605406847', + 'title': '', + 'user_id': 400799, + 'width': 2693 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2738, + 'img_id': 396150023, + 'img_id_str': '396150023', + 'title': '', + 'user_id': 400799, + 'width': 1956 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2745, + 'img_id': 341559197, + 'img_id_str': '341559197', + 'title': '', + 'user_id': 400799, + 'width': 1960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2643, + 'img_id': 95536630, + 'img_id_str': '95536630', + 'title': '', + 'user_id': 400799, + 'width': 1888 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2694, + 'img_id': 128173382, + 'img_id_str': '128173382', + 'title': '', + 'user_id': 400799, + 'width': 1924 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月06日', + 'post_id': 61458416, + 'published_at': '2020-01-06 18:13:16', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'baiyizhang.tuchong.com', + 'followers': 4888, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_400799_10', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '白一张', + 'site_id': '400799', + 'type': 'user', + 'url': 'https://baiyizhang.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '400799', + 'sites': [], + 'tags': ['人像', '色彩', '风光', '美女', '生活', '日系'], + 'title': 'Fall/Winter', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://baiyizhang.tuchong.com/61458416/', + 'views': 1816 + }, + { + 'author_id': '7771840', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '行走在城市中的恋人 记录瞬间', + 'created_at': '2019-12-29 21:38:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '行走在城市中的恋人 记录瞬间', + 'favorite_list_prefix': [], + 'favorites': 18, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 602981353, + 'img_id_str': '602981353', + 'title': '1479416', + 'user_id': 7771840, + 'width': 1701 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 345294272, + 'img_id_str': '345294272', + 'title': '1479417', + 'user_id': 7771840, + 'width': 1875 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 325174269, + 'img_id_str': '325174269', + 'title': '1479418', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 512542767, + 'img_id_str': '512542767', + 'title': '1479419', + 'user_id': 7771840, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 362923164, + 'img_id_str': '362923164', + 'title': '1479420', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 95667579, + 'img_id_str': '95667579', + 'title': '1479421', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1674, + 'img_id': 63947943, + 'img_id_str': '63947943', + 'title': '1479422', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 326944005, + 'img_id_str': '326944005', + 'title': '1479423', + 'user_id': 7771840, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1685, + 'img_id': 197248739, + 'img_id_str': '197248739', + 'title': '1479424', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 118998784, + 'img_id_str': '118998784', + 'title': '1479425', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1743, + 'img_id': 497403766, + 'img_id_str': '497403766', + 'title': '1479426', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 98682236, + 'img_id_str': '98682236', + 'title': '1479427', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 62244686, + 'img_id_str': '62244686', + 'title': '1479428', + 'user_id': 7771840, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 357091107, + 'img_id_str': '357091107', + 'title': '1479429', + 'user_id': 7771840, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '2019年12月29日', + 'post_id': 61157165, + 'published_at': '2019-12-29 21:38:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深婚礼婚纱摄影师', + 'domain': '', + 'followers': 1361, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_7771840_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师高登俊', + 'site_id': '7771840', + 'type': 'user', + 'url': 'https://tuchong.com/7771840/', + 'verification_list': [ + {'verification_reason': '资深婚礼婚纱摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '7771840', + 'sites': [], + 'tags': ['年轻', '旅行', '城市', '街拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/7771840/61157165/', + 'views': 906 + }, + { + 'author_id': '3939189', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2019-12-30 17:11:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['1SharePlus静物', '1252PHOTO', '我要上开屏', '拍拍好吃的', '图库热卖图:春'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 50, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2049, + 'img_id': 507233688, + 'img_id_str': '507233688', + 'title': '001', + 'user_id': 3939189, + 'width': 1366 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 471319780, + 'img_id_str': '471319780', + 'title': '001', + 'user_id': 3939189, + 'width': 1365 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1917, + 'img_id': 533185799, + 'img_id_str': '533185799', + 'title': '001', + 'user_id': 3939189, + 'width': 1278 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 448841033, + 'img_id_str': '448841033', + 'title': '001', + 'user_id': 3939189, + 'width': 1366 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月30日', + 'post_id': 61188859, + 'published_at': '2019-12-30 17:11:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深美食摄影师', + 'domain': '', + 'followers': 5554, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3939189_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Marzo27', + 'site_id': '3939189', + 'type': 'user', + 'url': 'https://tuchong.com/3939189/', + 'verification_list': [ + {'verification_reason': '资深美食摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3939189', + 'sites': [], + 'tags': ['1SharePlus静物', '1252PHOTO', '我要上开屏', '拍拍好吃的', '图库热卖图:春', '面条'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3939189/61188859/', + 'views': 1814 + }, + { + 'author_id': '3261912', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 88, + 'content': '赛博朋克重庆 鸿恩阁 夜景 雾都', + 'created_at': '2019-11-10 13:52:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫城市建筑'], + 'excerpt': '赛博朋克重庆 鸿恩阁 夜景 雾都', + 'favorite_list_prefix': [], + 'favorites': 1331, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5833, + 'img_id': 67812640, + 'img_id_str': '67812640', + 'title': '2007852', + 'user_id': 3261912, + 'width': 3889 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3889, + 'img_id': 256294309, + 'img_id_str': '256294309', + 'title': '2007846', + 'user_id': 3261912, + 'width': 5833 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '66', + 'passed_time': '2019年11月10日', + 'post_id': 58244993, + 'published_at': '2019-11-10 13:52:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 61, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 1385, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3261912_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '川包Vision', + 'site_id': '3261912', + 'type': 'user', + 'url': 'https://tuchong.com/3261912/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3261912', + 'sites': [], + 'tags': ['图虫城市建筑', '宝塔', '寺庙', '重庆', '夜晚'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3261912/58244993/', + 'views': 43823 + }, + { + 'author_id': '3994129', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 11, + 'content': 'Next Space', + 'created_at': '2020-01-14 09:04:19', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '摄影机位探索', + '我在西安拍照', + '极简主义摄影', + '西安摄影爱好者', + '陕西科技大学摄影圈', + '一起拍建筑', + '我们都是城市探险家', + '西安爬楼联盟圈子' + ], + 'excerpt': 'Next Space', + 'favorite_list_prefix': [], + 'favorites': 80, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 200525350, + 'img_id_str': '200525350', + 'title': '924235', + 'user_id': 3994129, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '01月14日', + 'post_id': 61692488, + 'published_at': '2020-01-14 09:04:19', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 3, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 1587, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3994129_12', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'DonyPhotography', + 'site_id': '3994129', + 'type': 'user', + 'url': 'https://tuchong.com/3994129/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3994129', + 'sites': [], + 'tags': ['摄影机位探索', '我在西安拍照', '极简主义摄影', '西安摄影爱好者', '陕西科技大学摄影圈', '一起拍建筑'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3994129/61692488/', + 'views': 1735 + }, + { + 'author_id': '451770', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 42, + 'content': + '如果一定要给2019做个总结的话,那么我的就是:\n@帅嘤嘤 和@ 保时捷\n\n2020年我们也要离开保时捷,离开这个熟悉的创作环境,离开那么多支持帮助我们的家人、朋友和同事了。\n\n我生活的那个小城市有太多值得留恋的地方,但我一直追求的不是安稳的生活,而是创作给我带来的那几分钟惊喜。2019下半年我基本没有拍创作,并非没有灵感,而是因为从构思到时候我就知道作品最终是啥样的,是什么水准的,会获得什么反响,所以想一想就行了不用拍了。不能带来惊喜的片子,都显得毫无意义。所以只能选择离开。\n\n很幸运的是,我靠着一堆猫片申请到了澳洲的摄影硕士,导师面试的时候说“我看你的片子都忍不住笑出声”。估计他也没见过拿猫来申请专业的人吧。\n\n后来家里人和同事都觉得我脑子秀逗了,读了两个研还要继续读第三个。不过我觉得,能跟着一流的艺术家磨练意识、探讨创作才是最有价值的事情。文凭归根结底只是一张纸而已。\n\n感谢帅帅愿意陪我再去南半球的岛上冒险,她是个很宅的人,怕虫,喜欢去的地方是日本,恋爱到结婚这么久,一直陪我住在一个四十平的出租屋,接下来还得陪我去土澳住更小的房间,跟袋鼠搏斗,跟苍蝇抢食,出门还得担心毒蜘蛛毒蝙蝠毒蜥蜴的袭击。接下来的两年,或许对她来说会更不容易吧。\n\n也感谢大家对我这个照相师傅的支持,明年我的作品和视频也会努力给大家带来一些惊喜的。', + 'created_at': '2020-01-01 15:02:04', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['对短发姑娘没有任何抵抗力!'], + 'excerpt': + '如果一定要给2019做个总结的话,那么我的就是:\n@帅嘤嘤 和@ 保时捷\n\n2020年我们也要离开保时捷,离开这个熟悉的创作环境,离开那么多支持帮助我们的家人、朋友和同事了。\n\n我生活的那个小城市有太多值得留恋的地方,但我一直追求的不是安稳的生活,而是创作给我带来的那几分钟惊喜。2019下半年我基本没有拍创作,并非没有灵感,而是因为从构思到时候我就知道作品最终是啥样的,是什么水准的,会获得什么反响,所以想一想就行了...', + 'favorite_list_prefix': [], + 'favorites': 885, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 900, + 'img_id': 235193859, + 'img_id_str': '235193859', + 'title': '001', + 'user_id': 451770, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1400, + 'img_id': 124765496, + 'img_id_str': '124765496', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 788, + 'img_id': 500313678, + 'img_id_str': '500313678', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1400, + 'img_id': 212888318, + 'img_id_str': '212888318', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1400, + 'img_id': 159172011, + 'img_id_str': '159172011', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1400, + 'img_id': 407185675, + 'img_id_str': '407185675', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 85247203, + 'img_id_str': '85247203', + 'title': '001', + 'user_id': 451770, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 354993273, + 'img_id_str': '354993273', + 'title': '001', + 'user_id': 451770, + 'width': 854 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1400, + 'img_id': 152280773, + 'img_id_str': '152280773', + 'title': '001', + 'user_id': 451770, + 'width': 1400 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '01月01日', + 'post_id': 61282535, + 'published_at': '2020-01-01 15:02:04', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 52, + 'site': { + 'description': '资深创意摄影师', + 'domain': '', + 'followers': 14243, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_451770_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Terry_F', + 'site_id': '451770', + 'type': 'user', + 'url': 'https://tuchong.com/451770/', + 'verification_list': [ + {'verification_reason': '资深创意摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '451770', + 'sites': [], + 'tags': ['对短发姑娘没有任何抵抗力!', '人像', '总结', '猫', '女神'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/451770/61282535/', + 'views': 44813 + }, + { + 'author_id': '958201', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': null, + 'created_at': '2019-12-24 09:59:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '拍瀑布的要点摘录:1.瀑布构图,一般用竖构图,但我更建议您现场横竖都比对一下;2.竖构图的时候,快装板下方的螺丝,一定要拧死,以防慢门长曝过程中,快装板松动,导致照片模糊;3.如果构图下方,是瀑布下的水面,那一定要有暗调的岩石、植物,来平衡构图重量;4.构图留有瀑布下方的水面,要用偏振镜滤除其多余反光;5.要想把瀑布拍出那种如丝般的感觉,快门速度一定要慢,用慢速快门记录水流或者光线的轨迹。把模式转盘到TV...', + 'favorite_list_prefix': [], + 'favorites': 16, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月24日', + 'post_id': 60905660, + 'published_at': '2019-12-24 09:59:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': 'Kase卡色滤镜官方图虫号', + 'domain': '', + 'followers': 1671, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_958201_14', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Kase卡色', + 'site_id': '958201', + 'type': 'user', + 'url': 'https://tuchong.com/958201/', + 'verification_list': [ + {'verification_reason': 'Kase卡色滤镜官方图虫号', 'verification_type': 11} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '958201', + 'sites': [], + 'tags': ['风光', '城市', '滤镜', '旅行'], + 'title': '【教程】手把手教您拍好瀑布流水', + 'title_image': { + 'width': 600, + 'height': 400, + 'url': 'https://tuchong.pstatp.com/958201/l/301319452.jpg' + }, + 'type': 'text', + 'update': false, + 'url': 'https://tuchong.com/958201/t/60905660/', + 'views': 984 + }, + { + 'author_id': '111634', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': '天灯节', + 'created_at': '2019-12-18 17:54:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '北京人像摄影', + '「行摄间」2组', + '魔都扫街', + '行摄部落', + '胶片人文和纪实交流', + '驚鴻·一眸', + '人文纪实手册', + '世界至色,缤纷无常', + '街头拍客', + '生于街头' + ], + 'excerpt': '天灯节', + 'favorite_list_prefix': [], + 'favorites': 171, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1648, + 'img_id': 410240105, + 'img_id_str': '410240105', + 'title': '298888', + 'user_id': 111634, + 'width': 2400 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年12月18日', + 'post_id': 60652765, + 'published_at': '2019-12-18 17:54:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 5, + 'site': { + 'description': '资深纪实摄影师', + 'domain': '', + 'followers': 18167, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_111634_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '雾里独自徘徊', + 'site_id': '111634', + 'type': 'user', + 'url': 'https://tuchong.com/111634/', + 'verification_list': [ + {'verification_reason': '资深纪实摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '111634', + 'sites': [], + 'tags': ['北京人像摄影', '「行摄间」2组', '魔都扫街', '行摄部落', '胶片人文和纪实交流', '驚鴻·一眸'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/111634/60652765/', + 'views': 3102 + }, + { + 'author_id': '6698986', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 9, + 'content': '清晨', + 'created_at': '2020-01-07 19:28:08', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '私密人像写真馆', + '有温度的人像', + '好色之图', + '暖色调人像', + '高颜值女神聚集地', + '写真人像摄影', + '分享神仙颜值', + '取景器里的小美好' + ], + 'excerpt': '清晨', + 'favorite_list_prefix': [], + 'favorites': 235, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 448316957, + 'img_id_str': '448316957', + 'title': '2743986', + 'user_id': 6698986, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 214550353, + 'img_id_str': '214550353', + 'title': '2743987', + 'user_id': 6698986, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3258, + 'img_id': 421447242, + 'img_id_str': '421447242', + 'title': '2743990', + 'user_id': 6698986, + 'width': 5093 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 506775070, + 'img_id_str': '506775070', + 'title': '2743989', + 'user_id': 6698986, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 347325925, + 'img_id_str': '347325925', + 'title': '2743988', + 'user_id': 6698986, + 'width': 5760 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '9', + 'passed_time': '01月07日', + 'post_id': 61493152, + 'published_at': '2020-01-07 19:28:08', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '3', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12498, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_6698986_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '柠檬的宁', + 'site_id': '6698986', + 'type': 'user', + 'url': 'https://tuchong.com/6698986/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '6698986', + 'sites': [], + 'tags': ['私密人像写真馆', '有温度的人像', '好色之图', '暖色调人像', '高颜值女神聚集地', '写真人像摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/6698986/61493152/', + 'views': 20191 + }, + { + 'author_id': '6698986', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 16, + 'content': '欢迎大家加入圈子: 私密人像写真馆', + 'created_at': '2020-01-07 15:52:00', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '私密人像写真馆', + '有温度的人像', + '好色之图', + '糖水人像小组', + '暖色调人像', + '高颜值女神聚集地', + '人像爱好者', + '唯美人像摄影', + '写真人像摄影', + '分享神仙颜值' + ], + 'excerpt': '欢迎大家加入圈子: 私密人像写真馆', + 'favorite_list_prefix': [], + 'favorites': 410, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 606979521, + 'img_id_str': '606979521', + 'title': '2730672', + 'user_id': 6698986, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3576, + 'img_id': 403293789, + 'img_id_str': '403293789', + 'title': '2730673', + 'user_id': 6698986, + 'width': 5214 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4217, + 'img_id': 654296348, + 'img_id_str': '654296348', + 'title': '2730671', + 'user_id': 6698986, + 'width': 2812 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5380, + 'img_id': 296207613, + 'img_id_str': '296207613', + 'title': '2730669', + 'user_id': 6698986, + 'width': 3586 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3191, + 'img_id': 479249658, + 'img_id_str': '479249658', + 'title': '2730668', + 'user_id': 6698986, + 'width': 4785 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '16', + 'passed_time': '01月07日', + 'post_id': 61487401, + 'published_at': '2020-01-07 15:52:00', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '8', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12498, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_6698986_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '柠檬的宁', + 'site_id': '6698986', + 'type': 'user', + 'url': 'https://tuchong.com/6698986/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '6698986', + 'sites': [], + 'tags': ['私密人像写真馆', '有温度的人像', '好色之图', '糖水人像小组', '暖色调人像', '高颜值女神聚集地'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/6698986/61487401/', + 'views': 33570 + }, + { + 'author_id': '1333118', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 33, + 'content': '', + 'created_at': '2019-10-10 18:06:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫封面你做主', '胶片集'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 545, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2706, + 'img_id': 36548714, + 'img_id_str': '36548714', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3538, + 'img_id': 638037960, + 'img_id_str': '638037960', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5010, + 'img_id': 85504887, + 'img_id_str': '85504887', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5412, + 'img_id': 654750010, + 'img_id_str': '654750010', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5010, + 'img_id': 397586770, + 'img_id_str': '397586770', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5236, + 'img_id': 44413374, + 'img_id_str': '44413374', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6097, + 'img_id': 66236668, + 'img_id_str': '66236668', + 'title': '001', + 'user_id': 1333118, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2695, + 'img_id': 301248759, + 'img_id_str': '301248759', + 'title': '001', + 'user_id': 1333118, + 'width': 1925 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1731, + 'img_id': 468365722, + 'img_id_str': '468365722', + 'title': '001', + 'user_id': 1333118, + 'width': 2423 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '33', + 'passed_time': '2019年10月10日', + 'post_id': 55482460, + 'published_at': '2019-10-10 18:06:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 35, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'kk-lee.tuchong.com', + 'followers': 4528, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1333118_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'KK-LEE', + 'site_id': '1333118', + 'type': 'user', + 'url': 'https://kk-lee.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1333118', + 'sites': [], + 'tags': ['图虫封面你做主', '胶片集', '女孩', '人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://kk-lee.tuchong.com/55482460/', + 'views': 58251 + }, + { + 'author_id': '484724', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 73, + 'content': '这一刻它们是自由的,我也是。', + 'created_at': '2019-09-26 10:25:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['第三届京东摄影金像奖'], + 'excerpt': '这一刻它们是自由的,我也是。', + 'favorite_list_prefix': [], + 'favorites': 1036, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 555067306, + 'img_id_str': '555067306', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 459909236, + 'img_id_str': '459909236', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 538159198, + 'img_id_str': '538159198', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2306, + 'img_id': 467117931, + 'img_id_str': '467117931', + 'title': '001', + 'user_id': 484724, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 314878430, + 'img_id_str': '314878430', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 169191388, + 'img_id_str': '169191388', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 479570082, + 'img_id_str': '479570082', + 'title': '001', + 'user_id': 484724, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 541370432, + 'img_id_str': '541370432', + 'title': '001', + 'user_id': 484724, + 'width': 3968 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2331, + 'img_id': 506511669, + 'img_id_str': '506511669', + 'title': '001', + 'user_id': 484724, + 'width': 3108 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '72', + 'passed_time': '2019年09月26日', + 'post_id': 53599767, + 'published_at': '2019-09-26 10:25:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 54, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4625, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_484724_32', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'ClouinKim', + 'site_id': '484724', + 'type': 'user', + 'url': 'https://tuchong.com/484724/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '484724', + 'sites': [], + 'tags': ['第三届京东摄影金像奖', 'JD最先锋'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/484724/53599767/', + 'views': 21848 + }, + { + 'author_id': '1193087', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 70, + 'content': '夏天的美少女\n\n你是我的一缕阳光', + 'created_at': '2019-08-18 15:39:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '夏天的美少女\n\n你是我的一缕阳光', + 'favorite_list_prefix': [], + 'favorites': 1482, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 611226376, + 'img_id_str': '611226376', + 'title': '154', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 584094153, + 'img_id_str': '584094153', + 'title': '159', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 307597987, + 'img_id_str': '307597987', + 'title': '156', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 471371981, + 'img_id_str': '471371981', + 'title': '158', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 328700522, + 'img_id_str': '328700522', + 'title': '153', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 644387669, + 'img_id_str': '644387669', + 'title': '152', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 439259843, + 'img_id_str': '439259843', + 'title': '157', + 'user_id': 1193087, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 611029657, + 'img_id_str': '611029657', + 'title': '155', + 'user_id': 1193087, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 469931111, + 'img_id_str': '469931111', + 'title': '160', + 'user_id': 1193087, + 'width': 3648 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '68', + 'passed_time': '2019年08月18日', + 'post_id': 49693874, + 'published_at': '2019-08-18 15:39:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 49, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4911, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1193087_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '拍照小师傅KK', + 'site_id': '1193087', + 'type': 'user', + 'url': 'https://tuchong.com/1193087/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1193087', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '小清新', '色彩', '校园'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1193087/49693874/', + 'views': 57930 + }, + { + 'author_id': '1182492', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 60, + 'content': '猫猫', + 'created_at': '2019-08-14 10:27:57', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '猫猫', + 'favorite_list_prefix': [], + 'favorites': 1457, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 381325548, + 'img_id_str': '381325548', + 'title': '001', + 'user_id': 1182492, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 528650039, + 'img_id_str': '528650039', + 'title': '001', + 'user_id': 1182492, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 145002274, + 'img_id_str': '145002274', + 'title': '001', + 'user_id': 1182492, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5019, + 'img_id': 287281209, + 'img_id_str': '287281209', + 'title': '001', + 'user_id': 1182492, + 'width': 2823 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 433622596, + 'img_id_str': '433622596', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 590450465, + 'img_id_str': '590450465', + 'title': '001', + 'user_id': 1182492, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 442994687, + 'img_id_str': '442994687', + 'title': '001', + 'user_id': 1182492, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 442535854, + 'img_id_str': '442535854', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 45649480, + 'img_id_str': '45649480', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '52', + 'passed_time': '2019年08月14日', + 'post_id': 49106052, + 'published_at': '2019-08-14 10:27:57', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 45, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 13242, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1182492_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'KINGVISION', + 'site_id': '1182492', + 'type': 'user', + 'url': 'https://tuchong.com/1182492/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1182492', + 'sites': [], + 'tags': ['分享神仙颜值', '体操服', '少女写真', '校园', '人像', '同济大学'], + 'title': '体操服少女', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1182492/49106052/', + 'views': 50783 + }, + { + 'author_id': '1591194', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 9, + 'content': '', + 'created_at': '2020-01-10 19:55:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '航拍玩家俱乐部', + '一起去拍城市天际线', + '图虫旅行摄影圈子', + '这张天空必须要分享', + '绝不停止记录的2019', + '我要上开屏', + '我要上“首页推荐位”', + '带我看看,你的城市', + '一起拍建筑' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 91, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5618, + 'img_id': 255051197, + 'img_id_str': '255051197', + 'title': '1226518', + 'user_id': 1591194, + 'width': 9586 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '01月10日', + 'post_id': 61585195, + 'published_at': '2020-01-10 19:55:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '', + 'domain': 'sutong0845.tuchong.com', + 'followers': 110, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1591194_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '金刚蛋儿', + 'site_id': '1591194', + 'type': 'user', + 'url': 'https://sutong0845.tuchong.com/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1591194', + 'sites': [], + 'tags': [ + '航拍玩家俱乐部', + '一起去拍城市天际线', + '图虫旅行摄影圈子', + '这张天空必须要分享', + '绝不停止记录的2019', + '我要上开屏' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sutong0845.tuchong.com/61585195/', + 'views': 1651 + }, + { + 'author_id': '14244906', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '新年伴手礼 奇趣曲奇', + 'created_at': '2020-01-05 17:49:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['生活小确幸', '静物美学', '拍拍好吃的', '生活太苦,吃点甜的'], + 'excerpt': '新年伴手礼 奇趣曲奇', + 'favorite_list_prefix': [], + 'favorites': 27, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 568444522, + 'img_id_str': '568444522', + 'title': '001', + 'user_id': 14244906, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 227001874, + 'img_id_str': '227001874', + 'title': '001', + 'user_id': 14244906, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 216450291, + 'img_id_str': '216450291', + 'title': '001', + 'user_id': 14244906, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月05日', + 'post_id': 61424205, + 'published_at': '2020-01-05 17:49:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深静物摄影师', + 'domain': '', + 'followers': 436, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_14244906_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '呆儿黄', + 'site_id': '14244906', + 'type': 'user', + 'url': 'https://tuchong.com/14244906/', + 'verification_list': [ + {'verification_reason': '资深静物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '14244906', + 'sites': [], + 'tags': ['生活小确幸', '静物美学', '拍拍好吃的', '生活太苦,吃点甜的', '曲奇', '烘焙'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/14244906/61424205/', + 'views': 1512 + }, + { + 'author_id': '2680080', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 31, + 'content': '紫禁城建成600年\n试着用电影的感觉拍了一次故宫\n小年快乐☁️', + 'created_at': '2020-01-17 10:58:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '北京自然风光小组', + '中国地理摄影', + '图虫旅行摄影圈子', + '风光摄影圈', + '环球旅行摄影', + '最满意的风光照', + '我要上“首页推荐位”', + '每人推荐一个旅行目的地', + '带我看看,你的城市', + '闪迪旅拍大赛', + '我离开,又回到了故土——记录故乡与他乡', + '第五届镜头中的中国年' + ], + 'excerpt': '紫禁城建成600年\n试着用电影的感觉拍了一次故宫\n小年快乐☁️', + 'favorite_list_prefix': [], + 'favorites': 182, + 'image_count': 36, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5337, + 'img_id': 319735463, + 'img_id_str': '319735463', + 'title': '001', + 'user_id': 2680080, + 'width': 9488 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5337, + 'img_id': 431474259, + 'img_id_str': '431474259', + 'title': '001', + 'user_id': 2680080, + 'width': 9488 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5267, + 'img_id': 144164450, + 'img_id_str': '144164450', + 'title': '001', + 'user_id': 2680080, + 'width': 9364 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5341, + 'img_id': 227133252, + 'img_id_str': '227133252', + 'title': '001', + 'user_id': 2680080, + 'width': 9496 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5346, + 'img_id': 373867776, + 'img_id_str': '373867776', + 'title': '001', + 'user_id': 2680080, + 'width': 9503 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5338, + 'img_id': 373343987, + 'img_id_str': '373343987', + 'title': '001', + 'user_id': 2680080, + 'width': 9490 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3004, + 'img_id': 129747021, + 'img_id_str': '129747021', + 'title': '001', + 'user_id': 2680080, + 'width': 5341 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4844, + 'img_id': 380028386, + 'img_id_str': '380028386', + 'title': '001', + 'user_id': 2680080, + 'width': 8612 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5346, + 'img_id': 391890629, + 'img_id_str': '391890629', + 'title': '001', + 'user_id': 2680080, + 'width': 9504 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4790, + 'img_id': 177522334, + 'img_id_str': '177522334', + 'title': '001', + 'user_id': 2680080, + 'width': 8514 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5344, + 'img_id': 65849308, + 'img_id_str': '65849308', + 'title': '001', + 'user_id': 2680080, + 'width': 9499 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6868, + 'img_id': 607241811, + 'img_id_str': '607241811', + 'title': '001', + 'user_id': 2680080, + 'width': 12211 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5339, + 'img_id': 404408636, + 'img_id_str': '404408636', + 'title': '001', + 'user_id': 2680080, + 'width': 9491 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5342, + 'img_id': 399754282, + 'img_id_str': '399754282', + 'title': '001', + 'user_id': 2680080, + 'width': 9496 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5239, + 'img_id': 76466014, + 'img_id_str': '76466014', + 'title': '001', + 'user_id': 2680080, + 'width': 9315 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5338, + 'img_id': 480299283, + 'img_id_str': '480299283', + 'title': '001', + 'user_id': 2680080, + 'width': 9491 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5342, + 'img_id': 53462970, + 'img_id_str': '53462970', + 'title': '001', + 'user_id': 2680080, + 'width': 9496 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4852, + 'img_id': 329565945, + 'img_id_str': '329565945', + 'title': '001', + 'user_id': 2680080, + 'width': 8626 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 106940446, + 'img_id_str': '106940446', + 'title': '001', + 'user_id': 2680080, + 'width': 8534 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4727, + 'img_id': 603244282, + 'img_id_str': '603244282', + 'title': '001', + 'user_id': 2680080, + 'width': 8403 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5218, + 'img_id': 350733645, + 'img_id_str': '350733645', + 'title': '001', + 'user_id': 2680080, + 'width': 9276 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5332, + 'img_id': 341624457, + 'img_id_str': '341624457', + 'title': '001', + 'user_id': 2680080, + 'width': 9480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5289, + 'img_id': 112182655, + 'img_id_str': '112182655', + 'title': '001', + 'user_id': 2680080, + 'width': 9403 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5232, + 'img_id': 410306034, + 'img_id_str': '410306034', + 'title': '001', + 'user_id': 2680080, + 'width': 9301 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5342, + 'img_id': 362137558, + 'img_id_str': '362137558', + 'title': '001', + 'user_id': 2680080, + 'width': 9497 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5335, + 'img_id': 435013429, + 'img_id_str': '435013429', + 'title': '001', + 'user_id': 2680080, + 'width': 9485 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5343, + 'img_id': 410568246, + 'img_id_str': '410568246', + 'title': '001', + 'user_id': 2680080, + 'width': 9498 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5349, + 'img_id': 552191618, + 'img_id_str': '552191618', + 'title': '001', + 'user_id': 2680080, + 'width': 9509 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4885, + 'img_id': 205965407, + 'img_id_str': '205965407', + 'title': '001', + 'user_id': 2680080, + 'width': 8685 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5345, + 'img_id': 538822312, + 'img_id_str': '538822312', + 'title': '001', + 'user_id': 2680080, + 'width': 9501 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 267175454, + 'img_id_str': '267175454', + 'title': '001', + 'user_id': 2680080, + 'width': 9493 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5219, + 'img_id': 383108927, + 'img_id_str': '383108927', + 'title': '001', + 'user_id': 2680080, + 'width': 9278 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5254, + 'img_id': 327338072, + 'img_id_str': '327338072', + 'title': '001', + 'user_id': 2680080, + 'width': 9340 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5342, + 'img_id': 341493202, + 'img_id_str': '341493202', + 'title': '001', + 'user_id': 2680080, + 'width': 9496 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5334, + 'img_id': 197576110, + 'img_id_str': '197576110', + 'title': '001', + 'user_id': 2680080, + 'width': 9483 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5338, + 'img_id': 412403587, + 'img_id_str': '412403587', + 'title': '001', + 'user_id': 2680080, + 'width': 9490 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '01月17日', + 'post_id': 61780318, + 'published_at': '2020-01-17 10:58:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '图虫图库销售达人', + 'domain': '', + 'followers': 4871, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2680080_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '北京豆包儿', + 'site_id': '2680080', + 'type': 'user', + 'url': 'https://tuchong.com/2680080/', + 'verification_list': [ + {'verification_reason': '图虫图库销售达人', 'verification_type': 14} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2680080', + 'sites': [], + 'tags': ['北京自然风光小组', '中国地理摄影', '图虫旅行摄影圈子', '风光摄影圈', '环球旅行摄影', '最满意的风光照'], + 'title': '紫禁城建成600年', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2680080/61780318/', + 'views': 5270 + }, + { + 'author_id': '363828', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 25, + 'content': '', + 'created_at': '2019-09-26 14:15:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 526, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 63154339, + 'img_id_str': '63154339', + 'title': '', + 'user_id': 363828, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 573941577, + 'img_id_str': '573941577', + 'title': '', + 'user_id': 363828, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 300853194, + 'img_id_str': '300853194', + 'title': '', + 'user_id': 363828, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 362653231, + 'img_id_str': '362653231', + 'title': '', + 'user_id': 363828, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 449226784, + 'img_id_str': '449226784', + 'title': '', + 'user_id': 363828, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 103392958, + 'img_id_str': '103392958', + 'title': '', + 'user_id': 363828, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 57518213, + 'img_id_str': '57518213', + 'title': '', + 'user_id': 363828, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '24', + 'passed_time': '2019年09月26日', + 'post_id': 53616046, + 'published_at': '2019-09-26 14:15:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '他注定是个低调的大侠,所以什么都懒的写', + 'domain': '', + 'followers': 5098, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_363828_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '麻叉', + 'site_id': '363828', + 'type': 'user', + 'url': 'https://tuchong.com/363828/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '363828', + 'sites': [], + 'tags': ['人像', '小清新', '美女', '少女', '腿', '美腿'], + 'title': '旗袍-目', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/363828/53616046/', + 'views': 28414 + }, + { + 'author_id': '1725860', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '杭州过客', + 'created_at': '2020-01-14 10:29:10', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['带我看看,你的城市', '我要上开屏', '每人推荐一个旅行目的地'], + 'excerpt': '杭州过客', + 'favorite_list_prefix': [], + 'favorites': 22, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 579913184, + 'img_id_str': '579913184', + 'title': '452198', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 64866259, + 'img_id_str': '64866259', + 'title': '458237', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 235783693, + 'img_id_str': '235783693', + 'title': '458235', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4640, + 'img_id': 619365863, + 'img_id_str': '619365863', + 'title': '452202', + 'user_id': 1725860, + 'width': 3712 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 350406603, + 'img_id_str': '350406603', + 'title': '452153', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 622708459, + 'img_id_str': '622708459', + 'title': '456574', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 286771282, + 'img_id_str': '286771282', + 'title': '452201', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 275105230, + 'img_id_str': '275105230', + 'title': '452200', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 216712438, + 'img_id_str': '216712438', + 'title': '458236', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5000, + 'img_id': 293652042, + 'img_id_str': '293652042', + 'title': '454949', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 261670952, + 'img_id_str': '261670952', + 'title': '454948', + 'user_id': 1725860, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 619234925, + 'img_id_str': '619234925', + 'title': '452154', + 'user_id': 1725860, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2864, + 'img_id': 204064203, + 'img_id_str': '204064203', + 'title': '458238', + 'user_id': 1725860, + 'width': 5092 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3375, + 'img_id': 183944975, + 'img_id_str': '183944975', + 'title': '452199', + 'user_id': 1725860, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月14日', + 'post_id': 61694529, + 'published_at': '2020-01-14 10:29:10', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深风光摄影师', + 'domain': 'dminor1996.tuchong.com', + 'followers': 1040, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1725860_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Dminor', + 'site_id': '1725860', + 'type': 'user', + 'url': 'https://dminor1996.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1725860', + 'sites': [], + 'tags': ['带我看看,你的城市', '我要上开屏', '每人推荐一个旅行目的地', '杭州', '城市', '旅行'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://dminor1996.tuchong.com/61694529/', + 'views': 1082 + }, + { + 'author_id': '11009227', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 53, + 'content': '霁雨', + 'created_at': '2019-11-23 10:38:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['对短发姑娘没有任何抵抗力!'], + 'excerpt': '霁雨', + 'favorite_list_prefix': [], + 'favorites': 877, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 610713130, + 'img_id_str': '610713130', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 586530602, + 'img_id_str': '586530602', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 378257441, + 'img_id_str': '378257441', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 69844971, + 'img_id_str': '69844971', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 367443839, + 'img_id_str': '367443839', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 131645462, + 'img_id_str': '131645462', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 418758721, + 'img_id_str': '418758721', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 310559092, + 'img_id_str': '310559092', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 51298605, + 'img_id_str': '51298605', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 374587351, + 'img_id_str': '374587351', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 438222671, + 'img_id_str': '438222671', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 249151157, + 'img_id_str': '249151157', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 532135415, + 'img_id_str': '532135415', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 283689398, + 'img_id_str': '283689398', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 234340570, + 'img_id_str': '234340570', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 43958540, + 'img_id_str': '43958540', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '50', + 'passed_time': '2019年11月23日', + 'post_id': 59127548, + 'published_at': '2019-11-23 10:38:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '15', + 'rqt_id': '', + 'shares': 55, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 9783, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_11009227_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '星野森', + 'site_id': '11009227', + 'type': 'user', + 'url': 'https://tuchong.com/11009227/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '11009227', + 'sites': [], + 'tags': ['对短发姑娘没有任何抵抗力!', '公园', '日系', '人像', '女孩', 'JK'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/11009227/59127548/', + 'views': 33807 + }, + { + 'author_id': '490904', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 24, + 'content': '夏天过去了', + 'created_at': '2019-10-21 12:06:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '高颜值女神聚集地', + '日系集', + '分享神仙颜值', + '人间四月天,找寻最美的你', + '人像爱好者', + '拍女友才是正经事' + ], + 'excerpt': '夏天过去了', + 'favorite_list_prefix': [], + 'favorites': 954, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 445752085, + 'img_id_str': '445752085', + 'title': '280472', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 541439336, + 'img_id_str': '541439336', + 'title': '280485', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 161002636, + 'img_id_str': '161002636', + 'title': '280483', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 316782234, + 'img_id_str': '316782234', + 'title': '280477', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 576238885, + 'img_id_str': '576238885', + 'title': '280473', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 399094728, + 'img_id_str': '399094728', + 'title': '280471', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 187671502, + 'img_id_str': '187671502', + 'title': '280467', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 526366126, + 'img_id_str': '526366126', + 'title': '280468', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 526169745, + 'img_id_str': '526169745', + 'title': '280470', + 'user_id': 490904, + 'width': 998 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '24', + 'passed_time': '2019年10月21日', + 'post_id': 56539579, + 'published_at': '2019-10-21 12:06:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12649, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_490904_8', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师CAT', + 'site_id': '490904', + 'type': 'user', + 'url': 'https://tuchong.com/490904/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '490904', + 'sites': [], + 'tags': [ + '高颜值女神聚集地', + '日系集', + '分享神仙颜值', + '人间四月天,找寻最美的你', + '人像爱好者', + '拍女友才是正经事' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/490904/56539579/', + 'views': 24764 + }, + { + 'author_id': '4518305', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 63, + 'content': + 'Sneak peak of a new aerial collection from the Highlands of Iceland I’m working on.\nMore images coming at the end of the week.\n\nThanks for watching.\nwww.marcograssiphotography', + 'created_at': '2019-12-19 03:30:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + 'Sneak peak of a new aerial collection from the Highlands of Iceland I’m working on.\nMore images coming at the end of the week.\n\nThanks for watching.\nwww.marcograssiphotography', + 'favorite_list_prefix': [], + 'favorites': 850, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 115263139, + 'img_id_str': '115263139', + 'title': '', + 'user_id': 4518305, + 'width': 2001 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '62', + 'passed_time': '2019年12月19日', + 'post_id': 60675265, + 'published_at': '2019-12-19 03:30:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 30, + 'site': { + 'description': '环球旅拍风光摄影师', + 'domain': '', + 'followers': 10557, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4518305_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'marcograssiphotography', + 'site_id': '4518305', + 'type': 'user', + 'url': 'https://tuchong.com/4518305/', + 'verification_list': [ + {'verification_reason': '环球旅拍风光摄影师', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4518305', + 'sites': [], + 'tags': ['Landscape', 'travel', '自然', 'Iceland', 'nature', 'phototour'], + 'title': 'Highlands of Iceland', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4518305/60675265/', + 'views': 12827 + }, + { + 'author_id': '2319253', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 69, + 'content': '?', + 'created_at': '2019-11-26 20:59:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['青岛圈子', '麦子儿童摄影课堂', '儿童摄影集', '有温度的人像'], + 'excerpt': '?', + 'favorite_list_prefix': [], + 'favorites': 1100, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 377995800, + 'img_id_str': '377995800', + 'title': '001', + 'user_id': 2319253, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 143049499, + 'img_id_str': '143049499', + 'title': '001', + 'user_id': 2319253, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 181387504, + 'img_id_str': '181387504', + 'title': '001', + 'user_id': 2319253, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 572112573, + 'img_id_str': '572112573', + 'title': '001', + 'user_id': 2319253, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 637191306, + 'img_id_str': '637191306', + 'title': '001', + 'user_id': 2319253, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 326483812, + 'img_id_str': '326483812', + 'title': '001', + 'user_id': 2319253, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 286441460, + 'img_id_str': '286441460', + 'title': '001', + 'user_id': 2319253, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 222084987, + 'img_id_str': '222084987', + 'title': '001', + 'user_id': 2319253, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 387104858, + 'img_id_str': '387104858', + 'title': '001', + 'user_id': 2319253, + 'width': 1500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '69', + 'passed_time': '2019年11月26日', + 'post_id': 59396370, + 'published_at': '2019-11-26 20:59:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 45, + 'site': { + 'description': '资深儿童摄影师', + 'domain': '', + 'followers': 18644, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2319253_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '麦子先森', + 'site_id': '2319253', + 'type': 'user', + 'url': 'https://tuchong.com/2319253/', + 'verification_list': [ + {'verification_reason': '资深儿童摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2319253', + 'sites': [], + 'tags': ['青岛圈子', '麦子儿童摄影课堂', '儿童摄影集', '有温度的人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2319253/59396370/', + 'views': 34964 + }, + { + 'author_id': '3919111', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 7, + 'content': + '2020年,萤火虫动漫音乐节,胶衣双马尾护士\n照片拍摄于琶洲保利世贸博物馆\n出镜:i御十二\n摄影:赵潮文\n后期:赵潮文\n设备:5d4,50定焦f1.2\n#摄影#', + 'created_at': '2020-01-04 09:02:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': + '2020年,萤火虫动漫音乐节,胶衣双马尾护士\n照片拍摄于琶洲保利世贸博物馆\n出镜:i御十二\n摄影:赵潮文\n后期:赵潮文\n设备:5d4,50定焦f1.2\n#摄影#', + 'favorite_list_prefix': [], + 'favorites': 50, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 342869805, + 'img_id_str': '342869805', + 'title': '203806', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 616089081, + 'img_id_str': '616089081', + 'title': '203807', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 216843608, + 'img_id_str': '216843608', + 'title': '203809', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 60016106, + 'img_id_str': '60016106', + 'title': '203808', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 331335167, + 'img_id_str': '331335167', + 'title': '203810', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 113493537, + 'img_id_str': '113493537', + 'title': '203805', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 152094236, + 'img_id_str': '152094236', + 'title': '203813', + 'user_id': 3919111, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 46056855, + 'img_id_str': '46056855', + 'title': '203812', + 'user_id': 3919111, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 549701122, + 'img_id_str': '549701122', + 'title': '203811', + 'user_id': 3919111, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '01月04日', + 'post_id': 61378749, + 'published_at': '2020-01-04 09:02:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '图虫签约摄影师,一位追梦路上的小哥哥!摄影约拍Q群:1021297879。', + 'domain': '', + 'followers': 362, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3919111_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '赵潮文CoCo', + 'site_id': '3919111', + 'type': 'user', + 'url': 'https://tuchong.com/3919111/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '3919111', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '美女', 'Cosplay', '二次元'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3919111/61378749/', + 'views': 4842 + }, + { + 'author_id': '2320813', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 6, + 'content': '明日方舟\n\n——\n\n凛冬', + 'created_at': '2020-01-10 08:37:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['富士Fujifilm圈子'], + 'excerpt': '明日方舟\n\n——\n\n凛冬', + 'favorite_list_prefix': [], + 'favorites': 119, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 54970287, + 'img_id_str': '54970287', + 'title': '550707', + 'user_id': 2320813, + 'width': 2880 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 635553289, + 'img_id_str': '635553289', + 'title': '550713', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 95077807, + 'img_id_str': '95077807', + 'title': '550711', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 302434183, + 'img_id_str': '302434183', + 'title': '550710', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 478528949, + 'img_id_str': '478528949', + 'title': '550709', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 96453845, + 'img_id_str': '96453845', + 'title': '550708', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 546096763, + 'img_id_str': '546096763', + 'title': '550714', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3414, + 'img_id': 124175893, + 'img_id_str': '124175893', + 'title': '550715', + 'user_id': 2320813, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 205899524, + 'img_id_str': '205899524', + 'title': '550705', + 'user_id': 2320813, + 'width': 1920 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '01月10日', + 'post_id': 61567831, + 'published_at': '2020-01-10 08:37:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 7, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 2790, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2320813_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Season685', + 'site_id': '2320813', + 'type': 'user', + 'url': 'https://tuchong.com/2320813/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2320813', + 'sites': [], + 'tags': ['富士Fujifilm圈子', '特效', 'cos', 'Cosplay', '广州漫展', '明日方舟'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2320813/61567831/', + 'views': 6264 + }, + { + 'author_id': '11009227', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 35, + 'content': '咩啊', + 'created_at': '2020-01-10 11:54:54', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['对短发姑娘没有任何抵抗力!'], + 'excerpt': '咩啊', + 'favorite_list_prefix': [], + 'favorites': 477, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 544983151, + 'img_id_str': '544983151', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 543344154, + 'img_id_str': '543344154', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 153339906, + 'img_id_str': '153339906', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 551077526, + 'img_id_str': '551077526', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2488, + 'img_id': 369936400, + 'img_id_str': '369936400', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 297256528, + 'img_id_str': '297256528', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 538363645, + 'img_id_str': '538363645', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 136628574, + 'img_id_str': '136628574', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 39896537, + 'img_id_str': '39896537', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 435865126, + 'img_id_str': '435865126', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 579978622, + 'img_id_str': '579978622', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 105694628, + 'img_id_str': '105694628', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 597149632, + 'img_id_str': '597149632', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '31', + 'passed_time': '01月10日', + 'post_id': 61572763, + 'published_at': '2020-01-10 11:54:54', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '10', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 9783, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_11009227_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '星野森', + 'site_id': '11009227', + 'type': 'user', + 'url': 'https://tuchong.com/11009227/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '11009227', + 'sites': [], + 'tags': ['对短发姑娘没有任何抵抗力!', '人像', '女孩', '街拍', 'JK', 'jk写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/11009227/61572763/', + 'views': 31395 + }, + { + 'author_id': '2600543', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '出境:@苏嫣嫣阿姨 \n后期:@苏嫣呐', + 'created_at': '2019-12-20 11:10:56', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '高颜值女神聚集地', + 'Cosplay摄影集中地', + '让摄影穿破次元壁', + '深大摄影交流群', + '图虫约拍圈子', + '飞图摄影学院评片会' + ], + 'excerpt': '出境:@苏嫣嫣阿姨 \n后期:@苏嫣呐', + 'favorite_list_prefix': [], + 'favorites': 225, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 626705241, + 'img_id_str': '626705241', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 92521753, + 'img_id_str': '92521753', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 568378899, + 'img_id_str': '568378899', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 188663079, + 'img_id_str': '188663079', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 642172217, + 'img_id_str': '642172217', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4672, + 'img_id': 475973411, + 'img_id_str': '475973411', + 'title': '', + 'user_id': 2600543, + 'width': 3503 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 521651278, + 'img_id_str': '521651278', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 56804397, + 'img_id_str': '56804397', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 546358489, + 'img_id_str': '546358489', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '2019年12月20日', + 'post_id': 60727218, + 'published_at': '2019-12-20 11:10:56', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 4, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'sanyue015.tuchong.com', + 'followers': 13818, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2600543_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '叁月life', + 'site_id': '2600543', + 'type': 'user', + 'url': 'https://sanyue015.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2600543', + 'sites': [], + 'tags': [ + '高颜值女神聚集地', + 'Cosplay摄影集中地', + '让摄影穿破次元壁', + '深大摄影交流群', + '图虫约拍圈子', + '飞图摄影学院评片会' + ], + 'title': '#王者荣耀 #圣诞 #貂蝉圣诞恋歌 #深圳约拍', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sanyue015.tuchong.com/60727218/', + 'views': 11607 + }, + { + 'author_id': '1953020', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2019-12-20 21:16:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 168, + 'image_count': 49, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 340641088, + 'img_id_str': '340641088', + 'title': '', + 'user_id': 1953020, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 274056323, + 'img_id_str': '274056323', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3780, + 'img_id': 499630956, + 'img_id_str': '499630956', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 505988437, + 'img_id_str': '505988437', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 432064026, + 'img_id_str': '432064026', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 216384895, + 'img_id_str': '216384895', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3668, + 'img_id': 75482017, + 'img_id_str': '75482017', + 'title': '', + 'user_id': 1953020, + 'width': 6521 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 162120591, + 'img_id_str': '162120591', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 529031760, + 'img_id_str': '529031760', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 195609852, + 'img_id_str': '195609852', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 242140618, + 'img_id_str': '242140618', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 102452553, + 'img_id_str': '102452553', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 322618654, + 'img_id_str': '322618654', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 591428097, + 'img_id_str': '591428097', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 490587279, + 'img_id_str': '490587279', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 106313040, + 'img_id_str': '106313040', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 171295669, + 'img_id_str': '171295669', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 142656367, + 'img_id_str': '142656367', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6025, + 'img_id': 529319105, + 'img_id_str': '529319105', + 'title': '', + 'user_id': 1953020, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 560841764, + 'img_id_str': '560841764', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 133645270, + 'img_id_str': '133645270', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3525, + 'img_id': 221937510, + 'img_id_str': '221937510', + 'title': '', + 'user_id': 1953020, + 'width': 6267 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3586, + 'img_id': 293258869, + 'img_id_str': '293258869', + 'title': '', + 'user_id': 1953020, + 'width': 6373 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4237, + 'img_id': 358532421, + 'img_id_str': '358532421', + 'title': '', + 'user_id': 1953020, + 'width': 6355 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 448372047, + 'img_id_str': '448372047', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3422, + 'img_id': 529122315, + 'img_id_str': '529122315', + 'title': '', + 'user_id': 1953020, + 'width': 6083 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 572310533, + 'img_id_str': '572310533', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3780, + 'img_id': 337298674, + 'img_id_str': '337298674', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 149209957, + 'img_id_str': '149209957', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 56804408, + 'img_id_str': '56804408', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 625657016, + 'img_id_str': '625657016', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 448447802, + 'img_id_str': '448447802', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 587379966, + 'img_id_str': '587379966', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4282, + 'img_id': 547013666, + 'img_id_str': '547013666', + 'title': '', + 'user_id': 1953020, + 'width': 6424 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 311543186, + 'img_id_str': '311543186', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 401916992, + 'img_id_str': '401916992', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 183158125, + 'img_id_str': '183158125', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 448381903, + 'img_id_str': '448381903', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 480494802, + 'img_id_str': '480494802', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3780, + 'img_id': 182764972, + 'img_id_str': '182764972', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 282314107, + 'img_id_str': '282314107', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 220579107, + 'img_id_str': '220579107', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 127321728, + 'img_id_str': '127321728', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5403, + 'img_id': 167757034, + 'img_id_str': '167757034', + 'title': '', + 'user_id': 1953020, + 'width': 3602 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 503301216, + 'img_id_str': '503301216', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 78037741, + 'img_id_str': '78037741', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3780, + 'img_id': 621528085, + 'img_id_str': '621528085', + 'title': '', + 'user_id': 1953020, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 581420617, + 'img_id_str': '581420617', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 472565139, + 'img_id_str': '472565139', + 'title': '', + 'user_id': 1953020, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月20日', + 'post_id': 60750302, + 'published_at': '2019-12-20 21:16:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 3, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1974, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1953020_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '三咩咩', + 'site_id': '1953020', + 'type': 'user', + 'url': 'https://tuchong.com/1953020/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1953020', + 'sites': [], + 'tags': ['2019你最满意的照片', '人像', '美女', '汉服', '古风', '佳能'], + 'title': '我的2019', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1953020/60750302/', + 'views': 5707 + }, + { + 'author_id': '1515046', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '大理旅拍|\n\n山朝我们走来,将夕阳放在你的发梢。', + 'created_at': '2020-01-09 16:32:16', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['人像爱好者'], + 'excerpt': '大理旅拍|\n\n山朝我们走来,将夕阳放在你的发梢。', + 'favorite_list_prefix': [], + 'favorites': 30, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 61654866, + 'img_id_str': '61654866', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 489473778, + 'img_id_str': '489473778', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 281724551, + 'img_id_str': '281724551', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 67028441, + 'img_id_str': '67028441', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 558220861, + 'img_id_str': '558220861', + 'title': '001', + 'user_id': 1515046, + 'width': 1688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1181, + 'img_id': 645842691, + 'img_id_str': '645842691', + 'title': '001', + 'user_id': 1515046, + 'width': 665 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 498648894, + 'img_id_str': '498648894', + 'title': '001', + 'user_id': 1515046, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 577160774, + 'img_id_str': '577160774', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 361023396, + 'img_id_str': '361023396', + 'title': '001', + 'user_id': 1515046, + 'width': 844 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月09日', + 'post_id': 61549663, + 'published_at': '2020-01-09 16:32:16', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深婚礼婚纱摄影师', + 'domain': '', + 'followers': 1089, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1515046_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '25号底片摄影工作室', + 'site_id': '1515046', + 'type': 'user', + 'url': 'https://tuchong.com/1515046/', + 'verification_list': [ + {'verification_reason': '资深婚礼婚纱摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1515046', + 'sites': [], + 'tags': ['人像爱好者', '爱', '婚纱', '旅拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1515046/61549663/', + 'views': 1793 + }, + { + 'author_id': '3787347', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '年代', + 'created_at': '2020-01-07 13:45:50', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '长沙人像写真', + '我要上“首页推荐位”', + '儿童摄影集', + '胶片人像摄影', + '谁还没点童年黑照', + '分享神仙颜值', + '暖色调人像', + '河北摄影圈', + '高颜值女神聚集地' + ], + 'excerpt': '年代', + 'favorite_list_prefix': [], + 'favorites': 49, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 490126961, + 'img_id_str': '490126961', + 'title': '1602186', + 'user_id': 3787347, + 'width': 1800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月07日', + 'post_id': 61484310, + 'published_at': '2020-01-07 13:45:50', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深儿童摄影师', + 'domain': '', + 'followers': 3899, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3787347_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '儿童摄影师灰太狼', + 'site_id': '3787347', + 'type': 'user', + 'url': 'https://tuchong.com/3787347/', + 'verification_list': [ + {'verification_reason': '资深儿童摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3787347', + 'sites': [], + 'tags': ['长沙人像写真', '我要上“首页推荐位”', '儿童摄影集', '胶片人像摄影', '谁还没点童年黑照', '分享神仙颜值'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3787347/61484310/', + 'views': 1983 + }, + { + 'author_id': '15957016', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2020-01-20 08:48:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['生活小确幸'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 7, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 110479286, + 'img_id_str': '110479286', + 'title': '239168', + 'user_id': 15957016, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 615, + 'img_id': 64931519, + 'img_id_str': '64931519', + 'title': '4365', + 'user_id': 15957016, + 'width': 740 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 300468383, + 'img_id_str': '300468383', + 'title': '5772', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2592, + 'img_id': 103663110, + 'img_id_str': '103663110', + 'title': '5567', + 'user_id': 15957016, + 'width': 4608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2592, + 'img_id': 472893406, + 'img_id_str': '472893406', + 'title': '5469', + 'user_id': 15957016, + 'width': 4608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 531744212, + 'img_id_str': '531744212', + 'title': '4990', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 119326369, + 'img_id_str': '119326369', + 'title': '4986', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 562874035, + 'img_id_str': '562874035', + 'title': '4776', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 61655027, + 'img_id_str': '61655027', + 'title': '4768', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2592, + 'img_id': 173656159, + 'img_id_str': '173656159', + 'title': '4725', + 'user_id': 15957016, + 'width': 4608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 417056399, + 'img_id_str': '417056399', + 'title': '4726', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2592, + 'img_id': 615040544, + 'img_id_str': '615040544', + 'title': '4719', + 'user_id': 15957016, + 'width': 4608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 476038554, + 'img_id_str': '476038554', + 'title': '4661', + 'user_id': 15957016, + 'width': 2592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 212125603, + 'img_id_str': '212125603', + 'title': '4631', + 'user_id': 15957016, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 358074513, + 'img_id_str': '358074513', + 'title': '5820', + 'user_id': 15957016, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 582338108, + 'img_id_str': '582338108', + 'title': '5506', + 'user_id': 15957016, + 'width': 900 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '8小时前', + 'post_id': 61858782, + 'published_at': '2020-01-20 08:48:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 8, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15957016_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'MM245211', + 'site_id': '15957016', + 'type': 'user', + 'url': 'https://tuchong.com/15957016/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15957016', + 'sites': [], + 'tags': ['生活小确幸', '房子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15957016/61858782/', + 'views': 361 + }, + { + 'author_id': '15960591', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '美的不是太阳,是光,是影,是人', + 'created_at': '2020-01-19 22:37:32', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['夕阳捕手'], + 'excerpt': '美的不是太阳,是光,是影,是人', + 'favorite_list_prefix': [], + 'favorites': 8, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2773, + 'img_id': 484427604, + 'img_id_str': '484427604', + 'title': '837888', + 'user_id': 15960591, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 427018134, + 'img_id_str': '427018134', + 'title': '748739', + 'user_id': 15960591, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 595839056, + 'img_id_str': '595839056', + 'title': '724998', + 'user_id': 15960591, + 'width': 3120 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '19小时前', + 'post_id': 61850552, + 'published_at': '2020-01-19 22:37:32', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 2, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15960591_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '清秋却惊寒', + 'site_id': '15960591', + 'type': 'user', + 'url': 'https://tuchong.com/15960591/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15960591', + 'sites': [], + 'tags': ['夕阳捕手'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15960591/61850552/', + 'views': 458 + }, + { + 'author_id': '15960226', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2020-01-19 21:49:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['广州摄影圈'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 10, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3829, + 'img_id': 172280218, + 'img_id_str': '172280218', + 'title': '001', + 'user_id': 15960226, + 'width': 5744 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3699, + 'img_id': 302172196, + 'img_id_str': '302172196', + 'title': '001', + 'user_id': 15960226, + 'width': 5549 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5761, + 'img_id': 389335332, + 'img_id_str': '389335332', + 'title': '001', + 'user_id': 15960226, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '19小时前', + 'post_id': 61849117, + 'published_at': '2020-01-19 21:49:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 2, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15960226_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'garyXC', + 'site_id': '15960226', + 'type': 'user', + 'url': 'https://tuchong.com/15960226/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15960226', + 'sites': [], + 'tags': ['广州摄影圈', '索尼a6400'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15960226/61849117/', + 'views': 360 + }, + { + 'author_id': '15939785', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '🏮小年里的前门·夕阳将落,华灯初上。', + 'created_at': '2020-01-19 20:46:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '带我看看,你的城市', + '拿起手机人人都是摄影师', + '中国手机摄影', + '生活小确幸', + '我用手机修照片', + '火烛一花精品摄影' + ], + 'excerpt': '🏮小年里的前门·夕阳将落,华灯初上。', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 210748996, + 'img_id_str': '210748996', + 'title': '001', + 'user_id': 15939785, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3425, + 'img_id': 347981454, + 'img_id_str': '347981454', + 'title': '001', + 'user_id': 15939785, + 'width': 2569 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 577160915, + 'img_id_str': '577160915', + 'title': '001', + 'user_id': 15939785, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 115590958, + 'img_id_str': '115590958', + 'title': '001', + 'user_id': 15939785, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 529451170, + 'img_id_str': '529451170', + 'title': '001', + 'user_id': 15939785, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3459, + 'img_id': 508675832, + 'img_id_str': '508675832', + 'title': '001', + 'user_id': 15939785, + 'width': 2173 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 100189501, + 'img_id_str': '100189501', + 'title': '001', + 'user_id': 15939785, + 'width': 2309 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3819, + 'img_id': 293193506, + 'img_id_str': '293193506', + 'title': '001', + 'user_id': 15939785, + 'width': 2268 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3653, + 'img_id': 37144476, + 'img_id_str': '37144476', + 'title': '001', + 'user_id': 15939785, + 'width': 2268 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3740, + 'img_id': 453887529, + 'img_id_str': '453887529', + 'title': '001', + 'user_id': 15939785, + 'width': 2268 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3643, + 'img_id': 326027388, + 'img_id_str': '326027388', + 'title': '001', + 'user_id': 15939785, + 'width': 2268 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 287360962, + 'img_id_str': '287360962', + 'title': '001', + 'user_id': 15939785, + 'width': 2268 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '20小时前', + 'post_id': 61847117, + 'published_at': '2020-01-19 20:46:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 10, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15939785_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '王力宏de手绘', + 'site_id': '15939785', + 'type': 'user', + 'url': 'https://tuchong.com/15939785/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15939785', + 'sites': [], + 'tags': [ + '带我看看,你的城市', + '拿起手机人人都是摄影师', + '中国手机摄影', + '生活小确幸', + '我用手机修照片', + '火烛一花精品摄影' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15939785/61847117/', + 'views': 700 + }, + { + 'author_id': '15959170', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '宋城旧照', + 'created_at': '2020-01-19 20:04:33', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我们都爱黑白摄影'], + 'excerpt': '宋城旧照', + 'favorite_list_prefix': [], + 'favorites': 10, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 117426494, + 'img_id_str': '117426494', + 'title': '1021874', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 583517796, + 'img_id_str': '583517796', + 'title': '1021875', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 149997005, + 'img_id_str': '149997005', + 'title': '1021876', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 72403030, + 'img_id_str': '72403030', + 'title': '1021877', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 424003381, + 'img_id_str': '424003381', + 'title': '1021878', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 601147093, + 'img_id_str': '601147093', + 'title': '1021879', + 'user_id': 15959170, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3120, + 'img_id': 609928818, + 'img_id_str': '609928818', + 'title': '1021880', + 'user_id': 15959170, + 'width': 4160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '21小时前', + 'post_id': 61846021, + 'published_at': '2020-01-19 20:04:33', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 2, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15959170_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '初夏夜未泯', + 'site_id': '15959170', + 'type': 'user', + 'url': 'https://tuchong.com/15959170/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15959170', + 'sites': [], + 'tags': ['我们都爱黑白摄影', '街道', '黑白'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15959170/61846021/', + 'views': 338 + }, + { + 'author_id': '13483557', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '', + 'created_at': '2020-01-19 17:40:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['火烛一花精品摄影'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 240371730, + 'img_id_str': '240371730', + 'title': '1268999', + 'user_id': 13483557, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 549111565, + 'img_id_str': '549111565', + 'title': '2031828', + 'user_id': 13483557, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3456, + 'img_id': 244762691, + 'img_id_str': '244762691', + 'title': '1892638', + 'user_id': 13483557, + 'width': 4608 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月19日', + 'post_id': 61842611, + 'published_at': '2020-01-19 17:40:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 2, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_13483557_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '叶子何时', + 'site_id': '13483557', + 'type': 'user', + 'url': 'https://tuchong.com/13483557/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '13483557', + 'sites': [], + 'tags': ['火烛一花精品摄影', '绽放', '莲花', '池塘', '花'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/13483557/61842611/', + 'views': 458 + }, + { + 'author_id': '15958327', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '常记花亭日暮,水光山色无数。斜阳满沙渚,何来渔舟可渡。且住,且住,惊散游鱼无数。\n\n——如梦令·花亭湖', + 'created_at': '2020-01-19 16:40:07', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['安徽省摄影家俱乐部'], + 'excerpt': '常记花亭日暮,水光山色无数。斜阳满沙渚,何来渔舟可渡。且住,且住,惊散游鱼无数。\n\n——如梦令·花亭湖', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2227, + 'img_id': 471518019, + 'img_id_str': '471518019', + 'title': '001', + 'user_id': 15958327, + 'width': 3242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2448, + 'img_id': 247252427, + 'img_id_str': '247252427', + 'title': '001', + 'user_id': 15958327, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 216123475, + 'img_id_str': '216123475', + 'title': '001', + 'user_id': 15958327, + 'width': 2448 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月19日', + 'post_id': 61841098, + 'published_at': '2020-01-19 16:40:07', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 6, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15958327_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '唐怀瑾', + 'site_id': '15958327', + 'type': 'user', + 'url': 'https://tuchong.com/15958327/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15958327', + 'sites': [], + 'tags': ['安徽省摄影家俱乐部'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15958327/61841098/', + 'views': 633 + }, + { + 'author_id': '15948666', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '扫街', + 'created_at': '2020-01-19 16:14:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['风光摄影圈', '带我看看,你的城市', '一个风光小组ONE'], + 'excerpt': '扫街', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 224839324, + 'img_id_str': '224839324', + 'title': '1706218', + 'user_id': 15948666, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 310363619, + 'img_id_str': '310363619', + 'title': '1706226', + 'user_id': 15948666, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3651, + 'img_id': 356632463, + 'img_id_str': '356632463', + 'title': '1706227', + 'user_id': 15948666, + 'width': 5477 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 265406934, + 'img_id_str': '265406934', + 'title': '1706228', + 'user_id': 15948666, + 'width': 3651 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61840507, + 'published_at': '2020-01-19 16:14:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '', + 'domain': '', + 'followers': 3, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15948666_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '自由落体551', + 'site_id': '15948666', + 'type': 'user', + 'url': 'https://tuchong.com/15948666/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15948666', + 'sites': [], + 'tags': ['风光摄影圈', '带我看看,你的城市', '一个风光小组ONE'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15948666/61840507/', + 'views': 340 + }, + { + 'author_id': '15943121', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2020-01-19 13:46:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['街拍俱乐部圈子'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3024, + 'img_id': 571065802, + 'img_id_str': '571065802', + 'title': '001', + 'user_id': 15943121, + 'width': 4032 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61837294, + 'published_at': '2020-01-19 13:46:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '做自己不喜欢的事 怎么会快乐呢', + 'domain': '', + 'followers': 5, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15943121_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '快快啊', + 'site_id': '15943121', + 'type': 'user', + 'url': 'https://tuchong.com/15943121/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15943121', + 'sites': [], + 'tags': ['街拍俱乐部圈子', '复古'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15943121/61837294/', + 'views': 630 + }, + { + 'author_id': '15955064', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '燃烧的☁️', + 'created_at': '2020-01-19 13:14:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['带我看看,你的城市', '这张天空必须要分享', '我们都是城市探险家', '光影者的风光摄影'], + 'excerpt': '燃烧的☁️', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 249677215, + 'img_id_str': '249677215', + 'title': '57642', + 'user_id': 15955064, + 'width': 2133 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 241878906, + 'img_id_str': '241878906', + 'title': '57643', + 'user_id': 15955064, + 'width': 2133 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61836583, + 'published_at': '2020-01-19 13:14:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 6, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15955064_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '不会照相的瑞仔', + 'site_id': '15955064', + 'type': 'user', + 'url': 'https://tuchong.com/15955064/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15955064', + 'sites': [], + 'tags': ['带我看看,你的城市', '这张天空必须要分享', '我们都是城市探险家', '光影者的风光摄影', '天空'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15955064/61836583/', + 'views': 538 + }, + { + 'author_id': '15945305', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '说不明的感觉。只能说这个感觉、这个角度、很心水、就拍下了。', + 'created_at': '2020-01-19 11:57:08', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['一起去拍城市天际线'], + 'excerpt': '说不明的感觉。只能说这个感觉、这个角度、很心水、就拍下了。', + 'favorite_list_prefix': [], + 'favorites': 11, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3456, + 'img_id': 225953919, + 'img_id_str': '225953919', + 'title': '74277', + 'user_id': 15945305, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2176, + 'img_id': 53659602, + 'img_id_str': '53659602', + 'title': '74278', + 'user_id': 15945305, + 'width': 4608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 491636280, + 'img_id_str': '491636280', + 'title': '74276', + 'user_id': 15945305, + 'width': 2176 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61835127, + 'published_at': '2020-01-19 11:57:08', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 6, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15945305_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '莫名用户', + 'site_id': '15945305', + 'type': 'user', + 'url': 'https://tuchong.com/15945305/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15945305', + 'sites': [], + 'tags': ['一起去拍城市天际线', '禅宗', '寺庙'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15945305/61835127/', + 'views': 565 + }, + { + 'author_id': '15956920', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '', + 'created_at': '2020-01-19 11:49:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['度假就要去海滩'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 166512201, + 'img_id_str': '166512201', + 'title': '001', + 'user_id': 15956920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 463324971, + 'img_id_str': '463324971', + 'title': '001', + 'user_id': 15956920, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月19日', + 'post_id': 61834985, + 'published_at': '2020-01-19 11:49:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 7, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15956920_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '方荣华', + 'site_id': '15956920', + 'type': 'user', + 'url': 'https://tuchong.com/15956920/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15956920', + 'sites': [], + 'tags': ['度假就要去海滩', '黎明'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15956920/61834985/', + 'views': 566 + }, + { + 'author_id': '15954097', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '军魂永驻', + 'created_at': '2020-01-18 20:58:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['最满意的风光照'], + 'excerpt': '军魂永驻', + 'favorite_list_prefix': [], + 'favorites': 16, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 502384401, + 'img_id_str': '502384401', + 'title': '001', + 'user_id': 15954097, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 366790353, + 'img_id_str': '366790353', + 'title': '001', + 'user_id': 15954097, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61820979, + 'published_at': '2020-01-18 20:58:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '只为就下那一瞬间~', + 'domain': '', + 'followers': 12, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15954097_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Rendering143', + 'site_id': '15954097', + 'type': 'user', + 'url': 'https://tuchong.com/15954097/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15954097', + 'sites': [], + 'tags': ['最满意的风光照', '背光', '天空', '太阳', '军人'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15954097/61820979/', + 'views': 704 + }, + { + 'author_id': '15950662', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '雪后#济南*大明湖', + 'created_at': '2020-01-18 14:16:31', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '中国手机摄影', + '拿起手机人人都是摄影师', + '手机摄影小分队', + '取景器里的小美好', + '华为摄影爱好者', + '带我看看,你的城市' + ], + 'excerpt': '雪后#济南*大明湖', + 'favorite_list_prefix': [], + 'favorites': 17, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 176605134, + 'img_id_str': '176605134', + 'title': '399488', + 'user_id': 15950662, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 33736528, + 'img_id_str': '33736528', + 'title': '399506', + 'user_id': 15950662, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1392, + 'img_id': 487114222, + 'img_id_str': '487114222', + 'title': '399493', + 'user_id': 15950662, + 'width': 1716 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 147506822, + 'img_id_str': '147506822', + 'title': '399490', + 'user_id': 15950662, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 92784607, + 'img_id_str': '92784607', + 'title': '399498', + 'user_id': 15950662, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 193447737, + 'img_id_str': '193447737', + 'title': '399489', + 'user_id': 15950662, + 'width': 2160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61811702, + 'published_at': '2020-01-18 14:16:31', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '用镜头记录生活中的每一个美好瞬间~', + 'domain': '', + 'followers': 8, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15950662_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '小晓雅', + 'site_id': '15950662', + 'type': 'user', + 'url': 'https://tuchong.com/15950662/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15950662', + 'sites': [], + 'tags': [ + '中国手机摄影', + '拿起手机人人都是摄影师', + '手机摄影小分队', + '取景器里的小美好', + '华为摄影爱好者', + '带我看看,你的城市' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15950662/61811702/', + 'views': 547 + }, + { + 'author_id': '1781920', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 54, + 'content': '秋の思绪', + 'created_at': '2019-10-03 00:11:38', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '武汉日系摄影师联盟', + '写真人像摄影', + '暖色调人像', + '日系集', + '人像摄影集', + '我们都爱日系摄影', + '分享神仙颜值', + '我要上开屏', + '糖水人像小组' + ], + 'excerpt': '秋の思绪', + 'favorite_list_prefix': [], + 'favorites': 638, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2879, + 'img_id': 473476209, + 'img_id_str': '473476209', + 'title': '1613968', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 395422808, + 'img_id_str': '395422808', + 'title': '1613958', + 'user_id': 1781920, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 345353172, + 'img_id_str': '345353172', + 'title': '1613960', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 43691277, + 'img_id_str': '43691277', + 'title': '1613957', + 'user_id': 1781920, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 581807127, + 'img_id_str': '581807127', + 'title': '1613959', + 'user_id': 1781920, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 278440499, + 'img_id_str': '278440499', + 'title': '1613956', + 'user_id': 1781920, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 540846970, + 'img_id_str': '540846970', + 'title': '1613962', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 74033694, + 'img_id_str': '74033694', + 'title': '1613769', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 91990873, + 'img_id_str': '91990873', + 'title': '1613764', + 'user_id': 1781920, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 560508417, + 'img_id_str': '560508417', + 'title': '1613765', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 90942438, + 'img_id_str': '90942438', + 'title': '1613771', + 'user_id': 1781920, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 604155042, + 'img_id_str': '604155042', + 'title': '1613971', + 'user_id': 1781920, + 'width': 1920 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '29', + 'passed_time': '2019年10月03日', + 'post_id': 54352347, + 'published_at': '2019-10-03 00:11:38', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 25, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3650, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1781920_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '背相机的大熊', + 'site_id': '1781920', + 'type': 'user', + 'url': 'https://tuchong.com/1781920/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1781920', + 'sites': [], + 'tags': ['武汉日系摄影师联盟', '写真人像摄影', '暖色调人像', '日系集', '人像摄影集', '我们都爱日系摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1781920/54352347/', + 'views': 21322 + }, + { + 'author_id': '15948588', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '科技之光', + 'created_at': '2020-01-19 15:28:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['中国手机摄影'], + 'excerpt': '科技之光', + 'favorite_list_prefix': [], + 'favorites': 9, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4351, + 'img_id': 522766401, + 'img_id_str': '522766401', + 'title': '923543', + 'user_id': 15948588, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61839461, + 'published_at': '2020-01-19 15:28:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '鲜花、美酒、美人,而我只喜欢你', + 'domain': '', + 'followers': 5, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15948588_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '朝夏与酒', + 'site_id': '15948588', + 'type': 'user', + 'url': 'https://tuchong.com/15948588/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15948588', + 'sites': [], + 'tags': ['中国手机摄影', '技术', '科学'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15948588/61839461/', + 'views': 454 + }, + { + 'author_id': '1417872', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '今天拍摄效率高,晚上要给自己加鸡腿~~', + 'created_at': '2019-12-26 18:20:20', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '1SharePlus静物', + '1252PHOTO', + '我要上开屏', + '生活小确幸', + '绝不停止记录的2019', + '我要上“首页推荐位”', + '拍拍好吃的' + ], + 'excerpt': '今天拍摄效率高,晚上要给自己加鸡腿~~', + 'favorite_list_prefix': [], + 'favorites': 50, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 118933078, + 'img_id_str': '118933078', + 'title': '001', + 'user_id': 1417872, + 'width': 1800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月26日', + 'post_id': 61001930, + 'published_at': '2019-12-26 18:20:20', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '2018“伯奇杯”中国创意摄影展入围摄影师', + 'domain': '', + 'followers': 33249, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1417872_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'KURAKO雅岚', + 'site_id': '1417872', + 'type': 'user', + 'url': 'https://tuchong.com/1417872/', + 'verification_list': [ + { + 'verification_reason': '2018“伯奇杯”中国创意摄影展入围摄影师', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1417872', + 'sites': [], + 'tags': [ + '1SharePlus静物', + '1252PHOTO', + '我要上开屏', + '生活小确幸', + '绝不停止记录的2019', + '我要上“首页推荐位”' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1417872/61001930/', + 'views': 2187 + }, + { + 'author_id': '15112973', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '', + 'created_at': '2019-12-19 09:53:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上“首页推荐位”'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 29, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 737, + 'img_id': 501269233, + 'img_id_str': '501269233', + 'title': '001', + 'user_id': 15112973, + 'width': 533 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 53724163, + 'img_id_str': '53724163', + 'title': '001', + 'user_id': 15112973, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 737, + 'img_id': 467190906, + 'img_id_str': '467190906', + 'title': '001', + 'user_id': 15112973, + 'width': 533 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 129614698, + 'img_id_str': '129614698', + 'title': '001', + 'user_id': 15112973, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 737, + 'img_id': 515884111, + 'img_id_str': '515884111', + 'title': '001', + 'user_id': 15112973, + 'width': 533 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 620610379, + 'img_id_str': '620610379', + 'title': '001', + 'user_id': 15112973, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月19日', + 'post_id': 60680609, + 'published_at': '2019-12-19 09:53:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深美食摄影师', + 'domain': '', + 'followers': 819, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15112973_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '北京美食摄影师龙一', + 'site_id': '15112973', + 'type': 'user', + 'url': 'https://tuchong.com/15112973/', + 'verification_list': [ + {'verification_reason': '资深美食摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '15112973', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '美味的', '早餐', '菜谱摄影', '美食', '食物'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15112973/60680609/', + 'views': 1783 + }, + { + 'author_id': '4811813', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '你的模样', + 'created_at': '2019-12-19 19:09:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '你的模样', + 'favorite_list_prefix': [], + 'favorites': 64, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1075, + 'img_id': 568180878, + 'img_id_str': '568180878', + 'title': '001', + 'user_id': 4811813, + 'width': 1613 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月19日', + 'post_id': 60701066, + 'published_at': '2019-12-19 19:09:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2089, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4811813_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '超子Max', + 'site_id': '4811813', + 'type': 'user', + 'url': 'https://tuchong.com/4811813/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4811813', + 'sites': [], + 'tags': ['分享神仙颜值', '比基尼泳装', '性感的', '美丽', '时尚', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4811813/60701066/', + 'views': 3351 + }, + { + 'author_id': '3028265', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 35, + 'content': 'An ode to the Black Forest.', + 'created_at': '2019-12-18 21:53:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '做人要低调,摄影也是', + '约拍馆摄影作品投稿', + '我要上“首页推荐位”', + '绝不停止记录的2019', + '高品人像摄影', + '人像爱好者', + '人像摄影集', + '暖色调人像', + '有温度的人像', + '人像写真摄影约拍' + ], + 'excerpt': 'An ode to the Black Forest.', + 'favorite_list_prefix': [], + 'favorites': 427, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2190, + 'img_id': 200262710, + 'img_id_str': '200262710', + 'title': '2610968', + 'user_id': 3028265, + 'width': 1549 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2306, + 'img_id': 243909661, + 'img_id_str': '243909661', + 'title': '2610967', + 'user_id': 3028265, + 'width': 1615 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2317, + 'img_id': 475644948, + 'img_id_str': '475644948', + 'title': '2610966', + 'user_id': 3028265, + 'width': 1605 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1350, + 'img_id': 236635167, + 'img_id_str': '236635167', + 'title': '2610951', + 'user_id': 3028265, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2287, + 'img_id': 149472242, + 'img_id_str': '149472242', + 'title': '2610946', + 'user_id': 3028265, + 'width': 1608 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '29', + 'passed_time': '2019年12月18日', + 'post_id': 60664715, + 'published_at': '2019-12-18 21:53:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 20, + 'site': { + 'description': '资深儿童摄影师', + 'domain': '', + 'followers': 3301, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3028265_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'CICIVisualStudio', + 'site_id': '3028265', + 'type': 'user', + 'url': 'https://tuchong.com/3028265/', + 'verification_list': [ + {'verification_reason': '资深儿童摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3028265', + 'sites': [], + 'tags': [ + '做人要低调,摄影也是', + '约拍馆摄影作品投稿', + '我要上“首页推荐位”', + '绝不停止记录的2019', + '高品人像摄影', + '人像爱好者' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3028265/60664715/', + 'views': 26644 + }, + { + 'author_id': '7547729', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '小窗风定曲肱眠,骨冷魂清梦易圆。 蝴蝶不飞花自落,海棠枝下月娟娟。', + 'created_at': '2019-12-18 18:03:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['成都人像爱好者', '成都约拍圈子', '古装摄影圈子', '古风摄影研习社', '周末好时光'], + 'excerpt': '小窗风定曲肱眠,骨冷魂清梦易圆。 蝴蝶不飞花自落,海棠枝下月娟娟。', + 'favorite_list_prefix': [], + 'favorites': 55, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3675, + 'img_id': 94683657, + 'img_id_str': '94683657', + 'title': '001', + 'user_id': 7547729, + 'width': 5512 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5461, + 'img_id': 358073837, + 'img_id_str': '358073837', + 'title': '001', + 'user_id': 7547729, + 'width': 3641 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 197117068, + 'img_id_str': '197117068', + 'title': '001', + 'user_id': 7547729, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 415352435, + 'img_id_str': '415352435', + 'title': '001', + 'user_id': 7547729, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3753, + 'img_id': 471777985, + 'img_id_str': '471777985', + 'title': '001', + 'user_id': 7547729, + 'width': 5630 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 433439594, + 'img_id_str': '433439594', + 'title': '001', + 'user_id': 7547729, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 393200542, + 'img_id_str': '393200542', + 'title': '001', + 'user_id': 7547729, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 196724326, + 'img_id_str': '196724326', + 'title': '001', + 'user_id': 7547729, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3322, + 'img_id': 395560533, + 'img_id_str': '395560533', + 'title': '001', + 'user_id': 7547729, + 'width': 4983 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3456, + 'img_id': 614188098, + 'img_id_str': '614188098', + 'title': '001', + 'user_id': 7547729, + 'width': 5184 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '2019年12月18日', + 'post_id': 60653137, + 'published_at': '2019-12-18 18:03:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 225, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_7547729_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '影青竹', + 'site_id': '7547729', + 'type': 'user', + 'url': 'https://tuchong.com/7547729/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '7547729', + 'sites': [], + 'tags': ['成都人像爱好者', '成都约拍圈子', '古装摄影圈子', '古风摄影研习社', '周末好时光', '夜景人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/7547729/60653137/', + 'views': 2497 + }, + { + 'author_id': '1807584', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 14, + 'content': '', + 'created_at': '2019-09-10 22:22:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 305, + 'image_count': 20, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 376414690, + 'img_id_str': '376414690', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 45850557, + 'img_id_str': '45850557', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 653500743, + 'img_id_str': '653500743', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3222, + 'img_id': 424714551, + 'img_id_str': '424714551', + 'title': '', + 'user_id': 1807584, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 447848916, + 'img_id_str': '447848916', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 180855163, + 'img_id_str': '180855163', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3166, + 'img_id': 410493653, + 'img_id_str': '410493653', + 'title': '', + 'user_id': 1807584, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 508928402, + 'img_id_str': '508928402', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 400597006, + 'img_id_str': '400597006', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 326213832, + 'img_id_str': '326213832', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 383492477, + 'img_id_str': '383492477', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 622567997, + 'img_id_str': '622567997', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 241934344, + 'img_id_str': '241934344', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 122200063, + 'img_id_str': '122200063', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 81633881, + 'img_id_str': '81633881', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 283287648, + 'img_id_str': '283287648', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 343515014, + 'img_id_str': '343515014', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 213230066, + 'img_id_str': '213230066', + 'title': '', + 'user_id': 1807584, + 'width': 2238 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 134127631, + 'img_id_str': '134127631', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 563650898, + 'img_id_str': '563650898', + 'title': '', + 'user_id': 1807584, + 'width': 2244 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '13', + 'passed_time': '2019年09月10日', + 'post_id': 52220392, + 'published_at': '2019-09-10 22:22:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 5, + 'site': { + 'description': '独立摄影师,参与「夏日短歌——图虫·OPEN MUJI摄影俳句展」', + 'domain': 'huenjs.tuchong.com', + 'followers': 5458, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1807584_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'huenjs', + 'site_id': '1807584', + 'type': 'user', + 'url': 'https://huenjs.tuchong.com/', + 'verification_list': [ + { + 'verification_reason': '独立摄影师,参与「夏日短歌——图虫·OPEN MUJI摄影俳句展」', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1807584', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '黑白', '胶片', '写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://huenjs.tuchong.com/52220392/', + 'views': 18261 + }, + { + 'author_id': '15957053', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '', + 'created_at': '2020-01-19 15:00:38', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['街拍纪实手册'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3456, + 'img_id': 235783765, + 'img_id_str': '235783765', + 'title': '001', + 'user_id': 15957053, + 'width': 5184 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3447, + 'img_id': 323798105, + 'img_id_str': '323798105', + 'title': '001', + 'user_id': 15957053, + 'width': 5170 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月19日', + 'post_id': 61838797, + 'published_at': '2020-01-19 15:00:38', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 3, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15957053_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '謝十玖', + 'site_id': '15957053', + 'type': 'user', + 'url': 'https://tuchong.com/15957053/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15957053', + 'sites': [], + 'tags': ['街拍纪实手册', '街道'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15957053/61838797/', + 'views': 507 + }, + { + 'author_id': '15956647', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '去年夏天的果子🎈', + 'created_at': '2020-01-19 10:57:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['静物美学'], + 'excerpt': '去年夏天的果子🎈', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 494716969, + 'img_id_str': '494716969', + 'title': '1164033', + 'user_id': 15956647, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61833802, + 'published_at': '2020-01-19 10:57:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 4, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15956647_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '州上洲', + 'site_id': '15956647', + 'type': 'user', + 'url': 'https://tuchong.com/15956647/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15956647', + 'sites': [], + 'tags': ['静物美学', '植物', '果实', '手机'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15956647/61833802/', + 'views': 607 + }, + { + 'author_id': '15942917', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 6, + 'content': '您的秋季女孩~', + 'created_at': '2020-01-18 14:15:53', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['有温度的人像', '我们都爱日系摄影', '分享神仙颜值', '拍女友才是正经事'], + 'excerpt': '您的秋季女孩~', + 'favorite_list_prefix': [], + 'favorites': 16, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5999, + 'img_id': 198559218, + 'img_id_str': '198559218', + 'title': '610790', + 'user_id': 15942917, + 'width': 3368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5193, + 'img_id': 314230368, + 'img_id_str': '314230368', + 'title': '610772', + 'user_id': 15942917, + 'width': 3368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5999, + 'img_id': 256231330, + 'img_id_str': '256231330', + 'title': '610792', + 'user_id': 15942917, + 'width': 3368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2843, + 'img_id': 246204204, + 'img_id_str': '246204204', + 'title': '610773', + 'user_id': 15942917, + 'width': 1899 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3368, + 'img_id': 265734004, + 'img_id_str': '265734004', + 'title': '610774', + 'user_id': 15942917, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3368, + 'img_id': 152684305, + 'img_id_str': '152684305', + 'title': '610776', + 'user_id': 15942917, + 'width': 5341 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5999, + 'img_id': 76269269, + 'img_id_str': '76269269', + 'title': '610777', + 'user_id': 15942917, + 'width': 3368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3368, + 'img_id': 324912920, + 'img_id_str': '324912920', + 'title': '610775', + 'user_id': 15942917, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2944, + 'img_id': 96978733, + 'img_id_str': '96978733', + 'title': '610778', + 'user_id': 15942917, + 'width': 1684 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3368, + 'img_id': 357811989, + 'img_id_str': '357811989', + 'title': '610819', + 'user_id': 15942917, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月18日', + 'post_id': 61811689, + 'published_at': '2020-01-18 14:15:53', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '微博 @没有摄影师\n扩列 Q3053379019', + 'domain': '', + 'followers': 8, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15942917_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '没有摄影师', + 'site_id': '15942917', + 'type': 'user', + 'url': 'https://tuchong.com/15942917/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15942917', + 'sites': [], + 'tags': ['有温度的人像', '我们都爱日系摄影', '分享神仙颜值', '拍女友才是正经事'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15942917/61811689/', + 'views': 624 + }, + { + 'author_id': '15663082', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2019-12-18 09:10:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '图虫旅行摄影圈子', + '街拍俱乐部圈子', + '人文纪实手册', + '带我看看,你的城市', + '人文天下', + '我们都是城市探险家', + '图虫城市建筑', + '街拍纪实手册' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 38, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 339133721, + 'img_id_str': '339133721', + 'title': '193765', + 'user_id': 15663082, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 81773880, + 'img_id_str': '81773880', + 'title': '193772', + 'user_id': 15663082, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月18日', + 'post_id': 60631146, + 'published_at': '2019-12-18 09:10:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '多多指教!', + 'domain': '', + 'followers': 81, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15663082_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Kanvz_Pat', + 'site_id': '15663082', + 'type': 'user', + 'url': 'https://tuchong.com/15663082/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15663082', + 'sites': [], + 'tags': [ + '图虫旅行摄影圈子', + '街拍俱乐部圈子', + '人文纪实手册', + '带我看看,你的城市', + '人文天下', + '我们都是城市探险家' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15663082/60631146/', + 'views': 1897 + }, + { + 'author_id': '2661037', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 62, + 'content': '', + 'created_at': '2019-10-12 01:18:19', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['新的一天,新的卡点'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1605, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4320, + 'img_id': 625128012, + 'img_id_str': '625128012', + 'title': '', + 'user_id': 2661037, + 'width': 2880 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4500, + 'img_id': 541961989, + 'img_id_str': '541961989', + 'title': '', + 'user_id': 2661037, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4500, + 'img_id': 333689303, + 'img_id_str': '333689303', + 'title': '', + 'user_id': 2661037, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4174, + 'img_id': 86225289, + 'img_id_str': '86225289', + 'title': '', + 'user_id': 2661037, + 'width': 2782 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 533115720, + 'img_id_str': '533115720', + 'title': '', + 'user_id': 2661037, + 'width': 4500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 493203723, + 'img_id_str': '493203723', + 'title': '', + 'user_id': 2661037, + 'width': 4500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4500, + 'img_id': 581284058, + 'img_id_str': '581284058', + 'title': '', + 'user_id': 2661037, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 640856745, + 'img_id_str': '640856745', + 'title': '', + 'user_id': 2661037, + 'width': 4500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4500, + 'img_id': 102871371, + 'img_id_str': '102871371', + 'title': '', + 'user_id': 2661037, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 86094868, + 'img_id_str': '86094868', + 'title': '', + 'user_id': 2661037, + 'width': 4500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '60', + 'passed_time': '2019年10月12日', + 'post_id': 55629324, + 'published_at': '2019-10-12 01:18:19', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 46, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'tarcyjia.tuchong.com', + 'followers': 15341, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2661037_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'TarcyJia', + 'site_id': '2661037', + 'type': 'user', + 'url': 'https://tarcyjia.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2661037', + 'sites': [], + 'tags': ['新的一天,新的卡点', '人像', '少女', '胶片', '写真', '摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tarcyjia.tuchong.com/55629324/', + 'views': 54236 + }, + { + 'author_id': '6948206', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '〔十二月〕', + 'created_at': '2019-12-16 19:46:35', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '〔十二月〕', + 'favorite_list_prefix': [], + 'favorites': 33, + 'image_count': 19, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4714, + 'img_id': 190104561, + 'img_id_str': '190104561', + 'title': '', + 'user_id': 6948206, + 'width': 3142 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3936, + 'img_id': 397526251, + 'img_id_str': '397526251', + 'title': '', + 'user_id': 6948206, + 'width': 2624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 200197155, + 'img_id_str': '200197155', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2624, + 'img_id': 202359384, + 'img_id_str': '202359384', + 'title': '', + 'user_id': 6948206, + 'width': 3936 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3936, + 'img_id': 497403354, + 'img_id_str': '497403354', + 'title': '', + 'user_id': 6948206, + 'width': 2624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4500, + 'img_id': 89048201, + 'img_id_str': '89048201', + 'title': '', + 'user_id': 6948206, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 438485612, + 'img_id_str': '438485612', + 'title': '', + 'user_id': 6948206, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5679, + 'img_id': 359057308, + 'img_id_str': '359057308', + 'title': '', + 'user_id': 6948206, + 'width': 3786 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3936, + 'img_id': 376947623, + 'img_id_str': '376947623', + 'title': '', + 'user_id': 6948206, + 'width': 2624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 521978952, + 'img_id_str': '521978952', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 642499684, + 'img_id_str': '642499684', + 'title': '', + 'user_id': 6948206, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 56672956, + 'img_id_str': '56672956', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 429573181, + 'img_id_str': '429573181', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3936, + 'img_id': 425706356, + 'img_id_str': '425706356', + 'title': '', + 'user_id': 6948206, + 'width': 2624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 79217589, + 'img_id_str': '79217589', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 364168161, + 'img_id_str': '364168161', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5100, + 'img_id': 432194737, + 'img_id_str': '432194737', + 'title': '', + 'user_id': 6948206, + 'width': 3400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 562021417, + 'img_id_str': '562021417', + 'title': '', + 'user_id': 6948206, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2269, + 'img_id': 394249240, + 'img_id_str': '394249240', + 'title': '', + 'user_id': 6948206, + 'width': 3402 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月16日', + 'post_id': 60555144, + 'published_at': '2019-12-16 19:46:35', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 6983, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_6948206_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '洛桑w伊梓', + 'site_id': '6948206', + 'type': 'user', + 'url': 'https://tuchong.com/6948206/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '6948206', + 'sites': [], + 'tags': ['日系', '男生写真', '写真', '人像', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/6948206/60555144/', + 'views': 2734 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 63, + 'content': '', + 'created_at': '2019-10-15 20:26:12', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1474, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5792, + 'img_id': 113554471, + 'img_id_str': '113554471', + 'title': '785977', + 'user_id': 3738183, + 'width': 8688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2428, + 'img_id': 652915682, + 'img_id_str': '652915682', + 'title': '786055', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 124367844, + 'img_id_str': '124367844', + 'title': '785976', + 'user_id': 3738183, + 'width': 5373 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 154579753, + 'img_id_str': '154579753', + 'title': '785975', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 214020918, + 'img_id_str': '214020918', + 'title': '785974', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 367703228, + 'img_id_str': '367703228', + 'title': '785973', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 601273027, + 'img_id_str': '601273027', + 'title': '785587', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 178893736, + 'img_id_str': '178893736', + 'title': '785583', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 68989749, + 'img_id_str': '68989749', + 'title': '785585', + 'user_id': 3738183, + 'width': 3500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '59', + 'passed_time': '2019年10月15日', + 'post_id': 55988727, + 'published_at': '2019-10-15 20:26:12', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 44, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '写真', '唯美'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/55988727/', + 'views': 47522 + }, + { + 'author_id': '5695193', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '草莓?季', + 'created_at': '2020-01-05 14:31:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['妍色同学会', '拍拍好吃的', '静物美学'], + 'excerpt': '草莓?季', + 'favorite_list_prefix': [], + 'favorites': 79, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 331204044, + 'img_id_str': '331204044', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 385336846, + 'img_id_str': '385336846', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 367511365, + 'img_id_str': '367511365', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 141215220, + 'img_id_str': '141215220', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 478921936, + 'img_id_str': '478921936', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 601802219, + 'img_id_str': '601802219', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 519816775, + 'img_id_str': '519816775', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 346080895, + 'img_id_str': '346080895', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6001, + 'img_id': 646366815, + 'img_id_str': '646366815', + 'title': '001', + 'user_id': 5695193, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '01月05日', + 'post_id': 61418795, + 'published_at': '2020-01-05 14:31:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 7, + 'site': { + 'description': '资深静物摄影师', + 'domain': '', + 'followers': 2696, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5695193_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '小懒猫yiyi', + 'site_id': '5695193', + 'type': 'user', + 'url': 'https://tuchong.com/5695193/', + 'verification_list': [ + {'verification_reason': '资深静物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5695193', + 'sites': [], + 'tags': ['妍色同学会', '拍拍好吃的', '静物美学', '草莓', '静物美食摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5695193/61418795/', + 'views': 2254 + }, + { + 'author_id': '15771562', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '大大大床房', + 'created_at': '2019-12-28 09:10:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['微缩摄影研究所', '中国创意摄影', '取景器里的小美好'], + 'excerpt': '大大大床房', + 'favorite_list_prefix': [], + 'favorites': 46, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 914, + 'img_id': 379767001, + 'img_id_str': '379767001', + 'title': '001', + 'user_id': 15771562, + 'width': 914 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月28日', + 'post_id': 61079247, + 'published_at': '2019-12-28 09:10:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深创意摄影师', + 'domain': '', + 'followers': 474, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15771562_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '感青影像', + 'site_id': '15771562', + 'type': 'user', + 'url': 'https://tuchong.com/15771562/', + 'verification_list': [ + {'verification_reason': '资深创意摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '15771562', + 'sites': [], + 'tags': ['微缩摄影研究所', '中国创意摄影', '取景器里的小美好', '微型创意摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15771562/61079247/', + 'views': 2230 + }, + { + 'author_id': '15791930', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '寺庙 青红色调', + 'created_at': '2019-12-25 20:15:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['带我看看,你的城市', '福建摄影圈', '让摄影穿破次元壁'], + 'excerpt': '寺庙 青红色调', + 'favorite_list_prefix': [], + 'favorites': 34, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 474989837, + 'img_id_str': '474989837', + 'title': '537552', + 'user_id': 15791930, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 542098582, + 'img_id_str': '542098582', + 'title': '537553', + 'user_id': 15791930, + 'width': 3651 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月25日', + 'post_id': 60971020, + 'published_at': '2019-12-25 20:15:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 15, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15791930_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'DoubleOreo', + 'site_id': '15791930', + 'type': 'user', + 'url': 'https://tuchong.com/15791930/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15791930', + 'sites': [], + 'tags': ['带我看看,你的城市', '福建摄影圈', '让摄影穿破次元壁', '寺庙', '建筑', '风光'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15791930/60971020/', + 'views': 1517 + }, + { + 'author_id': '1790780', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '蓝色\n\n摄影:@萌琦琦M77', + 'created_at': '2019-08-16 17:21:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '蓝色\n\n摄影:@萌琦琦M77', + 'favorite_list_prefix': [], + 'favorites': 1087, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2999, + 'img_id': 66031546, + 'img_id_str': '66031546', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 360419821, + 'img_id_str': '360419821', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 480219210, + 'img_id_str': '480219210', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 262640377, + 'img_id_str': '262640377', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 70095688, + 'img_id_str': '70095688', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 565285304, + 'img_id_str': '565285304', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 96702726, + 'img_id_str': '96702726', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 374968500, + 'img_id_str': '374968500', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 570790260, + 'img_id_str': '570790260', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '41', + 'passed_time': '2019年08月16日', + 'post_id': 49432246, + 'published_at': '2019-08-16 17:21:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 16, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4991, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1790780_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '萌琦琦M77', + 'site_id': '1790780', + 'type': 'user', + 'url': 'https://tuchong.com/1790780/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1790780', + 'sites': [], + 'tags': ['少女写真', '美少女', '日系小清新', '日系写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1790780/49432246/', + 'views': 49887 + }, + { + 'author_id': '1303010', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 53, + 'content': 'cp25场照', + 'created_at': '2019-12-25 16:17:31', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Cosplay摄影集中地'], + 'excerpt': 'cp25场照', + 'favorite_list_prefix': [], + 'favorites': 914, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 81904549, + 'img_id_str': '81904549', + 'title': '913651', + 'user_id': 1303010, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 212452816, + 'img_id_str': '212452816', + 'title': '913650', + 'user_id': 1303010, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 624280683, + 'img_id_str': '624280683', + 'title': '913649', + 'user_id': 1303010, + 'width': 1066 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 478201230, + 'img_id_str': '478201230', + 'title': '913648', + 'user_id': 1303010, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 337233337, + 'img_id_str': '337233337', + 'title': '913647', + 'user_id': 1303010, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1066, + 'img_id': 45794309, + 'img_id_str': '45794309', + 'title': '913646', + 'user_id': 1303010, + 'width': 1895 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '46', + 'passed_time': '2019年12月25日', + 'post_id': 60962339, + 'published_at': '2019-12-25 16:17:31', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 53, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'devilkman.tuchong.com', + 'followers': 4653, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1303010_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '咕哒囧子', + 'site_id': '1303010', + 'type': 'user', + 'url': 'https://devilkman.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1303010', + 'sites': [], + 'tags': ['Cosplay摄影集中地', 'Cosplay'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://devilkman.tuchong.com/60962339/', + 'views': 44224 + }, + { + 'author_id': '15879549', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 12, + 'content': '风雪夜归人', + 'created_at': '2020-01-15 21:08:45', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '风光人文地理', + '我们都在孤独星球', + '晒晒旅行打卡照', + '图虫旅行摄影圈子', + '一个风光摄影圈', + '光影者的风光摄影', + '中国地理摄影', + '风光摄影集', + '极致风光摄影', + '风光摄影圈', + '闪迪旅拍大赛' + ], + 'excerpt': '风雪夜归人', + 'favorite_list_prefix': [], + 'favorites': 85, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5504, + 'img_id': 449561976, + 'img_id_str': '449561976', + 'title': '001', + 'user_id': 15879549, + 'width': 8256 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '01月15日', + 'post_id': 61739255, + 'published_at': '2020-01-15 21:08:45', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 417, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15879549_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Greatwangjia', + 'site_id': '15879549', + 'type': 'user', + 'url': 'https://tuchong.com/15879549/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '15879549', + 'sites': [], + 'tags': [ + '风光人文地理', + '我们都在孤独星球', + '晒晒旅行打卡照', + '图虫旅行摄影圈子', + '一个风光摄影圈', + '光影者的风光摄影' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15879549/61739255/', + 'views': 1337 + }, + { + 'author_id': '3802000', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 66, + 'content': null, + 'created_at': '2019-12-31 20:48:54', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '图虫编者按:2019年已经过去,在这一年里,大家又拍摄了哪些喜欢的照片?自己在这一年有什么收获。欢迎大家都来总结一下自己一年的收获,跟大家来分享一下自己的摄影故事。分享自己的摄影故事,请打上 #年度总结# 标签,我们会筛选有趣的内容跟大家分享。我从十八还是十九岁出来社会打拼,从一无所有,发展到身无分文,再从身无分文到负债累累!所幸今年年末明确了目标,学会了思考.感谢感恩身边的所遇到的每个人。2019年有一...', + 'favorite_list_prefix': [], + 'favorites': 123, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年12月31日', + 'post_id': 61243712, + 'published_at': '2019-12-31 20:48:54', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 26, + 'site': { + 'description': '擅治愈、清新风格.VB.@小龙在拍照', + 'domain': '', + 'followers': 323, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3802000_10', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '小龙在拍照', + 'site_id': '3802000', + 'type': 'user', + 'url': 'https://tuchong.com/3802000/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '3802000', + 'sites': [], + 'tags': ['松果计划', '摄影心得', '摄影教程', '年度总结'], + 'title': '2019年终总结', + 'title_image': { + 'width': 600, + 'height': 269, + 'url': 'https://tuchong.pstatp.com/3802000/l/475514660.jpg' + }, + 'type': 'text', + 'update': false, + 'url': 'https://tuchong.com/3802000/t/61243712/', + 'views': 5106 + }, + { + 'author_id': '4586948', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '下课', + 'created_at': '2019-12-19 07:14:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['暖色调人像', '写真人像摄影', '高颜值女神聚集地', '人像爱好者', '我们都爱日系摄影'], + 'excerpt': '下课', + 'favorite_list_prefix': [], + 'favorites': 45, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 160285367, + 'img_id_str': '160285367', + 'title': '001', + 'user_id': 4586948, + 'width': 2678 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月19日', + 'post_id': 60676388, + 'published_at': '2019-12-19 07:14:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 794, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4586948_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '慧子photo', + 'site_id': '4586948', + 'type': 'user', + 'url': 'https://tuchong.com/4586948/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4586948', + 'sites': [], + 'tags': ['暖色调人像', '写真人像摄影', '高颜值女神聚集地', '人像爱好者', '我们都爱日系摄影', '在室内'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4586948/60676388/', + 'views': 2225 + }, + { + 'author_id': '1004274', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2019-12-23 13:31:09', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 23, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 122602313, + 'img_id_str': '122602313', + 'title': '', + 'user_id': 1004274, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 434685176, + 'img_id_str': '434685176', + 'title': '', + 'user_id': 1004274, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 502973502, + 'img_id_str': '502973502', + 'title': '', + 'user_id': 1004274, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6521, + 'img_id': 276021779, + 'img_id_str': '276021779', + 'title': '', + 'user_id': 1004274, + 'width': 3668 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 489866516, + 'img_id_str': '489866516', + 'title': '', + 'user_id': 1004274, + 'width': 3780 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 600360137, + 'img_id_str': '600360137', + 'title': '', + 'user_id': 1004274, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月23日', + 'post_id': 60871698, + 'published_at': '2019-12-23 13:31:09', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'soushou.tuchong.com', + 'followers': 6347, + 'has_everphoto_note': false, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1004274_25', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'soushou', + 'site_id': '1004274', + 'type': 'user', + 'url': 'https://soushou.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1004274', + 'sites': [], + 'tags': ['色彩', '人像', '佳能', '美女', '少女', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://soushou.tuchong.com/60871698/', + 'views': 1606 + }, + { + 'author_id': '45644', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '', + 'created_at': '2019-12-29 13:43:47', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '我要上“首页推荐位”', + '糖水人像小组', + '分享神仙颜值', + '我要上开屏', + '上海外拍活动', + '美女人像群', + '人像爱好者', + '高颜值女神聚集地', + '上海人像圈子' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 183, + 'image_count': 27, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 631358799, + 'img_id_str': '631358799', + 'title': '1389814', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 246072738, + 'img_id_str': '246072738', + 'title': '1389813', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 189318518, + 'img_id_str': '189318518', + 'title': '1389819', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 236242766, + 'img_id_str': '236242766', + 'title': '1389816', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 608486768, + 'img_id_str': '608486768', + 'title': '1389821', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 482854638, + 'img_id_str': '482854638', + 'title': '1389823', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 247317339, + 'img_id_str': '247317339', + 'title': '1389822', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 384157460, + 'img_id_str': '384157460', + 'title': '1389817', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 418039485, + 'img_id_str': '418039485', + 'title': '1389824', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 399951419, + 'img_id_str': '399951419', + 'title': '1389825', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 301713344, + 'img_id_str': '301713344', + 'title': '1389827', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 421906010, + 'img_id_str': '421906010', + 'title': '1389826', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 116901835, + 'img_id_str': '116901835', + 'title': '1389832', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 458213268, + 'img_id_str': '458213268', + 'title': '1389828', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 431670789, + 'img_id_str': '431670789', + 'title': '1389829', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 628933923, + 'img_id_str': '628933923', + 'title': '1389830', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 501400746, + 'img_id_str': '501400746', + 'title': '1389840', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 648594903, + 'img_id_str': '648594903', + 'title': '1389846', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 171295910, + 'img_id_str': '171295910', + 'title': '1389833', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 352634391, + 'img_id_str': '352634391', + 'title': '1389835', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 168740185, + 'img_id_str': '168740185', + 'title': '1389842', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 287753714, + 'img_id_str': '287753714', + 'title': '1389844', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 204130146, + 'img_id_str': '204130146', + 'title': '1389845', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 224577226, + 'img_id_str': '224577226', + 'title': '1389841', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 474793423, + 'img_id_str': '474793423', + 'title': '1389838', + 'user_id': 45644, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 592758406, + 'img_id_str': '592758406', + 'title': '1389831', + 'user_id': 45644, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 307676791, + 'img_id_str': '307676791', + 'title': '1389836', + 'user_id': 45644, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '9', + 'passed_time': '2019年12月29日', + 'post_id': 61137324, + 'published_at': '2019-12-29 13:43:47', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深人像摄影师', + 'domain': '95hugo.tuchong.com', + 'followers': 880, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_45644_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '九月的雨果', + 'site_id': '45644', + 'type': 'user', + 'url': 'https://95hugo.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '45644', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '糖水人像小组', '分享神仙颜值', '我要上开屏', '上海外拍活动', '美女人像群'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://95hugo.tuchong.com/61137324/', + 'views': 7627 + }, + { + 'author_id': '2981258', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '日出申华', + 'created_at': '2020-01-09 23:38:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '华理视觉摄影社', + '城市·夜晚', + '极致风光摄影', + '我要上开屏', + '风光摄影集', + '图虫城市建筑', + '带我看看,你的城市', + '华东理工大学摄影圈', + '绝不停止记录的2019', + '我要上“首页推荐位”' + ], + 'excerpt': '日出申华', + 'favorite_list_prefix': [], + 'favorites': 39, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3873, + 'img_id': 324716207, + 'img_id_str': '324716207', + 'title': '001', + 'user_id': 2981258, + 'width': 6048 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月09日', + 'post_id': 61561630, + 'published_at': '2020-01-09 23:38:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 7097, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2981258_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'MaxWell_Z', + 'site_id': '2981258', + 'type': 'user', + 'url': 'https://tuchong.com/2981258/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2981258', + 'sites': [], + 'tags': ['华理视觉摄影社', '城市·夜晚', '极致风光摄影', '我要上开屏', '风光摄影集', '图虫城市建筑'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2981258/61561630/', + 'views': 916 + }, + { + 'author_id': '390179', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '小森林的秋冬暖阳\n\n从有你的清晨醒来\n生活变成了电影\n岛屿变成星星\n在海里放光明\n\n场地@加糖写真馆', + 'created_at': '2019-12-27 13:21:57', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['写真人像摄影', '人像摄影集', '约拍馆摄影作品投稿'], + 'excerpt': '小森林的秋冬暖阳\n\n从有你的清晨醒来\n生活变成了电影\n岛屿变成星星\n在海里放光明\n\n场地@加糖写真馆', + 'favorite_list_prefix': [], + 'favorites': 58, + 'image_count': 26, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 363513300, + 'img_id_str': '363513300', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 566019556, + 'img_id_str': '566019556', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 469944079, + 'img_id_str': '469944079', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 313639857, + 'img_id_str': '313639857', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3349, + 'img_id': 134727105, + 'img_id_str': '134727105', + 'title': '001', + 'user_id': 390179, + 'width': 2263 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 251380844, + 'img_id_str': '251380844', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 275301287, + 'img_id_str': '275301287', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 343393440, + 'img_id_str': '343393440', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 306824877, + 'img_id_str': '306824877', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 582731111, + 'img_id_str': '582731111', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 260490482, + 'img_id_str': '260490482', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 547734810, + 'img_id_str': '547734810', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 200329244, + 'img_id_str': '200329244', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 419480634, + 'img_id_str': '419480634', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 261211410, + 'img_id_str': '261211410', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 311477341, + 'img_id_str': '311477341', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 90555731, + 'img_id_str': '90555731', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 354403800, + 'img_id_str': '354403800', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 600032276, + 'img_id_str': '600032276', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 252102098, + 'img_id_str': '252102098', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 572048731, + 'img_id_str': '572048731', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 653575686, + 'img_id_str': '653575686', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 407553424, + 'img_id_str': '407553424', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 277792391, + 'img_id_str': '277792391', + 'title': '001', + 'user_id': 390179, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 353486069, + 'img_id_str': '353486069', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 458671708, + 'img_id_str': '458671708', + 'title': '001', + 'user_id': 390179, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月27日', + 'post_id': 61026480, + 'published_at': '2019-12-27 13:21:57', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 115, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_390179_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '兔丁小姐', + 'site_id': '390179', + 'type': 'user', + 'url': 'https://tuchong.com/390179/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '390179', + 'sites': [], + 'tags': ['写真人像摄影', '人像摄影集', '约拍馆摄影作品投稿', '人像', '日系', '少女写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/390179/61026480/', + 'views': 2373 + }, + { + 'author_id': '300897', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '', + 'created_at': '2019-12-30 17:39:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片', '闪迪旅拍大赛', '悦拍评片会', '飞图摄影学院评片会', '2020适马睛典'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 67, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 542492787, + 'img_id_str': '542492787', + 'title': '', + 'user_id': 300897, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '2019年12月30日', + 'post_id': 61189888, + 'published_at': '2019-12-30 17:39:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 4, + 'site': { + 'description': '资深旅行摄影师', + 'domain': 'hockingcao.tuchong.com', + 'followers': 4195, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_300897_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Hockingcao', + 'site_id': '300897', + 'type': 'user', + 'url': 'https://hockingcao.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '300897', + 'sites': [], + 'tags': ['2019你最满意的照片', '闪迪旅拍大赛', '悦拍评片会', '飞图摄影学院评片会', '2020适马睛典', '风光'], + 'title': '圣托里尼晚霞', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://hockingcao.tuchong.com/61189888/', + 'views': 1960 + }, + { + 'author_id': '1738925', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '这组定制客片,从筹备到拍摄,只用了两天的时间,是我拍摄定制写真筹备最快的一次。', + 'created_at': '2019-12-25 13:28:32', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片'], + 'excerpt': '这组定制客片,从筹备到拍摄,只用了两天的时间,是我拍摄定制写真筹备最快的一次。', + 'favorite_list_prefix': [], + 'favorites': 25, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1364, + 'img_id': 71419233, + 'img_id_str': '71419233', + 'title': '', + 'user_id': 1738925, + 'width': 2047 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1364, + 'img_id': 573424948, + 'img_id_str': '573424948', + 'title': '', + 'user_id': 1738925, + 'width': 2047 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1364, + 'img_id': 96585025, + 'img_id_str': '96585025', + 'title': '', + 'user_id': 1738925, + 'width': 2045 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1360, + 'img_id': 576242950, + 'img_id_str': '576242950', + 'title': '', + 'user_id': 1738925, + 'width': 2045 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 461161887, + 'img_id_str': '461161887', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 517064260, + 'img_id_str': '517064260', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 411354221, + 'img_id_str': '411354221', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 556844204, + 'img_id_str': '556844204', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 69518344, + 'img_id_str': '69518344', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 286311726, + 'img_id_str': '286311726', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 558810792, + 'img_id_str': '558810792', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 69649370, + 'img_id_str': '69649370', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2206, + 'img_id': 226280942, + 'img_id_str': '226280942', + 'title': '', + 'user_id': 1738925, + 'width': 1471 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '2019年12月25日', + 'post_id': 60956923, + 'published_at': '2019-12-25 13:28:32', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '相互关注,相互关照。', + 'domain': '', + 'followers': 101, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1738925_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '李佩珊', + 'site_id': '1738925', + 'type': 'user', + 'url': 'https://tuchong.com/1738925/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1738925', + 'sites': [], + 'tags': ['2019你最满意的照片', '2019-所爱', '色彩', '人像', '美女', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1738925/60956923/', + 'views': 1655 + }, + { + 'author_id': '1609854', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '', + 'created_at': '2020-01-07 15:48:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2020适马睛典'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 32, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6336, + 'img_id': 572770058, + 'img_id_str': '572770058', + 'title': '001', + 'user_id': 1609854, + 'width': 9504 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月07日', + 'post_id': 61487318, + 'published_at': '2020-01-07 15:48:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深旅行摄影师', + 'domain': 'carrotjam.tuchong.com', + 'followers': 12084, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1609854_8', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '胡萝卜果酱', + 'site_id': '1609854', + 'type': 'user', + 'url': 'https://carrotjam.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1609854', + 'sites': [], + 'tags': ['2020适马睛典', '睛典风光组', '山', '晚上', '天空', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://carrotjam.tuchong.com/61487318/', + 'views': 927 + }, + { + 'author_id': '1534403', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '冬', + 'created_at': '2019-12-18 19:17:29', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '冬', + 'favorite_list_prefix': [], + 'favorites': 104, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 604291631, + 'img_id_str': '604291631', + 'title': '4287357', + 'user_id': 1534403, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '2019年12月18日', + 'post_id': 60656433, + 'published_at': '2019-12-18 19:17:29', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7389, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1534403_27', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Akasa空影照见', + 'site_id': '1534403', + 'type': 'user', + 'url': 'https://tuchong.com/1534403/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1534403', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1534403/60656433/', + 'views': 4094 + }, + { + 'author_id': '2874671', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '坐着爷爷的摩托去巴扎', + 'created_at': '2020-01-16 12:10:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '图虫旅行摄影圈子', + '街事圈子', + '我爱街拍摄影小组圈子', + '街头拍客', + '人文纪实手册', + '街头人物圈子', + '街拍纪实手册', + '人文天下', + '街拍俱乐部圈子', + '有温度的人像' + ], + 'excerpt': '坐着爷爷的摩托去巴扎', + 'favorite_list_prefix': [], + 'favorites': 21, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2729, + 'img_id': 483640919, + 'img_id_str': '483640919', + 'title': '001', + 'user_id': 2874671, + 'width': 4096 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月16日', + 'post_id': 61754269, + 'published_at': '2020-01-16 12:10:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '不是摄影师', + 'domain': '', + 'followers': 25, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2874671_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '木司晨', + 'site_id': '2874671', + 'type': 'user', + 'url': 'https://tuchong.com/2874671/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '2874671', + 'sites': [], + 'tags': ['图虫旅行摄影圈子', '街事圈子', '我爱街拍摄影小组圈子', '街头拍客', '人文纪实手册', '街头人物圈子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2874671/61754269/', + 'views': 996 + }, + { + 'author_id': '2693179', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 74, + 'content': null, + 'created_at': '2019-12-21 14:32:27', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '陈 萧 伊出生于中国四川,2014年获得伦敦艺术大学纯艺术摄影硕士学位,目前工作生活于成都。她的作品曾获得中国第七届三影堂摄影奖,入选福布斯2017“30 UNDER 30(Art)”亚洲榜单,并参与诸多国内外展览。她的作品基于摄影,但并不局限于具体的媒介。通过生产图像的方式,她关注生命体的微妙感知,通过不断挑战既定的逻辑、感知与想象,来探讨存在本身的问题。她一直感怀并向往着远古时代,她觉得古人的生活里有太多的智慧,物...', + 'favorite_list_prefix': [], + 'favorites': 138, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '60', + 'passed_time': '2019年12月21日', + 'post_id': 60778056, + 'published_at': '2019-12-21 14:32:27', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 61, + 'site': { + 'description': '图虫品牌项目,包括演讲、展览、文创及出版', + 'domain': 'opensee.tuchong.com', + 'followers': 128878, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2693179_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'OpenSee', + 'site_id': '2693179', + 'type': 'user', + 'url': 'https://opensee.tuchong.com/', + 'verification_list': [ + { + 'verification_reason': '图虫品牌项目,包括演讲、展览、文创及出版', + 'verification_type': 11 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2693179', + 'sites': [], + 'tags': [], + 'title': '凝视冰川、月亮和岩石,陈萧伊用摄影探寻世界隐秘的本原', + 'title_image': { + 'width': 600, + 'height': 253, + 'url': 'https://tuchong.pstatp.com/2693179/l/576178325.jpg' + }, + 'type': 'text', + 'update': false, + 'url': 'https://opensee.tuchong.com/t/60778056/', + 'views': 11595 + }, + { + 'author_id': '4091385', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': 'The simple portraits\nModel: Zenia', + 'created_at': '2020-01-16 16:40:07', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['糖水人像小组', '有温度的人像', '暖色调人像'], + 'excerpt': 'The simple portraits\nModel: Zenia', + 'favorite_list_prefix': [], + 'favorites': 49, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 418564081, + 'img_id_str': '418564081', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 620939231, + 'img_id_str': '620939231', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 269076266, + 'img_id_str': '269076266', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 388482651, + 'img_id_str': '388482651', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5523, + 'img_id': 491505331, + 'img_id_str': '491505331', + 'title': '001', + 'user_id': 4091385, + 'width': 3682 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6610, + 'img_id': 538822304, + 'img_id_str': '538822304', + 'title': '001', + 'user_id': 4091385, + 'width': 4407 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 462669858, + 'img_id_str': '462669858', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 222152520, + 'img_id_str': '222152520', + 'title': '001', + 'user_id': 4091385, + 'width': 6240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 90688011, + 'img_id_str': '90688011', + 'title': '001', + 'user_id': 4091385, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5056, + 'img_id': 138659221, + 'img_id_str': '138659221', + 'title': '001', + 'user_id': 4091385, + 'width': 3371 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月16日', + 'post_id': 61759996, + 'published_at': '2020-01-16 16:40:07', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 4, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1434, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4091385_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '開米小關', + 'site_id': '4091385', + 'type': 'user', + 'url': 'https://tuchong.com/4091385/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4091385', + 'sites': [], + 'tags': ['糖水人像小组', '有温度的人像', '暖色调人像', '人像', '肖像', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4091385/61759996/', + 'views': 1992 + }, + { + 'author_id': '8110595', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '碧蓝幻想-美黛拉', + 'created_at': '2019-12-24 21:09:09', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Cosplay摄影集中地'], + 'excerpt': '碧蓝幻想-美黛拉', + 'favorite_list_prefix': [], + 'favorites': 87, + 'image_count': 17, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 250791302, + 'img_id_str': '250791302', + 'title': '001', + 'user_id': 8110595, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 239715567, + 'img_id_str': '239715567', + 'title': '001', + 'user_id': 8110595, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 389858914, + 'img_id_str': '389858914', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 594724153, + 'img_id_str': '594724153', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 160875916, + 'img_id_str': '160875916', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 446415831, + 'img_id_str': '446415831', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 362988627, + 'img_id_str': '362988627', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 116769853, + 'img_id_str': '116769853', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 394315233, + 'img_id_str': '394315233', + 'title': '001', + 'user_id': 8110595, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5689, + 'img_id': 540394286, + 'img_id_str': '540394286', + 'title': '001', + 'user_id': 8110595, + 'width': 3793 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 650102110, + 'img_id_str': '650102110', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 568248103, + 'img_id_str': '568248103', + 'title': '001', + 'user_id': 8110595, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 39765074, + 'img_id_str': '39765074', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 148882650, + 'img_id_str': '148882650', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 331793578, + 'img_id_str': '331793578', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 344377060, + 'img_id_str': '344377060', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 198035263, + 'img_id_str': '198035263', + 'title': '001', + 'user_id': 8110595, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月24日', + 'post_id': 60930883, + 'published_at': '2019-12-24 21:09:09', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 5741, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_8110595_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '小穗穗穗sui', + 'site_id': '8110595', + 'type': 'user', + 'url': 'https://tuchong.com/8110595/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '8110595', + 'sites': [], + 'tags': ['Cosplay摄影集中地', '圣诞', 'Cosplay', '人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8110595/60930883/', + 'views': 4452 + }, + { + 'author_id': '1517263', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '「汉口杂片集」冬季的日夜雨晴', + 'created_at': '2020-01-17 10:32:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '武汉城记', + '城市·夜晚', + '带我看看,你的城市', + '富士Fujifilm圈子', + '街拍纪实手册', + '我用手机修照片', + '街事圈子', + '我们都是城市探险家' + ], + 'excerpt': '「汉口杂片集」冬季的日夜雨晴', + 'favorite_list_prefix': [], + 'favorites': 36, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 271435251, + 'img_id_str': '271435251', + 'title': '001', + 'user_id': 1517263, + 'width': 1079 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 105760527, + 'img_id_str': '105760527', + 'title': '001', + 'user_id': 1517263, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 306365934, + 'img_id_str': '306365934', + 'title': '001', + 'user_id': 1517263, + 'width': 1079 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1279, + 'img_id': 463128718, + 'img_id_str': '463128718', + 'title': '001', + 'user_id': 1517263, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 610387702, + 'img_id_str': '610387702', + 'title': '001', + 'user_id': 1517263, + 'width': 1279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1279, + 'img_id': 436521125, + 'img_id_str': '436521125', + 'title': '001', + 'user_id': 1517263, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1279, + 'img_id': 422627760, + 'img_id_str': '422627760', + 'title': '001', + 'user_id': 1517263, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 542623416, + 'img_id_str': '542623416', + 'title': '001', + 'user_id': 1517263, + 'width': 1079 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 204981888, + 'img_id_str': '204981888', + 'title': '001', + 'user_id': 1517263, + 'width': 1079 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 415155849, + 'img_id_str': '415155849', + 'title': '001', + 'user_id': 1517263, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1279, + 'img_id': 209503360, + 'img_id_str': '209503360', + 'title': '001', + 'user_id': 1517263, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 527353774, + 'img_id_str': '527353774', + 'title': '001', + 'user_id': 1517263, + 'width': 1079 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月17日', + 'post_id': 61779732, + 'published_at': '2020-01-17 10:32:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深纪实摄影师', + 'domain': 'whoken.tuchong.com', + 'followers': 1785, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1517263_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '狼来了OKEN', + 'site_id': '1517263', + 'type': 'user', + 'url': 'https://whoken.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深纪实摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1517263', + 'sites': [], + 'tags': [ + '武汉城记', + '城市·夜晚', + '带我看看,你的城市', + '富士Fujifilm圈子', + '街拍纪实手册', + '我用手机修照片' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://whoken.tuchong.com/61779732/', + 'views': 1260 + }, + { + 'author_id': '2400018', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': 'PAKSE@CITY.LAOS ...', + 'created_at': '2020-01-19 09:13:38', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '异国风光情报站', + '晒晒旅行打卡照', + '图虫旅行摄影圈子', + '人文纪实手册', + '人文天下', + '风光人文地理', + '闪迪旅拍大赛' + ], + 'excerpt': 'PAKSE@CITY.LAOS ...', + 'favorite_list_prefix': [], + 'favorites': 50, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1298, + 'img_id': 82691755, + 'img_id_str': '82691755', + 'title': '', + 'user_id': 2400018, + 'width': 2048 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '7', + 'passed_time': '01月19日', + 'post_id': 61831585, + 'published_at': '2020-01-19 09:13:38', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 5553, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2400018_21', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'FOX86', + 'site_id': '2400018', + 'type': 'user', + 'url': 'https://tuchong.com/2400018/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2400018', + 'sites': [], + 'tags': ['异国风光情报站', '晒晒旅行打卡照', '图虫旅行摄影圈子', '人文纪实手册', '人文天下', '风光人文地理'], + 'title': '... 讀ღ萬象(PAKSE.紀實-28)', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2400018/61831585/', + 'views': 1402 + }, + { + 'author_id': '1945520', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '涩谷繁华处', + 'created_at': '2020-01-10 16:28:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '生活小确幸', + '美图汇', + '取景器里的小美好', + '街拍纪实手册', + '我要上开屏', + '我们都是城市探险家' + ], + 'excerpt': '涩谷繁华处', + 'favorite_list_prefix': [], + 'favorites': 36, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4096, + 'img_id': 295356207, + 'img_id_str': '295356207', + 'title': '001', + 'user_id': 1945520, + 'width': 2304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5168, + 'img_id': 223791022, + 'img_id_str': '223791022', + 'title': '001', + 'user_id': 1945520, + 'width': 3448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 633325604, + 'img_id_str': '633325604', + 'title': '001', + 'user_id': 1945520, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2907, + 'img_id': 459130845, + 'img_id_str': '459130845', + 'title': '001', + 'user_id': 1945520, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2870, + 'img_id': 463848751, + 'img_id_str': '463848751', + 'title': '001', + 'user_id': 1945520, + 'width': 5102 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月10日', + 'post_id': 61579799, + 'published_at': '2020-01-10 16:28:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 5454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1945520_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师芊芊', + 'site_id': '1945520', + 'type': 'user', + 'url': 'https://tuchong.com/1945520/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1945520', + 'sites': [], + 'tags': ['生活小确幸', '美图汇', '取景器里的小美好', '街拍纪实手册', '我要上开屏', '我们都是城市探险家'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1945520/61579799/', + 'views': 1594 + }, + { + 'author_id': '3379664', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 6, + 'content': '———?ここらで休んでみませんか,ねぇうちにおいで温めてあげるよ?———', + 'created_at': '2019-12-27 23:05:28', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['日系集', '分享神仙颜值', '光环摄影美学'], + 'excerpt': '———?ここらで休んでみませんか,ねぇうちにおいで温めてあげるよ?———', + 'favorite_list_prefix': [], + 'favorites': 43, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 210617534, + 'img_id_str': '210617534', + 'title': '001', + 'user_id': 3379664, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5436, + 'img_id': 339526919, + 'img_id_str': '339526919', + 'title': '001', + 'user_id': 3379664, + 'width': 3050 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4859, + 'img_id': 43173048, + 'img_id_str': '43173048', + 'title': '001', + 'user_id': 3379664, + 'width': 2993 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 53003381, + 'img_id_str': '53003381', + 'title': '001', + 'user_id': 3379664, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3921, + 'img_id': 260425116, + 'img_id_str': '260425116', + 'title': '001', + 'user_id': 3379664, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2995, + 'img_id': 247383422, + 'img_id_str': '247383422', + 'title': '001', + 'user_id': 3379664, + 'width': 5577 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5065, + 'img_id': 616416612, + 'img_id_str': '616416612', + 'title': '001', + 'user_id': 3379664, + 'width': 2997 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4712, + 'img_id': 409846993, + 'img_id_str': '409846993', + 'title': '001', + 'user_id': 3379664, + 'width': 2944 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 438027803, + 'img_id_str': '438027803', + 'title': '001', + 'user_id': 3379664, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月27日', + 'post_id': 61066271, + 'published_at': '2019-12-27 23:05:28', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '一个喜欢汉服,日系的摄影,拍自己喜欢的人事物,然后吸引喜欢自己的人。微博同名,约片请加wx763343787', + 'domain': '', + 'followers': 36, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3379664_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '陈司空Freedom', + 'site_id': '3379664', + 'type': 'user', + 'url': 'https://tuchong.com/3379664/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '3379664', + 'sites': [], + 'tags': ['日系集', '分享神仙颜值', '光环摄影美学', '秋季', '人像', 'JK'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3379664/61066271/', + 'views': 2302 + }, + { + 'author_id': '1142826', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '乡村的小房子', + 'created_at': '2019-12-25 10:33:08', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '最满意的风光照', + '北京自然风光小组', + '极致风光摄影', + '风光摄影圈', + '图虫旅行摄影圈子', + '图虫封面你做主', + '直到世界的尽头', + '我们都在孤独星球' + ], + 'excerpt': '乡村的小房子', + 'favorite_list_prefix': [], + 'favorites': 99, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 7360, + 'img_id': 459326964, + 'img_id_str': '459326964', + 'title': '961590', + 'user_id': 1142826, + 'width': 4912 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '2019年12月25日', + 'post_id': 60950933, + 'published_at': '2019-12-25 10:33:08', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深风光摄影师', + 'domain': 'kiddhuang.tuchong.com', + 'followers': 7405, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1142826_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '哈哈熊Kidd_Huang', + 'site_id': '1142826', + 'type': 'user', + 'url': 'https://kiddhuang.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1142826', + 'sites': [], + 'tags': ['最满意的风光照', '北京自然风光小组', '极致风光摄影', '风光摄影圈', '图虫旅行摄影圈子', '图虫封面你做主'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://kiddhuang.tuchong.com/60950933/', + 'views': 2728 + }, + { + 'author_id': '1903140', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 8, + 'content': null, + 'created_at': '2020-01-07 11:51:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 3, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '01月07日', + 'post_id': 61481339, + 'published_at': '2020-01-07 11:51:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '努力有朝一日拍出糖水片', + 'domain': '', + 'followers': 397, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1903140_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '炸酱面同学', + 'site_id': '1903140', + 'type': 'user', + 'url': 'https://tuchong.com/1903140/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1903140', + 'sites': [], + 'tags': ['评论斗图大赛'], + 'title': '你有什么关于摄影的表情包吗?评论里发出来给大家看看', + 'title_image': { + 'width': 270, + 'height': 270, + 'url': 'https://tuchong.pstatp.com/1903140/f/146916790.jpg' + }, + 'type': 'text', + 'update': false, + 'url': 'https://tuchong.com/1903140/t/61481339/', + 'views': 336 + }, + { + 'author_id': '7159375', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '蛋黄酥', + 'created_at': '2019-12-20 09:49:53', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['拍拍好吃的'], + 'excerpt': '蛋黄酥', + 'favorite_list_prefix': [], + 'favorites': 65, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 75154568, + 'img_id_str': '75154568', + 'title': '001', + 'user_id': 7159375, + 'width': 3329 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 634373825, + 'img_id_str': '634373825', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 160941388, + 'img_id_str': '160941388', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 457229653, + 'img_id_str': '457229653', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 590988106, + 'img_id_str': '590988106', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 55493468, + 'img_id_str': '55493468', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 420267109, + 'img_id_str': '420267109', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 423609431, + 'img_id_str': '423609431', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 436388774, + 'img_id_str': '436388774', + 'title': '001', + 'user_id': 7159375, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '2019年12月20日', + 'post_id': 60724371, + 'published_at': '2019-12-20 09:49:53', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深美食摄影师', + 'domain': '', + 'followers': 3863, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_7159375_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '薯Mica', + 'site_id': '7159375', + 'type': 'user', + 'url': 'https://tuchong.com/7159375/', + 'verification_list': [ + {'verification_reason': '资深美食摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '7159375', + 'sites': [], + 'tags': ['拍拍好吃的', '早餐', '静物', '茶点', '糕点', '美味的'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/7159375/60724371/', + 'views': 2683 + }, + { + 'author_id': '11009227', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 6, + 'content': '竹里馆', + 'created_at': '2019-12-11 12:10:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['对短发姑娘没有任何抵抗力!'], + 'excerpt': '竹里馆', + 'favorite_list_prefix': [], + 'favorites': 305, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 354403197, + 'img_id_str': '354403197', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 227722302, + 'img_id_str': '227722302', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 586269701, + 'img_id_str': '586269701', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 223331333, + 'img_id_str': '223331333', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2136, + 'img_id': 265078230, + 'img_id_str': '265078230', + 'title': '001', + 'user_id': 11009227, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 307610344, + 'img_id_str': '307610344', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 564052764, + 'img_id_str': '564052764', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 516276848, + 'img_id_str': '516276848', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 603571190, + 'img_id_str': '603571190', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 109429460, + 'img_id_str': '109429460', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 321962809, + 'img_id_str': '321962809', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 286049066, + 'img_id_str': '286049066', + 'title': '001', + 'user_id': 11009227, + 'width': 2136 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '6', + 'passed_time': '2019年12月11日', + 'post_id': 60255004, + 'published_at': '2019-12-11 12:10:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '2', + 'rqt_id': '', + 'shares': 9, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 9783, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_11009227_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '星野森', + 'site_id': '11009227', + 'type': 'user', + 'url': 'https://tuchong.com/11009227/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '11009227', + 'sites': [], + 'tags': ['对短发姑娘没有任何抵抗力!', '短裙', '大自然', '竹', 'JK', 'JK制服'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/11009227/60255004/', + 'views': 16244 + }, + { + 'author_id': '1667050', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2020-01-02 09:38:12', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 28, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4788, + 'img_id': 618579729, + 'img_id_str': '618579729', + 'title': '', + 'user_id': 1667050, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4920, + 'img_id': 447006399, + 'img_id_str': '447006399', + 'title': '', + 'user_id': 1667050, + 'width': 3204 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 634243064, + 'img_id_str': '634243064', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4896, + 'img_id': 377275805, + 'img_id_str': '377275805', + 'title': '', + 'user_id': 1667050, + 'width': 3156 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4248, + 'img_id': 212714957, + 'img_id_str': '212714957', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 209569416, + 'img_id_str': '209569416', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 84788031, + 'img_id_str': '84788031', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 478791647, + 'img_id_str': '478791647', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4692, + 'img_id': 351388740, + 'img_id_str': '351388740', + 'title': '', + 'user_id': 1667050, + 'width': 3060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 643876974, + 'img_id_str': '643876974', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4104, + 'img_id': 463783297, + 'img_id_str': '463783297', + 'title': '', + 'user_id': 1667050, + 'width': 2736 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月02日', + 'post_id': 61313180, + 'published_at': '2020-01-02 09:38:12', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '每个人都有一份礼物,藏在内心的最深处~', + 'domain': '', + 'followers': 14195, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1667050_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '如馨Lee', + 'site_id': '1667050', + 'type': 'user', + 'url': 'https://tuchong.com/1667050/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1667050', + 'sites': [], + 'tags': ['色彩', '风光', '旅行', '抓拍', '人像', '美女'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1667050/61313180/', + 'views': 1301 + }, + { + 'author_id': '3229117', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 44, + 'content': '这个夏天,晚上一起散步吧,可以的话,带上你的猫。', + 'created_at': '2019-10-17 11:07:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '日系集', + '咔了个图', + '糖水人像小组', + '高颜值女神聚集地', + '人像爱好者', + '我要上“首页推荐位”', + '分享神仙颜值', + '趣味话题:唯美如你', + '冷色调人像', + '人像写真摄影约拍', + '2019你最满意的照片' + ], + 'excerpt': '这个夏天,晚上一起散步吧,可以的话,带上你的猫。', + 'favorite_list_prefix': [], + 'favorites': 987, + 'image_count': 45, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 273986266, + 'img_id_str': '273986266', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2856, + 'img_id': 368882422, + 'img_id_str': '368882422', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 161264202, + 'img_id_str': '161264202', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 505918265, + 'img_id_str': '505918265', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 564048864, + 'img_id_str': '564048864', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3556, + 'img_id': 425505798, + 'img_id_str': '425505798', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 134067048, + 'img_id_str': '134067048', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3047, + 'img_id': 208843622, + 'img_id_str': '208843622', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3037, + 'img_id': 64992636, + 'img_id_str': '64992636', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 644723734, + 'img_id_str': '644723734', + 'title': '001', + 'user_id': 3229117, + 'width': 3018 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2979, + 'img_id': 266777684, + 'img_id_str': '266777684', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1125, + 'img_id': 312390413, + 'img_id_str': '312390413', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 371569671, + 'img_id_str': '371569671', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 502641792, + 'img_id_str': '502641792', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3049, + 'img_id': 435204882, + 'img_id_str': '435204882', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3030, + 'img_id': 267039729, + 'img_id_str': '267039729', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 267039730, + 'img_id_str': '267039730', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 63353766, + 'img_id_str': '63353766', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 189183066, + 'img_id_str': '189183066', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 414823412, + 'img_id_str': '414823412', + 'title': '001', + 'user_id': 3229117, + 'width': 3176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 500937802, + 'img_id_str': '500937802', + 'title': '001', + 'user_id': 3229117, + 'width': 3029 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 219460752, + 'img_id_str': '219460752', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 475378723, + 'img_id_str': '475378723', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 157463197, + 'img_id_str': '157463197', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 507491069, + 'img_id_str': '507491069', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 227193537, + 'img_id_str': '227193537', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 247575440, + 'img_id_str': '247575440', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 394769119, + 'img_id_str': '394769119', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 444642556, + 'img_id_str': '444642556', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 457421692, + 'img_id_str': '457421692', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3061, + 'img_id': 616018937, + 'img_id_str': '616018937', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 211858290, + 'img_id_str': '211858290', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3047, + 'img_id': 651343059, + 'img_id_str': '651343059', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 157135706, + 'img_id_str': '157135706', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2940, + 'img_id': 563721683, + 'img_id_str': '563721683', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 103199939, + 'img_id_str': '103199939', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 80458658, + 'img_id_str': '80458658', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 464433878, + 'img_id_str': '464433878', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 470987678, + 'img_id_str': '470987678', + 'title': '001', + 'user_id': 3229117, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 581350208, + 'img_id_str': '581350208', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 71152722, + 'img_id_str': '71152722', + 'title': '001', + 'user_id': 3229117, + 'width': 3555 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 228504107, + 'img_id_str': '228504107', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 313439599, + 'img_id_str': '313439599', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 392606487, + 'img_id_str': '392606487', + 'title': '001', + 'user_id': 3229117, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 597079052, + 'img_id_str': '597079052', + 'title': '001', + 'user_id': 3229117, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '34', + 'passed_time': '2019年10月17日', + 'post_id': 56119158, + 'published_at': '2019-10-17 11:07:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 38, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3071, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3229117_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '黑猫阿姨', + 'site_id': '3229117', + 'type': 'user', + 'url': 'https://tuchong.com/3229117/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3229117', + 'sites': [], + 'tags': ['日系集', '咔了个图', '糖水人像小组', '高颜值女神聚集地', '人像爱好者', '我要上“首页推荐位”'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3229117/56119158/', + 'views': 44503 + }, + { + 'author_id': '5417230', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '深圳冰与火三叉戟', + 'created_at': '2020-01-18 15:46:09', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫城市建筑'], + 'excerpt': '深圳冰与火三叉戟', + 'favorite_list_prefix': [], + 'favorites': 17, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5309, + 'img_id': 534759491, + 'img_id_str': '534759491', + 'title': '001', + 'user_id': 5417230, + 'width': 7955 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月18日', + 'post_id': 61813662, + 'published_at': '2020-01-18 15:46:09', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 173, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5417230_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Franky-Wang', + 'site_id': '5417230', + 'type': 'user', + 'url': 'https://tuchong.com/5417230/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5417230', + 'sites': [], + 'tags': ['图虫城市建筑', '天际线', '日落', '建筑', '城市', '薄暮'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5417230/61813662/', + 'views': 694 + }, + { + 'author_id': '2441927', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '今年最后一次的随心拍摄!', + 'created_at': '2019-12-28 17:47:00', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '纯粹黑白圈子', + '人像写真摄影约拍', + '人像爱好者', + '我要上开屏', + '我要上“首页推荐位”', + '绝不停止记录的2019', + '做人要低调,摄影也是', + '人像摄影集', + '无创意,不摄影', + '分享决定性瞬间' + ], + 'excerpt': '今年最后一次的随心拍摄!', + 'favorite_list_prefix': [], + 'favorites': 32, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5048, + 'img_id': 293390358, + 'img_id_str': '293390358', + 'title': '1540309', + 'user_id': 2441927, + 'width': 5048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2990, + 'img_id': 561366087, + 'img_id_str': '561366087', + 'title': '1540307', + 'user_id': 2441927, + 'width': 2990 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2992, + 'img_id': 444056532, + 'img_id_str': '444056532', + 'title': '1540305', + 'user_id': 2441927, + 'width': 2992 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3078, + 'img_id': 301319583, + 'img_id_str': '301319583', + 'title': '1540308', + 'user_id': 2441927, + 'width': 3078 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3998, + 'img_id': 366397143, + 'img_id_str': '366397143', + 'title': '1540311', + 'user_id': 2441927, + 'width': 7108 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3002, + 'img_id': 253150255, + 'img_id_str': '253150255', + 'title': '1540306', + 'user_id': 2441927, + 'width': 3002 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5036, + 'img_id': 586139225, + 'img_id_str': '586139225', + 'title': '1540310', + 'user_id': 2441927, + 'width': 5036 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3020, + 'img_id': 378651973, + 'img_id_str': '378651973', + 'title': '1540304', + 'user_id': 2441927, + 'width': 3020 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2998, + 'img_id': 361219570, + 'img_id_str': '361219570', + 'title': '1540312', + 'user_id': 2441927, + 'width': 2998 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月28日', + 'post_id': 61099958, + 'published_at': '2019-12-28 17:47:00', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1823, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2441927_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '玩摄影的鱼', + 'site_id': '2441927', + 'type': 'user', + 'url': 'https://tuchong.com/2441927/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2441927', + 'sites': [], + 'tags': [ + '纯粹黑白圈子', + '人像写真摄影约拍', + '人像爱好者', + '我要上开屏', + '我要上“首页推荐位”', + '绝不停止记录的2019' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2441927/61099958/', + 'views': 1415 + }, + { + 'author_id': '384622', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '圣诞?画报女孩\n拍摄:佐小夕 出镜:嘉鱼儿\nblingbling圣诞girl\n韩国女团的赶脚 ✨', + 'created_at': '2019-12-24 17:07:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['人像爱好者'], + 'excerpt': '圣诞?画报女孩\n拍摄:佐小夕 出镜:嘉鱼儿\nblingbling圣诞girl\n韩国女团的赶脚 ✨', + 'favorite_list_prefix': [], + 'favorites': 109, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 556582696, + 'img_id_str': '556582696', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 589874927, + 'img_id_str': '589874927', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 547800382, + 'img_id_str': '547800382', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 261473603, + 'img_id_str': '261473603', + 'title': '001', + 'user_id': 384622, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 408208572, + 'img_id_str': '408208572', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 282314237, + 'img_id_str': '282314237', + 'title': '001', + 'user_id': 384622, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 603309190, + 'img_id_str': '603309190', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 618645148, + 'img_id_str': '618645148', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1216, + 'img_id': 112969306, + 'img_id_str': '112969306', + 'title': '001', + 'user_id': 384622, + 'width': 1823 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 146130245, + 'img_id_str': '146130245', + 'title': '001', + 'user_id': 384622, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月24日', + 'post_id': 60920602, + 'published_at': '2019-12-24 17:07:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 11, + 'site': { + 'description': '新浪微博:@佐小夕 摄影教学班微博持续招生中~~~', + 'domain': 'zuoxiaoxi.tuchong.com', + 'followers': 6350, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_384622_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '佐小夕', + 'site_id': '384622', + 'type': 'user', + 'url': 'https://zuoxiaoxi.tuchong.com/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '384622', + 'sites': [], + 'tags': ['人像爱好者', '人像', '美女', '圣诞节', '时尚', '性感的'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://zuoxiaoxi.tuchong.com/60920602/', + 'views': 3709 + }, + { + 'author_id': '15787944', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 54, + 'content': null, + 'created_at': '2019-12-25 09:34:03', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['胶片人文和纪实交流', '胶片人像摄影', '胶片集'], + 'excerpt': + '现在看去电影院看电影,大部分是数码影片了,也有胶卷版,很少播放了。你在家网络看在线?或者下载?都是数码版了无论静态相片和动态视频,数码胶片早就不用讨论了', + 'favorite_list_prefix': [], + 'favorites': 1, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '43', + 'passed_time': '2019年12月25日', + 'post_id': 60947952, + 'published_at': '2019-12-25 09:34:03', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 3, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15787944_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '七分之一的想念', + 'site_id': '15787944', + 'type': 'user', + 'url': 'https://tuchong.com/15787944/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15787944', + 'sites': [], + 'tags': ['胶片人文和纪实交流', '胶片人像摄影', '胶片集'], + 'title': '你觉得胶片机的时代过去了吗?为什么?', + 'title_image': null, + 'type': 'text', + 'update': false, + 'url': 'https://tuchong.com/15787944/t/60947952/', + 'views': 783 + }, + { + 'author_id': '1732078', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 8, + 'content': '猎德大桥。', + 'created_at': '2020-01-02 09:37:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + 'E▪shutter', + '图虫旅行摄影圈子', + '光影者的风光摄影', + '图虫城市建筑', + '极致风光摄影', + '最满意的风光照', + '我们都是城市探险家', + '风光摄影圈', + '一起拍建筑', + '直到世界的尽头' + ], + 'excerpt': '猎德大桥。', + 'favorite_list_prefix': [], + 'favorites': 41, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 316655214, + 'img_id_str': '316655214', + 'title': '001', + 'user_id': 1732078, + 'width': 1125 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '01月02日', + 'post_id': 61313157, + 'published_at': '2020-01-02 09:37:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 1389, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1732078_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '一念初见丶', + 'site_id': '1732078', + 'type': 'user', + 'url': 'https://tuchong.com/1732078/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1732078', + 'sites': [], + 'tags': [ + 'E▪shutter', + '图虫旅行摄影圈子', + '光影者的风光摄影', + '图虫城市建筑', + '极致风光摄影', + '最满意的风光照' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1732078/61313157/', + 'views': 2108 + }, + { + 'author_id': '4296004', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': 'A Dream', + 'created_at': '2020-01-13 18:36:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['人像写真摄影约拍'], + 'excerpt': 'A Dream', + 'favorite_list_prefix': [], + 'favorites': 10, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 79546086, + 'img_id_str': '79546086', + 'title': '001', + 'user_id': 4296004, + 'width': 2690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5918, + 'img_id': 153208780, + 'img_id_str': '153208780', + 'title': '001', + 'user_id': 4296004, + 'width': 3947 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 488883546, + 'img_id_str': '488883546', + 'title': '001', + 'user_id': 4296004, + 'width': 2689 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 479315652, + 'img_id_str': '479315652', + 'title': '001', + 'user_id': 4296004, + 'width': 2690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2690, + 'img_id': 361875193, + 'img_id_str': '361875193', + 'title': '001', + 'user_id': 4296004, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 513132289, + 'img_id_str': '513132289', + 'title': '001', + 'user_id': 4296004, + 'width': 2690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 259377099, + 'img_id_str': '259377099', + 'title': '001', + 'user_id': 4296004, + 'width': 2690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 399165599, + 'img_id_str': '399165599', + 'title': '001', + 'user_id': 4296004, + 'width': 2690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4084, + 'img_id': 277137153, + 'img_id_str': '277137153', + 'title': '001', + 'user_id': 4296004, + 'width': 6122 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月13日', + 'post_id': 61676200, + 'published_at': '2020-01-13 18:36:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 554, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4296004_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'BonBon的Pan', + 'site_id': '4296004', + 'type': 'user', + 'url': 'https://tuchong.com/4296004/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4296004', + 'sites': [], + 'tags': ['人像写真摄影约拍', '北海道', '二世古', '羊蹄山', '风光', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4296004/61676200/', + 'views': 310 + }, + { + 'author_id': '7848088', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '瓦拉纳西的印度教徒清晨起来打扫他的住所', + 'created_at': '2019-12-18 21:20:54', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片'], + 'excerpt': '瓦拉纳西的印度教徒清晨起来打扫他的住所', + 'favorite_list_prefix': [], + 'favorites': 34, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5503, + 'img_id': 357090789, + 'img_id_str': '357090789', + 'title': '1563797', + 'user_id': 7848088, + 'width': 3598 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '2019年12月18日', + 'post_id': 60662919, + 'published_at': '2019-12-18 21:20:54', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '鸟人', + 'domain': '', + 'followers': 59, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_7848088_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '琛羽', + 'site_id': '7848088', + 'type': 'user', + 'url': 'https://tuchong.com/7848088/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '7848088', + 'sites': [], + 'tags': ['2019你最满意的照片', '2019-旅程'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/7848088/60662919/', + 'views': 1384 + }, + { + 'author_id': '2726856', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '白鹭相伴', + 'created_at': '2020-01-02 09:57:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['中国手机摄影'], + 'excerpt': '白鹭相伴', + 'favorite_list_prefix': [], + 'favorites': 56, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 637388692, + 'img_id_str': '637388692', + 'title': '001', + 'user_id': 2726856, + 'width': 1202 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '01月02日', + 'post_id': 61313646, + 'published_at': '2020-01-02 09:57:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 3, + 'site': { + 'description': '第三届京东金像奖年度作品奖获得者', + 'domain': '', + 'followers': 5231, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2726856_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'ALUphotography', + 'site_id': '2726856', + 'type': 'user', + 'url': 'https://tuchong.com/2726856/', + 'verification_list': [ + {'verification_reason': '第三届京东金像奖年度作品奖获得者', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2726856', + 'sites': [], + 'tags': ['中国手机摄影', '风光', '旅行', '色彩', '城市', '亲子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2726856/61313646/', + 'views': 2138 + }, + { + 'author_id': '1028071', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 11, + 'content': 'Beauty', + 'created_at': '2019-12-20 14:18:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地', '分享神仙颜值'], + 'excerpt': 'Beauty', + 'favorite_list_prefix': [], + 'favorites': 195, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 126075906, + 'img_id_str': '126075906', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 494847231, + 'img_id_str': '494847231', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 184730593, + 'img_id_str': '184730593', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 191743002, + 'img_id_str': '191743002', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 609993411, + 'img_id_str': '609993411', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 506971060, + 'img_id_str': '506971060', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 361153315, + 'img_id_str': '361153315', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 132498581, + 'img_id_str': '132498581', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2208, + 'img_id': 379307530, + 'img_id_str': '379307530', + 'title': '001', + 'user_id': 1028071, + 'width': 1242 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '11', + 'passed_time': '2019年12月20日', + 'post_id': 60733833, + 'published_at': '2019-12-20 14:18:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '5', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'ysgart.tuchong.com', + 'followers': 1370, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1028071_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '一束光ART', + 'site_id': '1028071', + 'type': 'user', + 'url': 'https://ysgart.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1028071', + 'sites': [], + 'tags': ['高颜值女神聚集地', '分享神仙颜值', '时尚', '漂亮的', '肖像', '人'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://ysgart.tuchong.com/60733833/', + 'views': 11206 + }, + { + 'author_id': '1', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 20, + 'content': null, + 'created_at': '2020-01-02 17:05:56', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '浙江摄影俱乐部', + '手机摄影小分队', + '华为摄影爱好者', + '极简主义摄影', + '极简主义,少即是多', + '火烛一花精品摄影', + '我爱街拍摄影小组圈子', + '生活小确幸', + '美图汇', + '静物美学' + ], + 'excerpt': + '第六期圈子互动排行榜重磅出炉!每周小秘书会统计大家在圈子里发布的评论,按照圈子成员的人均评论数由高到低进行排名。恭喜以下摄影师管理的圈子成功上榜 !✿✿ヽ( ̄▽ ̄)ノ✿撒花撒花~~~第一名:静物美学圈主:@林大胖本胖第二名:美图汇圈主:@琥珀Hooper第三名:生活小确幸圈主@恬梦想第四名:我爱街拍摄影小组圈子圈主:@葫韵雅笛第五名:火烛一花精品摄影圈主@火烛鸣花第六名:极简主义,少即是多圈主@藏在取景器后的鹿先森...', + 'favorite_list_prefix': [], + 'favorites': 118, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '13', + 'passed_time': '01月02日', + 'post_id': 61325862, + 'published_at': '2020-01-02 17:05:56', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 7, + 'site': { + 'description': '图虫官方账号', + 'domain': 'webmaster.tuchong.com', + 'followers': 9932336, + 'has_everphoto_note': true, + 'icon': 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '图虫小秘书', + 'site_id': '1', + 'type': 'user', + 'url': 'https://webmaster.tuchong.com/', + 'verification_list': [ + {'verification_reason': '图虫官方账号', 'verification_type': 11} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1', + 'sites': [], + 'tags': [ + '浙江摄影俱乐部', + '手机摄影小分队', + '华为摄影爱好者', + '极简主义摄影', + '极简主义,少即是多', + '火烛一花精品摄影' + ], + 'title': '第六期圈子互动排行榜重磅出炉!', + 'title_image': { + 'width': 600, + 'height': 355, + 'url': 'https://tuchong.pstatp.com/1/l/94228315.jpg' + }, + 'type': 'text', + 'update': false, + 'url': 'https://webmaster.tuchong.com/t/61325862/', + 'views': 23235 + }, + { + 'author_id': '332120', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '冬天想念着夏天,秋天期待着春天。淡淡的期盼最美。', + 'created_at': '2019-12-30 18:14:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地', '人像爱好者', '暖色调人像', '成都约拍圈子', '分享神仙颜值'], + 'excerpt': '冬天想念着夏天,秋天期待着春天。淡淡的期盼最美。', + 'favorite_list_prefix': [], + 'favorites': 62, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2600, + 'img_id': 616285717, + 'img_id_str': '616285717', + 'title': '463571', + 'user_id': 332120, + 'width': 1734 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2600, + 'img_id': 469484695, + 'img_id_str': '469484695', + 'title': '463572', + 'user_id': 332120, + 'width': 1733 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2600, + 'img_id': 582665618, + 'img_id_str': '582665618', + 'title': '463573', + 'user_id': 332120, + 'width': 1733 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月30日', + 'post_id': 61191162, + 'published_at': '2019-12-30 18:14:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1917, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_332120_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '陈皮兔的片场', + 'site_id': '332120', + 'type': 'user', + 'url': 'https://tuchong.com/332120/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '332120', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像爱好者', '暖色调人像', '成都约拍圈子', '分享神仙颜值', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/332120/61191162/', + 'views': 3115 + }, + { + 'author_id': '3330966', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '是一个关于旅行的故事~\n出镜:南水 小一', + 'created_at': '2019-12-29 21:08:14', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '是一个关于旅行的故事~\n出镜:南水 小一', + 'favorite_list_prefix': [], + 'favorites': 46, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 271631127, + 'img_id_str': '271631127', + 'title': '', + 'user_id': 3330966, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 478266846, + 'img_id_str': '478266846', + 'title': '', + 'user_id': 3330966, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 247121572, + 'img_id_str': '247121572', + 'title': '', + 'user_id': 3330966, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 481412215, + 'img_id_str': '481412215', + 'title': '', + 'user_id': 3330966, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5859, + 'img_id': 364758555, + 'img_id_str': '364758555', + 'title': '', + 'user_id': 3330966, + 'width': 3906 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 515294557, + 'img_id_str': '515294557', + 'title': '', + 'user_id': 3330966, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 315804647, + 'img_id_str': '315804647', + 'title': '', + 'user_id': 3330966, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 212846078, + 'img_id_str': '212846078', + 'title': '', + 'user_id': 3330966, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月29日', + 'post_id': 61155623, + 'published_at': '2019-12-29 21:08:14', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3097, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3330966_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '与倾-', + 'site_id': '3330966', + 'type': 'user', + 'url': 'https://tuchong.com/3330966/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3330966', + 'sites': [], + 'tags': ['人像', '旅行', '南京', 'Sony', 'lolita'], + 'title': '爱与死双子~', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3330966/61155623/', + 'views': 2718 + }, + { + 'author_id': '9089124', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 27, + 'content': '時代在變,記憶不變', + 'created_at': '2019-12-20 14:28:42', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片'], + 'excerpt': '時代在變,記憶不變', + 'favorite_list_prefix': [], + 'favorites': 240, + 'image_count': 47, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5602, + 'img_id': 596951717, + 'img_id_str': '596951717', + 'title': '001', + 'user_id': 9089124, + 'width': 4423 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 297583740, + 'img_id_str': '297583740', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 260293341, + 'img_id_str': '260293341', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2517, + 'img_id': 330089828, + 'img_id_str': '330089828', + 'title': '001', + 'user_id': 9089124, + 'width': 4043 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3650, + 'img_id': 515884147, + 'img_id_str': '515884147', + 'title': '001', + 'user_id': 9089124, + 'width': 6489 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4566, + 'img_id': 149865482, + 'img_id_str': '149865482', + 'title': '001', + 'user_id': 9089124, + 'width': 3960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3825, + 'img_id': 596493261, + 'img_id_str': '596493261', + 'title': '001', + 'user_id': 9089124, + 'width': 3825 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6017, + 'img_id': 309511243, + 'img_id_str': '309511243', + 'title': '001', + 'user_id': 9089124, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4007, + 'img_id': 124765002, + 'img_id_str': '124765002', + 'title': '001', + 'user_id': 9089124, + 'width': 2254 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3755, + 'img_id': 56148820, + 'img_id_str': '56148820', + 'title': '001', + 'user_id': 9089124, + 'width': 6680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3513, + 'img_id': 324715710, + 'img_id_str': '324715710', + 'title': '001', + 'user_id': 9089124, + 'width': 2823 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3690, + 'img_id': 497272330, + 'img_id_str': '497272330', + 'title': '001', + 'user_id': 9089124, + 'width': 6560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4299, + 'img_id': 602588072, + 'img_id_str': '602588072', + 'title': '001', + 'user_id': 9089124, + 'width': 4981 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4977, + 'img_id': 379241629, + 'img_id_str': '379241629', + 'title': '001', + 'user_id': 9089124, + 'width': 4477 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 572048529, + 'img_id_str': '572048529', + 'title': '001', + 'user_id': 9089124, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2938, + 'img_id': 288146706, + 'img_id_str': '288146706', + 'title': '001', + 'user_id': 9089124, + 'width': 2595 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 79873366, + 'img_id_str': '79873366', + 'title': '001', + 'user_id': 9089124, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3977, + 'img_id': 356107390, + 'img_id_str': '356107390', + 'title': '001', + 'user_id': 9089124, + 'width': 4935 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3761, + 'img_id': 355910721, + 'img_id_str': '355910721', + 'title': '001', + 'user_id': 9089124, + 'width': 4540 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5119, + 'img_id': 122668590, + 'img_id_str': '122668590', + 'title': '001', + 'user_id': 9089124, + 'width': 3968 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3411, + 'img_id': 242860815, + 'img_id_str': '242860815', + 'title': '001', + 'user_id': 9089124, + 'width': 6137 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3373, + 'img_id': 651609141, + 'img_id_str': '651609141', + 'title': '001', + 'user_id': 9089124, + 'width': 5999 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3211, + 'img_id': 555533821, + 'img_id_str': '555533821', + 'title': '001', + 'user_id': 9089124, + 'width': 5710 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3431, + 'img_id': 612418685, + 'img_id_str': '612418685', + 'title': '001', + 'user_id': 9089124, + 'width': 6101 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3039, + 'img_id': 266519712, + 'img_id_str': '266519712', + 'title': '001', + 'user_id': 9089124, + 'width': 5403 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3343, + 'img_id': 100975829, + 'img_id_str': '100975829', + 'title': '001', + 'user_id': 9089124, + 'width': 5943 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2817, + 'img_id': 102614545, + 'img_id_str': '102614545', + 'title': '001', + 'user_id': 9089124, + 'width': 4699 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3871, + 'img_id': 382911747, + 'img_id_str': '382911747', + 'title': '001', + 'user_id': 9089124, + 'width': 3976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6328, + 'img_id': 319473207, + 'img_id_str': '319473207', + 'title': '001', + 'user_id': 9089124, + 'width': 4289 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4235, + 'img_id': 570213541, + 'img_id_str': '570213541', + 'title': '001', + 'user_id': 9089124, + 'width': 5946 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5697, + 'img_id': 529188052, + 'img_id_str': '529188052', + 'title': '001', + 'user_id': 9089124, + 'width': 3206 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6188, + 'img_id': 620020812, + 'img_id_str': '620020812', + 'title': '001', + 'user_id': 9089124, + 'width': 3245 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5483, + 'img_id': 147506237, + 'img_id_str': '147506237', + 'title': '001', + 'user_id': 9089124, + 'width': 3084 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5869, + 'img_id': 277660283, + 'img_id_str': '277660283', + 'title': '001', + 'user_id': 9089124, + 'width': 4012 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 610190159, + 'img_id_str': '610190159', + 'title': '001', + 'user_id': 9089124, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 61588625, + 'img_id_str': '61588625', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3717, + 'img_id': 611828747, + 'img_id_str': '611828747', + 'title': '001', + 'user_id': 9089124, + 'width': 2306 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 146785537, + 'img_id_str': '146785537', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5620, + 'img_id': 259179578, + 'img_id_str': '259179578', + 'title': '001', + 'user_id': 9089124, + 'width': 3161 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5151, + 'img_id': 259703570, + 'img_id_str': '259703570', + 'title': '001', + 'user_id': 9089124, + 'width': 3569 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5787, + 'img_id': 211927861, + 'img_id_str': '211927861', + 'title': '001', + 'user_id': 9089124, + 'width': 3868 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6719, + 'img_id': 531154000, + 'img_id_str': '531154000', + 'title': '001', + 'user_id': 9089124, + 'width': 3779 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5396, + 'img_id': 604423238, + 'img_id_str': '604423238', + 'title': '001', + 'user_id': 9089124, + 'width': 3400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 150258828, + 'img_id_str': '150258828', + 'title': '001', + 'user_id': 9089124, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 510444586, + 'img_id_str': '510444586', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 428459236, + 'img_id_str': '428459236', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 118932899, + 'img_id_str': '118932899', + 'title': '001', + 'user_id': 9089124, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '19', + 'passed_time': '2019年12月20日', + 'post_id': 60734171, + 'published_at': '2019-12-20 14:28:42', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 19, + 'site': { + 'description': '资深纪实摄影师', + 'domain': 'sky369369.tuchong.com', + 'followers': 8458, + 'has_everphoto_note': false, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_9089124_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '拾光朝圣者', + 'site_id': '9089124', + 'type': 'user', + 'url': 'https://sky369369.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深纪实摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '9089124', + 'sites': [], + 'tags': ['2019你最满意的照片', '风光', '色彩', '城市', '纪实', '抓拍'], + 'title': '時代在變,記憶不變', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sky369369.tuchong.com/60734171/', + 'views': 9654 + }, + { + 'author_id': '2408598', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '忙碌的圣诞季~', + 'created_at': '2019-12-20 08:20:56', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '上海人像圈子', + '上海大学摄影圈', + '图虫旅行摄影圈子', + '高颜值女神聚集地', + '尼康器材党', + '绝不停止记录的2019', + '我要上“首页推荐位”', + '我要上开屏', + '分享神仙颜值', + '拍女友才是正经事' + ], + 'excerpt': '忙碌的圣诞季~', + 'favorite_list_prefix': [], + 'favorites': 37, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1924, + 'img_id': 204391728, + 'img_id_str': '204391728', + 'title': '001', + 'user_id': 2408598, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 144622598, + 'img_id_str': '144622598', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 160941386, + 'img_id_str': '160941386', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 373671086, + 'img_id_str': '373671086', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 172147877, + 'img_id_str': '172147877', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 394183699, + 'img_id_str': '394183699', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 94029031, + 'img_id_str': '94029031', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1924, + 'img_id': 175686845, + 'img_id_str': '175686845', + 'title': '001', + 'user_id': 2408598, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1924, + 'img_id': 93701664, + 'img_id_str': '93701664', + 'title': '001', + 'user_id': 2408598, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 427148654, + 'img_id_str': '427148654', + 'title': '001', + 'user_id': 2408598, + 'width': 1924 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1924, + 'img_id': 616678766, + 'img_id_str': '616678766', + 'title': '001', + 'user_id': 2408598, + 'width': 1280 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '2019年12月20日', + 'post_id': 60721603, + 'published_at': '2019-12-20 08:20:56', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7436, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2408598_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '甄隐', + 'site_id': '2408598', + 'type': 'user', + 'url': 'https://tuchong.com/2408598/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2408598', + 'sites': [], + 'tags': [ + '上海人像圈子', + '上海大学摄影圈', + '图虫旅行摄影圈子', + '高颜值女神聚集地', + '尼康器材党', + '绝不停止记录的2019' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2408598/60721603/', + 'views': 2353 + }, + { + 'author_id': '15323144', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '妈妈带你飞!婆罗洲长臂猿母子,拍摄于万合地理刚刚结束的跨年的婆罗洲热带雨林行程。', + 'created_at': '2020-01-08 10:15:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '野生动物摄影与保护', + '河北摄影家俱乐部', + '在图虫看动物世界', + '江苏摄影俱乐部', + '浙江摄影俱乐部', + '广深摄影联盟', + '环球旅行摄影', + '上海交通大学摄影圈', + '图虫旅行摄影圈子', + '深圳摄影圈' + ], + 'excerpt': '妈妈带你飞!婆罗洲长臂猿母子,拍摄于万合地理刚刚结束的跨年的婆罗洲热带雨林行程。', + 'favorite_list_prefix': [], + 'favorites': 20, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2836, + 'img_id': 358729319, + 'img_id_str': '358729319', + 'title': '001', + 'user_id': 15323144, + 'width': 5043 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月08日', + 'post_id': 61510102, + 'published_at': '2020-01-08 10:15:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '2019年Nature’s Best Photography自然视频最佳荣誉奖获得者', + 'domain': '', + 'followers': 9974, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15323144_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '万合地理', + 'site_id': '15323144', + 'type': 'user', + 'url': 'https://tuchong.com/15323144/', + 'verification_list': [ + { + 'verification_reason': '2019年Nature’s Best Photography自然视频最佳荣誉奖获得者', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '15323144', + 'sites': [], + 'tags': [ + '野生动物摄影与保护', + '河北摄影家俱乐部', + '在图虫看动物世界', + '江苏摄影俱乐部', + '浙江摄影俱乐部', + '广深摄影联盟' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15323144/61510102/', + 'views': 497 + }, + { + 'author_id': '1654881', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '贝加尔湖的傍晚', + 'created_at': '2019-12-20 10:07:03', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['晒晒旅行打卡照'], + 'excerpt': '贝加尔湖的傍晚', + 'favorite_list_prefix': [], + 'favorites': 56, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 267895931, + 'img_id_str': '267895931', + 'title': '76300', + 'user_id': 1654881, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月20日', + 'post_id': 60724918, + 'published_at': '2019-12-20 10:07:03', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深旅行摄影师', + 'domain': 'gaoshushuphoto.tuchong.com', + 'followers': 3876, + 'has_everphoto_note': false, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1654881_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '高叔叔旅行摄影', + 'site_id': '1654881', + 'type': 'user', + 'url': 'https://gaoshushuphoto.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1654881', + 'sites': [], + 'tags': ['晒晒旅行打卡照', '旅行'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://gaoshushuphoto.tuchong.com/60724918/', + 'views': 2190 + }, + { + 'author_id': '373645', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '冬季北极圈的正午,太阳短暂的升起后又即将落下,余晖中月亮清晰可见~', + 'created_at': '2020-01-05 14:51:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '冬季北极圈的正午,太阳短暂的升起后又即将落下,余晖中月亮清晰可见~', + 'favorite_list_prefix': [], + 'favorites': 51, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1201, + 'img_id': 39634649, + 'img_id_str': '39634649', + 'title': '', + 'user_id': 373645, + 'width': 1800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月05日', + 'post_id': 61419304, + 'published_at': '2020-01-05 14:51:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '图虫图库销售达人', + 'domain': 'jiachenji.tuchong.com', + 'followers': 5579, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_373645_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '阿琛JiachenJi', + 'site_id': '373645', + 'type': 'user', + 'url': 'https://jiachenji.tuchong.com/', + 'verification_list': [ + {'verification_reason': '图虫图库销售达人', 'verification_type': 14} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '373645', + 'sites': [], + 'tags': ['风光', '色彩', '旅行', '日落', '夜景', '长曝光'], + 'title': '《正午的月》', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://jiachenji.tuchong.com/61419304/', + 'views': 1480 + }, + { + 'author_id': '1167303', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 11, + 'content': '没有刻意地见面\n\n就真的没有见过了/\n\n@摄影讲师李小龙', + 'created_at': '2019-11-25 16:21:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '没有刻意地见面\n\n就真的没有见过了/\n\n@摄影讲师李小龙', + 'favorite_list_prefix': [], + 'favorites': 231, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4044, + 'img_id': 419348211, + 'img_id_str': '419348211', + 'title': '', + 'user_id': 1167303, + 'width': 2696 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 333299830, + 'img_id_str': '333299830', + 'title': '', + 'user_id': 1167303, + 'width': 4464 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4323, + 'img_id': 513720581, + 'img_id_str': '513720581', + 'title': '', + 'user_id': 1167303, + 'width': 2882 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2878, + 'img_id': 385924927, + 'img_id_str': '385924927', + 'title': '', + 'user_id': 1167303, + 'width': 4317 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4290, + 'img_id': 256098005, + 'img_id_str': '256098005', + 'title': '', + 'user_id': 1167303, + 'width': 2860 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4227, + 'img_id': 101826311, + 'img_id_str': '101826311', + 'title': '', + 'user_id': 1167303, + 'width': 2818 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2804, + 'img_id': 106283225, + 'img_id_str': '106283225', + 'title': '', + 'user_id': 1167303, + 'width': 4206 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4183, + 'img_id': 86556889, + 'img_id_str': '86556889', + 'title': '', + 'user_id': 1167303, + 'width': 2789 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4209, + 'img_id': 424394895, + 'img_id_str': '424394895', + 'title': '', + 'user_id': 1167303, + 'width': 2806 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '2019年11月25日', + 'post_id': 59315666, + 'published_at': '2019-11-25 16:21:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 9131, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1167303_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄影讲师李小龙', + 'site_id': '1167303', + 'type': 'user', + 'url': 'https://tuchong.com/1167303/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1167303', + 'sites': [], + 'tags': ['人像', '色彩', '情绪', '摄影讲师李小龙'], + 'title': '没有刻意地见面 就真的没有见过了/ @摄影讲师李小龙', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1167303/59315666/', + 'views': 21569 + }, + { + 'author_id': '1457161', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2019-12-26 22:41:12', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片', '2020适马睛典'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 47, + 'image_count': 31, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 243451135, + 'img_id_str': '243451135', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 613467369, + 'img_id_str': '613467369', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 78366124, + 'img_id_str': '78366124', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 411026953, + 'img_id_str': '411026953', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 39503365, + 'img_id_str': '39503365', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 388024071, + 'img_id_str': '388024071', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 601671139, + 'img_id_str': '601671139', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 170837455, + 'img_id_str': '170837455', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 117426055, + 'img_id_str': '117426055', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 236569766, + 'img_id_str': '236569766', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 648791371, + 'img_id_str': '648791371', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1446, + 'img_id': 259769491, + 'img_id_str': '259769491', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 108512253, + 'img_id_str': '108512253', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 204653811, + 'img_id_str': '204653811', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 425117373, + 'img_id_str': '425117373', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1461, + 'img_id': 95274442, + 'img_id_str': '95274442', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 295748782, + 'img_id_str': '295748782', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 601867762, + 'img_id_str': '601867762', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 576308716, + 'img_id_str': '576308716', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 55887494, + 'img_id_str': '55887494', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 550946219, + 'img_id_str': '550946219', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 599180556, + 'img_id_str': '599180556', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 354010553, + 'img_id_str': '354010553', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1548, + 'img_id': 408012170, + 'img_id_str': '408012170', + 'title': '', + 'user_id': 1457161, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 158582281, + 'img_id_str': '158582281', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 74171694, + 'img_id_str': '74171694', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 197117327, + 'img_id_str': '197117327', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 351782042, + 'img_id_str': '351782042', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 565298718, + 'img_id_str': '565298718', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 329762116, + 'img_id_str': '329762116', + 'title': '', + 'user_id': 1457161, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 361153506, + 'img_id_str': '361153506', + 'title': '', + 'user_id': 1457161, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '2019年12月26日', + 'post_id': 61010097, + 'published_at': '2019-12-26 22:41:12', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深静物摄影师', + 'domain': 'lixiaojian00.tuchong.com', + 'followers': 1687, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1457161_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '李小简', + 'site_id': '1457161', + 'type': 'user', + 'url': 'https://lixiaojian00.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深静物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1457161', + 'sites': [], + 'tags': ['2019你最满意的照片', '2020适马睛典', '少女', '人像', '胶片', '女孩'], + 'title': '《 游乐园 》', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://lixiaojian00.tuchong.com/61010097/', + 'views': 2323 + }, + { + 'author_id': '33937', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 95, + 'content': '志异书·羽见', + 'created_at': '2019-09-14 23:59:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['武汉人像摄影', '宜昌摄影小组', '华中农业大学', 'Alphastyle', '我要上开屏'], + 'excerpt': '志异书·羽见', + 'favorite_list_prefix': [], + 'favorites': 2263, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5094, + 'img_id': 397648555, + 'img_id_str': '397648555', + 'title': '001', + 'user_id': 33937, + 'width': 3396 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5486, + 'img_id': 391356992, + 'img_id_str': '391356992', + 'title': '001', + 'user_id': 33937, + 'width': 3658 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 393585472, + 'img_id_str': '393585472', + 'title': '001', + 'user_id': 33937, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5616, + 'img_id': 407478990, + 'img_id_str': '407478990', + 'title': '001', + 'user_id': 33937, + 'width': 3744 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4808, + 'img_id': 248554219, + 'img_id_str': '248554219', + 'title': '001', + 'user_id': 33937, + 'width': 3206 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5334, + 'img_id': 52929322, + 'img_id_str': '52929322', + 'title': '001', + 'user_id': 33937, + 'width': 3556 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2502, + 'img_id': 58827801, + 'img_id_str': '58827801', + 'title': '001', + 'user_id': 33937, + 'width': 3752 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 236888875, + 'img_id_str': '236888875', + 'title': '001', + 'user_id': 33937, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 437757072, + 'img_id_str': '437757072', + 'title': '001', + 'user_id': 33937, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '77', + 'passed_time': '2019年09月14日', + 'post_id': 52625444, + 'published_at': '2019-09-14 23:59:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 58, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'rhine.tuchong.com', + 'followers': 3804, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_33937_13', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '时雨Rhyne', + 'site_id': '33937', + 'type': 'user', + 'url': 'https://rhine.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '33937', + 'sites': [], + 'tags': ['武汉人像摄影', '宜昌摄影小组', '华中农业大学', 'Alphastyle', '我要上开屏', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://rhine.tuchong.com/52625444/', + 'views': 61504 + }, + { + 'author_id': '326444', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 19, + 'content': 'Wei', + 'created_at': '2020-01-15 11:28:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['人像写真精选'], + 'excerpt': 'Wei', + 'favorite_list_prefix': [], + 'favorites': 241, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 186238840, + 'img_id_str': '186238840', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 97437401, + 'img_id_str': '97437401', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 68536117, + 'img_id_str': '68536117', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 520734392, + 'img_id_str': '520734392', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 538560074, + 'img_id_str': '538560074', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 565102028, + 'img_id_str': '565102028', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 280086359, + 'img_id_str': '280086359', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 230278901, + 'img_id_str': '230278901', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 442222005, + 'img_id_str': '442222005', + 'title': '001', + 'user_id': 326444, + 'width': 1500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '19', + 'passed_time': '01月15日', + 'post_id': 61725771, + 'published_at': '2020-01-15 11:28:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '7', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3424, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_326444_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '羊扬杨', + 'site_id': '326444', + 'type': 'user', + 'url': 'https://tuchong.com/326444/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '326444', + 'sites': [], + 'tags': ['人像写真精选', '床', '卧室', '女孩', '人像', '写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/326444/61725771/', + 'views': 17899 + }, + { + 'author_id': '2976763', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 67, + 'content': 'Photographer:顾小白Hala\nModel:猫病\nOrganizer:文珺Ronnie', + 'created_at': '2019-11-26 16:55:16', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '高颜值女神聚集地', + '上海人像圈子', + '糖水人像小组', + '人像爱好者', + '绝不停止记录的2019', + '分享神仙颜值', + '暖色调人像' + ], + 'excerpt': 'Photographer:顾小白Hala\nModel:猫病\nOrganizer:文珺Ronnie', + 'favorite_list_prefix': [], + 'favorites': 3097, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 7472, + 'img_id': 58441791, + 'img_id_str': '58441791', + 'title': '', + 'user_id': 2976763, + 'width': 4983 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7270, + 'img_id': 181977193, + 'img_id_str': '181977193', + 'title': '', + 'user_id': 2976763, + 'width': 4850 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7376, + 'img_id': 275628276, + 'img_id_str': '275628276', + 'title': '', + 'user_id': 2976763, + 'width': 4920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 209436826, + 'img_id_str': '209436826', + 'title': '', + 'user_id': 2976763, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 457424979, + 'img_id_str': '457424979', + 'title': '', + 'user_id': 2976763, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7525, + 'img_id': 382910660, + 'img_id_str': '382910660', + 'title': '', + 'user_id': 2976763, + 'width': 5019 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7535, + 'img_id': 91733984, + 'img_id_str': '91733984', + 'title': '', + 'user_id': 2976763, + 'width': 5026 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6932, + 'img_id': 557432970, + 'img_id_str': '557432970', + 'title': '', + 'user_id': 2976763, + 'width': 4624 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7160, + 'img_id': 178045317, + 'img_id_str': '178045317', + 'title': '', + 'user_id': 2976763, + 'width': 4776 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 94617967, + 'img_id_str': '94617967', + 'title': '', + 'user_id': 2976763, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 205700718, + 'img_id_str': '205700718', + 'title': '', + 'user_id': 2976763, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 350666874, + 'img_id_str': '350666874', + 'title': '', + 'user_id': 2976763, + 'width': 5304 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '60', + 'passed_time': '2019年11月26日', + 'post_id': 59381354, + 'published_at': '2019-11-26 16:55:16', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 74, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'gxbhala.tuchong.com', + 'followers': 39077, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2976763_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '顾小白Hala', + 'site_id': '2976763', + 'type': 'user', + 'url': 'https://gxbhala.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2976763', + 'sites': [], + 'tags': [ + '高颜值女神聚集地', + '上海人像圈子', + '糖水人像小组', + '人像爱好者', + '绝不停止记录的2019', + '分享神仙颜值' + ], + 'title': '七月的风八月的雨', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://gxbhala.tuchong.com/59381354/', + 'views': 93517 + }, + { + 'author_id': '1413882', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 12, + 'content': 'Girl and toy', + 'created_at': '2019-11-26 09:29:35', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['写真人像摄影', '成都约拍圈子', '成都人像爱好者', '高颜值女神聚集地', '分享神仙颜值'], + 'excerpt': 'Girl and toy', + 'favorite_list_prefix': [], + 'favorites': 205, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3092, + 'img_id': 297451301, + 'img_id_str': '297451301', + 'title': '001', + 'user_id': 1413882, + 'width': 4638 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 344375776, + 'img_id_str': '344375776', + 'title': '001', + 'user_id': 1413882, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3823, + 'img_id': 489734451, + 'img_id_str': '489734451', + 'title': '001', + 'user_id': 1413882, + 'width': 5734 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '11', + 'passed_time': '2019年11月26日', + 'post_id': 59359309, + 'published_at': '2019-11-26 09:29:35', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2548, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1413882_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Batkid', + 'site_id': '1413882', + 'type': 'user', + 'url': 'https://tuchong.com/1413882/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1413882', + 'sites': [], + 'tags': ['写真人像摄影', '成都约拍圈子', '成都人像爱好者', '高颜值女神聚集地', '分享神仙颜值', '人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1413882/59359309/', + 'views': 12689 + }, + { + 'author_id': '1167303', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 26, + 'content': 'flowers/\n摄影:@摄影讲师李小龙', + 'created_at': '2019-11-24 09:13:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': 'flowers/\n摄影:@摄影讲师李小龙', + 'favorite_list_prefix': [], + 'favorites': 554, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 381927278, + 'img_id_str': '381927278', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 591970623, + 'img_id_str': '591970623', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 219529401, + 'img_id_str': '219529401', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2666, + 'img_id': 561692553, + 'img_id_str': '561692553', + 'title': '', + 'user_id': 1167303, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 553107480, + 'img_id_str': '553107480', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 312066273, + 'img_id_str': '312066273', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 607830143, + 'img_id_str': '607830143', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 135839640, + 'img_id_str': '135839640', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5333, + 'img_id': 584433655, + 'img_id_str': '584433655', + 'title': '', + 'user_id': 1167303, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2666, + 'img_id': 478003022, + 'img_id_str': '478003022', + 'title': '', + 'user_id': 1167303, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 151764971, + 'img_id_str': '151764971', + 'title': '', + 'user_id': 1167303, + 'width': 2666 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '26', + 'passed_time': '2019年11月24日', + 'post_id': 59209950, + 'published_at': '2019-11-24 09:13:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '10', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 9131, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1167303_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄影讲师李小龙', + 'site_id': '1167303', + 'type': 'user', + 'url': 'https://tuchong.com/1167303/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1167303', + 'sites': [], + 'tags': ['人像', '色彩', '写真', '唯美', '武汉摄影', '摄影讲师李小龙'], + 'title': 'flowers/ @摄影讲师李小龙', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1167303/59209950/', + 'views': 18940 + }, + { + 'author_id': '1878099', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 14, + 'content': '#喜欢秋天?\n 连打喷嚏的时候\n 都会变成"爱秋"~\n\n ???', + 'created_at': '2019-10-20 16:00:30', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '#喜欢秋天?\n 连打喷嚏的时候\n 都会变成"爱秋"~\n\n ???', + 'favorite_list_prefix': [], + 'favorites': 317, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 43562163, + 'img_id_str': '43562163', + 'title': '001', + 'user_id': 1878099, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 89372283, + 'img_id_str': '89372283', + 'title': '001', + 'user_id': 1878099, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3557, + 'img_id': 217167268, + 'img_id_str': '217167268', + 'title': '001', + 'user_id': 1878099, + 'width': 5336 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 484226447, + 'img_id_str': '484226447', + 'title': '001', + 'user_id': 1878099, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1984, + 'img_id': 518042896, + 'img_id_str': '518042896', + 'title': '001', + 'user_id': 1878099, + 'width': 1323 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 564573467, + 'img_id_str': '564573467', + 'title': '001', + 'user_id': 1878099, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3166, + 'img_id': 411415776, + 'img_id_str': '411415776', + 'title': '001', + 'user_id': 1878099, + 'width': 4749 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 451130560, + 'img_id_str': '451130560', + 'title': '001', + 'user_id': 1878099, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '14', + 'passed_time': '2019年10月20日', + 'post_id': 56451282, + 'published_at': '2019-10-20 16:00:30', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 461, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1878099_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '阿俊的家常摄影', + 'site_id': '1878099', + 'type': 'user', + 'url': 'https://tuchong.com/1878099/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1878099', + 'sites': [], + 'tags': ['浴室少女', '洗澡'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1878099/56451282/', + 'views': 16518 + }, + { + 'author_id': '8080241', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '体操服少女『上篇』\n\n摄于深大,下篇将会去到户外体育场,敬请期待', + 'created_at': '2020-01-15 16:20:18', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Alphastyle', '高颜值女神聚集地', '糖水人像小组'], + 'excerpt': '体操服少女『上篇』\n\n摄于深大,下篇将会去到户外体育场,敬请期待', + 'favorite_list_prefix': [], + 'favorites': 259, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3375, + 'img_id': 244631432, + 'img_id_str': '244631432', + 'title': '001', + 'user_id': 8080241, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 136562376, + 'img_id_str': '136562376', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 534825029, + 'img_id_str': '534825029', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 445826467, + 'img_id_str': '445826467', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 536528189, + 'img_id_str': '536528189', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 151701271, + 'img_id_str': '151701271', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 160876358, + 'img_id_str': '160876358', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 483968653, + 'img_id_str': '483968653', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 593479525, + 'img_id_str': '593479525', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 328451914, + 'img_id_str': '328451914', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 206620333, + 'img_id_str': '206620333', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 183420535, + 'img_id_str': '183420535', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 300599215, + 'img_id_str': '300599215', + 'title': '001', + 'user_id': 8080241, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '01月15日', + 'post_id': 61732092, + 'published_at': '2020-01-15 16:20:18', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2263, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_8080241_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '黄轩wower', + 'site_id': '8080241', + 'type': 'user', + 'url': 'https://tuchong.com/8080241/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '8080241', + 'sites': [], + 'tags': ['Alphastyle', '高颜值女神聚集地', '糖水人像小组', '体操服', '少女', '写真'], + 'title': '体操服少女『上篇』『室内篇』', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8080241/61732092/', + 'views': 12653 + }, + { + 'author_id': '3062259', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '', + 'created_at': '2020-01-07 22:36:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['毛茸茸的小动物'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 23, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3909, + 'img_id': 610125360, + 'img_id_str': '610125360', + 'title': '001', + 'user_id': 3062259, + 'width': 5864 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月07日', + 'post_id': 61499223, + 'published_at': '2020-01-07 22:36:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深宠物摄影师', + 'domain': '', + 'followers': 855, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3062259_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '布约二筒摄影工作室', + 'site_id': '3062259', + 'type': 'user', + 'url': 'https://tuchong.com/3062259/', + 'verification_list': [ + {'verification_reason': '资深宠物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3062259', + 'sites': [], + 'tags': ['毛茸茸的小动物', '狗', '犬科', '宠物', '可爱', '滑稽'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3062259/61499223/', + 'views': 962 + }, + { + 'author_id': '1937912', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 13, + 'content': '摄影:紫荞\n模特:CC\n地址:小鹿奔跑了摄影工作室\n—一组少女室内写真-', + 'created_at': '2019-11-07 10:02:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫·OPENSEE2019'], + 'excerpt': '摄影:紫荞\n模特:CC\n地址:小鹿奔跑了摄影工作室\n—一组少女室内写真-', + 'favorite_list_prefix': [], + 'favorites': 458, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 551860724, + 'img_id_str': '551860724', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 285522968, + 'img_id_str': '285522968', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3980, + 'img_id': 610515614, + 'img_id_str': '610515614', + 'title': '001', + 'user_id': 1937912, + 'width': 5851 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 272349957, + 'img_id_str': '272349957', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 51821070, + 'img_id_str': '51821070', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6068, + 'img_id': 191478595, + 'img_id_str': '191478595', + 'title': '001', + 'user_id': 1937912, + 'width': 4035 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6172, + 'img_id': 332315518, + 'img_id_str': '332315518', + 'title': '001', + 'user_id': 1937912, + 'width': 4075 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 446741124, + 'img_id_str': '446741124', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5911, + 'img_id': 102546487, + 'img_id_str': '102546487', + 'title': '001', + 'user_id': 1937912, + 'width': 4043 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '13', + 'passed_time': '2019年11月07日', + 'post_id': 57990560, + 'published_at': '2019-11-07 10:02:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7144, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1937912_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '紫荞姑娘', + 'site_id': '1937912', + 'type': 'user', + 'url': 'https://tuchong.com/1937912/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1937912', + 'sites': [], + 'tags': ['图虫·OPENSEE2019', '在室内', '人像', '深圳约拍', '时光是个美人', '文艺小清新'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1937912/57990560/', + 'views': 16320 + }, + { + 'author_id': '1724834', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '“ 愿有人陪你疯陪你傻 陪你成熟直到长大 ”\n\n? 丨 @漫三摄影工作室', + 'created_at': '2019-12-19 17:02:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地', '带我看看,你的城市', '我要上开屏', '趣味话题:唯美如你'], + 'excerpt': '“ 愿有人陪你疯陪你傻 陪你成熟直到长大 ”\n\n? 丨 @漫三摄影工作室', + 'favorite_list_prefix': [], + 'favorites': 38, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 314164137, + 'img_id_str': '314164137', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 644137804, + 'img_id_str': '644137804', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 547275898, + 'img_id_str': '547275898', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 425640946, + 'img_id_str': '425640946', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 639485093, + 'img_id_str': '639485093', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 483312457, + 'img_id_str': '483312457', + 'title': '001', + 'user_id': 1724834, + 'width': 1620 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 408011927, + 'img_id_str': '408011927', + 'title': '001', + 'user_id': 1724834, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 522896403, + 'img_id_str': '522896403', + 'title': '001', + 'user_id': 1724834, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 200459305, + 'img_id_str': '200459305', + 'title': '001', + 'user_id': 1724834, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '2019年12月19日', + 'post_id': 60696153, + 'published_at': '2019-12-19 17:02:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1356, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1724834_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '漫三摄影工作室', + 'site_id': '1724834', + 'type': 'user', + 'url': 'https://tuchong.com/1724834/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1724834', + 'sites': [], + 'tags': ['高颜值女神聚集地', '带我看看,你的城市', '我要上开屏', '趣味话题:唯美如你'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1724834/60696153/', + 'views': 2134 + }, + { + 'author_id': '1182492', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 63, + 'content': '有你的避风港', + 'created_at': '2019-10-07 13:12:24', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['人像摄影集', '分享神仙颜值'], + 'excerpt': '有你的避风港', + 'favorite_list_prefix': [], + 'favorites': 2051, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 110538869, + 'img_id_str': '110538869', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 506572916, + 'img_id_str': '506572916', + 'title': '001', + 'user_id': 1182492, + 'width': 3780 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 519745408, + 'img_id_str': '519745408', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 109096819, + 'img_id_str': '109096819', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 612740712, + 'img_id_str': '612740712', + 'title': '001', + 'user_id': 1182492, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 324382323, + 'img_id_str': '324382323', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 466202652, + 'img_id_str': '466202652', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 108179491, + 'img_id_str': '108179491', + 'title': '001', + 'user_id': 1182492, + 'width': 3780 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 562933975, + 'img_id_str': '562933975', + 'title': '001', + 'user_id': 1182492, + 'width': 3780 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '60', + 'passed_time': '2019年10月07日', + 'post_id': 55083333, + 'published_at': '2019-10-07 13:12:24', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 52, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 13242, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1182492_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'KINGVISION', + 'site_id': '1182492', + 'type': 'user', + 'url': 'https://tuchong.com/1182492/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1182492', + 'sites': [], + 'tags': ['人像摄影集', '分享神仙颜值', '人像', '少女写真', '在室内'], + 'title': '有你的避风港', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1182492/55083333/', + 'views': 78437 + }, + { + 'author_id': '1182492', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 19, + 'content': '放学后一起去看银杏', + 'created_at': '2019-12-10 01:14:08', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地', '人像摄影集', '分享神仙颜值', '我们都爱日系摄影'], + 'excerpt': '放学后一起去看银杏', + 'favorite_list_prefix': [], + 'favorites': 385, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 646825098, + 'img_id_str': '646825098', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 377537285, + 'img_id_str': '377537285', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 379503513, + 'img_id_str': '379503513', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 607175504, + 'img_id_str': '607175504', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 428655253, + 'img_id_str': '428655253', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 33932015, + 'img_id_str': '33932015', + 'title': '001', + 'user_id': 1182492, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 171623852, + 'img_id_str': '171623852', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 240174086, + 'img_id_str': '240174086', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 245088936, + 'img_id_str': '245088936', + 'title': '001', + 'user_id': 1182492, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 60671065, + 'img_id_str': '60671065', + 'title': '001', + 'user_id': 1182492, + 'width': 3375 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '19', + 'passed_time': '2019年12月10日', + 'post_id': 60190047, + 'published_at': '2019-12-10 01:14:08', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 18, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 13242, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1182492_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'KINGVISION', + 'site_id': '1182492', + 'type': 'user', + 'url': 'https://tuchong.com/1182492/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1182492', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像摄影集', '分享神仙颜值', '我们都爱日系摄影', '银杏', 'JK'], + 'title': '放学后一起去看银杏', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1182492/60190047/', + 'views': 11610 + }, + { + 'author_id': '1785951', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 33, + 'content': '', + 'created_at': '2019-11-15 22:16:39', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 794, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 477740566, + 'img_id_str': '477740566', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 524467616, + 'img_id_str': '524467616', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 232374269, + 'img_id_str': '232374269', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 654425499, + 'img_id_str': '654425499', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 529579538, + 'img_id_str': '529579538', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 251313460, + 'img_id_str': '251313460', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 439467689, + 'img_id_str': '439467689', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 283426327, + 'img_id_str': '283426327', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 382778549, + 'img_id_str': '382778549', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 321568079, + 'img_id_str': '321568079', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 94878979, + 'img_id_str': '94878979', + 'title': '001', + 'user_id': 1785951, + 'width': 2460 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 356040094, + 'img_id_str': '356040094', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 149339692, + 'img_id_str': '149339692', + 'title': '001', + 'user_id': 1785951, + 'width': 3648 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '30', + 'passed_time': '2019年11月15日', + 'post_id': 58622763, + 'published_at': '2019-11-15 22:16:39', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 9, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 934, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1785951_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '苏冬至', + 'site_id': '1785951', + 'type': 'user', + 'url': 'https://tuchong.com/1785951/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1785951', + 'sites': [], + 'tags': [], + 'title': '“热爱世间万物,无最爱,无例外”', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1785951/58622763/', + 'views': 49073 + }, + { + 'author_id': '15728263', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': null, + 'created_at': '2019-12-15 09:35:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['文艺私房圈子', '美女人像群', '人像摄影集', '写真人像摄影', '暖色调人像'], + 'excerpt': + '1.模特,是让摄影师拍的对象,但是,模特是有血有肉的人,所以要考虑她的内心想法和感受,不能说摄影师想怎么拍就怎么拍,事先肯定要交流沟通的2.确定好了拍摄的主题,定好时间地点去完成拍摄,期间要有耐心的去引导模特,让彼此都能处于愉快的工作拍摄状态3.拍摄期间注意休息,休息时候可以一起看拍摄出来的照片,及时沟通调整4.模特自己喜欢的照片,希望摄影师能分享给她', + 'favorite_list_prefix': [], + 'favorites': 2, + 'image_count': 0, + 'images': [], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '4', + 'passed_time': '2019年12月15日', + 'post_id': 60471782, + 'published_at': '2019-12-15 09:35:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 0, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15728263_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '友成茗茶老板娘', + 'site_id': '15728263', + 'type': 'user', + 'url': 'https://tuchong.com/15728263/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15728263', + 'sites': [], + 'tags': ['文艺私房圈子', '美女人像群', '人像摄影集', '写真人像摄影', '暖色调人像'], + 'title': '摄影模特眼里的摄影师都有哪些类型?模特喜欢和什么样的摄影师长期合作呢?', + 'title_image': null, + 'type': 'text', + 'update': false, + 'url': 'https://tuchong.com/15728263/t/60471782/', + 'views': 920 + }, + { + 'author_id': '5417230', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '天外飞仙,黄山仙境', + 'created_at': '2020-01-18 18:41:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['最满意的风光照'], + 'excerpt': '天外飞仙,黄山仙境', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4740, + 'img_id': 425117771, + 'img_id_str': '425117771', + 'title': '001', + 'user_id': 5417230, + 'width': 6822 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月18日', + 'post_id': 61817452, + 'published_at': '2020-01-18 18:41:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 173, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5417230_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Franky-Wang', + 'site_id': '5417230', + 'type': 'user', + 'url': 'https://tuchong.com/5417230/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5417230', + 'sites': [], + 'tags': ['最满意的风光照', '山', '旅行', '雪', '风景优美的', '岩石'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5417230/61817452/', + 'views': 550 + }, + { + 'author_id': '2976763', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 51, + 'content': 'Photographer:顾小白Hala\nModel:木木\nOrganizer:文珺Ronnie', + 'created_at': '2020-01-05 16:15:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': 'Photographer:顾小白Hala\nModel:木木\nOrganizer:文珺Ronnie', + 'favorite_list_prefix': [], + 'favorites': 1090, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 271304520, + 'img_id_str': '271304520', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5890, + 'img_id': 607373428, + 'img_id_str': '607373428', + 'title': '', + 'user_id': 2976763, + 'width': 3926 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 330286271, + 'img_id_str': '330286271', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 261408236, + 'img_id_str': '261408236', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 61720558, + 'img_id_str': '61720558', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 495240899, + 'img_id_str': '495240899', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 439666298, + 'img_id_str': '439666298', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5922, + 'img_id': 490391266, + 'img_id_str': '490391266', + 'title': '', + 'user_id': 2976763, + 'width': 3948 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 528598547, + 'img_id_str': '528598547', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 147703357, + 'img_id_str': '147703357', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6424, + 'img_id': 212321628, + 'img_id_str': '212321628', + 'title': '', + 'user_id': 2976763, + 'width': 4283 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4136, + 'img_id': 272090926, + 'img_id_str': '272090926', + 'title': '', + 'user_id': 2976763, + 'width': 6204 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 149537798, + 'img_id_str': '149537798', + 'title': '', + 'user_id': 2976763, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 55035638, + 'img_id_str': '55035638', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '46', + 'passed_time': '01月05日', + 'post_id': 61421507, + 'published_at': '2020-01-05 16:15:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'gxbhala.tuchong.com', + 'followers': 39077, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2976763_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '顾小白Hala', + 'site_id': '2976763', + 'type': 'user', + 'url': 'https://gxbhala.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2976763', + 'sites': [], + 'tags': ['人像', '佳能', '小清新', '美女', '女孩', '少女'], + 'title': '二十岁的某一天', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://gxbhala.tuchong.com/61421507/', + 'views': 47936 + }, + { + 'author_id': '1117387', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 61, + 'content': '拥有你和猫咪,就是最幸福的事~', + 'created_at': '2019-11-27 14:42:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['半厨分享', '分享神仙颜值'], + 'excerpt': '拥有你和猫咪,就是最幸福的事~', + 'favorite_list_prefix': [], + 'favorites': 1134, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1819, + 'img_id': 109625297, + 'img_id_str': '109625297', + 'title': '001', + 'user_id': 1117387, + 'width': 1233 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1829, + 'img_id': 289259645, + 'img_id_str': '289259645', + 'title': '001', + 'user_id': 1117387, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1826, + 'img_id': 653508779, + 'img_id_str': '653508779', + 'title': '001', + 'user_id': 1117387, + 'width': 1211 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1768, + 'img_id': 285786071, + 'img_id_str': '285786071', + 'title': '001', + 'user_id': 1117387, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1793, + 'img_id': 124501713, + 'img_id_str': '124501713', + 'title': '001', + 'user_id': 1117387, + 'width': 1208 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1805, + 'img_id': 648593575, + 'img_id_str': '648593575', + 'title': '001', + 'user_id': 1117387, + 'width': 1229 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1828, + 'img_id': 513589103, + 'img_id_str': '513589103', + 'title': '001', + 'user_id': 1117387, + 'width': 1242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1759, + 'img_id': 378715961, + 'img_id_str': '378715961', + 'title': '001', + 'user_id': 1117387, + 'width': 1230 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1515, + 'img_id': 430227509, + 'img_id_str': '430227509', + 'title': '001', + 'user_id': 1117387, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1789, + 'img_id': 59818462, + 'img_id_str': '59818462', + 'title': '001', + 'user_id': 1117387, + 'width': 1240 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '55', + 'passed_time': '2019年11月27日', + 'post_id': 59435437, + 'published_at': '2019-11-27 14:42:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '33', + 'rqt_id': '', + 'shares': 55, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 6224, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1117387_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '陈半厨', + 'site_id': '1117387', + 'type': 'user', + 'url': 'https://tuchong.com/1117387/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1117387', + 'sites': [], + 'tags': ['半厨分享', '分享神仙颜值', '人像', '美女', '小清新', '佳能'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1117387/59435437/', + 'views': 55736 + }, + { + 'author_id': '999799', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 32, + 'content': '出镜:@GAMA伽马', + 'created_at': '2019-10-09 15:06:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '出镜:@GAMA伽马', + 'favorite_list_prefix': [], + 'favorites': 1195, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 233681205, + 'img_id_str': '233681205', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5417, + 'img_id': 125087680, + 'img_id_str': '125087680', + 'title': '', + 'user_id': 999799, + 'width': 3616 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5625, + 'img_id': 587706414, + 'img_id_str': '587706414', + 'title': '', + 'user_id': 999799, + 'width': 3755 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 340963716, + 'img_id_str': '340963716', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 73642374, + 'img_id_str': '73642374', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 539734245, + 'img_id_str': '539734245', + 'title': '', + 'user_id': 999799, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5107, + 'img_id': 297054517, + 'img_id_str': '297054517', + 'title': '', + 'user_id': 999799, + 'width': 3409 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5569, + 'img_id': 460501234, + 'img_id_str': '460501234', + 'title': '', + 'user_id': 999799, + 'width': 3717 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 248557656, + 'img_id_str': '248557656', + 'title': '', + 'user_id': 999799, + 'width': 4016 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年10月09日', + 'post_id': 55358786, + 'published_at': '2019-10-09 15:06:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 6436, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_999799_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '歌罢', + 'site_id': '999799', + 'type': 'user', + 'url': 'https://tuchong.com/999799/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '999799', + 'sites': [], + 'tags': ['JK', '少女', '人像', '日系', '情绪', '尼康'], + 'title': 'JK制服美少女', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/999799/55358786/', + 'views': 48325 + }, + { + 'author_id': '8261035', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '金色望京城。', + 'created_at': '2020-01-07 09:44:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '环球旅行摄影', + '中国爬楼联盟圈子', + '城市·夜晚', + '每人推荐一个旅行目的地', + '街拍纪实手册', + '这张天空必须要分享', + '最满意的风光照', + '风光人文地理', + '行摄部落', + '带我看看,你的城市' + ], + 'excerpt': '金色望京城。', + 'favorite_list_prefix': [], + 'favorites': 53, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3543, + 'img_id': 121160770, + 'img_id_str': '121160770', + 'title': '001', + 'user_id': 8261035, + 'width': 5315 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月07日', + 'post_id': 61477943, + 'published_at': '2020-01-07 09:44:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 1, + 'site': { + 'description': '', + 'domain': '', + 'followers': 156, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_8261035_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'aotu7', + 'site_id': '8261035', + 'type': 'user', + 'url': 'https://tuchong.com/8261035/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '8261035', + 'sites': [], + 'tags': [ + '环球旅行摄影', + '中国爬楼联盟圈子', + '城市·夜晚', + '每人推荐一个旅行目的地', + '街拍纪实手册', + '这张天空必须要分享' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8261035/61477943/', + 'views': 1885 + }, + { + 'author_id': '458707', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 97, + 'content': '', + 'created_at': '2019-09-16 17:22:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2691, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 450404980, + 'img_id_str': '450404980', + 'title': '', + 'user_id': 458707, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 451257409, + 'img_id_str': '451257409', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 182428566, + 'img_id_str': '182428566', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 414164208, + 'img_id_str': '414164208', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 513254262, + 'img_id_str': '513254262', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 142647887, + 'img_id_str': '142647887', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 130721194, + 'img_id_str': '130721194', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 294298547, + 'img_id_str': '294298547', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 578004279, + 'img_id_str': '578004279', + 'title': '', + 'user_id': 458707, + 'width': 1334 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '85', + 'passed_time': '2019年09月16日', + 'post_id': 52771050, + 'published_at': '2019-09-16 17:22:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 93, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 8735, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_458707_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '青焱', + 'site_id': '458707', + 'type': 'user', + 'url': 'https://tuchong.com/458707/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '458707', + 'sites': [], + 'tags': ['人像'], + 'title': '肖像', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/458707/52771050/', + 'views': 154323 + }, + { + 'author_id': '1790780', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 45, + 'content': '摩卡摩卡巧克力', + 'created_at': '2019-10-01 17:56:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '摩卡摩卡巧克力', + 'favorite_list_prefix': [], + 'favorites': 1328, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 480684592, + 'img_id_str': '480684592', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2999, + 'img_id': 247704251, + 'img_id_str': '247704251', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 197438488, + 'img_id_str': '197438488', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 361606110, + 'img_id_str': '361606110', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 429828736, + 'img_id_str': '429828736', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 265399596, + 'img_id_str': '265399596', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 652782167, + 'img_id_str': '652782167', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 517253831, + 'img_id_str': '517253831', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3001, + 'img_id': 646229285, + 'img_id_str': '646229285', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 365734200, + 'img_id_str': '365734200', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6552, + 'img_id': 628992869, + 'img_id_str': '628992869', + 'title': '001', + 'user_id': 1790780, + 'width': 4368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 261204599, + 'img_id_str': '261204599', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 646425309, + 'img_id_str': '646425309', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 125480100, + 'img_id_str': '125480100', + 'title': '001', + 'user_id': 1790780, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '2019年10月01日', + 'post_id': 54166249, + 'published_at': '2019-10-01 17:56:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 54, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4991, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1790780_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '萌琦琦M77', + 'site_id': '1790780', + 'type': 'user', + 'url': 'https://tuchong.com/1790780/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1790780', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1790780/54166249/', + 'views': 51924 + }, + { + 'author_id': '1366787', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 66, + 'content': + '这组片子有些地方借鉴了一些lwasong,delfinacarmona,iamwinter的元素\n希望以后更厉害了能吸收得了大师们的东西,也希望能有更多属于我自己的元素', + 'created_at': '2019-07-23 13:05:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019华为新影像', '2019上海公益创作年展', 'ien姥姥摄影课堂'], + 'excerpt': + '这组片子有些地方借鉴了一些lwasong,delfinacarmona,iamwinter的元素\n希望以后更厉害了能吸收得了大师们的东西,也希望能有更多属于我自己的元素', + 'favorite_list_prefix': [], + 'favorites': 2340, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3426, + 'img_id': 530479509, + 'img_id_str': '530479509', + 'title': '', + 'user_id': 1366787, + 'width': 5140 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3748, + 'img_id': 309164504, + 'img_id_str': '309164504', + 'title': '', + 'user_id': 1366787, + 'width': 5622 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3379, + 'img_id': 116423049, + 'img_id_str': '116423049', + 'title': '', + 'user_id': 1366787, + 'width': 3379 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4493, + 'img_id': 271022625, + 'img_id_str': '271022625', + 'title': '', + 'user_id': 1366787, + 'width': 4494 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 178944511, + 'img_id_str': '178944511', + 'title': '', + 'user_id': 1366787, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5620, + 'img_id': 478313131, + 'img_id_str': '478313131', + 'title': '', + 'user_id': 1366787, + 'width': 3747 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3139, + 'img_id': 57965372, + 'img_id_str': '57965372', + 'title': '', + 'user_id': 1366787, + 'width': 5362 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3384, + 'img_id': 135232091, + 'img_id_str': '135232091', + 'title': '', + 'user_id': 1366787, + 'width': 5561 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3235, + 'img_id': 79723045, + 'img_id_str': '79723045', + 'title': '', + 'user_id': 1366787, + 'width': 3235 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '62', + 'passed_time': '2019年07月23日', + 'post_id': 45833869, + 'published_at': '2019-07-23 13:05:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 63, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3372, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1366787_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'ien姥姥', + 'site_id': '1366787', + 'type': 'user', + 'url': 'https://tuchong.com/1366787/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1366787', + 'sites': [], + 'tags': ['2019华为新影像', '2019上海公益创作年展', 'ien姥姥摄影课堂', '人像', '情绪', '观念'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1366787/45833869/', + 'views': 94286 + }, + { + 'author_id': '1561136', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '', + 'created_at': '2020-01-13 15:52:04', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['闪迪旅拍大赛', '2019你最满意的照片'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 32, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 874, + 'img_id': 238404981, + 'img_id_str': '238404981', + 'title': '', + 'user_id': 1561136, + 'width': 1400 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月13日', + 'post_id': 61672334, + 'published_at': '2020-01-13 15:52:04', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': + '披星戴月,踏浪冒雪,寒来暑往,风雨兼程。主拍大连风光。摄影QQ:664512936,微信:manlan123456', + 'domain': 'yuhe.tuchong.com', + 'followers': 452, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1561136_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '雨禾9', + 'site_id': '1561136', + 'type': 'user', + 'url': 'https://yuhe.tuchong.com/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1561136', + 'sites': [], + 'tags': ['闪迪旅拍大赛', '2019你最满意的照片', '风光', '人像', '旅行', '尼康'], + 'title': '童话雪域', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://yuhe.tuchong.com/61672334/', + 'views': 1516 + }, + { + 'author_id': '2677003', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 72, + 'content': '《定格瞬间的情绪》喜欢街拍的朋友,欢迎加入我的圈子【街拍纪实手册】', + 'created_at': '2019-12-16 20:16:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '街拍纪实手册', + '火烛一花精品摄影', + '街头拍客', + '街头人物圈子', + '街事圈子', + '我爱街拍摄影小组圈子', + '人文纪实手册', + '我要上“首页推荐位”', + '绝不停止记录的2019', + '行摄部落' + ], + 'excerpt': '《定格瞬间的情绪》喜欢街拍的朋友,欢迎加入我的圈子【街拍纪实手册】', + 'favorite_list_prefix': [], + 'favorites': 324, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 317571737, + 'img_id_str': '317571737', + 'title': '579425', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 545178388, + 'img_id_str': '545178388', + 'title': '579427', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 360694509, + 'img_id_str': '360694509', + 'title': '579429', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 512410271, + 'img_id_str': '512410271', + 'title': '579426', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 649249586, + 'img_id_str': '649249586', + 'title': '579431', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 497927403, + 'img_id_str': '497927403', + 'title': '579433', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 363447089, + 'img_id_str': '363447089', + 'title': '579428', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 388613170, + 'img_id_str': '388613170', + 'title': '579430', + 'user_id': 2677003, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 456508578, + 'img_id_str': '456508578', + 'title': '579434', + 'user_id': 2677003, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '49', + 'passed_time': '2019年12月16日', + 'post_id': 60556903, + 'published_at': '2019-12-16 20:16:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 16, + 'site': { + 'description': '资深纪实摄影师', + 'domain': 'gewala81.tuchong.com', + 'followers': 4103, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2677003_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '格瓦拉81', + 'site_id': '2677003', + 'type': 'user', + 'url': 'https://gewala81.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深纪实摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2677003', + 'sites': [], + 'tags': ['街拍纪实手册', '火烛一花精品摄影', '街头拍客', '街头人物圈子', '街事圈子', '我爱街拍摄影小组圈子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://gewala81.tuchong.com/60556903/', + 'views': 8500 + }, + { + 'author_id': '1807584', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 23, + 'content': '', + 'created_at': '2019-08-09 22:23:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 761, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 36014793, + 'img_id_str': '36014793', + 'title': '', + 'user_id': 1807584, + 'width': 3235 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2144, + 'img_id': 372541799, + 'img_id_str': '372541799', + 'title': '', + 'user_id': 1807584, + 'width': 1725 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3065, + 'img_id': 96832604, + 'img_id_str': '96832604', + 'title': '', + 'user_id': 1807584, + 'width': 2189 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2839, + 'img_id': 599034818, + 'img_id_str': '599034818', + 'title': '', + 'user_id': 1807584, + 'width': 2182 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3288, + 'img_id': 87853716, + 'img_id_str': '87853716', + 'title': '', + 'user_id': 1807584, + 'width': 2202 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3256, + 'img_id': 266177203, + 'img_id_str': '266177203', + 'title': '', + 'user_id': 1807584, + 'width': 2208 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3132, + 'img_id': 149195244, + 'img_id_str': '149195244', + 'title': '', + 'user_id': 1807584, + 'width': 2191 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3140, + 'img_id': 427985410, + 'img_id_str': '427985410', + 'title': '', + 'user_id': 1807584, + 'width': 2076 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2196, + 'img_id': 614304383, + 'img_id_str': '614304383', + 'title': '', + 'user_id': 1807584, + 'width': 3245 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3262, + 'img_id': 274041679, + 'img_id_str': '274041679', + 'title': '', + 'user_id': 1807584, + 'width': 2195 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2057, + 'img_id': 236489331, + 'img_id_str': '236489331', + 'title': '', + 'user_id': 1807584, + 'width': 3152 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1011, + 'img_id': 177965893, + 'img_id_str': '177965893', + 'title': '', + 'user_id': 1807584, + 'width': 1481 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3271, + 'img_id': 115772073, + 'img_id_str': '115772073', + 'title': '', + 'user_id': 1807584, + 'width': 2198 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3117, + 'img_id': 140675600, + 'img_id_str': '140675600', + 'title': '', + 'user_id': 1807584, + 'width': 2198 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3259, + 'img_id': 521374232, + 'img_id_str': '521374232', + 'title': '', + 'user_id': 1807584, + 'width': 2196 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3257, + 'img_id': 484936484, + 'img_id_str': '484936484', + 'title': '', + 'user_id': 1807584, + 'width': 2187 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年08月09日', + 'post_id': 48453784, + 'published_at': '2019-08-09 22:23:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 15, + 'site': { + 'description': '独立摄影师,参与「夏日短歌——图虫·OPEN MUJI摄影俳句展」', + 'domain': 'huenjs.tuchong.com', + 'followers': 5458, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1807584_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'huenjs', + 'site_id': '1807584', + 'type': 'user', + 'url': 'https://huenjs.tuchong.com/', + 'verification_list': [ + { + 'verification_reason': '独立摄影师,参与「夏日短歌——图虫·OPEN MUJI摄影俳句展」', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1807584', + 'sites': [], + 'tags': ['分享神仙颜值', '风光', '人像', '胶片', '杭州约拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://huenjs.tuchong.com/48453784/', + 'views': 29844 + }, + { + 'author_id': '4171230', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': + '早安呦,今日份早餐一人食滴卡\n感恩每一天的早餐,无论是阴天,还是晴天,它都如期而至,不将就的生活,要从不将就的心态开始。今日份早餐 柠檬三文鱼+南瓜+西葫芦+蘑菇+彩椒,手冲咖啡。喜欢的草莓杯到了,这个年可以好好过了,果然剁手最开心', + 'created_at': '2020-01-14 09:56:14', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': + '早安呦,今日份早餐一人食滴卡\n感恩每一天的早餐,无论是阴天,还是晴天,它都如期而至,不将就的生活,要从不将就的心态开始。今日份早餐 柠檬三文鱼+南瓜+西葫芦+蘑菇+彩椒,手冲咖啡。喜欢的草莓杯到了,这个年可以好好过了,果然剁手最开心', + 'favorite_list_prefix': [], + 'favorites': 33, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 445499315, + 'img_id_str': '445499315', + 'title': '1059443', + 'user_id': 4171230, + 'width': 4928 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 274384726, + 'img_id_str': '274384726', + 'title': '1059442', + 'user_id': 4171230, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 399099057, + 'img_id_str': '399099057', + 'title': '1059441', + 'user_id': 4171230, + 'width': 4928 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 358729419, + 'img_id_str': '358729419', + 'title': '1059440', + 'user_id': 4171230, + 'width': 4928 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 55887855, + 'img_id_str': '55887855', + 'title': '1059439', + 'user_id': 4171230, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 411092844, + 'img_id_str': '411092844', + 'title': '1059438', + 'user_id': 4171230, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 99796628, + 'img_id_str': '99796628', + 'title': '1059437', + 'user_id': 4171230, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 356632377, + 'img_id_str': '356632377', + 'title': '1059436', + 'user_id': 4171230, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 205768205, + 'img_id_str': '205768205', + 'title': '1059435', + 'user_id': 4171230, + 'width': 4928 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月14日', + 'post_id': 61693769, + 'published_at': '2020-01-14 09:56:14', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深静物摄影师', + 'domain': '', + 'followers': 2207, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4171230_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'cynthia-shan', + 'site_id': '4171230', + 'type': 'user', + 'url': 'https://tuchong.com/4171230/', + 'verification_list': [ + {'verification_reason': '资深静物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4171230', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4171230/61693769/', + 'views': 1154 + }, + { + 'author_id': '1896147', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '图虫影像历,小欢喜。', + 'created_at': '2020-01-02 20:36:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['取景器里的小美好', '日系静物摄影圈子', '静物美学', '生活小确幸', '我要上开屏'], + 'excerpt': '图虫影像历,小欢喜。', + 'favorite_list_prefix': [], + 'favorites': 40, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 228377624, + 'img_id_str': '228377624', + 'title': '3194871', + 'user_id': 1896147, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 59229710, + 'img_id_str': '59229710', + 'title': '3194873', + 'user_id': 1896147, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 335528879, + 'img_id_str': '335528879', + 'title': '3194872', + 'user_id': 1896147, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 568379280, + 'img_id_str': '568379280', + 'title': '3194870', + 'user_id': 1896147, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 376031010, + 'img_id_str': '376031010', + 'title': '3194869', + 'user_id': 1896147, + 'width': 6720 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月02日', + 'post_id': 61331733, + 'published_at': '2020-01-02 20:36:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深静物摄影师', + 'domain': '', + 'followers': 4738, + 'has_everphoto_note': false, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1896147_9', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '韩逍子', + 'site_id': '1896147', + 'type': 'user', + 'url': 'https://tuchong.com/1896147/', + 'verification_list': [ + {'verification_reason': '资深静物摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1896147', + 'sites': [], + 'tags': ['取景器里的小美好', '日系静物摄影圈子', '静物美学', '生活小确幸', '我要上开屏'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1896147/61331733/', + 'views': 2102 + }, + { + 'author_id': '2378810', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '傣族人民结婚的时候都喜欢用自己的民族服装做嫁衣,对于她们来说傣装等同于白纱一样重要。\n你们呢喜欢什么民族。', + 'created_at': '2020-01-17 17:48:10', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '傣族人民结婚的时候都喜欢用自己的民族服装做嫁衣,对于她们来说傣装等同于白纱一样重要。\n你们呢喜欢什么民族。', + 'favorite_list_prefix': [], + 'favorites': 29, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 294701214, + 'img_id_str': '294701214', + 'title': '001', + 'user_id': 2378810, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 610780710, + 'img_id_str': '610780710', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 144558014, + 'img_id_str': '144558014', + 'title': '001', + 'user_id': 2378810, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 641386218, + 'img_id_str': '641386218', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 408929786, + 'img_id_str': '408929786', + 'title': '001', + 'user_id': 2378810, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 228050924, + 'img_id_str': '228050924', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 356042471, + 'img_id_str': '356042471', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 373933911, + 'img_id_str': '373933911', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 94684297, + 'img_id_str': '94684297', + 'title': '001', + 'user_id': 2378810, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月17日', + 'post_id': 61789312, + 'published_at': '2020-01-17 17:48:10', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1304, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2378810_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '赵无敌丿', + 'site_id': '2378810', + 'type': 'user', + 'url': 'https://tuchong.com/2378810/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2378810', + 'sites': [], + 'tags': ['民族'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2378810/61789312/', + 'views': 1342 + }, + { + 'author_id': '3052006', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '辛巴', + 'created_at': '2019-12-23 09:19:50', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫旅行摄影圈子', '在图虫看动物世界', '捕捉最萌瞬间'], + 'excerpt': '辛巴', + 'favorite_list_prefix': [], + 'favorites': 23, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2274, + 'img_id': 378258834, + 'img_id_str': '378258834', + 'title': '001', + 'user_id': 3052006, + 'width': 4096 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月23日', + 'post_id': 60863273, + 'published_at': '2019-12-23 09:19:50', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 1016, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3052006_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '六一纪录', + 'site_id': '3052006', + 'type': 'user', + 'url': 'https://tuchong.com/3052006/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3052006', + 'sites': [], + 'tags': ['图虫旅行摄影圈子', '在图虫看动物世界', '捕捉最萌瞬间', '唐怀瑟·电影滤镜', '纪实', '非洲'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3052006/60863273/', + 'views': 1321 + }, + { + 'author_id': '1207473', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 0, + 'content': '《念》\n爱上你恋上这座城市,人海里第一眼就认出你', + 'created_at': '2020-01-07 22:11:53', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['富士Fujifilm圈子', '人像爱好者', '约拍长沙'], + 'excerpt': '《念》\n爱上你恋上这座城市,人海里第一眼就认出你', + 'favorite_list_prefix': [], + 'favorites': 18, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 557500028, + 'img_id_str': '557500028', + 'title': '78992', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4787, + 'img_id': 502449778, + 'img_id_str': '502449778', + 'title': '78994', + 'user_id': 1207473, + 'width': 3191 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 71419509, + 'img_id_str': '71419509', + 'title': '78993', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 488818312, + 'img_id_str': '488818312', + 'title': '78991', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 635750086, + 'img_id_str': '635750086', + 'title': '78988', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 456509179, + 'img_id_str': '456509179', + 'title': '78995', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5495, + 'img_id': 347457887, + 'img_id_str': '347457887', + 'title': '78987', + 'user_id': 1207473, + 'width': 3663 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 237815311, + 'img_id_str': '237815311', + 'title': '78989', + 'user_id': 1207473, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 511756026, + 'img_id_str': '511756026', + 'title': '78990', + 'user_id': 1207473, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '0', + 'passed_time': '01月07日', + 'post_id': 61498305, + 'published_at': '2020-01-07 22:11:53', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1260, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1207473_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '平凡爱拍照玩儿', + 'site_id': '1207473', + 'type': 'user', + 'url': 'https://tuchong.com/1207473/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1207473', + 'sites': [], + 'tags': ['富士Fujifilm圈子', '人像爱好者', '约拍长沙', '人像', '街拍', '城市的'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1207473/61498305/', + 'views': 1219 + }, + { + 'author_id': '5588814', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 33, + 'content': '', + 'created_at': '2019-09-29 15:01:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 772, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 666, + 'img_id': 441624905, + 'img_id_str': '441624905', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 376874906, + 'img_id_str': '376874906', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 108243981, + 'img_id_str': '108243981', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 285715060, + 'img_id_str': '285715060', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 586853077, + 'img_id_str': '586853077', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 260942614, + 'img_id_str': '260942614', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 478587499, + 'img_id_str': '478587499', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 191211464, + 'img_id_str': '191211464', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 467905176, + 'img_id_str': '467905176', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 667, + 'img_id': 282437912, + 'img_id_str': '282437912', + 'title': '', + 'user_id': 5588814, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年09月29日', + 'post_id': 53912573, + 'published_at': '2019-09-29 15:01:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 16, + 'site': { + 'description': '义乌专业淘宝商业摄影 ,视频制作,详情页设计', + 'domain': '', + 'followers': 1844, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5588814_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '义乌金刚摄影', + 'site_id': '5588814', + 'type': 'user', + 'url': 'https://tuchong.com/5588814/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '5588814', + 'sites': [], + 'tags': ['人像', '电商摄影', '淘宝摄'], + 'title': '保暖衣拍摄', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5588814/53912573/', + 'views': 58714 + }, + { + 'author_id': '912745', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 18, + 'content': '夏至已至', + 'created_at': '2019-09-26 01:24:32', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['广深摄影联盟'], + 'excerpt': '夏至已至', + 'favorite_list_prefix': [], + 'favorites': 397, + 'image_count': 29, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 400729988, + 'img_id_str': '400729988', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3431, + 'img_id': 385984564, + 'img_id_str': '385984564', + 'title': '001', + 'user_id': 912745, + 'width': 2295 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 259106640, + 'img_id_str': '259106640', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 490317805, + 'img_id_str': '490317805', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 228370131, + 'img_id_str': '228370131', + 'title': '001', + 'user_id': 912745, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 280602985, + 'img_id_str': '280602985', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 409249592, + 'img_id_str': '409249592', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 247637893, + 'img_id_str': '247637893', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 508274785, + 'img_id_str': '508274785', + 'title': '001', + 'user_id': 912745, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 528197548, + 'img_id_str': '528197548', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 541501230, + 'img_id_str': '541501230', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3348, + 'img_id': 269134075, + 'img_id_str': '269134075', + 'title': '001', + 'user_id': 912745, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 290039482, + 'img_id_str': '290039482', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 532719703, + 'img_id_str': '532719703', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 235317387, + 'img_id_str': '235317387', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 441624538, + 'img_id_str': '441624538', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 525379422, + 'img_id_str': '525379422', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 451716777, + 'img_id_str': '451716777', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 289319271, + 'img_id_str': '289319271', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 355641204, + 'img_id_str': '355641204', + 'title': '001', + 'user_id': 912745, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 107391052, + 'img_id_str': '107391052', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 519874359, + 'img_id_str': '519874359', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 566404842, + 'img_id_str': '566404842', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 243378172, + 'img_id_str': '243378172', + 'title': '001', + 'user_id': 912745, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 143501154, + 'img_id_str': '143501154', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 540977155, + 'img_id_str': '540977155', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 175876229, + 'img_id_str': '175876229', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3429, + 'img_id': 529639379, + 'img_id_str': '529639379', + 'title': '001', + 'user_id': 912745, + 'width': 2294 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 170436642, + 'img_id_str': '170436642', + 'title': '001', + 'user_id': 912745, + 'width': 2433 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '16', + 'passed_time': '2019年09月26日', + 'post_id': 53586675, + 'published_at': '2019-09-26 01:24:32', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 15, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 790, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_912745_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '张晨婷', + 'site_id': '912745', + 'type': 'user', + 'url': 'https://tuchong.com/912745/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '912745', + 'sites': [], + 'tags': ['广深摄影联盟', '人像', '女孩', '日系写真', '胶片'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/912745/53586675/', + 'views': 16334 + }, + { + 'author_id': '2668748', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 26, + 'content': '阴天', + 'created_at': '2019-08-06 07:47:43', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['郑州职业技术学院摄影圈'], + 'excerpt': '阴天', + 'favorite_list_prefix': [], + 'favorites': 464, + 'image_count': 30, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 157779691, + 'img_id_str': '157779691', + 'title': '1180698', + 'user_id': 2668748, + 'width': 3358 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 308905823, + 'img_id_str': '308905823', + 'title': '1180700', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 173246244, + 'img_id_str': '173246244', + 'title': '1180699', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 306153008, + 'img_id_str': '306153008', + 'title': '1180696', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 636651315, + 'img_id_str': '636651315', + 'title': '1180695', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 321292194, + 'img_id_str': '321292194', + 'title': '1180701', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 615155491, + 'img_id_str': '615155491', + 'title': '1180702', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 311527515, + 'img_id_str': '311527515', + 'title': '1180703', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 602965691, + 'img_id_str': '602965691', + 'title': '1180704', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 340559577, + 'img_id_str': '340559577', + 'title': '1180705', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 110594219, + 'img_id_str': '110594219', + 'title': '1180706', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3413, + 'img_id': 258770978, + 'img_id_str': '258770978', + 'title': '1180707', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 55543740, + 'img_id_str': '55543740', + 'title': '1180708', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3413, + 'img_id': 594380340, + 'img_id_str': '594380340', + 'title': '1180709', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 605980507, + 'img_id_str': '605980507', + 'title': '1180694', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 318408277, + 'img_id_str': '318408277', + 'title': '1180693', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1525, + 'img_id': 148998080, + 'img_id_str': '148998080', + 'title': '1180690', + 'user_id': 2668748, + 'width': 2712 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 461211504, + 'img_id_str': '461211504', + 'title': '1180691', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 385976190, + 'img_id_str': '385976190', + 'title': '1180692', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 113215492, + 'img_id_str': '113215492', + 'title': '1180689', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 310412940, + 'img_id_str': '310412940', + 'title': '1180688', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3413, + 'img_id': 544769710, + 'img_id_str': '544769710', + 'title': '1180687', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5428, + 'img_id': 605718106, + 'img_id_str': '605718106', + 'title': '1180686', + 'user_id': 2668748, + 'width': 3349 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2879, + 'img_id': 215189237, + 'img_id_str': '215189237', + 'title': '1180676', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 349013902, + 'img_id_str': '349013902', + 'title': '1180677', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 234129786, + 'img_id_str': '234129786', + 'title': '1180675', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 136546111, + 'img_id_str': '136546111', + 'title': '1180674', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 445154885, + 'img_id_str': '445154885', + 'title': '1180671', + 'user_id': 2668748, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 332367852, + 'img_id_str': '332367852', + 'title': '1180672', + 'user_id': 2668748, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 258312261, + 'img_id_str': '258312261', + 'title': '1180673', + 'user_id': 2668748, + 'width': 5120 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '14', + 'passed_time': '2019年08月06日', + 'post_id': 47874715, + 'published_at': '2019-08-06 07:47:43', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1828, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2668748_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师Linn', + 'site_id': '2668748', + 'type': 'user', + 'url': 'https://tuchong.com/2668748/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2668748', + 'sites': [], + 'tags': ['郑州职业技术学院摄影圈', '女人', '人像', '色彩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2668748/47874715/', + 'views': 19422 + }, + { + 'author_id': '3258736', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '乘叮叮车沿途城市景观记录。', + 'created_at': '2019-12-17 11:14:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '乘叮叮车沿途城市景观记录。', + 'favorite_list_prefix': [], + 'favorites': 46, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 177653009, + 'img_id_str': '177653009', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 640074932, + 'img_id_str': '640074932', + 'title': '', + 'user_id': 3258736, + 'width': 1688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1687, + 'img_id': 629130345, + 'img_id_str': '629130345', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 331596784, + 'img_id_str': '331596784', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1687, + 'img_id': 326288601, + 'img_id_str': '326288601', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 487965985, + 'img_id_str': '487965985', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 533054761, + 'img_id_str': '533054761', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 548848661, + 'img_id_str': '548848661', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 303482045, + 'img_id_str': '303482045', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 281461505, + 'img_id_str': '281461505', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 57590567, + 'img_id_str': '57590567', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1688, + 'img_id': 52086132, + 'img_id_str': '52086132', + 'title': '', + 'user_id': 3258736, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '2019年12月17日', + 'post_id': 60585063, + 'published_at': '2019-12-17 11:14:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 1462, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3258736_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'mau5', + 'site_id': '3258736', + 'type': 'user', + 'url': 'https://tuchong.com/3258736/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3258736', + 'sites': [], + 'tags': ['香港', '叮叮车', '港岛', '电车', '交通', '人文'], + 'title': '叮叮车合集', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3258736/60585063/', + 'views': 2688 + }, + { + 'author_id': '1108701', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 99, + 'content': '', + 'created_at': '2019-11-01 10:22:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['瓦特摄影学院'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1534, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 238991249, + 'img_id_str': '238991249', + 'title': '', + 'user_id': 1108701, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5363, + 'img_id': 262453812, + 'img_id_str': '262453812', + 'title': '', + 'user_id': 1108701, + 'width': 3576 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 472627522, + 'img_id_str': '472627522', + 'title': '', + 'user_id': 1108701, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5561, + 'img_id': 300268348, + 'img_id_str': '300268348', + 'title': '', + 'user_id': 1108701, + 'width': 3707 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5661, + 'img_id': 483637397, + 'img_id_str': '483637397', + 'title': '', + 'user_id': 1108701, + 'width': 3774 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 521844960, + 'img_id_str': '521844960', + 'title': '', + 'user_id': 1108701, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 315341314, + 'img_id_str': '315341314', + 'title': '', + 'user_id': 1108701, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 189184471, + 'img_id_str': '189184471', + 'title': '', + 'user_id': 1108701, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '94', + 'passed_time': '2019年11月01日', + 'post_id': 57469920, + 'published_at': '2019-11-01 10:22:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 129, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 5141, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1108701_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '浅溪先生', + 'site_id': '1108701', + 'type': 'user', + 'url': 'https://tuchong.com/1108701/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1108701', + 'sites': [], + 'tags': ['瓦特摄影学院', '人像', '汉服', '古风', '汉服摄影'], + 'title': '霜降', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1108701/57469920/', + 'views': 42937 + }, + { + 'author_id': '1604446', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 60, + 'content': '同一天的周而复始,若不在哪里留下折痕,说不定会产生错觉。', + 'created_at': '2019-11-07 13:00:33', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上“首页推荐位”'], + 'excerpt': '同一天的周而复始,若不在哪里留下折痕,说不定会产生错觉。', + 'favorite_list_prefix': [], + 'favorites': 985, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 277592920, + 'img_id_str': '277592920', + 'title': '001', + 'user_id': 1604446, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 563723584, + 'img_id_str': '563723584', + 'title': '001', + 'user_id': 1604446, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 141605939, + 'img_id_str': '141605939', + 'title': '001', + 'user_id': 1604446, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '52', + 'passed_time': '2019年11月07日', + 'post_id': 58001231, + 'published_at': '2019-11-07 13:00:33', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 33, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'zmsilent.tuchong.com', + 'followers': 6471, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1604446_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '瓦子卡', + 'site_id': '1604446', + 'type': 'user', + 'url': 'https://zmsilent.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1604446', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '人像', '北京约拍', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://zmsilent.tuchong.com/58001231/', + 'views': 32607 + }, + { + 'author_id': '1001036', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 29, + 'content': '摄影&后期:@会拍照的咔咔\n模特:@嘿是你的牛奶', + 'created_at': '2019-10-11 12:20:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '摄影&后期:@会拍照的咔咔\n模特:@嘿是你的牛奶', + 'favorite_list_prefix': [], + 'favorites': 870, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 316190905, + 'img_id_str': '316190905', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 113684678, + 'img_id_str': '113684678', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 395751551, + 'img_id_str': '395751551', + 'title': '', + 'user_id': 1001036, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 192917690, + 'img_id_str': '192917690', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 289255788, + 'img_id_str': '289255788', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 311472224, + 'img_id_str': '311472224', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 476492564, + 'img_id_str': '476492564', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 286830697, + 'img_id_str': '286830697', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 263106689, + 'img_id_str': '263106689', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 134394952, + 'img_id_str': '134394952', + 'title': '', + 'user_id': 1001036, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 96973146, + 'img_id_str': '96973146', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 132624781, + 'img_id_str': '132624781', + 'title': '', + 'user_id': 1001036, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年10月11日', + 'post_id': 55555111, + 'published_at': '2019-10-11 12:20:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '11', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12656, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1001036_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '会拍照的咔咔', + 'site_id': '1001036', + 'type': 'user', + 'url': 'https://tuchong.com/1001036/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1001036', + 'sites': [], + 'tags': ['人像', '写真', '日系', '小清新'], + 'title': '嘿是你的牛奶', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1001036/55555111/', + 'views': 37706 + }, + { + 'author_id': '5265270', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 45, + 'content': '秋日里的绿。。。', + 'created_at': '2019-10-15 20:44:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '秋日里的绿。。。', + 'favorite_list_prefix': [], + 'favorites': 734, + 'image_count': 15, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 569094813, + 'img_id_str': '569094813', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 226014274, + 'img_id_str': '226014274', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1536, + 'img_id': 581874524, + 'img_id_str': '581874524', + 'title': '001', + 'user_id': 5265270, + 'width': 2304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 361870141, + 'img_id_str': '361870141', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1536, + 'img_id': 537178914, + 'img_id_str': '537178914', + 'title': '001', + 'user_id': 5265270, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1536, + 'img_id': 555070310, + 'img_id_str': '555070310', + 'title': '001', + 'user_id': 5265270, + 'width': 2304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2302, + 'img_id': 57979870, + 'img_id_str': '57979870', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 474067925, + 'img_id_str': '474067925', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 530821931, + 'img_id_str': '530821931', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 430748301, + 'img_id_str': '430748301', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 235320253, + 'img_id_str': '235320253', + 'title': '001', + 'user_id': 5265270, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 413905535, + 'img_id_str': '413905535', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1536, + 'img_id': 556511895, + 'img_id_str': '556511895', + 'title': '001', + 'user_id': 5265270, + 'width': 2304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 176665329, + 'img_id_str': '176665329', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 288600810, + 'img_id_str': '288600810', + 'title': '001', + 'user_id': 5265270, + 'width': 1536 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '45', + 'passed_time': '2019年10月15日', + 'post_id': 55990626, + 'published_at': '2019-10-15 20:44:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深儿童摄影师', + 'domain': '', + 'followers': 4251, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5265270_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '林小玲LIN00', + 'site_id': '5265270', + 'type': 'user', + 'url': 'https://tuchong.com/5265270/', + 'verification_list': [ + {'verification_reason': '资深儿童摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5265270', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5265270/55990626/', + 'views': 28302 + }, + { + 'author_id': '1401628', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': '不问归期\n出镜:@老鼠窜过雨棚 \n拍摄:@青子wj', + 'created_at': '2019-12-05 23:24:27', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '不问归期\n出镜:@老鼠窜过雨棚 \n拍摄:@青子wj', + 'favorite_list_prefix': [], + 'favorites': 693, + 'image_count': 18, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 287163380, + 'img_id_str': '287163380', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3181, + 'img_id': 394379932, + 'img_id_str': '394379932', + 'title': '', + 'user_id': 1401628, + 'width': 4563 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 51167630, + 'img_id_str': '51167630', + 'title': '', + 'user_id': 1401628, + 'width': 4982 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 153797162, + 'img_id_str': '153797162', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 87671601, + 'img_id_str': '87671601', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2496, + 'img_id': 628998760, + 'img_id_str': '628998760', + 'title': '', + 'user_id': 1401628, + 'width': 2783 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 277987480, + 'img_id_str': '277987480', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3339, + 'img_id': 58310923, + 'img_id_str': '58310923', + 'title': '', + 'user_id': 1401628, + 'width': 4262 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4918, + 'img_id': 458604528, + 'img_id_str': '458604528', + 'title': '', + 'user_id': 1401628, + 'width': 3281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 336118361, + 'img_id_str': '336118361', + 'title': '', + 'user_id': 1401628, + 'width': 4592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 57590015, + 'img_id_str': '57590015', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2973, + 'img_id': 170639681, + 'img_id_str': '170639681', + 'title': '', + 'user_id': 1401628, + 'width': 4451 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3370, + 'img_id': 72467000, + 'img_id_str': '72467000', + 'title': '', + 'user_id': 1401628, + 'width': 2660 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 46383430, + 'img_id_str': '46383430', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 431997369, + 'img_id_str': '431997369', + 'title': '', + 'user_id': 1401628, + 'width': 4112 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 597672354, + 'img_id_str': '597672354', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 285328103, + 'img_id_str': '285328103', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3448, + 'img_id': 107790432, + 'img_id_str': '107790432', + 'title': '', + 'user_id': 1401628, + 'width': 5168 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '2019年12月05日', + 'post_id': 59947400, + 'published_at': '2019-12-05 23:24:27', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 21, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 17304, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1401628_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '青子wj', + 'site_id': '1401628', + 'type': 'user', + 'url': 'https://tuchong.com/1401628/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1401628', + 'sites': [], + 'tags': ['人像'], + 'title': '不问归期', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1401628/59947400/', + 'views': 58185 + }, + { + 'author_id': '1468214', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 25, + 'content': '《夏末的和声》', + 'created_at': '2019-10-14 22:46:39', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '《夏末的和声》', + 'favorite_list_prefix': [], + 'favorites': 751, + 'image_count': 24, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 608416221, + 'img_id_str': '608416221', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 261272384, + 'img_id_str': '261272384', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 573420494, + 'img_id_str': '573420494', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 166048421, + 'img_id_str': '166048421', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6828, + 'img_id': 362066395, + 'img_id_str': '362066395', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6432, + 'img_id': 212251404, + 'img_id_str': '212251404', + 'title': '001', + 'user_id': 1468214, + 'width': 4384 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 399094070, + 'img_id_str': '399094070', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 614118156, + 'img_id_str': '614118156', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 605991892, + 'img_id_str': '605991892', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 254652742, + 'img_id_str': '254652742', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 642625980, + 'img_id_str': '642625980', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 49853025, + 'img_id_str': '49853025', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 198750560, + 'img_id_str': '198750560', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 334213934, + 'img_id_str': '334213934', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 610644674, + 'img_id_str': '610644674', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 329822691, + 'img_id_str': '329822691', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 634500564, + 'img_id_str': '634500564', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 146977626, + 'img_id_str': '146977626', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 119780335, + 'img_id_str': '119780335', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6504, + 'img_id': 271692897, + 'img_id_str': '271692897', + 'title': '001', + 'user_id': 1468214, + 'width': 4336 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 448443121, + 'img_id_str': '448443121', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 564245350, + 'img_id_str': '564245350', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6392, + 'img_id': 338408454, + 'img_id_str': '338408454', + 'title': '001', + 'user_id': 1468214, + 'width': 4261 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 546550290, + 'img_id_str': '546550290', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年10月14日', + 'post_id': 55920277, + 'published_at': '2019-10-14 22:46:39', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 24, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 71180, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1468214_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'GK__', + 'site_id': '1468214', + 'type': 'user', + 'url': 'https://tuchong.com/1468214/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1468214', + 'sites': [], + 'tags': ['人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1468214/55920277/', + 'views': 29610 + }, + { + 'author_id': '1737793', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 18, + 'content': '天空', + 'created_at': '2019-07-30 21:24:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上开屏'], + 'excerpt': '天空', + 'favorite_list_prefix': [], + 'favorites': 718, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4464, + 'img_id': 608469570, + 'img_id_str': '608469570', + 'title': '1200830', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 601260572, + 'img_id_str': '601260572', + 'title': '1200829', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 122585222, + 'img_id_str': '122585222', + 'title': '1200791', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 193626308, + 'img_id_str': '193626308', + 'title': '1200828', + 'user_id': 1737793, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 402686436, + 'img_id_str': '402686436', + 'title': '1200833', + 'user_id': 1737793, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 163545558, + 'img_id_str': '163545558', + 'title': '1200834', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 618693047, + 'img_id_str': '618693047', + 'title': '1200831', + 'user_id': 1737793, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 568951105, + 'img_id_str': '568951105', + 'title': '1200832', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 235963065, + 'img_id_str': '235963065', + 'title': '1200826', + 'user_id': 1737793, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 616006157, + 'img_id_str': '616006157', + 'title': '1200790', + 'user_id': 1737793, + 'width': 5472 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 583172277, + 'img_id_str': '583172277', + 'title': '1200789', + 'user_id': 1737793, + 'width': 5472 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '15', + 'passed_time': '2019年07月30日', + 'post_id': 46963068, + 'published_at': '2019-07-30 21:24:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 18, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3037, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1737793_14', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '米线95', + 'site_id': '1737793', + 'type': 'user', + 'url': 'https://tuchong.com/1737793/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1737793', + 'sites': [], + 'tags': ['我要上开屏', '小清新', '日系', '美女', '50mm', '情绪'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1737793/46963068/', + 'views': 24285 + }, + { + 'author_id': '3094448', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 54, + 'content': '红色点裙子遇上美丽的光线!', + 'created_at': '2019-09-04 15:24:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '红色点裙子遇上美丽的光线!', + 'favorite_list_prefix': [], + 'favorites': 1147, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 359701902, + 'img_id_str': '359701902', + 'title': '230016', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 532913707, + 'img_id_str': '532913707', + 'title': '230010', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 429497738, + 'img_id_str': '429497738', + 'title': '230014', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2060, + 'img_id': 282042282, + 'img_id_str': '282042282', + 'title': '230011', + 'user_id': 3094448, + 'width': 3091 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 620273391, + 'img_id_str': '620273391', + 'title': '230013', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 238460799, + 'img_id_str': '238460799', + 'title': '230009', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 291937852, + 'img_id_str': '291937852', + 'title': '230012', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 629841114, + 'img_id_str': '629841114', + 'title': '230015', + 'user_id': 3094448, + 'width': 2060 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3091, + 'img_id': 592027583, + 'img_id_str': '592027583', + 'title': '230017', + 'user_id': 3094448, + 'width': 2060 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '53', + 'passed_time': '2019年09月04日', + 'post_id': 51625094, + 'published_at': '2019-09-04 15:24:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 68, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4527, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3094448_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '大猫与茶树', + 'site_id': '3094448', + 'type': 'user', + 'url': 'https://tuchong.com/3094448/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3094448', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3094448/51625094/', + 'views': 32566 + }, + { + 'author_id': '15956661', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '天津', + 'created_at': '2020-01-19 15:37:07', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫城市建筑'], + 'excerpt': '天津', + 'favorite_list_prefix': [], + 'favorites': 11, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3024, + 'img_id': 638961453, + 'img_id_str': '638961453', + 'title': '001', + 'user_id': 15956661, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2763, + 'img_id': 35178604, + 'img_id_str': '35178604', + 'title': '001', + 'user_id': 15956661, + 'width': 4032 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月19日', + 'post_id': 61839634, + 'published_at': '2020-01-19 15:37:07', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '师承EDC 给光就能拍 喜欢加关注互相学习 v:superheroZD', + 'domain': '', + 'followers': 23, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15956661_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '余生很苦你很甜', + 'site_id': '15956661', + 'type': 'user', + 'url': 'https://tuchong.com/15956661/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15956661', + 'sites': [], + 'tags': ['图虫城市建筑', '赛博朋克滤镜', '天际线', '天津'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15956661/61839634/', + 'views': 710 + }, + { + 'author_id': '8603934', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2020-01-19 10:22:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['华为摄影爱好者', '漳州市手机摄影协会', '带我看看,你的城市'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 29, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 487769821, + 'img_id_str': '487769821', + 'title': '734821', + 'user_id': 8603934, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月19日', + 'post_id': 61833062, + 'published_at': '2020-01-19 10:22:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '只用华为手机拍摄', + 'domain': '', + 'followers': 309, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_8603934_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'dlzxy远山', + 'site_id': '8603934', + 'type': 'user', + 'url': 'https://tuchong.com/8603934/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '8603934', + 'sites': [], + 'tags': ['华为摄影爱好者', '漳州市手机摄影协会', '带我看看,你的城市'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8603934/61833062/', + 'views': 1084 + }, + { + 'author_id': '15947431', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '深圳·晴雨难测', + 'created_at': '2020-01-19 09:37:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '晒晒旅行打卡照', + '一起去拍城市天际线', + '带我看看,你的城市', + '街拍俱乐部圈子', + '街事圈子', + '街头拍客', + '分享决定性瞬间' + ], + 'excerpt': '深圳·晴雨难测', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2439, + 'img_id': 636012692, + 'img_id_str': '636012692', + 'title': '001', + 'user_id': 15947431, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2448, + 'img_id': 126142216, + 'img_id_str': '126142216', + 'title': '001', + 'user_id': 15947431, + 'width': 3264 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月19日', + 'post_id': 61832090, + 'published_at': '2020-01-19 09:37:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '一期一会', + 'domain': '', + 'followers': 12, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15947431_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '巴茨先生', + 'site_id': '15947431', + 'type': 'user', + 'url': 'https://tuchong.com/15947431/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15947431', + 'sites': [], + 'tags': ['晒晒旅行打卡照', '一起去拍城市天际线', '带我看看,你的城市', '街拍俱乐部圈子', '街事圈子', '街头拍客'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15947431/61832090/', + 'views': 601 + }, + { + 'author_id': '8089423', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '红尘艳(二)\n娴静妖娆点头羞,一入红尘己夏秋;\n借问何时悟禅意,佛坐莲台捋佛珠。', + 'created_at': '2020-01-18 22:29:14', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['火烛一花精品摄影'], + 'excerpt': '红尘艳(二)\n娴静妖娆点头羞,一入红尘己夏秋;\n借问何时悟禅意,佛坐莲台捋佛珠。', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 19, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 443074078, + 'img_id_str': '443074078', + 'title': '690', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 502253450, + 'img_id_str': '502253450', + 'title': '692', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 137086554, + 'img_id_str': '137086554', + 'title': '687', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 540788893, + 'img_id_str': '540788893', + 'title': '728', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 472368861, + 'img_id_str': '472368861', + 'title': '716', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 237946645, + 'img_id_str': '237946645', + 'title': '809', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 630507426, + 'img_id_str': '630507426', + 'title': '767', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 312264823, + 'img_id_str': '312264823', + 'title': '758', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 60278214, + 'img_id_str': '60278214', + 'title': '681', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 613664692, + 'img_id_str': '613664692', + 'title': '891', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 159696734, + 'img_id_str': '159696734', + 'title': '917', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 129681278, + 'img_id_str': '129681278', + 'title': '905', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 530696031, + 'img_id_str': '530696031', + 'title': '824', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 433571907, + 'img_id_str': '433571907', + 'title': '876', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 49269079, + 'img_id_str': '49269079', + 'title': '873', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 319670203, + 'img_id_str': '319670203', + 'title': '719', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4288, + 'img_id': 617334313, + 'img_id_str': '617334313', + 'title': '789', + 'user_id': 8089423, + 'width': 3216 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 385206081, + 'img_id_str': '385206081', + 'title': '828', + 'user_id': 8089423, + 'width': 4288 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3216, + 'img_id': 639289324, + 'img_id_str': '639289324', + 'title': '4462', + 'user_id': 8089423, + 'width': 4288 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61823614, + 'published_at': '2020-01-18 22:29:14', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 3, + 'site': { + 'description': '', + 'domain': '', + 'followers': 14, + 'has_everphoto_note': true, + 'icon': 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_u_0', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '用户155719282960626', + 'site_id': '8089423', + 'type': 'user', + 'url': 'https://tuchong.com/8089423/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '8089423', + 'sites': [], + 'tags': ['火烛一花精品摄影', '花园', '绽放', '花', '植物'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/8089423/61823614/', + 'views': 610 + }, + { + 'author_id': '15950662', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '月上柳梢头~', + 'created_at': '2020-01-18 22:02:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '中国手机摄影', + '拿起手机人人都是摄影师', + '我用手机修照片', + '手机摄影小分队', + '华为摄影爱好者', + '取景器里的小美好', + '风光摄影圈', + '城市·夜晚', + '街头拍客', + '一个风光摄影圈' + ], + 'excerpt': '月上柳梢头~', + 'favorite_list_prefix': [], + 'favorites': 14, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 331597459, + 'img_id_str': '331597459', + 'title': '410208', + 'user_id': 15950662, + 'width': 2160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61822764, + 'published_at': '2020-01-18 22:02:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '用镜头记录生活中的每一个美好瞬间~', + 'domain': '', + 'followers': 8, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15950662_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '小晓雅', + 'site_id': '15950662', + 'type': 'user', + 'url': 'https://tuchong.com/15950662/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15950662', + 'sites': [], + 'tags': [ + '中国手机摄影', + '拿起手机人人都是摄影师', + '我用手机修照片', + '手机摄影小分队', + '华为摄影爱好者', + '取景器里的小美好' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15950662/61822764/', + 'views': 610 + }, + { + 'author_id': '15954090', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '是温柔的冬樱花啊', + 'created_at': '2020-01-18 20:31:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫旅行摄影圈子'], + 'excerpt': '是温柔的冬樱花啊', + 'favorite_list_prefix': [], + 'favorites': 12, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2717, + 'img_id': 205638074, + 'img_id_str': '205638074', + 'title': '001', + 'user_id': 15954090, + 'width': 1529 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2350, + 'img_id': 51103323, + 'img_id_str': '51103323', + 'title': '001', + 'user_id': 15954090, + 'width': 1321 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2114, + 'img_id': 540460919, + 'img_id_str': '540460919', + 'title': '001', + 'user_id': 15954090, + 'width': 1191 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3760, + 'img_id': 304203386, + 'img_id_str': '304203386', + 'title': '001', + 'user_id': 15954090, + 'width': 2114 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3704, + 'img_id': 618841523, + 'img_id_str': '618841523', + 'title': '001', + 'user_id': 15954090, + 'width': 2084 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3943, + 'img_id': 610518560, + 'img_id_str': '610518560', + 'title': '001', + 'user_id': 15954090, + 'width': 2218 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5596, + 'img_id': 392153253, + 'img_id_str': '392153253', + 'title': '001', + 'user_id': 15954090, + 'width': 3148 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 617989591, + 'img_id_str': '617989591', + 'title': '001', + 'user_id': 15954090, + 'width': 3374 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2207, + 'img_id': 34851110, + 'img_id_str': '34851110', + 'title': '001', + 'user_id': 15954090, + 'width': 1232 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61820195, + 'published_at': '2020-01-18 20:31:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 3, + 'site': { + 'description': '快乐存甜罐´•ᴥ•`', + 'domain': '', + 'followers': 3, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15954090_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Evelyn是只兔子', + 'site_id': '15954090', + 'type': 'user', + 'url': 'https://tuchong.com/15954090/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15954090', + 'sites': [], + 'tags': ['图虫旅行摄影圈子', '花', '樱桃木', '绽放', '季节', '明亮'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15954090/61820195/', + 'views': 541 + }, + { + 'author_id': '15948588', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '山水人间', + 'created_at': '2020-01-18 19:43:45', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['最满意的风光照'], + 'excerpt': '山水人间', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 393201197, + 'img_id_str': '393201197', + 'title': '923529', + 'user_id': 15948588, + 'width': 963 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61818871, + 'published_at': '2020-01-18 19:43:45', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '鲜花、美酒、美人,而我只喜欢你', + 'domain': '', + 'followers': 5, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15948588_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '朝夏与酒', + 'site_id': '15948588', + 'type': 'user', + 'url': 'https://tuchong.com/15948588/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15948588', + 'sites': [], + 'tags': ['最满意的风光照', '小瀑布', '岩石'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15948588/61818871/', + 'views': 665 + }, + { + 'author_id': '15953166', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '老街•巷子\n偶遇\n手工皮鞋铺', + 'created_at': '2020-01-18 18:10:20', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['带我看看,你的城市', '人文天下'], + 'excerpt': '老街•巷子\n偶遇\n手工皮鞋铺', + 'favorite_list_prefix': [], + 'favorites': 13, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3163, + 'img_id': 574736049, + 'img_id_str': '574736049', + 'title': '1611759', + 'user_id': 15953166, + 'width': 5619 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 59820083, + 'img_id_str': '59820083', + 'title': '1611758', + 'user_id': 15953166, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5540, + 'img_id': 620087198, + 'img_id_str': '620087198', + 'title': '1611760', + 'user_id': 15953166, + 'width': 3121 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5814, + 'img_id': 533972433, + 'img_id_str': '533972433', + 'title': '1611757', + 'user_id': 15953166, + 'width': 3876 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 187615218, + 'img_id_str': '187615218', + 'title': '1611761', + 'user_id': 15953166, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 57591273, + 'img_id_str': '57591273', + 'title': '1607304', + 'user_id': 15953166, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61816743, + 'published_at': '2020-01-18 18:10:20', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 8, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15953166_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '阿雷要努力鸭', + 'site_id': '15953166', + 'type': 'user', + 'url': 'https://tuchong.com/15953166/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15953166', + 'sites': [], + 'tags': ['带我看看,你的城市', '人文天下', '城市', '纪实'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15953166/61816743/', + 'views': 723 + }, + { + 'author_id': '15951067', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '', + 'created_at': '2020-01-18 14:26:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫旅行摄影圈子'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 18, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 80922504, + 'img_id_str': '80922504', + 'title': '314700', + 'user_id': 15951067, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 358336148, + 'img_id_str': '358336148', + 'title': '314703', + 'user_id': 15951067, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月18日', + 'post_id': 61811892, + 'published_at': '2020-01-18 14:26:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '', + 'domain': '', + 'followers': 7, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15951067_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '勇者不惧909', + 'site_id': '15951067', + 'type': 'user', + 'url': 'https://tuchong.com/15951067/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15951067', + 'sites': [], + 'tags': ['图虫旅行摄影圈子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15951067/61811892/', + 'views': 839 + }, + { + 'author_id': '15935548', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '机场的尽头通往回家的路\n升起的月亮将见证我们相聚', + 'created_at': '2020-01-18 09:41:24', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['生活小确幸', '街拍纪实手册'], + 'excerpt': '机场的尽头通往回家的路\n升起的月亮将见证我们相聚', + 'favorite_list_prefix': [], + 'favorites': 12, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2665, + 'img_id': 154847060, + 'img_id_str': '154847060', + 'title': '001', + 'user_id': 15935548, + 'width': 3556 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61805805, + 'published_at': '2020-01-18 09:41:24', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '仅做记录之用', + 'domain': '', + 'followers': 4, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15935548_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '蓝蓝柒', + 'site_id': '15935548', + 'type': 'user', + 'url': 'https://tuchong.com/15935548/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15935548', + 'sites': [], + 'tags': ['生活小确幸', '街拍纪实手册', '古典蓝晒', 'Toning1滤镜', '机场'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15935548/61805805/', + 'views': 601 + }, + { + 'author_id': '15947431', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '大连体育中心', + 'created_at': '2020-01-18 08:13:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '带我看看,你的城市', + '华为摄影爱好者', + '我们都是城市探险家', + '图虫旅行摄影圈子', + '极简主义,少即是多' + ], + 'excerpt': '大连体育中心', + 'favorite_list_prefix': [], + 'favorites': 14, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 271173705, + 'img_id_str': '271173705', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2345, + 'img_id': 580240931, + 'img_id_str': '580240931', + 'title': '001', + 'user_id': 15947431, + 'width': 3516 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2333, + 'img_id': 433178939, + 'img_id_str': '433178939', + 'title': '001', + 'user_id': 15947431, + 'width': 3070 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 107071148, + 'img_id_str': '107071148', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 462079880, + 'img_id_str': '462079880', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 202688013, + 'img_id_str': '202688013', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 223200942, + 'img_id_str': '223200942', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2736, + 'img_id': 178047037, + 'img_id_str': '178047037', + 'title': '001', + 'user_id': 15947431, + 'width': 3648 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61804174, + 'published_at': '2020-01-18 08:13:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '一期一会', + 'domain': '', + 'followers': 12, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15947431_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '巴茨先生', + 'site_id': '15947431', + 'type': 'user', + 'url': 'https://tuchong.com/15947431/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15947431', + 'sites': [], + 'tags': [ + '带我看看,你的城市', + '华为摄影爱好者', + '我们都是城市探险家', + '图虫旅行摄影圈子', + '极简主义,少即是多', + '体育场' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15947431/61804174/', + 'views': 427 + }, + { + 'author_id': '15938645', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': + '一千四百多年历史的双林寺,距离平遥高铁站很近,高铁站始发的108路公交车只需一站地。在晋中热门人气排行榜上它排在20名开外,在这个看颜值的时代,它的确并不讨喜。双林寺外表真的很朴实,墙不高大,殿堂矮小,就连这一千岁的国槐长的都那么低调。但它在佛学界和艺术界却享有着非常高的声誉。', + 'created_at': '2020-01-18 07:18:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['各地教堂大赏'], + 'excerpt': + '一千四百多年历史的双林寺,距离平遥高铁站很近,高铁站始发的108路公交车只需一站地。在晋中热门人气排行榜上它排在20名开外,在这个看颜值的时代,它的确并不讨喜。双林寺外表真的很朴实,墙不高大,殿堂矮小,就连这一千岁的国槐长的都那么低调。但它在佛学界和艺术界却享有着非常高的声誉。', + 'favorite_list_prefix': [], + 'favorites': 11, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 528533615, + 'img_id_str': '528533615', + 'title': '740518', + 'user_id': 15938645, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 568510052, + 'img_id_str': '568510052', + 'title': '740517', + 'user_id': 15938645, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 206424010, + 'img_id_str': '206424010', + 'title': '740516', + 'user_id': 15938645, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 382584340, + 'img_id_str': '382584340', + 'title': '740515', + 'user_id': 15938645, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4608, + 'img_id': 540068198, + 'img_id_str': '540068198', + 'title': '740514', + 'user_id': 15938645, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61803501, + 'published_at': '2020-01-18 07:18:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': + '无论走到哪里\n都应该记住\n过去都是假的\n回忆是一条没有尽头的路\n一切以往的春天都不复存在\n就连那最坚韧而又狂乱的爱情\n归根结底也不过是一种转瞬即逝的现实\n唯有孤独永恒', + 'domain': '', + 'followers': 16, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15938645_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'waterfallice', + 'site_id': '15938645', + 'type': 'user', + 'url': 'https://tuchong.com/15938645/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15938645', + 'sites': [], + 'tags': ['各地教堂大赏'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15938645/61803501/', + 'views': 435 + }, + { + 'author_id': '4463835', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '家乡的村庄', + 'created_at': '2020-01-16 17:43:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['风光摄影集'], + 'excerpt': '家乡的村庄', + 'favorite_list_prefix': [], + 'favorites': 17, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3295, + 'img_id': 262195258, + 'img_id_str': '262195258', + 'title': '208150', + 'user_id': 4463835, + 'width': 5184 + }, + { + 'description': '', + 'excerpt': '', + 'height': 999, + 'img_id': 335464520, + 'img_id_str': '335464520', + 'title': '207834', + 'user_id': 4463835, + 'width': 2160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月16日', + 'post_id': 61761626, + 'published_at': '2020-01-16 17:43:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '摄我所爱无关名利', + 'domain': '', + 'followers': 386, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4463835_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '李非洋', + 'site_id': '4463835', + 'type': 'user', + 'url': 'https://tuchong.com/4463835/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '4463835', + 'sites': [], + 'tags': ['风光摄影集', '天空', '建筑物', '住房', '房子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4463835/61761626/', + 'views': 880 + }, + { + 'author_id': '458707', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '', + 'created_at': '2019-11-04 17:41:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2211, + 'image_count': 21, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 614971914, + 'img_id_str': '614971914', + 'title': '', + 'user_id': 458707, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 604486319, + 'img_id_str': '604486319', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 311737134, + 'img_id_str': '311737134', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 402504266, + 'img_id_str': '402504266', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 301251202, + 'img_id_str': '301251202', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 166836684, + 'img_id_str': '166836684', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 123124381, + 'img_id_str': '123124381', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 506510374, + 'img_id_str': '506510374', + 'title': '', + 'user_id': 458707, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 128825800, + 'img_id_str': '128825800', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 148552312, + 'img_id_str': '148552312', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 655080862, + 'img_id_str': '655080862', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 200326299, + 'img_id_str': '200326299', + 'title': '', + 'user_id': 458707, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 179222989, + 'img_id_str': '179222989', + 'title': '', + 'user_id': 458707, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 338475449, + 'img_id_str': '338475449', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 202750585, + 'img_id_str': '202750585', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 477739683, + 'img_id_str': '477739683', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 447265062, + 'img_id_str': '447265062', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 523876778, + 'img_id_str': '523876778', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 654883737, + 'img_id_str': '654883737', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 520796736, + 'img_id_str': '520796736', + 'title': '', + 'user_id': 458707, + 'width': 1334 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 566147436, + 'img_id_str': '566147436', + 'title': '', + 'user_id': 458707, + 'width': 1334 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '47', + 'passed_time': '2019年11月04日', + 'post_id': 57789518, + 'published_at': '2019-11-04 17:41:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '2', + 'rqt_id': '', + 'shares': 68, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 8735, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_458707_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '青焱', + 'site_id': '458707', + 'type': 'user', + 'url': 'https://tuchong.com/458707/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '458707', + 'sites': [], + 'tags': ['人像', '小清新', '日系', '长沙'], + 'title': '爱笑的眼睛', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/458707/57789518/', + 'views': 96677 + }, + { + 'author_id': '1468214', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 42, + 'content': '《夏有三木》', + 'created_at': '2019-10-09 17:47:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '《夏有三木》', + 'favorite_list_prefix': [], + 'favorites': 1314, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 617262885, + 'img_id_str': '617262885', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 413380778, + 'img_id_str': '413380778', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 124826083, + 'img_id_str': '124826083', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 408334788, + 'img_id_str': '408334788', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 420327821, + 'img_id_str': '420327821', + 'title': '001', + 'user_id': 1468214, + 'width': 6528 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 128823316, + 'img_id_str': '128823316', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4600, + 'img_id': 453095940, + 'img_id_str': '453095940', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4584, + 'img_id': 176009200, + 'img_id_str': '176009200', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 416198466, + 'img_id_str': '416198466', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 281981005, + 'img_id_str': '281981005', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 163229643, + 'img_id_str': '163229643', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 109228259, + 'img_id_str': '109228259', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 575517059, + 'img_id_str': '575517059', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 359575674, + 'img_id_str': '359575674', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 98545687, + 'img_id_str': '98545687', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 573879010, + 'img_id_str': '573879010', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '39', + 'passed_time': '2019年10月09日', + 'post_id': 55373134, + 'published_at': '2019-10-09 17:47:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 71180, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1468214_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'GK__', + 'site_id': '1468214', + 'type': 'user', + 'url': 'https://tuchong.com/1468214/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1468214', + 'sites': [], + 'tags': ['人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1468214/55373134/', + 'views': 66215 + }, + { + 'author_id': '1066625', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 29, + 'content': '摄影师:SOOHU\n灯光:木白\n化妆/造型师:李文静\n模特:张萌\n后期:银鹏工作室', + 'created_at': '2019-10-03 18:36:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '摄影师:SOOHU\n灯光:木白\n化妆/造型师:李文静\n模特:张萌\n后期:银鹏工作室', + 'favorite_list_prefix': [], + 'favorites': 440, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2705, + 'img_id': 337357746, + 'img_id_str': '337357746', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2705, + 'img_id': 336702505, + 'img_id_str': '336702505', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2705, + 'img_id': 542551319, + 'img_id_str': '542551319', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1358, + 'img_id': 562933171, + 'img_id_str': '562933171', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 831, + 'img_id': 633776989, + 'img_id_str': '633776989', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2705, + 'img_id': 399486016, + 'img_id_str': '399486016', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1359, + 'img_id': 639609739, + 'img_id_str': '639609739', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1198, + 'img_id': 415215159, + 'img_id_str': '415215159', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1198, + 'img_id': 624929701, + 'img_id_str': '624929701', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2705, + 'img_id': 347188228, + 'img_id_str': '347188228', + 'title': '', + 'user_id': 1066625, + 'width': 1800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年10月03日', + 'post_id': 54438188, + 'published_at': '2019-10-03 18:36:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 41, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7538, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1066625_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '银鹏', + 'site_id': '1066625', + 'type': 'user', + 'url': 'https://tuchong.com/1066625/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1066625', + 'sites': [], + 'tags': ['人像', '美女'], + 'title': '蜜桃臀', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1066625/54438188/', + 'views': 33568 + }, + { + 'author_id': '2349130', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 21, + 'content': '奶油般温柔', + 'created_at': '2019-09-26 10:33:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '奶油般温柔', + 'favorite_list_prefix': [], + 'favorites': 585, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 583182110, + 'img_id_str': '583182110', + 'title': '001', + 'user_id': 2349130, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 363899098, + 'img_id_str': '363899098', + 'title': '001', + 'user_id': 2349130, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '17', + 'passed_time': '2019年09月26日', + 'post_id': 53600326, + 'published_at': '2019-09-26 10:33:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 11, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3391, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2349130_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '羊小暖', + 'site_id': '2349130', + 'type': 'user', + 'url': 'https://tuchong.com/2349130/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2349130', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '美女', '佳能', '日系', '少女写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2349130/53600326/', + 'views': 16727 + }, + { + 'author_id': '2326533', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 44, + 'content': '舞者来自中央芭蕾舞团王佳宝,这是在中国铁道博物馆拍摄的,想表现古老与现代的相遇,柔与刚的碰撞,', + 'created_at': '2019-09-18 18:21:07', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '舞者来自中央芭蕾舞团王佳宝,这是在中国铁道博物馆拍摄的,想表现古老与现代的相遇,柔与刚的碰撞,', + 'favorite_list_prefix': [], + 'favorites': 847, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 393258177, + 'img_id_str': '393258177', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 529376215, + 'img_id_str': '529376215', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 504603328, + 'img_id_str': '504603328', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 188589512, + 'img_id_str': '188589512', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 354984830, + 'img_id_str': '354984830', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2689, + 'img_id': 451257600, + 'img_id_str': '451257600', + 'title': '', + 'user_id': 2326533, + 'width': 4032 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '43', + 'passed_time': '2019年09月18日', + 'post_id': 52931816, + 'published_at': '2019-09-18 18:21:07', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 24, + 'site': { + 'description': '光影中立定精神 . 镜头下决出生活', + 'domain': 'shilei.tuchong.com', + 'followers': 2892, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2326533_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '石磊-空境舞集摄影', + 'site_id': '2326533', + 'type': 'user', + 'url': 'https://shilei.tuchong.com/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '2326533', + 'sites': [], + 'tags': ['舞蹈', '舞蹈摄影', '芭蕾舞', '现代芭蕾', '线条', '火车'], + 'title': '当芭蕾遇上火车', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://shilei.tuchong.com/52931816/', + 'views': 49116 + }, + { + 'author_id': '3477512', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 97, + 'content': '上海夜景-魔都三件套', + 'created_at': '2019-08-23 21:48:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '上海夜景-魔都三件套', + 'favorite_list_prefix': [], + 'favorites': 2607, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 394761957, + 'img_id_str': '394761957', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 347379130, + 'img_id_str': '347379130', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 491689982, + 'img_id_str': '491689982', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 236754869, + 'img_id_str': '236754869', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 74749519, + 'img_id_str': '74749519', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 391812813, + 'img_id_str': '391812813', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 456628112, + 'img_id_str': '456628112', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 233019363, + 'img_id_str': '233019363', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 636458661, + 'img_id_str': '636458661', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 537630454, + 'img_id_str': '537630454', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 279549604, + 'img_id_str': '279549604', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 101750610, + 'img_id_str': '101750610', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 158897918, + 'img_id_str': '158897918', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '80', + 'passed_time': '2019年08月23日', + 'post_id': 50371085, + 'published_at': '2019-08-23 21:48:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 80, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 44864, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3477512_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Cissy_Li', + 'site_id': '3477512', + 'type': 'user', + 'url': 'https://tuchong.com/3477512/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3477512', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3477512/50371085/', + 'views': 112505 + }, + { + 'author_id': '2574940', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 75, + 'content': '', + 'created_at': '2019-08-22 15:35:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2485, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 599299386, + 'img_id_str': '599299386', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 533436405, + 'img_id_str': '533436405', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 509581284, + 'img_id_str': '509581284', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 329553488, + 'img_id_str': '329553488', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 309958236, + 'img_id_str': '309958236', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 82941327, + 'img_id_str': '82941327', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 388994736, + 'img_id_str': '388994736', + 'title': '', + 'user_id': 2574940, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 438473981, + 'img_id_str': '438473981', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 342201717, + 'img_id_str': '342201717', + 'title': '', + 'user_id': 2574940, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 573150702, + 'img_id_str': '573150702', + 'title': '', + 'user_id': 2574940, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 138712326, + 'img_id_str': '138712326', + 'title': '', + 'user_id': 2574940, + 'width': 3456 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '71', + 'passed_time': '2019年08月22日', + 'post_id': 50206881, + 'published_at': '2019-08-22 15:35:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '91', + 'rqt_id': '', + 'shares': 114, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'mixmico.tuchong.com', + 'followers': 48506, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2574940_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'MixMico米扣', + 'site_id': '2574940', + 'type': 'user', + 'url': 'https://mixmico.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2574940', + 'sites': [], + 'tags': ['人像', '色彩', '美女', '写真', '眼镜', '产品'], + 'title': 'Glasses', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://mixmico.tuchong.com/50206881/', + 'views': 97862 + }, + { + 'author_id': '985660', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 37, + 'content': '终于圆了去这里拍照的怨念··哈哈哈··开心\n出镜:巧音\n同行:@小超童鞋', + 'created_at': '2019-08-16 16:51:27', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我们都爱日系摄影'], + 'excerpt': '终于圆了去这里拍照的怨念··哈哈哈··开心\n出镜:巧音\n同行:@小超童鞋', + 'favorite_list_prefix': [], + 'favorites': 970, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1088, + 'img_id': 490115637, + 'img_id_str': '490115637', + 'title': '', + 'user_id': 985660, + 'width': 1633 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1236, + 'img_id': 651858122, + 'img_id_str': '651858122', + 'title': '', + 'user_id': 985660, + 'width': 1644 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 570986713, + 'img_id_str': '570986713', + 'title': '', + 'user_id': 985660, + 'width': 1237 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 118722905, + 'img_id_str': '118722905', + 'title': '', + 'user_id': 985660, + 'width': 1237 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1088, + 'img_id': 404591297, + 'img_id_str': '404591297', + 'title': '', + 'user_id': 985660, + 'width': 1633 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1088, + 'img_id': 524062977, + 'img_id_str': '524062977', + 'title': '', + 'user_id': 985660, + 'width': 1633 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 204247528, + 'img_id_str': '204247528', + 'title': '', + 'user_id': 985660, + 'width': 1237 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1236, + 'img_id': 500142483, + 'img_id_str': '500142483', + 'title': '', + 'user_id': 985660, + 'width': 1644 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 38834538, + 'img_id_str': '38834538', + 'title': '', + 'user_id': 985660, + 'width': 1237 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1088, + 'img_id': 306483565, + 'img_id_str': '306483565', + 'title': '', + 'user_id': 985660, + 'width': 1633 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 217223598, + 'img_id_str': '217223598', + 'title': '', + 'user_id': 985660, + 'width': 1237 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1236, + 'img_id': 187404240, + 'img_id_str': '187404240', + 'title': '', + 'user_id': 985660, + 'width': 1644 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1088, + 'img_id': 405573504, + 'img_id_str': '405573504', + 'title': '', + 'user_id': 985660, + 'width': 1633 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1646, + 'img_id': 441684191, + 'img_id_str': '441684191', + 'title': '', + 'user_id': 985660, + 'width': 1237 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '30', + 'passed_time': '2019年08月16日', + 'post_id': 49428555, + 'published_at': '2019-08-16 16:51:27', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '7', + 'rqt_id': '', + 'shares': 28, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'patlabor.tuchong.com', + 'followers': 2609, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_985660_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '逍遥小兵', + 'site_id': '985660', + 'type': 'user', + 'url': 'https://patlabor.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '985660', + 'sites': [], + 'tags': ['我们都爱日系摄影', '人像', '小清新', '少女', '日系'], + 'title': '暑中见舞い', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://patlabor.tuchong.com/49428555/', + 'views': 58643 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 59, + 'content': '给我一个点赞,我就把吃不胖的秘密告诉你,一般人我不告诉Ta', + 'created_at': '2019-08-15 22:35:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上“首页推荐位”'], + 'excerpt': '给我一个点赞,我就把吃不胖的秘密告诉你,一般人我不告诉Ta', + 'favorite_list_prefix': [], + 'favorites': 1670, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 531993021, + 'img_id_str': '531993021', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 540316148, + 'img_id_str': '540316148', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2333, + 'img_id': 84774537, + 'img_id_str': '84774537', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 213618752, + 'img_id_str': '213618752', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 335778057, + 'img_id_str': '335778057', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 271617773, + 'img_id_str': '271617773', + 'title': '001', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1278, + 'img_id': 613978400, + 'img_id_str': '613978400', + 'title': '001', + 'user_id': 3738183, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '51', + 'passed_time': '2019年08月15日', + 'post_id': 49342525, + 'published_at': '2019-08-15 22:35:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 43, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '享受', '放松', '休闲'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/49342525/', + 'views': 51413 + }, + { + 'author_id': '1328495', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 220, + 'content': '额济纳金秋', + 'created_at': '2019-08-09 17:44:27', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['世界华人风光摄影小组圈子'], + 'excerpt': '额济纳金秋', + 'favorite_list_prefix': [], + 'favorites': 2963, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 357272201, + 'img_id_str': '357272201', + 'title': '1566883', + 'user_id': 1328495, + 'width': 2500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1438, + 'img_id': 604933208, + 'img_id_str': '604933208', + 'title': '1566884', + 'user_id': 1328495, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 577997552, + 'img_id_str': '577997552', + 'title': '1566881', + 'user_id': 1328495, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1621, + 'img_id': 632130551, + 'img_id_str': '632130551', + 'title': '1566880', + 'user_id': 1328495, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 591628503, + 'img_id_str': '591628503', + 'title': '1566879', + 'user_id': 1328495, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 420580002, + 'img_id_str': '420580002', + 'title': '1566885', + 'user_id': 1328495, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 621185999, + 'img_id_str': '621185999', + 'title': '1566882', + 'user_id': 1328495, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 64719789, + 'img_id_str': '64719789', + 'title': '1566888', + 'user_id': 1328495, + 'width': 3000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '213', + 'passed_time': '2019年08月09日', + 'post_id': 48408355, + 'published_at': '2019-08-09 17:44:27', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 230, + 'site': { + 'description': '资深旅行摄影师', + 'domain': 'zylm8899.tuchong.com', + 'followers': 4272, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1328495_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '独客', + 'site_id': '1328495', + 'type': 'user', + 'url': 'https://zylm8899.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1328495', + 'sites': [], + 'tags': ['世界华人风光摄影小组圈子', '秋季', '内蒙古额济纳旗', '额济纳', '坝上主题摄影小组圈子', '水胡杨'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://zylm8899.tuchong.com/48408355/', + 'views': 90747 + }, + { + 'author_id': '2717528', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 40, + 'content': '', + 'created_at': '2019-07-22 19:41:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Cosplay摄影集中地'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 921, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 269318827, + 'img_id_str': '269318827', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 431192505, + 'img_id_str': '431192505', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 528644393, + 'img_id_str': '528644393', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 328300981, + 'img_id_str': '328300981', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 97352169, + 'img_id_str': '97352169', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 45643992, + 'img_id_str': '45643992', + 'title': '001', + 'user_id': 2717528, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2240, + 'img_id': 379288230, + 'img_id_str': '379288230', + 'title': '001', + 'user_id': 2717528, + 'width': 3360 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3279, + 'img_id': 216758328, + 'img_id_str': '216758328', + 'title': '001', + 'user_id': 2717528, + 'width': 2186 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2240, + 'img_id': 622492140, + 'img_id_str': '622492140', + 'title': '001', + 'user_id': 2717528, + 'width': 3360 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2240, + 'img_id': 198146317, + 'img_id_str': '198146317', + 'title': '001', + 'user_id': 2717528, + 'width': 3360 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '39', + 'passed_time': '2019年07月22日', + 'post_id': 45726171, + 'published_at': '2019-07-22 19:41:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 18, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 11801, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2717528_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '卡巴拉岛的回忆', + 'site_id': '2717528', + 'type': 'user', + 'url': 'https://tuchong.com/2717528/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2717528', + 'sites': [], + 'tags': ['Cosplay摄影集中地', 'Cosplay', '人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2717528/45726171/', + 'views': 43788 + }, + { + 'author_id': '2598104', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': '《古墓丽影》劳拉克劳馥 COS ɪɴs.enjinight ​​​', + 'created_at': '2020-01-06 14:23:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '《古墓丽影》劳拉克劳馥 COS ɪɴs.enjinight ​​​', + 'favorite_list_prefix': [], + 'favorites': 196, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 168413208, + 'img_id_str': '168413208', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 262457191, + 'img_id_str': '262457191', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 396870731, + 'img_id_str': '396870731', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 78955937, + 'img_id_str': '78955937', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 324322786, + 'img_id_str': '324322786', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1200, + 'img_id': 495568404, + 'img_id_str': '495568404', + 'title': '001', + 'user_id': 2598104, + 'width': 800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '22', + 'passed_time': '01月06日', + 'post_id': 61452547, + 'published_at': '2020-01-06 14:23:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '知名摄影博主', + 'domain': '', + 'followers': 10365, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2598104_12', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '写真bot', + 'site_id': '2598104', + 'type': 'user', + 'url': 'https://tuchong.com/2598104/', + 'verification_list': [ + {'verification_reason': '知名摄影博主', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2598104', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2598104/61452547/', + 'views': 14214 + }, + { + 'author_id': '1475907', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 37, + 'content': '', + 'created_at': '2019-12-15 13:35:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 665, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 453886742, + 'img_id_str': '453886742', + 'title': '', + 'user_id': 1475907, + 'width': 3560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 108054209, + 'img_id_str': '108054209', + 'title': '', + 'user_id': 1475907, + 'width': 3560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 194430153, + 'img_id_str': '194430153', + 'title': '', + 'user_id': 1475907, + 'width': 3560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 259769116, + 'img_id_str': '259769116', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 498975447, + 'img_id_str': '498975447', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 260621348, + 'img_id_str': '260621348', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 175948795, + 'img_id_str': '175948795', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 464766262, + 'img_id_str': '464766262', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 410305264, + 'img_id_str': '410305264', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 471777845, + 'img_id_str': '471777845', + 'title': '', + 'user_id': 1475907, + 'width': 3560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 350012707, + 'img_id_str': '350012707', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 86688512, + 'img_id_str': '86688512', + 'title': '', + 'user_id': 1475907, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5340, + 'img_id': 464110677, + 'img_id_str': '464110677', + 'title': '', + 'user_id': 1475907, + 'width': 3560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 52216800, + 'img_id_str': '52216800', + 'title': '', + 'user_id': 1475907, + 'width': 5472 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '32', + 'passed_time': '2019年12月15日', + 'post_id': 60478104, + 'published_at': '2019-12-15 13:35:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 40, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'alianya.tuchong.com', + 'followers': 2387, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1475907_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '阿脸呀alianya', + 'site_id': '1475907', + 'type': 'user', + 'url': 'https://alianya.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1475907', + 'sites': [], + 'tags': ['小清新', '日系', '旅行'], + 'title': '泳衣写真', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://alianya.tuchong.com/60478104/', + 'views': 38970 + }, + { + 'author_id': '282981', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 19, + 'content': '摄影&后期:@摄影师张翼鹏', + 'created_at': '2019-11-24 21:37:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '摄影&后期:@摄影师张翼鹏', + 'favorite_list_prefix': [], + 'favorites': 439, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 280346749, + 'img_id_str': '280346749', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 349094014, + 'img_id_str': '349094014', + 'title': '', + 'user_id': 282981, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 270712684, + 'img_id_str': '270712684', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 432324280, + 'img_id_str': '432324280', + 'title': '', + 'user_id': 282981, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 103071548, + 'img_id_str': '103071548', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 601866374, + 'img_id_str': '601866374', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 230080271, + 'img_id_str': '230080271', + 'title': '', + 'user_id': 282981, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 440057688, + 'img_id_str': '440057688', + 'title': '', + 'user_id': 282981, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 538427303, + 'img_id_str': '538427303', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 195542739, + 'img_id_str': '195542739', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 199540833, + 'img_id_str': '199540833', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 315080512, + 'img_id_str': '315080512', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 643743806, + 'img_id_str': '643743806', + 'title': '', + 'user_id': 282981, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 195346976, + 'img_id_str': '195346976', + 'title': '', + 'user_id': 282981, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '18', + 'passed_time': '2019年11月24日', + 'post_id': 59266734, + 'published_at': '2019-11-24 21:37:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 16, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'jiafei.tuchong.com', + 'followers': 7142, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_282981_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '加菲视觉', + 'site_id': '282981', + 'type': 'user', + 'url': 'https://jiafei.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '282981', + 'sites': [], + 'tags': ['人像', '美女', '情绪', '写真', '女生'], + 'title': '【加菲视觉】—— zixin', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://jiafei.tuchong.com/59266734/', + 'views': 17515 + }, + { + 'author_id': '959534', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 113, + 'content': '我的人像摄影教学已经开始招生,咨询报名请加vx:18310080899或majingbossma', + 'created_at': '2019-10-25 10:46:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '我的人像摄影教学已经开始招生,咨询报名请加vx:18310080899或majingbossma', + 'favorite_list_prefix': [], + 'favorites': 3344, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 523089616, + 'img_id_str': '523089616', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 304723546, + 'img_id_str': '304723546', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 313178029, + 'img_id_str': '313178029', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2273, + 'img_id': 295548477, + 'img_id_str': '295548477', + 'title': '', + 'user_id': 959534, + 'width': 3410 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5656, + 'img_id': 404600808, + 'img_id_str': '404600808', + 'title': '', + 'user_id': 959534, + 'width': 3771 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 557299614, + 'img_id_str': '557299614', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3475, + 'img_id': 49919589, + 'img_id_str': '49919589', + 'title': '', + 'user_id': 959534, + 'width': 5213 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 239581020, + 'img_id_str': '239581020', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3446, + 'img_id': 484226895, + 'img_id_str': '484226895', + 'title': '', + 'user_id': 959534, + 'width': 5169 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 358856009, + 'img_id_str': '358856009', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 632272613, + 'img_id_str': '632272613', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 168605607, + 'img_id_str': '168605607', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2952, + 'img_id': 234862244, + 'img_id_str': '234862244', + 'title': '', + 'user_id': 959534, + 'width': 4429 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 123844189, + 'img_id_str': '123844189', + 'title': '', + 'user_id': 959534, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '98', + 'passed_time': '2019年10月25日', + 'post_id': 56875719, + 'published_at': '2019-10-25 10:46:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '2', + 'rqt_id': '', + 'shares': 217, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'xxmbossma66.tuchong.com', + 'followers': 90414, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_959534_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '马大兴BossMa', + 'site_id': '959534', + 'type': 'user', + 'url': 'https://xxmbossma66.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '959534', + 'sites': [], + 'tags': ['色彩', '人像', '佳能', '小清新', '美女', '135mm'], + 'title': '夏日有终曲,但人生无限时。', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://xxmbossma66.tuchong.com/56875719/', + 'views': 128748 + }, + { + 'author_id': '490904', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 32, + 'content': '暖阳', + 'created_at': '2019-10-21 15:04:45', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '糖水人像小组', + '分享神仙颜值', + '拍女友才是正经事', + '青春,我爱过的那个女孩!', + '高颜值女神聚集地', + '暖色调人像' + ], + 'excerpt': '暖阳', + 'favorite_list_prefix': [], + 'favorites': 1131, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 603170005, + 'img_id_str': '603170005', + 'title': '280194', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 653309780, + 'img_id_str': '653309780', + 'title': '280188', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 311670188, + 'img_id_str': '311670188', + 'title': '280193', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 523809658, + 'img_id_str': '523809658', + 'title': '280195', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 353481996, + 'img_id_str': '353481996', + 'title': '280191', + 'user_id': 490904, + 'width': 998 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 272021028, + 'img_id_str': '272021028', + 'title': '280190', + 'user_id': 490904, + 'width': 998 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '32', + 'passed_time': '2019年10月21日', + 'post_id': 56552752, + 'published_at': '2019-10-21 15:04:45', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 28, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12649, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_490904_8', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师CAT', + 'site_id': '490904', + 'type': 'user', + 'url': 'https://tuchong.com/490904/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '490904', + 'sites': [], + 'tags': [ + '糖水人像小组', + '分享神仙颜值', + '拍女友才是正经事', + '青春,我爱过的那个女孩!', + '高颜值女神聚集地', + '暖色调人像' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/490904/56552752/', + 'views': 30412 + }, + { + 'author_id': '1579511', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': 'Fade into you', + 'created_at': '2019-10-18 03:10:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': 'Fade into you', + 'favorite_list_prefix': [], + 'favorites': 578, + 'image_count': 15, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5830, + 'img_id': 396015089, + 'img_id_str': '396015089', + 'title': '', + 'user_id': 1579511, + 'width': 3794 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5828, + 'img_id': 431338687, + 'img_id_str': '431338687', + 'title': '', + 'user_id': 1579511, + 'width': 3891 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 223196130, + 'img_id_str': '223196130', + 'title': '', + 'user_id': 1579511, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5468, + 'img_id': 213497433, + 'img_id_str': '213497433', + 'title': '', + 'user_id': 1579511, + 'width': 3579 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4258, + 'img_id': 378975474, + 'img_id_str': '378975474', + 'title': '', + 'user_id': 1579511, + 'width': 3716 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3793, + 'img_id': 573748529, + 'img_id_str': '573748529', + 'title': '', + 'user_id': 1579511, + 'width': 5500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2753, + 'img_id': 582989229, + 'img_id_str': '582989229', + 'title': '', + 'user_id': 1579511, + 'width': 2159 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4641, + 'img_id': 68727788, + 'img_id_str': '68727788', + 'title': '', + 'user_id': 1579511, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4162, + 'img_id': 42447672, + 'img_id_str': '42447672', + 'title': '', + 'user_id': 1579511, + 'width': 3922 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5522, + 'img_id': 640202020, + 'img_id_str': '640202020', + 'title': '', + 'user_id': 1579511, + 'width': 3761 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3820, + 'img_id': 343782460, + 'img_id_str': '343782460', + 'title': '', + 'user_id': 1579511, + 'width': 5747 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 651867114, + 'img_id_str': '651867114', + 'title': '', + 'user_id': 1579511, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3612, + 'img_id': 462599021, + 'img_id_str': '462599021', + 'title': '', + 'user_id': 1579511, + 'width': 5328 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1760, + 'img_id': 121155967, + 'img_id_str': '121155967', + 'title': '', + 'user_id': 1579511, + 'width': 2841 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 210613111, + 'img_id_str': '210613111', + 'title': '', + 'user_id': 1579511, + 'width': 4631 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '22', + 'passed_time': '2019年10月18日', + 'post_id': 56194034, + 'published_at': '2019-10-18 03:10:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'shanelu.tuchong.com', + 'followers': 6054, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1579511_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '肖肖路', + 'site_id': '1579511', + 'type': 'user', + 'url': 'https://shanelu.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1579511', + 'sites': [], + 'tags': ['复古', '暗调', '光影', '唯美', '人像'], + 'title': 'Fade into you', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://shanelu.tuchong.com/56194034/', + 'views': 21396 + }, + { + 'author_id': '2736211', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 14, + 'content': '', + 'created_at': '2019-10-06 17:31:59', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 617, + 'image_count': 17, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5444, + 'img_id': 304000606, + 'img_id_str': '304000606', + 'title': '', + 'user_id': 2736211, + 'width': 3378 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2983, + 'img_id': 48869335, + 'img_id_str': '48869335', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3154, + 'img_id': 528133725, + 'img_id_str': '528133725', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2874, + 'img_id': 353153400, + 'img_id_str': '353153400', + 'title': '', + 'user_id': 2736211, + 'width': 5726 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3438, + 'img_id': 91729487, + 'img_id_str': '91729487', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2973, + 'img_id': 345681596, + 'img_id_str': '345681596', + 'title': '', + 'user_id': 2736211, + 'width': 5965 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3135, + 'img_id': 586723004, + 'img_id_str': '586723004', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3187, + 'img_id': 194162534, + 'img_id_str': '194162534', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 190754197, + 'img_id_str': '190754197', + 'title': '', + 'user_id': 2736211, + 'width': 3526 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3376, + 'img_id': 293645916, + 'img_id_str': '293645916', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 119516500, + 'img_id_str': '119516500', + 'title': '', + 'user_id': 2736211, + 'width': 3376 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2415, + 'img_id': 458796491, + 'img_id_str': '458796491', + 'title': '', + 'user_id': 2736211, + 'width': 5200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2713, + 'img_id': 34975616, + 'img_id_str': '34975616', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5022, + 'img_id': 544518100, + 'img_id_str': '544518100', + 'title': '', + 'user_id': 2736211, + 'width': 3242 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2742, + 'img_id': 190361095, + 'img_id_str': '190361095', + 'title': '', + 'user_id': 2736211, + 'width': 5757 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2931, + 'img_id': 576695928, + 'img_id_str': '576695928', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2443, + 'img_id': 434548397, + 'img_id_str': '434548397', + 'title': '', + 'user_id': 2736211, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '13', + 'passed_time': '2019年10月06日', + 'post_id': 54966007, + 'published_at': '2019-10-06 17:31:59', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 27, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2333, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2736211_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '洛洛-', + 'site_id': '2736211', + 'type': 'user', + 'url': 'https://tuchong.com/2736211/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2736211', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '抓拍', '美女', '写真', '胶片'], + 'title': '生活碎片', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2736211/54966007/', + 'views': 26755 + }, + { + 'author_id': '397965', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 41, + 'content': '', + 'created_at': '2019-09-01 22:23:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['拍女友才是正经事', '2020适马睛典'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1350, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 636787965, + 'img_id_str': '636787965', + 'title': '', + 'user_id': 397965, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 522296221, + 'img_id_str': '522296221', + 'title': '', + 'user_id': 397965, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 83467576, + 'img_id_str': '83467576', + 'title': '', + 'user_id': 397965, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 274439113, + 'img_id_str': '274439113', + 'title': '', + 'user_id': 397965, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 415865826, + 'img_id_str': '415865826', + 'title': '', + 'user_id': 397965, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 124951701, + 'img_id_str': '124951701', + 'title': '', + 'user_id': 397965, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 620731445, + 'img_id_str': '620731445', + 'title': '', + 'user_id': 397965, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 499948848, + 'img_id_str': '499948848', + 'title': '', + 'user_id': 397965, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 414752116, + 'img_id_str': '414752116', + 'title': '', + 'user_id': 397965, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '34', + 'passed_time': '2019年09月01日', + 'post_id': 51389145, + 'published_at': '2019-09-01 22:23:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '6', + 'rqt_id': '', + 'shares': 42, + 'site': { + 'description': '图虫签约摄影,QQ3365549820,微信18777169499,微博@WINGZERO1991', + 'domain': '', + 'followers': 1455, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_397965_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'WINGZERO1991', + 'site_id': '397965', + 'type': 'user', + 'url': 'https://tuchong.com/397965/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '397965', + 'sites': [], + 'tags': ['拍女友才是正经事', '2020适马睛典', '美女', '人像', '南宁', '南宁约拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/397965/51389145/', + 'views': 64036 + }, + { + 'author_id': '1341135', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 19, + 'content': '', + 'created_at': '2019-08-17 23:39:02', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 388, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3710, + 'img_id': 311595450, + 'img_id_str': '311595450', + 'title': '', + 'user_id': 1341135, + 'width': 2520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3491, + 'img_id': 649434159, + 'img_id_str': '649434159', + 'title': '', + 'user_id': 1341135, + 'width': 2689 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5099, + 'img_id': 154374967, + 'img_id_str': '154374967', + 'title': '', + 'user_id': 1341135, + 'width': 3564 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4993, + 'img_id': 354193798, + 'img_id_str': '354193798', + 'title': '', + 'user_id': 1341135, + 'width': 3261 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4459, + 'img_id': 180261553, + 'img_id_str': '180261553', + 'title': '', + 'user_id': 1341135, + 'width': 3292 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3816, + 'img_id': 361075719, + 'img_id_str': '361075719', + 'title': '', + 'user_id': 1341135, + 'width': 3798 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2879, + 'img_id': 597660212, + 'img_id_str': '597660212', + 'title': '', + 'user_id': 1341135, + 'width': 1724 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '15', + 'passed_time': '2019年08月17日', + 'post_id': 49624838, + 'published_at': '2019-08-17 23:39:02', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 13723, + 'has_everphoto_note': false, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1341135_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '震业', + 'site_id': '1341135', + 'type': 'user', + 'url': 'https://tuchong.com/1341135/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1341135', + 'sites': [], + 'tags': ['情绪', '少女', '胶片', '尼康', '人像', '写真'], + 'title': '无法封存的记忆', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1341135/49624838/', + 'views': 24838 + }, + { + 'author_id': '1548800', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 52, + 'content': '', + 'created_at': '2019-07-28 05:55:30', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['日系集'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1352, + 'image_count': 18, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 95649634, + 'img_id_str': '95649634', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 642023166, + 'img_id_str': '642023166', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 588087039, + 'img_id_str': '588087039', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4400, + 'img_id': 445546583, + 'img_id_str': '445546583', + 'title': '001', + 'user_id': 1548800, + 'width': 4400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4200, + 'img_id': 180715057, + 'img_id_str': '180715057', + 'title': '001', + 'user_id': 1548800, + 'width': 4200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 139558724, + 'img_id_str': '139558724', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 385384268, + 'img_id_str': '385384268', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 245726862, + 'img_id_str': '245726862', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4200, + 'img_id': 561675793, + 'img_id_str': '561675793', + 'title': '001', + 'user_id': 1548800, + 'width': 4200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 322928252, + 'img_id_str': '322928252', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 255754088, + 'img_id_str': '255754088', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 644251440, + 'img_id_str': '644251440', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 524254628, + 'img_id_str': '524254628', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 377585211, + 'img_id_str': '377585211', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 334397564, + 'img_id_str': '334397564', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 45645720, + 'img_id_str': '45645720', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 265453478, + 'img_id_str': '265453478', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 586776740, + 'img_id_str': '586776740', + 'title': '001', + 'user_id': 1548800, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '45', + 'passed_time': '2019年07月28日', + 'post_id': 46552979, + 'published_at': '2019-07-28 05:55:30', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 42, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2007, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1548800_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影_一万', + 'site_id': '1548800', + 'type': 'user', + 'url': 'https://tuchong.com/1548800/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1548800', + 'sites': [], + 'tags': ['日系集', '人像', '色彩', '日系人像', '人'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1548800/46552979/', + 'views': 83698 + }, + { + 'author_id': '15956987', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '', + 'created_at': '2020-01-19 11:53:09', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['谁还没点童年黑照'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 12, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 193054314, + 'img_id_str': '193054314', + 'title': '584783', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 164087695, + 'img_id_str': '164087695', + 'title': '584782', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 604358446, + 'img_id_str': '604358446', + 'title': '584780', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 391497763, + 'img_id_str': '391497763', + 'title': '584779', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 214746906, + 'img_id_str': '214746906', + 'title': '584778', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 638240249, + 'img_id_str': '638240249', + 'title': '584775', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 122734150, + 'img_id_str': '122734150', + 'title': '583391', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 134989549, + 'img_id_str': '134989549', + 'title': '583390', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 88131245, + 'img_id_str': '88131245', + 'title': '583389', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 609601613, + 'img_id_str': '609601613', + 'title': '583388', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 600492086, + 'img_id_str': '600492086', + 'title': '583387', + 'user_id': 15956987, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 341624488, + 'img_id_str': '341624488', + 'title': '584781', + 'user_id': 15956987, + 'width': 4000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61835061, + 'published_at': '2020-01-19 11:53:09', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 1, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15956987_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '李同168', + 'site_id': '15956987', + 'type': 'user', + 'url': 'https://tuchong.com/15956987/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15956987', + 'sites': [], + 'tags': ['谁还没点童年黑照', '公园', '环境'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15956987/61835061/', + 'views': 585 + }, + { + 'author_id': '15943193', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 3, + 'content': '静物光影', + 'created_at': '2020-01-18 22:39:35', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['纯粹黑白圈子'], + 'excerpt': '静物光影', + 'favorite_list_prefix': [], + 'favorites': 17, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3556, + 'img_id': 315410257, + 'img_id_str': '315410257', + 'title': '1254227', + 'user_id': 15943193, + 'width': 5333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2829, + 'img_id': 205768263, + 'img_id_str': '205768263', + 'title': '1254229', + 'user_id': 15943193, + 'width': 4298 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2640, + 'img_id': 123521280, + 'img_id_str': '123521280', + 'title': '1254228', + 'user_id': 15943193, + 'width': 3960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3403, + 'img_id': 562808716, + 'img_id_str': '562808716', + 'title': '1254226', + 'user_id': 15943193, + 'width': 5105 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月18日', + 'post_id': 61823921, + 'published_at': '2020-01-18 22:39:35', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 10, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15943193_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '楠姐1959', + 'site_id': '15943193', + 'type': 'user', + 'url': 'https://tuchong.com/15943193/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15943193', + 'sites': [], + 'tags': ['纯粹黑白圈子', '静物'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15943193/61823921/', + 'views': 471 + }, + { + 'author_id': '15946115', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '被惦记该有多好', + 'created_at': '2020-01-18 22:27:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['胶片人像摄影'], + 'excerpt': '被惦记该有多好', + 'favorite_list_prefix': [], + 'favorites': 14, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 551863811, + 'img_id_str': '551863811', + 'title': '2541999', + 'user_id': 15946115, + 'width': 1920 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61823558, + 'published_at': '2020-01-18 22:27:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 12, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15946115_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'DIDIL', + 'site_id': '15946115', + 'type': 'user', + 'url': 'https://tuchong.com/15946115/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15946115', + 'sites': [], + 'tags': ['胶片人像摄影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15946115/61823558/', + 'views': 680 + }, + { + 'author_id': '15946944', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '橘子味汽水', + 'created_at': '2020-01-18 20:55:39', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '日出日落奇迹时间', + '胶片人像摄影', + '暖色调人像', + '有温度的人像', + '分享神仙颜值', + '胶片集', + '校园摄影师这样拍' + ], + 'excerpt': '橘子味汽水', + 'favorite_list_prefix': [], + 'favorites': 12, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 217368426, + 'img_id_str': '217368426', + 'title': '1733971', + 'user_id': 15946944, + 'width': 1437 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 600425986, + 'img_id_str': '600425986', + 'title': '1733968', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 493864737, + 'img_id_str': '493864737', + 'title': '1733964', + 'user_id': 15946944, + 'width': 1437 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 214550536, + 'img_id_str': '214550536', + 'title': '1733960', + 'user_id': 15946944, + 'width': 1437 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 190891765, + 'img_id_str': '190891765', + 'title': '1733955', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 62506763, + 'img_id_str': '62506763', + 'title': '1733954', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 551732989, + 'img_id_str': '551732989', + 'title': '1733952', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 306825297, + 'img_id_str': '306825297', + 'title': '1733947', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 416073484, + 'img_id_str': '416073484', + 'title': '1733942', + 'user_id': 15946944, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2001, + 'img_id': 334546752, + 'img_id_str': '334546752', + 'title': '1733940', + 'user_id': 15946944, + 'width': 1483 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 383305386, + 'img_id_str': '383305386', + 'title': '1733939', + 'user_id': 15946944, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 196331053, + 'img_id_str': '196331053', + 'title': '1733893', + 'user_id': 15946944, + 'width': 1437 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61820906, + 'published_at': '2020-01-18 20:55:39', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '个人摄影', + 'domain': '', + 'followers': 6, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15946944_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '被名字遗忘的博主', + 'site_id': '15946944', + 'type': 'user', + 'url': 'https://tuchong.com/15946944/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15946944', + 'sites': [], + 'tags': ['日出日落奇迹时间', '胶片人像摄影', '暖色调人像', '有温度的人像', '分享神仙颜值', '胶片集'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15946944/61820906/', + 'views': 699 + }, + { + 'author_id': '15951134', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2020-01-18 14:13:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['中国创意摄影'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 11, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3968, + 'img_id': 495305816, + 'img_id_str': '495305816', + 'title': '73984', + 'user_id': 15951134, + 'width': 2976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 641975775, + 'img_id_str': '641975775', + 'title': '73985', + 'user_id': 15951134, + 'width': 3968 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月18日', + 'post_id': 61811635, + 'published_at': '2020-01-18 14:13:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 9, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15951134_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '笛声枯竭干涸', + 'site_id': '15951134', + 'type': 'user', + 'url': 'https://tuchong.com/15951134/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15951134', + 'sites': [], + 'tags': ['中国创意摄影', '博物馆', '剑', '文物'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15951134/61811635/', + 'views': 529 + }, + { + 'author_id': '372183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 41, + 'content': '', + 'created_at': '2019-11-06 10:43:40', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019胶片摄影赛', '分享神仙颜值'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 760, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 604617432, + 'img_id_str': '604617432', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 512605170, + 'img_id_str': '512605170', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 162249271, + 'img_id_str': '162249271', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 85899640, + 'img_id_str': '85899640', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 557234699, + 'img_id_str': '557234699', + 'title': '', + 'user_id': 372183, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 599505286, + 'img_id_str': '599505286', + 'title': '', + 'user_id': 372183, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 133675638, + 'img_id_str': '133675638', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 457620408, + 'img_id_str': '457620408', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 38976262, + 'img_id_str': '38976262', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 619166438, + 'img_id_str': '619166438', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 523942565, + 'img_id_str': '523942565', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 205896616, + 'img_id_str': '205896616', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 486390331, + 'img_id_str': '486390331', + 'title': '', + 'user_id': 372183, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 436320812, + 'img_id_str': '436320812', + 'title': '', + 'user_id': 372183, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2193, + 'img_id': 593541550, + 'img_id_str': '593541550', + 'title': '', + 'user_id': 372183, + 'width': 3192 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 235584285, + 'img_id_str': '235584285', + 'title': '', + 'user_id': 372183, + 'width': 3318 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '36', + 'passed_time': '2019年11月06日', + 'post_id': 57918905, + 'published_at': '2019-11-06 10:43:40', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '7', + 'rqt_id': '', + 'shares': 24, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 11898, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_372183_7', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄影师暗栀', + 'site_id': '372183', + 'type': 'user', + 'url': 'https://tuchong.com/372183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '372183', + 'sites': [], + 'tags': ['2019胶片摄影赛', '分享神仙颜值', '胶片', '写真', '夏天', '青春映像节摄影大赛'], + 'title': 'RAIN', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/372183/57918905/', + 'views': 31935 + }, + { + 'author_id': '1349328', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 61, + 'content': '在你的心里呀 在你的心底呀\n\n不管是多远的远方 不要害怕我在身旁', + 'created_at': '2019-10-10 17:40:56', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '在你的心里呀 在你的心底呀\n\n不管是多远的远方 不要害怕我在身旁', + 'favorite_list_prefix': [], + 'favorites': 2143, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3300, + 'img_id': 59617329, + 'img_id_str': '59617329', + 'title': '', + 'user_id': 1349328, + 'width': 2200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 549565227, + 'img_id_str': '549565227', + 'title': '', + 'user_id': 1349328, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 643478139, + 'img_id_str': '643478139', + 'title': '', + 'user_id': 1349328, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 197767343, + 'img_id_str': '197767343', + 'title': '', + 'user_id': 1349328, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 517451777, + 'img_id_str': '517451777', + 'title': '', + 'user_id': 1349328, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3104, + 'img_id': 625651990, + 'img_id_str': '625651990', + 'title': '', + 'user_id': 1349328, + 'width': 2070 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '50', + 'passed_time': '2019年10月10日', + 'post_id': 55479953, + 'published_at': '2019-10-10 17:40:56', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 63, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7901, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1349328_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '壹梵i', + 'site_id': '1349328', + 'type': 'user', + 'url': 'https://tuchong.com/1349328/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1349328', + 'sites': [], + 'tags': ['人像', '佳能'], + 'title': '我只想做你的太阳 你的太阳', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1349328/55479953/', + 'views': 64650 + }, + { + 'author_id': '1937912', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 14, + 'content': '摄影:紫荞\n模特:cc\n地址:小鹿奔跑了摄影工作室\n—室内写真-', + 'created_at': '2019-10-08 09:08:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '摄影:紫荞\n模特:cc\n地址:小鹿奔跑了摄影工作室\n—室内写真-', + 'favorite_list_prefix': [], + 'favorites': 274, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 310226554, + 'img_id_str': '310226554', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 340242406, + 'img_id_str': '340242406', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 593080710, + 'img_id_str': '593080710', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5263, + 'img_id': 451326551, + 'img_id_str': '451326551', + 'title': '001', + 'user_id': 1937912, + 'width': 3423 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4070, + 'img_id': 117878802, + 'img_id_str': '117878802', + 'title': '001', + 'user_id': 1937912, + 'width': 6140 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 643281258, + 'img_id_str': '643281258', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 408662263, + 'img_id_str': '408662263', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 574009311, + 'img_id_str': '574009311', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 176730442, + 'img_id_str': '176730442', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 402173999, + 'img_id_str': '402173999', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 48017103, + 'img_id_str': '48017103', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 642035672, + 'img_id_str': '642035672', + 'title': '001', + 'user_id': 1937912, + 'width': 4160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '14', + 'passed_time': '2019年10月08日', + 'post_id': 55191671, + 'published_at': '2019-10-08 09:08:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 4, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7144, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1937912_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '紫荞姑娘', + 'site_id': '1937912', + 'type': 'user', + 'url': 'https://tuchong.com/1937912/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1937912', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '书桌', '深圳约拍', '旧时光是个美人', '教室'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1937912/55191671/', + 'views': 9888 + }, + { + 'author_id': '3477512', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 51, + 'content': '', + 'created_at': '2019-09-27 16:07:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1250, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 299477022, + 'img_id_str': '299477022', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 62367761, + 'img_id_str': '62367761', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2033, + 'img_id': 443918746, + 'img_id_str': '443918746', + 'title': '001', + 'user_id': 3477512, + 'width': 3048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 274573889, + 'img_id_str': '274573889', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 570796266, + 'img_id_str': '570796266', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 200321604, + 'img_id_str': '200321604', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 498182265, + 'img_id_str': '498182265', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3048, + 'img_id': 562866193, + 'img_id_str': '562866193', + 'title': '001', + 'user_id': 3477512, + 'width': 2033 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '50', + 'passed_time': '2019年09月27日', + 'post_id': 53711715, + 'published_at': '2019-09-27 16:07:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 33, + 'site': { + 'description': '资深旅行摄影师', + 'domain': '', + 'followers': 44864, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3477512_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Cissy_Li', + 'site_id': '3477512', + 'type': 'user', + 'url': 'https://tuchong.com/3477512/', + 'verification_list': [ + {'verification_reason': '资深旅行摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3477512', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3477512/53711715/', + 'views': 55161 + }, + { + 'author_id': '1609287', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 72, + 'content': '老图存档', + 'created_at': '2019-09-05 09:47:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '老图存档', + 'favorite_list_prefix': [], + 'favorites': 1486, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 631741741, + 'img_id_str': '631741741', + 'title': '', + 'user_id': 1609287, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 341352081, + 'img_id_str': '341352081', + 'title': '', + 'user_id': 1609287, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 40410275, + 'img_id_str': '40410275', + 'title': '', + 'user_id': 1609287, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 244555717, + 'img_id_str': '244555717', + 'title': '', + 'user_id': 1609287, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4700, + 'img_id': 584228741, + 'img_id_str': '584228741', + 'title': '', + 'user_id': 1609287, + 'width': 3327 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 464101158, + 'img_id_str': '464101158', + 'title': '', + 'user_id': 1609287, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 462200265, + 'img_id_str': '462200265', + 'title': '', + 'user_id': 1609287, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 388144648, + 'img_id_str': '388144648', + 'title': '', + 'user_id': 1609287, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 551133041, + 'img_id_str': '551133041', + 'title': '', + 'user_id': 1609287, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 603627113, + 'img_id_str': '603627113', + 'title': '', + 'user_id': 1609287, + 'width': 3200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '67', + 'passed_time': '2019年09月05日', + 'post_id': 51686073, + 'published_at': '2019-09-05 09:47:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 92, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 69550, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1609287_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '皓子_', + 'site_id': '1609287', + 'type': 'user', + 'url': 'https://tuchong.com/1609287/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1609287', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '色彩', '女神', 'JK', '私影'], + 'title': '这是一场 蓝色的 关于海洋的梦', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1609287/51686073/', + 'views': 53256 + }, + { + 'author_id': '406880', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 58, + 'content': '又是一波预告,哈哈哈?', + 'created_at': '2019-11-01 21:20:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '又是一波预告,哈哈哈?', + 'favorite_list_prefix': [], + 'favorites': 776, + 'image_count': 3, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 510507203, + 'img_id_str': '510507203', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 513587249, + 'img_id_str': '513587249', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 122403027, + 'img_id_str': '122403027', + 'title': '001', + 'user_id': 406880, + 'width': 960 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '54', + 'passed_time': '2019年11月01日', + 'post_id': 57521816, + 'published_at': '2019-11-01 21:20:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 23, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 24454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_406880_9', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '风-vision', + 'site_id': '406880', + 'type': 'user', + 'url': 'https://tuchong.com/406880/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '406880', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/406880/57521816/', + 'views': 31253 + }, + { + 'author_id': '58885', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 42, + 'content': '彼岸的光永远也照不进遥远的森林里', + 'created_at': '2019-10-28 17:46:39', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '彼岸的光永远也照不进遥远的森林里', + 'favorite_list_prefix': [], + 'favorites': 1045, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 85309505, + 'img_id_str': '85309505', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 39499918, + 'img_id_str': '39499918', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 222410923, + 'img_id_str': '222410923', + 'title': '', + 'user_id': 58885, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 330020981, + 'img_id_str': '330020981', + 'title': '', + 'user_id': 58885, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 591639939, + 'img_id_str': '591639939', + 'title': '', + 'user_id': 58885, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 400865260, + 'img_id_str': '400865260', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 451328623, + 'img_id_str': '451328623', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 475576830, + 'img_id_str': '475576830', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 478787916, + 'img_id_str': '478787916', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 94418445, + 'img_id_str': '94418445', + 'title': '', + 'user_id': 58885, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 92452676, + 'img_id_str': '92452676', + 'title': '', + 'user_id': 58885, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '35', + 'passed_time': '2019年10月28日', + 'post_id': 57184774, + 'published_at': '2019-10-28 17:46:39', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'somy.tuchong.com', + 'followers': 21627, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_58885_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '骨灰级烧卖', + 'site_id': '58885', + 'type': 'user', + 'url': 'https://somy.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '58885', + 'sites': [], + 'tags': ['色彩', '人像', '美女'], + 'title': '彼岸的光', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://somy.tuchong.com/57184774/', + 'views': 36050 + }, + { + 'author_id': '3591420', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 8, + 'content': '', + 'created_at': '2019-10-10 00:39:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['杭州摄影爱好者'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 312, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1806, + 'img_id': 335458806, + 'img_id_str': '335458806', + 'title': '', + 'user_id': 3591420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 150974551, + 'img_id_str': '150974551', + 'title': '', + 'user_id': 3591420, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 512864494, + 'img_id_str': '512864494', + 'title': '', + 'user_id': 3591420, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 270774399, + 'img_id_str': '270774399', + 'title': '', + 'user_id': 3591420, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1755, + 'img_id': 427864865, + 'img_id_str': '427864865', + 'title': '', + 'user_id': 3591420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6092, + 'img_id': 543404108, + 'img_id_str': '543404108', + 'title': '', + 'user_id': 3591420, + 'width': 4036 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4022, + 'img_id': 41529519, + 'img_id_str': '41529519', + 'title': '', + 'user_id': 3591420, + 'width': 6034 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3738, + 'img_id': 350990284, + 'img_id_str': '350990284', + 'title': '', + 'user_id': 3591420, + 'width': 6240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 621064250, + 'img_id_str': '621064250', + 'title': '', + 'user_id': 3591420, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3751, + 'img_id': 417705587, + 'img_id_str': '417705587', + 'title': '', + 'user_id': 3591420, + 'width': 5609 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 509194485, + 'img_id_str': '509194485', + 'title': '', + 'user_id': 3591420, + 'width': 6240 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '2019年10月10日', + 'post_id': 55422924, + 'published_at': '2019-10-10 00:39:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 810, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3591420_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '沐生阿', + 'site_id': '3591420', + 'type': 'user', + 'url': 'https://tuchong.com/3591420/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3591420', + 'sites': [], + 'tags': ['杭州摄影爱好者', '人像', '少女', '情绪', '日系', '和服'], + 'title': '吾蕊—', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3591420/55422924/', + 'views': 9804 + }, + { + 'author_id': '1670980', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 129, + 'content': '', + 'created_at': '2019-09-10 10:16:57', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2233, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 207855882, + 'img_id_str': '207855882', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 66035577, + 'img_id_str': '66035577', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 535797870, + 'img_id_str': '535797870', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 366518384, + 'img_id_str': '366518384', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 85827788, + 'img_id_str': '85827788', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 246260128, + 'img_id_str': '246260128', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 291938562, + 'img_id_str': '291938562', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 476946558, + 'img_id_str': '476946558', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 429694972, + 'img_id_str': '429694972', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 338665718, + 'img_id_str': '338665718', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 76717721, + 'img_id_str': '76717721', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '104', + 'passed_time': '2019年09月10日', + 'post_id': 52159682, + 'published_at': '2019-09-10 10:16:57', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 131, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12358, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1670980_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '沐秋-王伟', + 'site_id': '1670980', + 'type': 'user', + 'url': 'https://tuchong.com/1670980/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1670980', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1670980/52159682/', + 'views': 158353 + }, + { + 'author_id': '2717528', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 36, + 'content': '', + 'created_at': '2019-09-04 19:11:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我们都爱日系摄影'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1110, + 'image_count': 34, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 96640479, + 'img_id_str': '96640479', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1680, + 'img_id': 166895241, + 'img_id_str': '166895241', + 'title': '001', + 'user_id': 2717528, + 'width': 2520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 640065066, + 'img_id_str': '640065066', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 641441323, + 'img_id_str': '641441323', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1680, + 'img_id': 632790316, + 'img_id_str': '632790316', + 'title': '001', + 'user_id': 2717528, + 'width': 2520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 583507461, + 'img_id_str': '583507461', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 94411886, + 'img_id_str': '94411886', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 507354915, + 'img_id_str': '507354915', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 290365003, + 'img_id_str': '290365003', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 461872818, + 'img_id_str': '461872818', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 555326989, + 'img_id_str': '555326989', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 351969024, + 'img_id_str': '351969024', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 141794721, + 'img_id_str': '141794721', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1260, + 'img_id': 56860340, + 'img_id_str': '56860340', + 'title': '001', + 'user_id': 2717528, + 'width': 840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 489070061, + 'img_id_str': '489070061', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 598252851, + 'img_id_str': '598252851', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 68394770, + 'img_id_str': '68394770', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 57712296, + 'img_id_str': '57712296', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 432251019, + 'img_id_str': '432251019', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 630234687, + 'img_id_str': '630234687', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1680, + 'img_id': 194485713, + 'img_id_str': '194485713', + 'title': '001', + 'user_id': 2717528, + 'width': 2520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 278306572, + 'img_id_str': '278306572', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 568434138, + 'img_id_str': '568434138', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 164601139, + 'img_id_str': '164601139', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 405773768, + 'img_id_str': '405773768', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 192453919, + 'img_id_str': '192453919', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 311664243, + 'img_id_str': '311664243', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1680, + 'img_id': 223452545, + 'img_id_str': '223452545', + 'title': '001', + 'user_id': 2717528, + 'width': 2520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 463642088, + 'img_id_str': '463642088', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 153001409, + 'img_id_str': '153001409', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 613916501, + 'img_id_str': '613916501', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1649, + 'img_id': 375955091, + 'img_id_str': '375955091', + 'title': '001', + 'user_id': 2717528, + 'width': 2474 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 165322085, + 'img_id_str': '165322085', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2520, + 'img_id': 455646831, + 'img_id_str': '455646831', + 'title': '001', + 'user_id': 2717528, + 'width': 1680 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '33', + 'passed_time': '2019年09月04日', + 'post_id': 51641574, + 'published_at': '2019-09-04 19:11:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 24, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 11801, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2717528_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '卡巴拉岛的回忆', + 'site_id': '2717528', + 'type': 'user', + 'url': 'https://tuchong.com/2717528/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2717528', + 'sites': [], + 'tags': ['我们都爱日系摄影', '人像', '色彩', '体操服'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2717528/51641574/', + 'views': 48484 + }, + { + 'author_id': '1531311', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 28, + 'content': '已经迫不及待的期盼着秋天的到来,先将画面改成秋天,金灿灿的秋色!\nwb:@王艺萌-\nvx:wyx_photo', + 'created_at': '2019-09-04 15:10:16', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '已经迫不及待的期盼着秋天的到来,先将画面改成秋天,金灿灿的秋色!\nwb:@王艺萌-\nvx:wyx_photo', + 'favorite_list_prefix': [], + 'favorites': 414, + 'image_count': 20, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 130981488, + 'img_id_str': '130981488', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 428449366, + 'img_id_str': '428449366', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 235904667, + 'img_id_str': '235904667', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 615686185, + 'img_id_str': '615686185', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 526688126, + 'img_id_str': '526688126', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 428056516, + 'img_id_str': '428056516', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 616275551, + 'img_id_str': '616275551', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 389783397, + 'img_id_str': '389783397', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 390766432, + 'img_id_str': '390766432', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 389062097, + 'img_id_str': '389062097', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 344038612, + 'img_id_str': '344038612', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 246455866, + 'img_id_str': '246455866', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 574332460, + 'img_id_str': '574332460', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 521182670, + 'img_id_str': '521182670', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 456301950, + 'img_id_str': '456301950', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 628923951, + 'img_id_str': '628923951', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 240361122, + 'img_id_str': '240361122', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 644259478, + 'img_id_str': '644259478', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 521379118, + 'img_id_str': '521379118', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 34905340, + 'img_id_str': '34905340', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年09月04日', + 'post_id': 51624155, + 'published_at': '2019-09-04 15:10:16', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 20, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'wangyimeng.tuchong.com', + 'followers': 11125, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1531311_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '王艺萌', + 'site_id': '1531311', + 'type': 'user', + 'url': 'https://wangyimeng.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1531311', + 'sites': [], + 'tags': ['小清新', '日系', '校园', '重庆', '少女'], + 'title': '「秋之季」', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://wangyimeng.tuchong.com/51624155/', + 'views': 16081 + }, + { + 'author_id': '1345449', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 66, + 'content': '', + 'created_at': '2019-08-31 18:37:10', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 835, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 8283, + 'img_id': 607821143, + 'img_id_str': '607821143', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8248, + 'img_id': 158833669, + 'img_id_str': '158833669', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3917, + 'img_id': 501193426, + 'img_id_str': '501193426', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8271, + 'img_id': 388144118, + 'img_id_str': '388144118', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8037, + 'img_id': 75733994, + 'img_id_str': '75733994', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7989, + 'img_id': 383819270, + 'img_id_str': '383819270', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8311, + 'img_id': 161520882, + 'img_id_str': '161520882', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8236, + 'img_id': 107257258, + 'img_id_str': '107257258', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8184, + 'img_id': 561683249, + 'img_id_str': '561683249', + 'title': '001', + 'user_id': 1345449, + 'width': 5197 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '65', + 'passed_time': '2019年08月31日', + 'post_id': 51241630, + 'published_at': '2019-08-31 18:37:10', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 25, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 9229, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1345449_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟思杰', + 'site_id': '1345449', + 'type': 'user', + 'url': 'https://tuchong.com/1345449/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1345449', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1345449/51241630/', + 'views': 49242 + }, + { + 'author_id': '1670980', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 15, + 'content': '', + 'created_at': '2019-08-07 10:17:20', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 537, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 561940355, + 'img_id_str': '561940355', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 552568829, + 'img_id_str': '552568829', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 301041608, + 'img_id_str': '301041608', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 566003884, + 'img_id_str': '566003884', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 339773496, + 'img_id_str': '339773496', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 465078232, + 'img_id_str': '465078232', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 156797479, + 'img_id_str': '156797479', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '15', + 'passed_time': '2019年08月07日', + 'post_id': 48037445, + 'published_at': '2019-08-07 10:17:20', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12358, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1670980_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '沐秋-王伟', + 'site_id': '1670980', + 'type': 'user', + 'url': 'https://tuchong.com/1670980/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1670980', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1670980/48037445/', + 'views': 33698 + }, + { + 'author_id': '344885', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 41, + 'content': '', + 'created_at': '2019-12-07 18:50:19', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 917, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 243319798, + 'img_id_str': '243319798', + 'title': '', + 'user_id': 344885, + 'width': 4002 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 515490449, + 'img_id_str': '515490449', + 'title': '', + 'user_id': 344885, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 91013501, + 'img_id_str': '91013501', + 'title': '', + 'user_id': 344885, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 42582414, + 'img_id_str': '42582414', + 'title': '', + 'user_id': 344885, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 210027059, + 'img_id_str': '210027059', + 'title': '', + 'user_id': 344885, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 360825728, + 'img_id_str': '360825728', + 'title': '', + 'user_id': 344885, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 164675845, + 'img_id_str': '164675845', + 'title': '', + 'user_id': 344885, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 217891588, + 'img_id_str': '217891588', + 'title': '', + 'user_id': 344885, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 222872283, + 'img_id_str': '222872283', + 'title': '', + 'user_id': 344885, + 'width': 5304 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '39', + 'passed_time': '2019年12月07日', + 'post_id': 60040503, + 'published_at': '2019-12-07 18:50:19', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 48, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'alstonchan.tuchong.com', + 'followers': 12812, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_344885_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Alston-西瓜呆毛汪', + 'site_id': '344885', + 'type': 'user', + 'url': 'https://alstonchan.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '344885', + 'sites': [], + 'tags': ['色彩', '人像', '小清新', '美女', '日系', 'Cosplay'], + 'title': '天火泳衣COSPLAY', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://alstonchan.tuchong.com/60040503/', + 'views': 35149 + }, + { + 'author_id': '1107388', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '初恋', + 'created_at': '2019-11-28 10:53:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '初恋', + 'favorite_list_prefix': [], + 'favorites': 544, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 584893019, + 'img_id_str': '584893019', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 45203660, + 'img_id_str': '45203660', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 301973729, + 'img_id_str': '301973729', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 411877727, + 'img_id_str': '411877727', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 408404567, + 'img_id_str': '408404567', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 88326320, + 'img_id_str': '88326320', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2133, + 'img_id': 101105727, + 'img_id_str': '101105727', + 'title': '001', + 'user_id': 1107388, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 118603819, + 'img_id_str': '118603819', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2333, + 'img_id': 256885160, + 'img_id_str': '256885160', + 'title': '001', + 'user_id': 1107388, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 92061729, + 'img_id_str': '92061729', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2333, + 'img_id': 184860971, + 'img_id_str': '184860971', + 'title': '001', + 'user_id': 1107388, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 344375883, + 'img_id_str': '344375883', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3450, + 'img_id': 431407184, + 'img_id_str': '431407184', + 'title': '001', + 'user_id': 1107388, + 'width': 2300 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2333, + 'img_id': 408731758, + 'img_id_str': '408731758', + 'title': '001', + 'user_id': 1107388, + 'width': 3500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '41', + 'passed_time': '2019年11月28日', + 'post_id': 59482620, + 'published_at': '2019-11-28 10:53:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 23, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2765, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1107388_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '太阳酱Catnip', + 'site_id': '1107388', + 'type': 'user', + 'url': 'https://tuchong.com/1107388/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1107388', + 'sites': [], + 'tags': ['可爱', '女孩', '人像写真', '日系小清新', '甜美', '贵阳约拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1107388/59482620/', + 'views': 16812 + }, + { + 'author_id': '1827482', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 85, + 'content': 'She blushed', + 'created_at': '2019-09-21 20:16:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['日出日落奇迹时间', '2019胶片摄影赛'], + 'excerpt': 'She blushed', + 'favorite_list_prefix': [], + 'favorites': 3257, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 551135050, + 'img_id_str': '551135050', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 428647896, + 'img_id_str': '428647896', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 101950865, + 'img_id_str': '101950865', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 408593604, + 'img_id_str': '408593604', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 179349038, + 'img_id_str': '179349038', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 139699621, + 'img_id_str': '139699621', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 462268252, + 'img_id_str': '462268252', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 165062003, + 'img_id_str': '165062003', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 512009538, + 'img_id_str': '512009538', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '72', + 'passed_time': '2019年09月21日', + 'post_id': 53196603, + 'published_at': '2019-09-21 20:16:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 84, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'j-leonardo.tuchong.com', + 'followers': 6303, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1827482_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '空镜Titanium', + 'site_id': '1827482', + 'type': 'user', + 'url': 'https://j-leonardo.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1827482', + 'sites': [], + 'tags': ['日出日落奇迹时间', '2019胶片摄影赛', '人像', '胶片', '色彩', '复古'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://j-leonardo.tuchong.com/53196603/', + 'views': 160455 + }, + { + 'author_id': '340199', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '宫', + 'created_at': '2019-12-18 10:49:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '宫', + 'favorite_list_prefix': [], + 'favorites': 212, + 'image_count': 24, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 289129669, + 'img_id_str': '289129669', + 'title': '001', + 'user_id': 340199, + 'width': 4512 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 96978052, + 'img_id_str': '96978052', + 'title': '001', + 'user_id': 340199, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 152290603, + 'img_id_str': '152290603', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 456639653, + 'img_id_str': '456639653', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 393528212, + 'img_id_str': '393528212', + 'title': '001', + 'user_id': 340199, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 209699905, + 'img_id_str': '209699905', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 488752286, + 'img_id_str': '488752286', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 254002056, + 'img_id_str': '254002056', + 'title': '001', + 'user_id': 340199, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 503038851, + 'img_id_str': '503038851', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 42321020, + 'img_id_str': '42321020', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 205308642, + 'img_id_str': '205308642', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 99796019, + 'img_id_str': '99796019', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 613073677, + 'img_id_str': '613073677', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 558679458, + 'img_id_str': '558679458', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 396739814, + 'img_id_str': '396739814', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 278840362, + 'img_id_str': '278840362', + 'title': '001', + 'user_id': 340199, + 'width': 3024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 526369980, + 'img_id_str': '526369980', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 345359459, + 'img_id_str': '345359459', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 506643573, + 'img_id_str': '506643573', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 151831963, + 'img_id_str': '151831963', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 312788302, + 'img_id_str': '312788302', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 399688592, + 'img_id_str': '399688592', + 'title': '001', + 'user_id': 340199, + 'width': 4512 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 600818395, + 'img_id_str': '600818395', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 99664817, + 'img_id_str': '99664817', + 'title': '001', + 'user_id': 340199, + 'width': 2448 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '2019年12月18日', + 'post_id': 60634988, + 'published_at': '2019-12-18 10:49:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '2017年iPhone摄影大赛(IPPAWARDS)年度最佳摄影师”和“日落组金奖”获得者', + 'domain': '', + 'followers': 15635, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_340199_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '张匡龙', + 'site_id': '340199', + 'type': 'user', + 'url': 'https://tuchong.com/340199/', + 'verification_list': [ + { + 'verification_reason': + '2017年iPhone摄影大赛(IPPAWARDS)年度最佳摄影师”和“日落组金奖”获得者', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '340199', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/340199/60634988/', + 'views': 10851 + }, + { + 'author_id': '4617804', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 24, + 'content': '仲夏夜之梦', + 'created_at': '2019-08-19 23:37:18', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '仲夏夜之梦', + 'favorite_list_prefix': [], + 'favorites': 507, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 562861115, + 'img_id_str': '562861115', + 'title': '001', + 'user_id': 4617804, + 'width': 4406 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5632, + 'img_id': 387552491, + 'img_id_str': '387552491', + 'title': '001', + 'user_id': 4617804, + 'width': 3952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6624, + 'img_id': 294359977, + 'img_id_str': '294359977', + 'title': '001', + 'user_id': 4617804, + 'width': 4385 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6609, + 'img_id': 173053391, + 'img_id_str': '173053391', + 'title': '001', + 'user_id': 4617804, + 'width': 4406 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 149918781, + 'img_id_str': '149918781', + 'title': '001', + 'user_id': 4617804, + 'width': 6603 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6167, + 'img_id': 385913749, + 'img_id_str': '385913749', + 'title': '001', + 'user_id': 4617804, + 'width': 4395 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 506696597, + 'img_id_str': '506696597', + 'title': '001', + 'user_id': 4617804, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 578000045, + 'img_id_str': '578000045', + 'title': '001', + 'user_id': 4617804, + 'width': 4343 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5849, + 'img_id': 415077243, + 'img_id_str': '415077243', + 'title': '001', + 'user_id': 4617804, + 'width': 4115 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7956, + 'img_id': 599167956, + 'img_id_str': '599167956', + 'title': '001', + 'user_id': 4617804, + 'width': 5193 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6719, + 'img_id': 387683006, + 'img_id_str': '387683006', + 'title': '001', + 'user_id': 4617804, + 'width': 4374 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '18', + 'passed_time': '2019年08月19日', + 'post_id': 49895454, + 'published_at': '2019-08-19 23:37:18', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '2', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4859, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4617804_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '曹小co', + 'site_id': '4617804', + 'type': 'user', + 'url': 'https://tuchong.com/4617804/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4617804', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '复古', '美女', '情绪', '女神'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4617804/49895454/', + 'views': 19395 + }, + { + 'author_id': '1670980', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 7, + 'content': '', + 'created_at': '2019-10-07 11:37:02', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 297, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 651014278, + 'img_id_str': '651014278', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 483897811, + 'img_id_str': '483897811', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 319467659, + 'img_id_str': '319467659', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 560901726, + 'img_id_str': '560901726', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 449884277, + 'img_id_str': '449884277', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 390377090, + 'img_id_str': '390377090', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 455651299, + 'img_id_str': '455651299', + 'title': '', + 'user_id': 1670980, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 635678800, + 'img_id_str': '635678800', + 'title': '', + 'user_id': 1670980, + 'width': 5760 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '6', + 'passed_time': '2019年10月07日', + 'post_id': 55072749, + 'published_at': '2019-10-07 11:37:02', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 9, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12358, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1670980_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '沐秋-王伟', + 'site_id': '1670980', + 'type': 'user', + 'url': 'https://tuchong.com/1670980/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1670980', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1670980/55072749/', + 'views': 15964 + }, + { + 'author_id': '959534', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 38, + 'content': '我的人像摄影教学已经开始招生,咨询报名请加vx:18310080899或majingbossma', + 'created_at': '2019-12-28 16:14:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '我的人像摄影教学已经开始招生,咨询报名请加vx:18310080899或majingbossma', + 'favorite_list_prefix': [], + 'favorites': 1039, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 324846727, + 'img_id_str': '324846727', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 615368312, + 'img_id_str': '615368312', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5551, + 'img_id': 278840649, + 'img_id_str': '278840649', + 'title': '', + 'user_id': 959534, + 'width': 3700 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 444449905, + 'img_id_str': '444449905', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 45139246, + 'img_id_str': '45139246', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 512214496, + 'img_id_str': '512214496', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4701, + 'img_id': 653772065, + 'img_id_str': '653772065', + 'title': '', + 'user_id': 959534, + 'width': 3133 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5668, + 'img_id': 487048347, + 'img_id_str': '487048347', + 'title': '', + 'user_id': 959534, + 'width': 3779 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 293914563, + 'img_id_str': '293914563', + 'title': '', + 'user_id': 959534, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 194168337, + 'img_id_str': '194168337', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 153011503, + 'img_id_str': '153011503', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 110806428, + 'img_id_str': '110806428', + 'title': '', + 'user_id': 959534, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3557, + 'img_id': 621921882, + 'img_id_str': '621921882', + 'title': '', + 'user_id': 959534, + 'width': 5335 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '36', + 'passed_time': '2019年12月28日', + 'post_id': 61095909, + 'published_at': '2019-12-28 16:14:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 32, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'xxmbossma66.tuchong.com', + 'followers': 90414, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_959534_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '马大兴BossMa', + 'site_id': '959534', + 'type': 'user', + 'url': 'https://xxmbossma66.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '959534', + 'sites': [], + 'tags': ['色彩', '人像', '佳能', '小清新', '美女', '壁纸'], + 'title': 'I Wanna Be Your Christmas', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://xxmbossma66.tuchong.com/61095909/', + 'views': 32221 + }, + { + 'author_id': '1339745', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 8, + 'content': '', + 'created_at': '2019-08-02 21:22:53', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['拍女友才是正经事'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 585, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 460424317, + 'img_id_str': '460424317', + 'title': '', + 'user_id': 1339745, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 220955968, + 'img_id_str': '220955968', + 'title': '', + 'user_id': 1339745, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6449, + 'img_id': 550143135, + 'img_id_str': '550143135', + 'title': '', + 'user_id': 1339745, + 'width': 4374 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 345670890, + 'img_id_str': '345670890', + 'title': '', + 'user_id': 1339745, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 559908423, + 'img_id_str': '559908423', + 'title': '', + 'user_id': 1339745, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 604275538, + 'img_id_str': '604275538', + 'title': '', + 'user_id': 1339745, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 136414135, + 'img_id_str': '136414135', + 'title': '', + 'user_id': 1339745, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '2019年08月02日', + 'post_id': 47393653, + 'published_at': '2019-08-02 21:22:53', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'meetanan.tuchong.com', + 'followers': 24876, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1339745_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '居里安安Alana', + 'site_id': '1339745', + 'type': 'user', + 'url': 'https://meetanan.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1339745', + 'sites': [], + 'tags': ['拍女友才是正经事', '人像', '写真', '少女'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://meetanan.tuchong.com/47393653/', + 'views': 14793 + }, + { + 'author_id': '1248442', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '', + 'created_at': '2019-12-18 21:24:39', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 483, + 'image_count': 24, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3086, + 'img_id': 206750429, + 'img_id_str': '206750429', + 'title': '', + 'user_id': 1248442, + 'width': 2068 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3261, + 'img_id': 45729285, + 'img_id_str': '45729285', + 'title': '', + 'user_id': 1248442, + 'width': 2184 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 552453204, + 'img_id_str': '552453204', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 196199348, + 'img_id_str': '196199348', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2145, + 'img_id': 218350670, + 'img_id_str': '218350670', + 'title': '', + 'user_id': 1248442, + 'width': 1437 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 252953434, + 'img_id_str': '252953434', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1996, + 'img_id': 110019582, + 'img_id_str': '110019582', + 'title': '', + 'user_id': 1248442, + 'width': 2980 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 574604187, + 'img_id_str': '574604187', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 397854052, + 'img_id_str': '397854052', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2897, + 'img_id': 549110899, + 'img_id_str': '549110899', + 'title': '', + 'user_id': 1248442, + 'width': 1941 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 211404170, + 'img_id_str': '211404170', + 'title': '', + 'user_id': 1248442, + 'width': 1929 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2522, + 'img_id': 265536672, + 'img_id_str': '265536672', + 'title': '', + 'user_id': 1248442, + 'width': 1690 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2900, + 'img_id': 35571625, + 'img_id_str': '35571625', + 'title': '', + 'user_id': 1248442, + 'width': 1943 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2690, + 'img_id': 76006448, + 'img_id_str': '76006448', + 'title': '', + 'user_id': 1248442, + 'width': 1802 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3301, + 'img_id': 158582015, + 'img_id_str': '158582015', + 'title': '', + 'user_id': 1248442, + 'width': 2212 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 591250899, + 'img_id_str': '591250899', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2766, + 'img_id': 642302650, + 'img_id_str': '642302650', + 'title': '', + 'user_id': 1248442, + 'width': 1853 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3284, + 'img_id': 328320277, + 'img_id_str': '328320277', + 'title': '', + 'user_id': 1248442, + 'width': 2200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 444056272, + 'img_id_str': '444056272', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3094, + 'img_id': 387564941, + 'img_id_str': '387564941', + 'title': '', + 'user_id': 1248442, + 'width': 2073 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 86688677, + 'img_id_str': '86688677', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 181060569, + 'img_id_str': '181060569', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3366, + 'img_id': 160220456, + 'img_id_str': '160220456', + 'title': '', + 'user_id': 1248442, + 'width': 2255 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2498, + 'img_id': 418235981, + 'img_id_str': '418235981', + 'title': '', + 'user_id': 1248442, + 'width': 2224 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '27', + 'passed_time': '2019年12月18日', + 'post_id': 60663134, + 'published_at': '2019-12-18 21:24:39', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '3', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 5916, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1248442_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Z同学同学', + 'site_id': '1248442', + 'type': 'user', + 'url': 'https://tuchong.com/1248442/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1248442', + 'sites': [], + 'tags': ['色彩', '人像', '胶片', '小清新', '美女', '50mm'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1248442/60663134/', + 'views': 28945 + }, + { + 'author_id': '479878', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 21, + 'content': '', + 'created_at': '2019-10-19 22:30:22', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['第三届京东摄影金像奖', '2019你最满意的照片'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 389, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 368555141, + 'img_id_str': '368555141', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 373470362, + 'img_id_str': '373470362', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5505, + 'img_id': 523219730, + 'img_id_str': '523219730', + 'title': '', + 'user_id': 479878, + 'width': 4144 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 454014208, + 'img_id_str': '454014208', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 265270379, + 'img_id_str': '265270379', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 215070072, + 'img_id_str': '215070072', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 471970807, + 'img_id_str': '471970807', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 521319377, + 'img_id_str': '521319377', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 376157322, + 'img_id_str': '376157322', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5952, + 'img_id': 240759543, + 'img_id_str': '240759543', + 'title': '', + 'user_id': 479878, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 487043980, + 'img_id_str': '487043980', + 'title': '', + 'user_id': 479878, + 'width': 5952 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年10月19日', + 'post_id': 56381172, + 'published_at': '2019-10-19 22:30:22', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15826, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_479878_8', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师山木', + 'site_id': '479878', + 'type': 'user', + 'url': 'https://tuchong.com/479878/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '479878', + 'sites': [], + 'tags': ['第三届京东摄影金像奖', '2019你最满意的照片', '人像', '少女', '情绪', '写真'], + 'title': '勿念', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/479878/56381172/', + 'views': 10053 + }, + { + 'author_id': '14218199', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '', + 'created_at': '2019-08-31 00:00:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2019, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1366, + 'img_id': 117677308, + 'img_id_str': '117677308', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1366, + 'img_id': 556374988, + 'img_id_str': '556374988', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1332, + 'img_id': 363240342, + 'img_id_str': '363240342', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 48274078, + 'img_id_str': '48274078', + 'title': '', + 'user_id': 14218199, + 'width': 1367 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1366, + 'img_id': 554343895, + 'img_id_str': '554343895', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1366, + 'img_id': 69770100, + 'img_id_str': '69770100', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1366, + 'img_id': 481204791, + 'img_id_str': '481204791', + 'title': '', + 'user_id': 14218199, + 'width': 2048 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '9', + 'passed_time': '2019年08月31日', + 'post_id': 51175586, + 'published_at': '2019-08-31 00:00:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 10, + 'site': { + 'description': '简简单单的拍~', + 'domain': '', + 'followers': 3807, + 'has_everphoto_note': false, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_14218199_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '人像专业户', + 'site_id': '14218199', + 'type': 'user', + 'url': 'https://tuchong.com/14218199/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '14218199', + 'sites': [], + 'tags': ['人像'], + 'title': '一组室外人像', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/14218199/51175586/', + 'views': 24274 + }, + { + 'author_id': '2391671', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 25, + 'content': '我在秋天收集浪漫,好在初冬赠予你。\n\n摄影/后期:毛茸茸CR2', + 'created_at': '2019-12-11 20:19:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '我在秋天收集浪漫,好在初冬赠予你。\n\n摄影/后期:毛茸茸CR2', + 'favorite_list_prefix': [], + 'favorites': 382, + 'image_count': 42, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 90096594, + 'img_id_str': '90096594', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 643351800, + 'img_id_str': '643351800', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 272548954, + 'img_id_str': '272548954', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 592037202, + 'img_id_str': '592037202', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3070, + 'img_id': 547406900, + 'img_id_str': '547406900', + 'title': '001', + 'user_id': 2391671, + 'width': 2057 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 208126656, + 'img_id_str': '208126656', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 85967474, + 'img_id_str': '85967474', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 102351975, + 'img_id_str': '102351975', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 544130446, + 'img_id_str': '544130446', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 372490522, + 'img_id_str': '372490522', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 301581882, + 'img_id_str': '301581882', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 335332300, + 'img_id_str': '335332300', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 42517600, + 'img_id_str': '42517600', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 595247855, + 'img_id_str': '595247855', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 112837392, + 'img_id_str': '112837392', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 450872188, + 'img_id_str': '450872188', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 240632421, + 'img_id_str': '240632421', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 88130319, + 'img_id_str': '88130319', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 531809063, + 'img_id_str': '531809063', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 320848985, + 'img_id_str': '320848985', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 452969315, + 'img_id_str': '452969315', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 43369319, + 'img_id_str': '43369319', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 495174504, + 'img_id_str': '495174504', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 348832001, + 'img_id_str': '348832001', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 350077801, + 'img_id_str': '350077801', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 513655548, + 'img_id_str': '513655548', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 353289546, + 'img_id_str': '353289546', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 198820556, + 'img_id_str': '198820556', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1763, + 'img_id': 230736931, + 'img_id_str': '230736931', + 'title': '001', + 'user_id': 2391671, + 'width': 1181 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 234013466, + 'img_id_str': '234013466', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2044, + 'img_id': 79282804, + 'img_id_str': '79282804', + 'title': '001', + 'user_id': 2391671, + 'width': 1370 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 250266352, + 'img_id_str': '250266352', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 578929518, + 'img_id_str': '578929518', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 261014354, + 'img_id_str': '261014354', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 213304710, + 'img_id_str': '213304710', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 133415679, + 'img_id_str': '133415679', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 113230657, + 'img_id_str': '113230657', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 164283086, + 'img_id_str': '164283086', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3578, + 'img_id': 88588939, + 'img_id_str': '88588939', + 'title': '001', + 'user_id': 2391671, + 'width': 2397 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 219530244, + 'img_id_str': '219530244', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 599769979, + 'img_id_str': '599769979', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2397, + 'img_id': 340312806, + 'img_id_str': '340312806', + 'title': '001', + 'user_id': 2391671, + 'width': 3578 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年12月11日', + 'post_id': 60276832, + 'published_at': '2019-12-11 20:19:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'rongrong.tuchong.com', + 'followers': 4905, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2391671_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '毛茸茸CR²', + 'site_id': '2391671', + 'type': 'user', + 'url': 'https://rongrong.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2391671', + 'sites': [], + 'tags': ['人像', '北京', '深圳', '写真', '约拍'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://rongrong.tuchong.com/60276832/', + 'views': 12249 + }, + { + 'author_id': '476401', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 68, + 'content': '', + 'created_at': '2019-12-04 00:14:45', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '上海人像圈子', + '高颜值女神聚集地', + '文珺Ronnie人像拍摄活动', + '我们都爱日系摄影', + '初恋的颜色是粉色', + '分享神仙颜值', + '写真人像摄影', + '糖水人像小组', + '我要上开屏', + '人像摄影集' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2388, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 617398503, + 'img_id_str': '617398503', + 'title': '001', + 'user_id': 476401, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 532464484, + 'img_id_str': '532464484', + 'title': '001', + 'user_id': 476401, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 593740168, + 'img_id_str': '593740168', + 'title': '001', + 'user_id': 476401, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 647873529, + 'img_id_str': '647873529', + 'title': '001', + 'user_id': 476401, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 348963306, + 'img_id_str': '348963306', + 'title': '001', + 'user_id': 476401, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 432063232, + 'img_id_str': '432063232', + 'title': '001', + 'user_id': 476401, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 282444138, + 'img_id_str': '282444138', + 'title': '001', + 'user_id': 476401, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 232767590, + 'img_id_str': '232767590', + 'title': '001', + 'user_id': 476401, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 463847568, + 'img_id_str': '463847568', + 'title': '001', + 'user_id': 476401, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 116245280, + 'img_id_str': '116245280', + 'title': '001', + 'user_id': 476401, + 'width': 2667 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '53', + 'passed_time': '2019年12月04日', + 'post_id': 59844569, + 'published_at': '2019-12-04 00:14:45', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 67, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'ronnie.tuchong.com', + 'followers': 69340, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_476401_10', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '文珺Ronnie', + 'site_id': '476401', + 'type': 'user', + 'url': 'https://ronnie.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '476401', + 'sites': [], + 'tags': [ + '上海人像圈子', + '高颜值女神聚集地', + '文珺Ronnie人像拍摄活动', + '我们都爱日系摄影', + '初恋的颜色是粉色', + '分享神仙颜值' + ], + 'title': '『九月微醺.少女日记』', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://ronnie.tuchong.com/59844569/', + 'views': 103606 + }, + { + 'author_id': '2598104', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 35, + 'content': '章若楠的颜', + 'created_at': '2019-11-11 15:23:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['少女写真圈子'], + 'excerpt': '章若楠的颜', + 'favorite_list_prefix': [], + 'favorites': 849, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 225361092, + 'img_id_str': '225361092', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 590461947, + 'img_id_str': '590461947', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 588889210, + 'img_id_str': '588889210', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 383237244, + 'img_id_str': '383237244', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 34519920, + 'img_id_str': '34519920', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 363445150, + 'img_id_str': '363445150', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 327531751, + 'img_id_str': '327531751', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 144555261, + 'img_id_str': '144555261', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 425311379, + 'img_id_str': '425311379', + 'title': '001', + 'user_id': 2598104, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '34', + 'passed_time': '2019年11月11日', + 'post_id': 58325283, + 'published_at': '2019-11-11 15:23:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 30, + 'site': { + 'description': '知名摄影博主', + 'domain': '', + 'followers': 10365, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2598104_12', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '写真bot', + 'site_id': '2598104', + 'type': 'user', + 'url': 'https://tuchong.com/2598104/', + 'verification_list': [ + {'verification_reason': '知名摄影博主', 'verification_type': 12} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2598104', + 'sites': [], + 'tags': ['少女写真圈子'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2598104/58325283/', + 'views': 30384 + }, + { + 'author_id': '333261', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 65, + 'content': '江头未是风波恶,别有人间行路难!\n出境:@庄翰 @释延戛 @大蛇\n#爱良安摄影教学#\n同行徒弟@急流@八千祟', + 'created_at': '2019-10-28 10:21:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '江头未是风波恶,别有人间行路难!\n出境:@庄翰 @释延戛 @大蛇\n#爱良安摄影教学#\n同行徒弟@急流@八千祟', + 'favorite_list_prefix': [], + 'favorites': 1236, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1077, + 'img_id': 343128005, + 'img_id_str': '343128005', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 278378489, + 'img_id_str': '278378489', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3579, + 'img_id': 271038510, + 'img_id_str': '271038510', + 'title': '', + 'user_id': 333261, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3754, + 'img_id': 87537737, + 'img_id_str': '87537737', + 'title': '', + 'user_id': 333261, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2845, + 'img_id': 89896840, + 'img_id_str': '89896840', + 'title': '', + 'user_id': 333261, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 399685385, + 'img_id_str': '399685385', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 424523575, + 'img_id_str': '424523575', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 223852759, + 'img_id_str': '223852759', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1766, + 'img_id': 424589152, + 'img_id_str': '424589152', + 'title': '', + 'user_id': 333261, + 'width': 1280 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '65', + 'passed_time': '2019年10月28日', + 'post_id': 57155152, + 'published_at': '2019-10-28 10:21:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 58, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'alasy.tuchong.com', + 'followers': 28007, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_333261_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '爱良安', + 'site_id': '333261', + 'type': 'user', + 'url': 'https://alasy.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '333261', + 'sites': [], + 'tags': ['人像', '人像摄影', '武侠', '古风'], + 'title': '定风波', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://alasy.tuchong.com/57155152/', + 'views': 49753 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 63, + 'content': '游官湖村~', + 'created_at': '2019-10-09 22:43:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '游官湖村~', + 'favorite_list_prefix': [], + 'favorites': 1762, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 363966820, + 'img_id_str': '363966820', + 'title': '707352', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 381530265, + 'img_id_str': '381530265', + 'title': '707355', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 423276663, + 'img_id_str': '423276663', + 'title': '707351', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 88649995, + 'img_id_str': '88649995', + 'title': '707357', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 385331529, + 'img_id_str': '385331529', + 'title': '707349', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 561492439, + 'img_id_str': '561492439', + 'title': '707348', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 342208537, + 'img_id_str': '342208537', + 'title': '707350', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 609202187, + 'img_id_str': '609202187', + 'title': '707354', + 'user_id': 3738183, + 'width': 1666 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2500, + 'img_id': 475442967, + 'img_id_str': '475442967', + 'title': '707356', + 'user_id': 3738183, + 'width': 1666 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '62', + 'passed_time': '2019年10月09日', + 'post_id': 55410216, + 'published_at': '2019-10-09 22:43:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 61, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['旅游', '外拍', '官湖村', '女孩'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/55410216/', + 'views': 61803 + }, + { + 'author_id': '2993890', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 51, + 'content': '黑白灰.', + 'created_at': '2019-10-01 22:29:20', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '黑白灰.', + 'favorite_list_prefix': [], + 'favorites': 1220, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 207137639, + 'img_id_str': '207137639', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1787, + 'img_id': 192588567, + 'img_id_str': '192588567', + 'title': '001', + 'user_id': 2993890, + 'width': 1191 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 264023083, + 'img_id_str': '264023083', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 208186020, + 'img_id_str': '208186020', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 475310528, + 'img_id_str': '475310528', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 400141439, + 'img_id_str': '400141439', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 178891672, + 'img_id_str': '178891672', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 368159626, + 'img_id_str': '368159626', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1792, + 'img_id': 570076065, + 'img_id_str': '570076065', + 'title': '001', + 'user_id': 2993890, + 'width': 1280 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '46', + 'passed_time': '2019年10月01日', + 'post_id': 54204555, + 'published_at': '2019-10-01 22:29:20', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 50, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 23392, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2993890_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '没有喵的尾巴巴', + 'site_id': '2993890', + 'type': 'user', + 'url': 'https://tuchong.com/2993890/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2993890', + 'sites': [], + 'tags': ['黑白'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2993890/54204555/', + 'views': 56522 + }, + { + 'author_id': '1468214', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 53, + 'content': '《昆曲·醉妃》', + 'created_at': '2019-09-30 00:53:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '《昆曲·醉妃》', + 'favorite_list_prefix': [], + 'favorites': 876, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 46311910, + 'img_id_str': '46311910', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 139831883, + 'img_id_str': '139831883', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 563784375, + 'img_id_str': '563784375', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4340, + 'img_id': 515090636, + 'img_id_str': '515090636', + 'title': '001', + 'user_id': 1468214, + 'width': 6510 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 166963522, + 'img_id_str': '166963522', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6620, + 'img_id': 326019950, + 'img_id_str': '326019950', + 'title': '001', + 'user_id': 1468214, + 'width': 4412 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 285125343, + 'img_id_str': '285125343', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4390, + 'img_id': 598583757, + 'img_id_str': '598583757', + 'title': '001', + 'user_id': 1468214, + 'width': 6586 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4216, + 'img_id': 613132925, + 'img_id_str': '613132925', + 'title': '001', + 'user_id': 1468214, + 'width': 6324 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 410691931, + 'img_id_str': '410691931', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 238004493, + 'img_id_str': '238004493', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6642, + 'img_id': 321038910, + 'img_id_str': '321038910', + 'title': '001', + 'user_id': 1468214, + 'width': 4428 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '48', + 'passed_time': '2019年09月30日', + 'post_id': 53975622, + 'published_at': '2019-09-30 00:53:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 71180, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1468214_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'GK__', + 'site_id': '1468214', + 'type': 'user', + 'url': 'https://tuchong.com/1468214/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1468214', + 'sites': [], + 'tags': ['人像', '戏剧'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1468214/53975622/', + 'views': 53623 + }, + { + 'author_id': '1075170', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 106, + 'content': '', + 'created_at': '2019-08-29 23:48:30', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 2106, + 'image_count': 15, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4912, + 'img_id': 85891769, + 'img_id_str': '85891769', + 'title': '', + 'user_id': 1075170, + 'width': 7360 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 565353501, + 'img_id_str': '565353501', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 220110318, + 'img_id_str': '220110318', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 280009496, + 'img_id_str': '280009496', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 396532527, + 'img_id_str': '396532527', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 452369073, + 'img_id_str': '452369073', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7360, + 'img_id': 335977624, + 'img_id_str': '335977624', + 'title': '', + 'user_id': 1075170, + 'width': 4912 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 375036841, + 'img_id_str': '375036841', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 381196677, + 'img_id_str': '381196677', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 237673402, + 'img_id_str': '237673402', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 249404243, + 'img_id_str': '249404243', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 69246353, + 'img_id_str': '69246353', + 'title': '', + 'user_id': 1075170, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 98802148, + 'img_id_str': '98802148', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4912, + 'img_id': 603167775, + 'img_id_str': '603167775', + 'title': '', + 'user_id': 1075170, + 'width': 7360 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 307337861, + 'img_id_str': '307337861', + 'title': '', + 'user_id': 1075170, + 'width': 5304 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '92', + 'passed_time': '2019年08月29日', + 'post_id': 51071348, + 'published_at': '2019-08-29 23:48:30', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 128, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'xuexianyu.tuchong.com', + 'followers': 18506, + 'has_everphoto_note': false, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1075170_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '薛咸鱼', + 'site_id': '1075170', + 'type': 'user', + 'url': 'https://xuexianyu.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1075170', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '色彩', '美女', '女孩', '日系'], + 'title': '武姬', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://xuexianyu.tuchong.com/51071348/', + 'views': 125023 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 153, + 'content': '高冷的女孩也有可爱的一面ớ ₃ờ', + 'created_at': '2019-08-08 23:19:02', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上“首页推荐位”'], + 'excerpt': '高冷的女孩也有可爱的一面ớ ₃ờ', + 'favorite_list_prefix': [], + 'favorites': 4366, + 'image_count': 8, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 71273442, + 'img_id_str': '71273442', + 'title': '476526', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 377850543, + 'img_id_str': '377850543', + 'title': '476528', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 43354680, + 'img_id_str': '43354680', + 'title': '476525', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 85559809, + 'img_id_str': '85559809', + 'title': '476521', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 104696138, + 'img_id_str': '104696138', + 'title': '476527', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 254773945, + 'img_id_str': '254773945', + 'title': '476529', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 123243073, + 'img_id_str': '123243073', + 'title': '476523', + 'user_id': 3738183, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 597133923, + 'img_id_str': '597133923', + 'title': '476522', + 'user_id': 3738183, + 'width': 5792 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '151', + 'passed_time': '2019年08月08日', + 'post_id': 48313503, + 'published_at': '2019-08-08 23:19:02', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 118, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '可爱', '漂亮的', '时尚'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/48313503/', + 'views': 150492 + }, + { + 'author_id': '381497', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 163, + 'content': '小紫', + 'created_at': '2019-11-19 17:33:28', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '小紫', + 'favorite_list_prefix': [], + 'favorites': 1947, + 'image_count': 24, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 114802345, + 'img_id_str': '114802345', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 593149404, + 'img_id_str': '593149404', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 516865941, + 'img_id_str': '516865941', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 44285325, + 'img_id_str': '44285325', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 576110215, + 'img_id_str': '576110215', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 501267742, + 'img_id_str': '501267742', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 351584375, + 'img_id_str': '351584375', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 451526347, + 'img_id_str': '451526347', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 601538229, + 'img_id_str': '601538229', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 68534055, + 'img_id_str': '68534055', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 275038022, + 'img_id_str': '275038022', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 243973718, + 'img_id_str': '243973718', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 206815409, + 'img_id_str': '206815409', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 486260166, + 'img_id_str': '486260166', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 398966769, + 'img_id_str': '398966769', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 586071364, + 'img_id_str': '586071364', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 138657116, + 'img_id_str': '138657116', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 263241389, + 'img_id_str': '263241389', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 171163012, + 'img_id_str': '171163012', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 520928758, + 'img_id_str': '520928758', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 587186131, + 'img_id_str': '587186131', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 498319803, + 'img_id_str': '498319803', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 489930317, + 'img_id_str': '489930317', + 'title': '', + 'user_id': 381497, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1799, + 'img_id': 611630647, + 'img_id_str': '611630647', + 'title': '', + 'user_id': 381497, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '140', + 'passed_time': '2019年11月19日', + 'post_id': 58888289, + 'published_at': '2019-11-19 17:33:28', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 109, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 38516, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_381497_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '老威威', + 'site_id': '381497', + 'type': 'user', + 'url': 'https://tuchong.com/381497/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '381497', + 'sites': [], + 'tags': ['人像', '美女', '小清新'], + 'title': '有酒靥的女孩', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/381497/58888289/', + 'views': 118958 + }, + { + 'author_id': '3568820', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 69, + 'content': '', + 'created_at': '2019-11-14 14:48:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 993, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 403291512, + 'img_id_str': '403291512', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 442416633, + 'img_id_str': '442416633', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 605797647, + 'img_id_str': '605797647', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 250133821, + 'img_id_str': '250133821', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 408140843, + 'img_id_str': '408140843', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5184, + 'img_id': 90750426, + 'img_id_str': '90750426', + 'title': '', + 'user_id': 3568820, + 'width': 3456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5254, + 'img_id': 507231542, + 'img_id_str': '507231542', + 'title': '', + 'user_id': 3568820, + 'width': 3502 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5254, + 'img_id': 374979805, + 'img_id_str': '374979805', + 'title': '', + 'user_id': 3568820, + 'width': 3502 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5646, + 'img_id': 180141656, + 'img_id_str': '180141656', + 'title': '', + 'user_id': 3568820, + 'width': 4232 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '67', + 'passed_time': '2019年11月14日', + 'post_id': 58524195, + 'published_at': '2019-11-14 14:48:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 67, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2473, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3568820_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '一木各照相馆', + 'site_id': '3568820', + 'type': 'user', + 'url': 'https://tuchong.com/3568820/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3568820', + 'sites': [], + 'tags': ['人像', '少女写真', '写真', '一木各', '网红照相馆'], + 'title': 'ANGEL·艺术形象照(一)', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3568820/58524195/', + 'views': 29628 + }, + { + 'author_id': '1642567', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 75, + 'content': '一种东方美的力量', + 'created_at': '2019-10-22 11:02:14', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '一种东方美的力量', + 'favorite_list_prefix': [], + 'favorites': 959, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2088, + 'img_id': 485799501, + 'img_id_str': '485799501', + 'title': '001', + 'user_id': 1642567, + 'width': 1174 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 259699734, + 'img_id_str': '259699734', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1921, + 'img_id': 178435493, + 'img_id_str': '178435493', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1921, + 'img_id': 516273362, + 'img_id_str': '516273362', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1672, + 'img_id': 654882471, + 'img_id_str': '654882471', + 'title': '001', + 'user_id': 1642567, + 'width': 940 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1918, + 'img_id': 248428339, + 'img_id_str': '248428339', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1921, + 'img_id': 591574016, + 'img_id_str': '591574016', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3831, + 'img_id': 163034275, + 'img_id_str': '163034275', + 'title': '001', + 'user_id': 1642567, + 'width': 2155 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1420, + 'img_id': 58832513, + 'img_id_str': '58832513', + 'title': '001', + 'user_id': 1642567, + 'width': 798 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 404862588, + 'img_id_str': '404862588', + 'title': '001', + 'user_id': 1642567, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '73', + 'passed_time': '2019年10月22日', + 'post_id': 56626071, + 'published_at': '2019-10-22 11:02:14', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 68, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 6844, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1642567_5', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '子夜鸟', + 'site_id': '1642567', + 'type': 'user', + 'url': 'https://tuchong.com/1642567/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1642567', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1642567/56626071/', + 'views': 21149 + }, + { + 'author_id': '1408220', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 53, + 'content': '午夜公园', + 'created_at': '2019-10-18 07:22:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '午夜公园', + 'favorite_list_prefix': [], + 'favorites': 711, + 'image_count': 21, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 597799730, + 'img_id_str': '597799730', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 326546636, + 'img_id_str': '326546636', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 617919509, + 'img_id_str': '617919509', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 512144390, + 'img_id_str': '512144390', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 126989202, + 'img_id_str': '126989202', + 'title': '001', + 'user_id': 1408220, + 'width': 3240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 596554994, + 'img_id_str': '596554994', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 458667289, + 'img_id_str': '458667289', + 'title': '001', + 'user_id': 1408220, + 'width': 3240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3377, + 'img_id': 261797035, + 'img_id_str': '261797035', + 'title': '001', + 'user_id': 1408220, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 455717549, + 'img_id_str': '455717549', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 438678131, + 'img_id_str': '438678131', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 419345070, + 'img_id_str': '419345070', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 521254011, + 'img_id_str': '521254011', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 261076479, + 'img_id_str': '261076479', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 64271095, + 'img_id_str': '64271095', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2160, + 'img_id': 68924571, + 'img_id_str': '68924571', + 'title': '001', + 'user_id': 1408220, + 'width': 3240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 107459650, + 'img_id_str': '107459650', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 652718978, + 'img_id_str': '652718978', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 248755272, + 'img_id_str': '248755272', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3377, + 'img_id': 387756859, + 'img_id_str': '387756859', + 'title': '001', + 'user_id': 1408220, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 389854393, + 'img_id_str': '389854393', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3240, + 'img_id': 179286621, + 'img_id_str': '179286621', + 'title': '001', + 'user_id': 1408220, + 'width': 2160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '27', + 'passed_time': '2019年10月18日', + 'post_id': 56196163, + 'published_at': '2019-10-18 07:22:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '11', + 'rqt_id': '', + 'shares': 19, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 16047, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1408220_15', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '雨罙_', + 'site_id': '1408220', + 'type': 'user', + 'url': 'https://tuchong.com/1408220/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1408220', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1408220/56196163/', + 'views': 44265 + }, + { + 'author_id': '1781920', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '天气渐渐凉,才会珍惜阳光的温度。\n\n大熊作品X谨谨 ‖ #写真#', + 'created_at': '2019-09-22 08:38:53', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['武汉日系摄影师联盟', '人像摄影集'], + 'excerpt': '天气渐渐凉,才会珍惜阳光的温度。\n\n大熊作品X谨谨 ‖ #写真#', + 'favorite_list_prefix': [], + 'favorites': 363, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4002, + 'img_id': 174958586, + 'img_id_str': '174958586', + 'title': '1586973', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 39495390, + 'img_id_str': '39495390', + 'title': '1586987', + 'user_id': 1781920, + 'width': 2668 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4002, + 'img_id': 453355607, + 'img_id_str': '453355607', + 'title': '1586971', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 360097445, + 'img_id_str': '360097445', + 'title': '1586969', + 'user_id': 1781920, + 'width': 4002 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4002, + 'img_id': 442410719, + 'img_id_str': '442410719', + 'title': '1586970', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 227256089, + 'img_id_str': '227256089', + 'title': '1586976', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4002, + 'img_id': 648193599, + 'img_id_str': '648193599', + 'title': '1586975', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 593995843, + 'img_id_str': '593995843', + 'title': '1586977', + 'user_id': 1781920, + 'width': 4002 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 321365080, + 'img_id_str': '321365080', + 'title': '1586988', + 'user_id': 1781920, + 'width': 4002 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4002, + 'img_id': 199010072, + 'img_id_str': '199010072', + 'title': '1586978', + 'user_id': 1781920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 332899481, + 'img_id_str': '332899481', + 'title': '1586979', + 'user_id': 1781920, + 'width': 4002 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '20', + 'passed_time': '2019年09月22日', + 'post_id': 53241074, + 'published_at': '2019-09-22 08:38:53', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 13, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3650, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1781920_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '背相机的大熊', + 'site_id': '1781920', + 'type': 'user', + 'url': 'https://tuchong.com/1781920/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1781920', + 'sites': [], + 'tags': ['武汉日系摄影师联盟', '人像摄影集', '冷色调', '情绪', '写真', '日系'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1781920/53241074/', + 'views': 15387 + }, + { + 'author_id': '2716090', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 99, + 'content': '一个人的婚纱', + 'created_at': '2019-09-13 10:40:43', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '一个人的婚纱', + 'favorite_list_prefix': [], + 'favorites': 1218, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 107258791, + 'img_id_str': '107258791', + 'title': '3061318', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 625844689, + 'img_id_str': '625844689', + 'title': '3061317', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 478323262, + 'img_id_str': '478323262', + 'title': '3061316', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 342598062, + 'img_id_str': '342598062', + 'title': '3061315', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 144417435, + 'img_id_str': '144417435', + 'title': '3061314', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 315597884, + 'img_id_str': '315597884', + 'title': '3061313', + 'user_id': 2716090, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 339649034, + 'img_id_str': '339649034', + 'title': '3061312', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 197304994, + 'img_id_str': '197304994', + 'title': '3061309', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 77505154, + 'img_id_str': '77505154', + 'title': '3061310', + 'user_id': 2716090, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1000, + 'img_id': 445292914, + 'img_id_str': '445292914', + 'title': '3061308', + 'user_id': 2716090, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 244425389, + 'img_id_str': '244425389', + 'title': '3061311', + 'user_id': 2716090, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '96', + 'passed_time': '2019年09月13日', + 'post_id': 52425210, + 'published_at': '2019-09-13 10:40:43', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 93, + 'site': { + 'description': '深圳自由摄影师', + 'domain': '', + 'followers': 5223, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2716090_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '蜂子', + 'site_id': '2716090', + 'type': 'user', + 'url': 'https://tuchong.com/2716090/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '2716090', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2716090/52425210/', + 'views': 88311 + }, + { + 'author_id': '11470935', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 32, + 'content': '', + 'created_at': '2019-09-10 20:44:41', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 698, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 998, + 'img_id': 111780128, + 'img_id_str': '111780128', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 274374988, + 'img_id_str': '274374988', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 527802415, + 'img_id_str': '527802415', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 443261380, + 'img_id_str': '443261380', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 143565083, + 'img_id_str': '143565083', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 372023714, + 'img_id_str': '372023714', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 207593546, + 'img_id_str': '207593546', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 48865752, + 'img_id_str': '48865752', + 'title': '001', + 'user_id': 11470935, + 'width': 1010 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 230728178, + 'img_id_str': '230728178', + 'title': '001', + 'user_id': 11470935, + 'width': 1010 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1010, + 'img_id': 369336620, + 'img_id_str': '369336620', + 'title': '001', + 'user_id': 11470935, + 'width': 1500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '28', + 'passed_time': '2019年09月10日', + 'post_id': 52208563, + 'published_at': '2019-09-10 20:44:41', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 23, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4470, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_11470935_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Saebyeok-choi', + 'site_id': '11470935', + 'type': 'user', + 'url': 'https://tuchong.com/11470935/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '11470935', + 'sites': [], + 'tags': ['胶片', '戀人', '愛情', '電影'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/11470935/52208563/', + 'views': 73191 + }, + { + 'author_id': '5411691', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 69, + 'content': '烂漫之时', + 'created_at': '2019-07-31 22:10:20', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '烂漫之时', + 'favorite_list_prefix': [], + 'favorites': 1202, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6124, + 'img_id': 217940567, + 'img_id_str': '217940567', + 'title': '001', + 'user_id': 5411691, + 'width': 4082 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4082, + 'img_id': 284983931, + 'img_id_str': '284983931', + 'title': '001', + 'user_id': 5411691, + 'width': 6124 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6040, + 'img_id': 204178018, + 'img_id_str': '204178018', + 'title': '001', + 'user_id': 5411691, + 'width': 4080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4082, + 'img_id': 383878062, + 'img_id_str': '383878062', + 'title': '001', + 'user_id': 5411691, + 'width': 6124 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1883, + 'img_id': 612205273, + 'img_id_str': '612205273', + 'title': '001', + 'user_id': 5411691, + 'width': 1368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6124, + 'img_id': 82740387, + 'img_id_str': '82740387', + 'title': '001', + 'user_id': 5411691, + 'width': 4082 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4032, + 'img_id': 150700668, + 'img_id_str': '150700668', + 'title': '001', + 'user_id': 5411691, + 'width': 2688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4082, + 'img_id': 51020544, + 'img_id_str': '51020544', + 'title': '001', + 'user_id': 5411691, + 'width': 6124 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6124, + 'img_id': 375227216, + 'img_id_str': '375227216', + 'title': '001', + 'user_id': 5411691, + 'width': 4082 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4082, + 'img_id': 395608856, + 'img_id_str': '395608856', + 'title': '001', + 'user_id': 5411691, + 'width': 6124 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '65', + 'passed_time': '2019年07月31日', + 'post_id': 47114221, + 'published_at': '2019-07-31 22:10:20', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 64, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 5825, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5411691_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '还有一粒', + 'site_id': '5411691', + 'type': 'user', + 'url': 'https://tuchong.com/5411691/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5411691', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '花', '柔光'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5411691/47114221/', + 'views': 49296 + }, + { + 'author_id': '2600543', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 13, + 'content': '出镜:@五更百鬼', + 'created_at': '2019-07-30 10:46:02', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值', 'Cosplay摄影集中地'], + 'excerpt': '出镜:@五更百鬼', + 'favorite_list_prefix': [], + 'favorites': 472, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4277, + 'img_id': 212042573, + 'img_id_str': '212042573', + 'title': '', + 'user_id': 2600543, + 'width': 6415 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6577, + 'img_id': 251167225, + 'img_id_str': '251167225', + 'title': '', + 'user_id': 2600543, + 'width': 4385 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6527, + 'img_id': 40665737, + 'img_id_str': '40665737', + 'title': '', + 'user_id': 2600543, + 'width': 4351 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 171343802, + 'img_id_str': '171343802', + 'title': '', + 'user_id': 2600543, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6558, + 'img_id': 267485880, + 'img_id_str': '267485880', + 'title': '', + 'user_id': 2600543, + 'width': 4372 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6415, + 'img_id': 360350217, + 'img_id_str': '360350217', + 'title': '', + 'user_id': 2600543, + 'width': 4277 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6216, + 'img_id': 356221510, + 'img_id_str': '356221510', + 'title': '', + 'user_id': 2600543, + 'width': 4144 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6125, + 'img_id': 220693109, + 'img_id_str': '220693109', + 'title': '', + 'user_id': 2600543, + 'width': 4083 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4376, + 'img_id': 580288663, + 'img_id_str': '580288663', + 'title': '', + 'user_id': 2600543, + 'width': 6564 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '8', + 'passed_time': '2019年07月30日', + 'post_id': 46876721, + 'published_at': '2019-07-30 10:46:02', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 5, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'sanyue015.tuchong.com', + 'followers': 13819, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2600543_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '叁月life', + 'site_id': '2600543', + 'type': 'user', + 'url': 'https://sanyue015.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2600543', + 'sites': [], + 'tags': ['分享神仙颜值', 'Cosplay摄影集中地', '人像', '摄影', 'cos', 'Cosplay'], + 'title': '#加藤惠 #兔女郎 #cos #深圳约拍', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sanyue015.tuchong.com/46876721/', + 'views': 21885 + }, + { + 'author_id': '406880', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 114, + 'content': '', + 'created_at': '2019-07-24 06:45:21', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1730, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 317877409, + 'img_id_str': '317877409', + 'title': '001', + 'user_id': 406880, + 'width': 958 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 104990288, + 'img_id_str': '104990288', + 'title': '001', + 'user_id': 406880, + 'width': 958 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '73', + 'passed_time': '2019年07月24日', + 'post_id': 45955842, + 'published_at': '2019-07-24 06:45:21', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 49, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 24454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_406880_9', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '风-vision', + 'site_id': '406880', + 'type': 'user', + 'url': 'https://tuchong.com/406880/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '406880', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/406880/45955842/', + 'views': 145954 + }, + { + 'author_id': '4667676', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 4, + 'content': '新街口夜色!', + 'created_at': '2019-12-28 09:07:08', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['江苏摄影俱乐部'], + 'excerpt': '新街口夜色!', + 'favorite_list_prefix': [], + 'favorites': 39, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 439141644, + 'img_id_str': '439141644', + 'title': '1245115', + 'user_id': 4667676, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '2019年12月28日', + 'post_id': 61079094, + 'published_at': '2019-12-28 09:07:08', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '视觉中国、图虫签约摄影师!\n中国摄影著作权协会、南京市摄影家协会会员', + 'domain': '', + 'followers': 583, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4667676_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '左岸的风', + 'site_id': '4667676', + 'type': 'user', + 'url': 'https://tuchong.com/4667676/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '4667676', + 'sites': [], + 'tags': ['江苏摄影俱乐部', '薄暮', '高楼', '建筑', '城市', '市中心'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4667676/61079094/', + 'views': 1747 + }, + { + 'author_id': '1468214', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 71, + 'content': '《十八岁的单车》', + 'created_at': '2019-09-11 00:15:59', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '《十八岁的单车》', + 'favorite_list_prefix': [], + 'favorites': 1718, + 'image_count': 30, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4537, + 'img_id': 563388801, + 'img_id_str': '563388801', + 'title': '001', + 'user_id': 1468214, + 'width': 4538 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 63676975, + 'img_id_str': '63676975', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4588, + 'img_id': 563978504, + 'img_id_str': '563978504', + 'title': '001', + 'user_id': 1468214, + 'width': 4590 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 334996197, + 'img_id_str': '334996197', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4584, + 'img_id': 44474419, + 'img_id_str': '44474419', + 'title': '001', + 'user_id': 1468214, + 'width': 4585 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4564, + 'img_id': 534225459, + 'img_id_str': '534225459', + 'title': '001', + 'user_id': 1468214, + 'width': 4565 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 196190370, + 'img_id_str': '196190370', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 37658965, + 'img_id_str': '37658965', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 427336366, + 'img_id_str': '427336366', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4552, + 'img_id': 301506947, + 'img_id_str': '301506947', + 'title': '001', + 'user_id': 1468214, + 'width': 4554 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 50962618, + 'img_id_str': '50962618', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4624, + 'img_id': 105882422, + 'img_id_str': '105882422', + 'title': '001', + 'user_id': 1468214, + 'width': 4626 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 239903878, + 'img_id_str': '239903878', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 499818541, + 'img_id_str': '499818541', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 450601300, + 'img_id_str': '450601300', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 67805658, + 'img_id_str': '67805658', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 266314241, + 'img_id_str': '266314241', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4476, + 'img_id': 185835747, + 'img_id_str': '185835747', + 'title': '001', + 'user_id': 1468214, + 'width': 4475 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 109355570, + 'img_id_str': '109355570', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 526688956, + 'img_id_str': '526688956', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 51683879, + 'img_id_str': '51683879', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 577217052, + 'img_id_str': '577217052', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 489267438, + 'img_id_str': '489267438', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 117940911, + 'img_id_str': '117940911', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 532194183, + 'img_id_str': '532194183', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 416588053, + 'img_id_str': '416588053', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 171614954, + 'img_id_str': '171614954', + 'title': '001', + 'user_id': 1468214, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4571, + 'img_id': 185966749, + 'img_id_str': '185966749', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4612, + 'img_id': 102015095, + 'img_id_str': '102015095', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4563, + 'img_id': 78094487, + 'img_id_str': '78094487', + 'title': '001', + 'user_id': 1468214, + 'width': 6720 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '65', + 'passed_time': '2019年09月11日', + 'post_id': 52232122, + 'published_at': '2019-09-11 00:15:59', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 97, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 71180, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1468214_7', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'GK__', + 'site_id': '1468214', + 'type': 'user', + 'url': 'https://tuchong.com/1468214/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1468214', + 'sites': [], + 'tags': ['人像', '骑自行车的人', '女人'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1468214/52232122/', + 'views': 72855 + }, + { + 'author_id': '1303010', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 27, + 'content': '', + 'created_at': '2019-10-28 18:14:16', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['写真人像摄影', '高颜值女神聚集地'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 492, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 295352321, + 'img_id_str': '295352321', + 'title': '635818', + 'user_id': 1303010, + 'width': 1067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 542095162, + 'img_id_str': '542095162', + 'title': '635819', + 'user_id': 1303010, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 401324002, + 'img_id_str': '401324002', + 'title': '635820', + 'user_id': 1303010, + 'width': 1067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 707, + 'img_id': 309770334, + 'img_id_str': '309770334', + 'title': '635834', + 'user_id': 1303010, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1080, + 'img_id': 212842485, + 'img_id_str': '212842485', + 'title': '635832', + 'user_id': 1303010, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 321959965, + 'img_id_str': '321959965', + 'title': '635833', + 'user_id': 1303010, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1600, + 'img_id': 545175314, + 'img_id_str': '545175314', + 'title': '635831', + 'user_id': 1303010, + 'width': 1067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 651344158, + 'img_id_str': '651344158', + 'title': '635830', + 'user_id': 1303010, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 542292166, + 'img_id_str': '542292166', + 'title': '635829', + 'user_id': 1303010, + 'width': 1600 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '25', + 'passed_time': '2019年10月28日', + 'post_id': 57186804, + 'published_at': '2019-10-28 18:14:16', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'devilkman.tuchong.com', + 'followers': 4653, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1303010_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '咕哒囧子', + 'site_id': '1303010', + 'type': 'user', + 'url': 'https://devilkman.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1303010', + 'sites': [], + 'tags': ['写真人像摄影', '高颜值女神聚集地', '水', '人像', 'lolita', '索尼'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://devilkman.tuchong.com/57186804/', + 'views': 13780 + }, + { + 'author_id': '5489136', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 36, + 'content': '“自由游曳在星光下的海上”', + 'created_at': '2019-11-10 23:16:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '写真人像摄影', + '江苏摄影俱乐部', + '糖水人像小组', + '暖色调人像', + '我要上开屏', + '分享神仙颜值', + '高颜值女神聚集地' + ], + 'excerpt': '“自由游曳在星光下的海上”', + 'favorite_list_prefix': [], + 'favorites': 647, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6764, + 'img_id': 47628604, + 'img_id_str': '47628604', + 'title': '001', + 'user_id': 5489136, + 'width': 4992 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4513, + 'img_id': 586136849, + 'img_id_str': '586136849', + 'title': '001', + 'user_id': 5489136, + 'width': 7418 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6991, + 'img_id': 409844753, + 'img_id_str': '409844753', + 'title': '001', + 'user_id': 5489136, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 609073511, + 'img_id_str': '609073511', + 'title': '001', + 'user_id': 5489136, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7424, + 'img_id': 87802047, + 'img_id_str': '87802047', + 'title': '001', + 'user_id': 5489136, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3954, + 'img_id': 438091150, + 'img_id_str': '438091150', + 'title': '001', + 'user_id': 5489136, + 'width': 7030 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5013, + 'img_id': 296795538, + 'img_id_str': '296795538', + 'title': '001', + 'user_id': 5489136, + 'width': 6153 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 342211570, + 'img_id_str': '342211570', + 'title': '001', + 'user_id': 5489136, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6194, + 'img_id': 484424819, + 'img_id_str': '484424819', + 'title': '001', + 'user_id': 5489136, + 'width': 4609 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4918, + 'img_id': 136821777, + 'img_id_str': '136821777', + 'title': '001', + 'user_id': 5489136, + 'width': 7573 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 56212746, + 'img_id_str': '56212746', + 'title': '001', + 'user_id': 5489136, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4440, + 'img_id': 199801646, + 'img_id_str': '199801646', + 'title': '001', + 'user_id': 5489136, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 293583843, + 'img_id_str': '293583843', + 'title': '001', + 'user_id': 5489136, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6785, + 'img_id': 224049935, + 'img_id_str': '224049935', + 'title': '001', + 'user_id': 5489136, + 'width': 5304 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年11月10日', + 'post_id': 58293836, + 'published_at': '2019-11-10 23:16:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 22, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 5800, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_5489136_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '挽歌大魔王', + 'site_id': '5489136', + 'type': 'user', + 'url': 'https://tuchong.com/5489136/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '5489136', + 'sites': [], + 'tags': ['写真人像摄影', '江苏摄影俱乐部', '糖水人像小组', '暖色调人像', '我要上开屏', '分享神仙颜值'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/5489136/58293836/', + 'views': 22539 + }, + { + 'author_id': '406880', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 26, + 'content': '古城游', + 'created_at': '2019-11-30 05:35:02', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '古城游', + 'favorite_list_prefix': [], + 'favorites': 406, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 58114606, + 'img_id_str': '58114606', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 319275371, + 'img_id_str': '319275371', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 90423394, + 'img_id_str': '90423394', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 442483726, + 'img_id_str': '442483726', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 220774156, + 'img_id_str': '220774156', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 374194676, + 'img_id_str': '374194676', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 434487868, + 'img_id_str': '434487868', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 545177620, + 'img_id_str': '545177620', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 181125726, + 'img_id_str': '181125726', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 77709345, + 'img_id_str': '77709345', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '25', + 'passed_time': '2019年11月30日', + 'post_id': 59596709, + 'published_at': '2019-11-30 05:35:02', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 7, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 24454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_406880_9', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '风-vision', + 'site_id': '406880', + 'type': 'user', + 'url': 'https://tuchong.com/406880/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '406880', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/406880/59596709/', + 'views': 12133 + }, + { + 'author_id': '2747704', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 32, + 'content': '模特:湘湘\n地点:华南农业大学', + 'created_at': '2019-11-09 13:38:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['图虫·OPENSEE2019'], + 'excerpt': '模特:湘湘\n地点:华南农业大学', + 'favorite_list_prefix': [], + 'favorites': 450, + 'image_count': 17, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 275627044, + 'img_id_str': '275627044', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 122206942, + 'img_id_str': '122206942', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 305380485, + 'img_id_str': '305380485', + 'title': '', + 'user_id': 2747704, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 404011956, + 'img_id_str': '404011956', + 'title': '', + 'user_id': 2747704, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 125156663, + 'img_id_str': '125156663', + 'title': '', + 'user_id': 2747704, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4024, + 'img_id': 380681496, + 'img_id_str': '380681496', + 'title': '', + 'user_id': 2747704, + 'width': 6048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6048, + 'img_id': 41270226, + 'img_id_str': '41270226', + 'title': '', + 'user_id': 2747704, + 'width': 4024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6048, + 'img_id': 93305821, + 'img_id_str': '93305821', + 'title': '', + 'user_id': 2747704, + 'width': 4024 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5903, + 'img_id': 528136992, + 'img_id_str': '528136992', + 'title': '', + 'user_id': 2747704, + 'width': 3916 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 368950282, + 'img_id_str': '368950282', + 'title': '', + 'user_id': 2747704, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 271301850, + 'img_id_str': '271301850', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 309115934, + 'img_id_str': '309115934', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 484948935, + 'img_id_str': '484948935', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4016, + 'img_id': 506444846, + 'img_id_str': '506444846', + 'title': '', + 'user_id': 2747704, + 'width': 6016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3960, + 'img_id': 445037074, + 'img_id_str': '445037074', + 'title': '', + 'user_id': 2747704, + 'width': 5921 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3487, + 'img_id': 568114332, + 'img_id_str': '568114332', + 'title': '', + 'user_id': 2747704, + 'width': 5223 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3668, + 'img_id': 82427134, + 'img_id_str': '82427134', + 'title': '', + 'user_id': 2747704, + 'width': 4288 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '16', + 'passed_time': '2019年11月09日', + 'post_id': 58153228, + 'published_at': '2019-11-09 13:38:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 14, + 'site': { + 'description': '资深视频创作者', + 'domain': 'pangchen.tuchong.com', + 'followers': 5678, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2747704_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师鹏少', + 'site_id': '2747704', + 'type': 'user', + 'url': 'https://pangchen.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深视频创作者', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2747704', + 'sites': [], + 'tags': ['图虫·OPENSEE2019', '人像', '美女', '小清新', '逆光', '制服'], + 'title': '下课铃响了。', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://pangchen.tuchong.com/58153228/', + 'views': 15050 + }, + { + 'author_id': '46448', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 43, + 'content': 'Grand City-E-scape.\n城市气息系列\n\n摄于东京/深圳/北京/厦门/南京/澳门/上海/首尔', + 'created_at': '2019-12-04 22:22:36', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019胶片摄影赛'], + 'excerpt': 'Grand City-E-scape.\n城市气息系列\n\n摄于东京/深圳/北京/厦门/南京/澳门/上海/首尔', + 'favorite_list_prefix': [], + 'favorites': 444, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6452, + 'img_id': 355320475, + 'img_id_str': '355320475', + 'title': '', + 'user_id': 46448, + 'width': 3179 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3556, + 'img_id': 40097884, + 'img_id_str': '40097884', + 'title': '', + 'user_id': 46448, + 'width': 2368 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3181, + 'img_id': 593674271, + 'img_id_str': '593674271', + 'title': '', + 'user_id': 46448, + 'width': 2122 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4184, + 'img_id': 273728165, + 'img_id_str': '273728165', + 'title': '', + 'user_id': 46448, + 'width': 2795 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3680, + 'img_id': 352567862, + 'img_id_str': '352567862', + 'title': '', + 'user_id': 46448, + 'width': 2456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2948, + 'img_id': 138134338, + 'img_id_str': '138134338', + 'title': '', + 'user_id': 46448, + 'width': 4416 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4416, + 'img_id': 279233126, + 'img_id_str': '279233126', + 'title': '', + 'user_id': 46448, + 'width': 2948 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3798, + 'img_id': 551928216, + 'img_id_str': '551928216', + 'title': '', + 'user_id': 46448, + 'width': 2848 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5152, + 'img_id': 335266137, + 'img_id_str': '335266137', + 'title': '', + 'user_id': 46448, + 'width': 3439 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '43', + 'passed_time': '2019年12月04日', + 'post_id': 59891088, + 'published_at': '2019-12-04 22:22:36', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 37, + 'site': { + 'description': '资深风光摄影师', + 'domain': 'stanleychen.tuchong.com', + 'followers': 59762, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_46448_13', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '陈曦Stanley', + 'site_id': '46448', + 'type': 'user', + 'url': 'https://stanleychen.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '46448', + 'sites': [], + 'tags': ['2019胶片摄影赛', '风光', '旅行', '索尼'], + 'title': 'Grand City-E-scape(全集)', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://stanleychen.tuchong.com/59891088/', + 'views': 12361 + }, + { + 'author_id': '4011742', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '出境:田心源\n裙子:娃娃屋', + 'created_at': '2019-12-25 18:05:55', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '我要上开屏', + '我要上“首页推荐位”', + '捕捉最萌瞬间', + 'Cosplay摄影集中地', + '分享神仙颜值', + '让摄影穿破次元壁', + '人像爱好者', + '绝不停止记录的2019', + '街拍俱乐部圈子' + ], + 'excerpt': '出境:田心源\n裙子:娃娃屋', + 'favorite_list_prefix': [], + 'favorites': 39, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 342344545, + 'img_id_str': '342344545', + 'title': '294057', + 'user_id': 4011742, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 222741649, + 'img_id_str': '222741649', + 'title': '294058', + 'user_id': 4011742, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 561497769, + 'img_id_str': '561497769', + 'title': '294060', + 'user_id': 4011742, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 508806363, + 'img_id_str': '508806363', + 'title': '294061', + 'user_id': 4011742, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 308004312, + 'img_id_str': '308004312', + 'title': '294059', + 'user_id': 4011742, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 396543172, + 'img_id_str': '396543172', + 'title': '294062', + 'user_id': 4011742, + 'width': 2667 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 631424201, + 'img_id_str': '631424201', + 'title': '294064', + 'user_id': 4011742, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2667, + 'img_id': 471123298, + 'img_id_str': '471123298', + 'title': '294063', + 'user_id': 4011742, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 37340310, + 'img_id_str': '37340310', + 'title': '294056', + 'user_id': 4011742, + 'width': 2667 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '2019年12月25日', + 'post_id': 60966008, + 'published_at': '2019-12-25 18:05:55', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 2, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 1652, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_4011742_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '貉子', + 'site_id': '4011742', + 'type': 'user', + 'url': 'https://tuchong.com/4011742/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '4011742', + 'sites': [], + 'tags': [ + '我要上开屏', + '我要上“首页推荐位”', + '捕捉最萌瞬间', + 'Cosplay摄影集中地', + '分享神仙颜值', + '让摄影穿破次元壁' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/4011742/60966008/', + 'views': 1575 + }, + { + 'author_id': '2759139', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 9, + 'content': '选10张照片总结一下自己的2019', + 'created_at': '2019-12-24 13:30:05', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019你最满意的照片'], + 'excerpt': '选10张照片总结一下自己的2019', + 'favorite_list_prefix': [], + 'favorites': 87, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 162112480, + 'img_id_str': '162112480', + 'title': '', + 'user_id': 2759139, + 'width': 1282 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1239, + 'img_id': 424624846, + 'img_id_str': '424624846', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1157, + 'img_id': 346015652, + 'img_id_str': '346015652', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1280, + 'img_id': 568113964, + 'img_id_str': '568113964', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1285, + 'img_id': 42118004, + 'img_id_str': '42118004', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1153, + 'img_id': 653964909, + 'img_id_str': '653964909', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 124109573, + 'img_id_str': '124109573', + 'title': '', + 'user_id': 2759139, + 'width': 1230 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 508477411, + 'img_id_str': '508477411', + 'title': '', + 'user_id': 2759139, + 'width': 1266 + }, + { + 'description': '', + 'excerpt': '', + 'height': 977, + 'img_id': 251464723, + 'img_id_str': '251464723', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1383, + 'img_id': 546771245, + 'img_id_str': '546771245', + 'title': '', + 'user_id': 2759139, + 'width': 1920 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '9', + 'passed_time': '2019年12月24日', + 'post_id': 60913037, + 'published_at': '2019-12-24 13:30:05', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 3727, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2759139_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '老虎不凶', + 'site_id': '2759139', + 'type': 'user', + 'url': 'https://tuchong.com/2759139/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2759139', + 'sites': [], + 'tags': ['2019你最满意的照片', '风光', '色彩', '2019', '总结', '回顾'], + 'title': '总结2019', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2759139/60913037/', + 'views': 2649 + }, + { + 'author_id': '43625', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 50, + 'content': '', + 'created_at': '2019-10-04 00:27:06', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 880, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2560, + 'img_id': 446934482, + 'img_id_str': '446934482', + 'title': '', + 'user_id': 43625, + 'width': 1706 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 590785509, + 'img_id_str': '590785509', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 113552786, + 'img_id_str': '113552786', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2560, + 'img_id': 181251218, + 'img_id_str': '181251218', + 'title': '', + 'user_id': 43625, + 'width': 1706 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 500018035, + 'img_id_str': '500018035', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 433630141, + 'img_id_str': '433630141', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 126659882, + 'img_id_str': '126659882', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2560, + 'img_id': 577416397, + 'img_id_str': '577416397', + 'title': '', + 'user_id': 43625, + 'width': 1706 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 172534868, + 'img_id_str': '172534868', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 47426601, + 'img_id_str': '47426601', + 'title': '', + 'user_id': 43625, + 'width': 2560 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1706, + 'img_id': 95071167, + 'img_id_str': '95071167', + 'title': '', + 'user_id': 43625, + 'width': 2560 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '50', + 'passed_time': '2019年10月04日', + 'post_id': 54499087, + 'published_at': '2019-10-04 00:27:06', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 40, + 'site': { + 'description': '', + 'domain': '', + 'followers': 3169, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_43625_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '要有光', + 'site_id': '43625', + 'type': 'user', + 'url': 'https://tuchong.com/43625/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '43625', + 'sites': [], + 'tags': ['色彩', '人像', '旅行', '小清新', '美女', '少女'], + 'title': '看海(九)', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/43625/54499087/', + 'views': 56026 + }, + { + 'author_id': '14404610', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 54, + 'content': '', + 'created_at': '2019-09-15 00:09:51', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1462, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 575972339, + 'img_id_str': '575972339', + 'title': '', + 'user_id': 14404610, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5358, + 'img_id': 64857058, + 'img_id_str': '64857058', + 'title': '', + 'user_id': 14404610, + 'width': 3577 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5452, + 'img_id': 439198604, + 'img_id_str': '439198604', + 'title': '', + 'user_id': 14404610, + 'width': 3640 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5773, + 'img_id': 108700393, + 'img_id_str': '108700393', + 'title': '', + 'user_id': 14404610, + 'width': 3854 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5981, + 'img_id': 237937407, + 'img_id_str': '237937407', + 'title': '', + 'user_id': 14404610, + 'width': 3993 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6016, + 'img_id': 328115065, + 'img_id_str': '328115065', + 'title': '', + 'user_id': 14404610, + 'width': 4016 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5725, + 'img_id': 362128596, + 'img_id_str': '362128596', + 'title': '', + 'user_id': 14404610, + 'width': 3822 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3507, + 'img_id': 246457215, + 'img_id_str': '246457215', + 'title': '', + 'user_id': 14404610, + 'width': 3494 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4737, + 'img_id': 48407787, + 'img_id_str': '48407787', + 'title': '', + 'user_id': 14404610, + 'width': 3162 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '54', + 'passed_time': '2019年09月15日', + 'post_id': 52626566, + 'published_at': '2019-09-15 00:09:51', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 47, + 'site': { + 'description': '越南籍商业摄影师, 曾为BAZAAR拍摄封面', + 'domain': '', + 'followers': 7415, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_14404610_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '_minhnhon_', + 'site_id': '14404610', + 'type': 'user', + 'url': 'https://tuchong.com/14404610/', + 'verification_list': [ + { + 'verification_reason': '越南籍商业摄影师, 曾为BAZAAR拍摄封面', + 'verification_type': 12 + } + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '14404610', + 'sites': [], + 'tags': [], + 'title': 'Our City', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/14404610/52626566/', + 'views': 66903 + }, + { + 'author_id': '2445806', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 18, + 'content': '红房间', + 'created_at': '2019-09-04 09:20:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['深圳小清新摄影小组', '富士摄影吧小分队', '我要上开屏'], + 'excerpt': '红房间', + 'favorite_list_prefix': [], + 'favorites': 537, + 'image_count': 23, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 38903340, + 'img_id_str': '38903340', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 208380044, + 'img_id_str': '208380044', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 54238712, + 'img_id_str': '54238712', + 'title': '001', + 'user_id': 2445806, + 'width': 2700 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 617979170, + 'img_id_str': '617979170', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 75407047, + 'img_id_str': '75407047', + 'title': '001', + 'user_id': 2445806, + 'width': 2700 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 322805121, + 'img_id_str': '322805121', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 425958737, + 'img_id_str': '425958737', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 254450925, + 'img_id_str': '254450925', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 53583283, + 'img_id_str': '53583283', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 275226123, + 'img_id_str': '275226123', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 419470527, + 'img_id_str': '419470527', + 'title': '001', + 'user_id': 2445806, + 'width': 2700 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 189111620, + 'img_id_str': '189111620', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 437558427, + 'img_id_str': '437558427', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 207134257, + 'img_id_str': '207134257', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 521576110, + 'img_id_str': '521576110', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 401186580, + 'img_id_str': '401186580', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 427532052, + 'img_id_str': '427532052', + 'title': '001', + 'user_id': 2445806, + 'width': 2700 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 170171726, + 'img_id_str': '170171726', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 132226651, + 'img_id_str': '132226651', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 153656765, + 'img_id_str': '153656765', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 60791882, + 'img_id_str': '60791882', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 337157893, + 'img_id_str': '337157893', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2700, + 'img_id': 549100943, + 'img_id_str': '549100943', + 'title': '001', + 'user_id': 2445806, + 'width': 1800 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '16', + 'passed_time': '2019年09月04日', + 'post_id': 51601078, + 'published_at': '2019-09-04 09:20:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 30, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 6010, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2445806_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '太太太洋', + 'site_id': '2445806', + 'type': 'user', + 'url': 'https://tuchong.com/2445806/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2445806', + 'sites': [], + 'tags': ['深圳小清新摄影小组', '富士摄影吧小分队', '我要上开屏', '人像', '暗房'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2445806/51601078/', + 'views': 25774 + }, + { + 'author_id': '3274149', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 24, + 'content': '柔软\n摄影后期:此岸', + 'created_at': '2019-08-14 12:07:03', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '柔软\n摄影后期:此岸', + 'favorite_list_prefix': [], + 'favorites': 1162, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 58232645, + 'img_id_str': '58232645', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 184062092, + 'img_id_str': '184062092', + 'title': '001', + 'user_id': 3274149, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 193629700, + 'img_id_str': '193629700', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 596414402, + 'img_id_str': '596414402', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 494899041, + 'img_id_str': '494899041', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 579178166, + 'img_id_str': '579178166', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 393449141, + 'img_id_str': '393449141', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 648384279, + 'img_id_str': '648384279', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 187928378, + 'img_id_str': '187928378', + 'title': '001', + 'user_id': 3274149, + 'width': 7952 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '23', + 'passed_time': '2019年08月14日', + 'post_id': 49117252, + 'published_at': '2019-08-14 12:07:03', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 42, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 20450, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3274149_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '方叉子', + 'site_id': '3274149', + 'type': 'user', + 'url': 'https://tuchong.com/3274149/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3274149', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3274149/49117252/', + 'views': 60086 + }, + { + 'author_id': '3212049', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 35, + 'content': '', + 'created_at': '2019-10-24 17:49:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 443, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 401587094, + 'img_id_str': '401587094', + 'title': '', + 'user_id': 3212049, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2800, + 'img_id': 576108082, + 'img_id_str': '576108082', + 'title': '', + 'user_id': 3212049, + 'width': 2100 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 202683773, + 'img_id_str': '202683773', + 'title': '', + 'user_id': 3212049, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2100, + 'img_id': 211924246, + 'img_id_str': '211924246', + 'title': '', + 'user_id': 3212049, + 'width': 2803 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 606385802, + 'img_id_str': '606385802', + 'title': '', + 'user_id': 3212049, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 62240834, + 'img_id_str': '62240834', + 'title': '', + 'user_id': 3212049, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 81311171, + 'img_id_str': '81311171', + 'title': '', + 'user_id': 3212049, + 'width': 3000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 565425765, + 'img_id_str': '565425765', + 'title': '', + 'user_id': 3212049, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 428062685, + 'img_id_str': '428062685', + 'title': '', + 'user_id': 3212049, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '31', + 'passed_time': '2019年10月24日', + 'post_id': 56822528, + 'published_at': '2019-10-24 17:49:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 14, + 'site': { + 'description': '商业摄影师,欢迎约拍。', + 'domain': '', + 'followers': 11345, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3212049_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '唯剑', + 'site_id': '3212049', + 'type': 'user', + 'url': 'https://tuchong.com/3212049/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '3212049', + 'sites': [], + 'tags': ['人像'], + 'title': '绿林女汉子', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3212049/56822528/', + 'views': 27997 + }, + { + 'author_id': '333261', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 88, + 'content': '拍自于9月坝上游学团。这次游学起早贪黑拍日出,日落拍过瘾了。\n欢迎参加11月金秋徽州游学。', + 'created_at': '2019-10-11 08:34:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '拍自于9月坝上游学团。这次游学起早贪黑拍日出,日落拍过瘾了。\n欢迎参加11月金秋徽州游学。', + 'favorite_list_prefix': [], + 'favorites': 1321, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 199143555, + 'img_id_str': '199143555', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 309441006, + 'img_id_str': '309441006', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 625717753, + 'img_id_str': '625717753', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 47427785, + 'img_id_str': '47427785', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 139899270, + 'img_id_str': '139899270', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 621130013, + 'img_id_str': '621130013', + 'title': '', + 'user_id': 333261, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 132558540, + 'img_id_str': '132558540', + 'title': '', + 'user_id': 333261, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 810, + 'img_id': 528396570, + 'img_id_str': '528396570', + 'title': '', + 'user_id': 333261, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 146780595, + 'img_id_str': '146780595', + 'title': '', + 'user_id': 333261, + 'width': 1440 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '87', + 'passed_time': '2019年10月11日', + 'post_id': 55540125, + 'published_at': '2019-10-11 08:34:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 85, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'alasy.tuchong.com', + 'followers': 28007, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_333261_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '爱良安', + 'site_id': '333261', + 'type': 'user', + 'url': 'https://alasy.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '333261', + 'sites': [], + 'tags': ['人像', '人像摄影', '古风'], + 'title': '短歌行', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://alasy.tuchong.com/55540125/', + 'views': 30467 + }, + { + 'author_id': '2299484', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 85, + 'content': '生命中最难的阶段不是没有人懂你,而是你不懂你自己。', + 'created_at': '2019-10-08 12:47:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '生命中最难的阶段不是没有人懂你,而是你不懂你自己。', + 'favorite_list_prefix': [], + 'favorites': 2345, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 190099435, + 'img_id_str': '190099435', + 'title': '1129651', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 655208332, + 'img_id_str': '655208332', + 'title': '1129573', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 419016828, + 'img_id_str': '419016828', + 'title': '1129548', + 'user_id': 2299484, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 321957926, + 'img_id_str': '321957926', + 'title': '1129547', + 'user_id': 2299484, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 42643507, + 'img_id_str': '42643507', + 'title': '1129544', + 'user_id': 2299484, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 331132885, + 'img_id_str': '331132885', + 'title': '1129545', + 'user_id': 2299484, + 'width': 3413 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 518238099, + 'img_id_str': '518238099', + 'title': '1129542', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 634629844, + 'img_id_str': '634629844', + 'title': '1129541', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3413, + 'img_id': 545501202, + 'img_id_str': '545501202', + 'title': '1129543', + 'user_id': 2299484, + 'width': 5120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 237023586, + 'img_id_str': '237023586', + 'title': '1129539', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 448376539, + 'img_id_str': '448376539', + 'title': '1129540', + 'user_id': 2299484, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5120, + 'img_id': 447394378, + 'img_id_str': '447394378', + 'title': '1129549', + 'user_id': 2299484, + 'width': 3413 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '67', + 'passed_time': '2019年10月08日', + 'post_id': 55214989, + 'published_at': '2019-10-08 12:47:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '4', + 'rqt_id': '', + 'shares': 78, + 'site': { + 'description': '马来西亚 新加坡 厦门 福州 广州 深圳 约拍加我m423736448 同行一概不加', + 'domain': '', + 'followers': 16767, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2299484_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师Moyan', + 'site_id': '2299484', + 'type': 'user', + 'url': 'https://tuchong.com/2299484/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '2299484', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2299484/55214989/', + 'views': 171040 + }, + { + 'author_id': '2587179', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 52, + 'content': '摄影 | Eric-Tsui\n修图 | 修图师杜娟', + 'created_at': '2019-09-23 12:37:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '摄影 | Eric-Tsui\n修图 | 修图师杜娟', + 'favorite_list_prefix': [], + 'favorites': 1546, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6582, + 'img_id': 448898487, + 'img_id_str': '448898487', + 'title': '', + 'user_id': 2587179, + 'width': 4388 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 478783503, + 'img_id_str': '478783503', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 244557843, + 'img_id_str': '244557843', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 202090277, + 'img_id_str': '202090277', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6587, + 'img_id': 225683495, + 'img_id_str': '225683495', + 'title': '', + 'user_id': 2587179, + 'width': 4391 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 486123260, + 'img_id_str': '486123260', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 116106888, + 'img_id_str': '116106888', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 478520750, + 'img_id_str': '478520750', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6570, + 'img_id': 379365035, + 'img_id_str': '379365035', + 'title': '', + 'user_id': 2587179, + 'width': 4380 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6582, + 'img_id': 614901729, + 'img_id_str': '614901729', + 'title': '', + 'user_id': 2587179, + 'width': 4388 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 164996858, + 'img_id_str': '164996858', + 'title': '', + 'user_id': 2587179, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '51', + 'passed_time': '2019年09月23日', + 'post_id': 53358878, + 'published_at': '2019-09-23 12:37:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 70, + 'site': { + 'description': '资深修图师', + 'domain': '', + 'followers': 13491, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2587179_7', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '修图培训杜娟', + 'site_id': '2587179', + 'type': 'user', + 'url': 'https://tuchong.com/2587179/', + 'verification_list': [ + {'verification_reason': '资深修图师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2587179', + 'sites': [], + 'tags': ['ps', '修图', '修图培训', '商业修图培训', '明星修图'], + 'title': '艺人《沈梦辰》', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2587179/53358878/', + 'views': 104858 + }, + { + 'author_id': '1827482', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 45, + 'content': '', + 'created_at': '2019-09-21 20:31:49', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['2019胶片摄影赛'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1803, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 302032856, + 'img_id_str': '302032856', + 'title': '', + 'user_id': 1827482, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 408462617, + 'img_id_str': '408462617', + 'title': '', + 'user_id': 1827482, + 'width': 1976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 309700167, + 'img_id_str': '309700167', + 'title': '', + 'user_id': 1827482, + 'width': 1976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 280077952, + 'img_id_str': '280077952', + 'title': '', + 'user_id': 1827482, + 'width': 1976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 535603055, + 'img_id_str': '535603055', + 'title': '', + 'user_id': 1827482, + 'width': 1976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2963, + 'img_id': 321234586, + 'img_id_str': '321234586', + 'title': '', + 'user_id': 1827482, + 'width': 1976 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3427, + 'img_id': 464627073, + 'img_id_str': '464627073', + 'title': '', + 'user_id': 1827482, + 'width': 2284 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3427, + 'img_id': 321496560, + 'img_id_str': '321496560', + 'title': '', + 'user_id': 1827482, + 'width': 2284 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3427, + 'img_id': 194094813, + 'img_id_str': '194094813', + 'title': '', + 'user_id': 1827482, + 'width': 2284 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '39', + 'passed_time': '2019年09月21日', + 'post_id': 53198482, + 'published_at': '2019-09-21 20:31:49', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 40, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'j-leonardo.tuchong.com', + 'followers': 6303, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1827482_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '空镜Titanium', + 'site_id': '1827482', + 'type': 'user', + 'url': 'https://j-leonardo.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1827482', + 'sites': [], + 'tags': ['2019胶片摄影赛', '人像', '色彩', '胶片', '复古'], + 'title': '【 琉璃暮色 】', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://j-leonardo.tuchong.com/53198482/', + 'views': 102699 + }, + { + 'author_id': '1610430', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 60, + 'content': '', + 'created_at': '2019-09-07 15:06:10', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 568, + 'image_count': 20, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 489397980, + 'img_id_str': '489397980', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5646, + 'img_id': 414097393, + 'img_id_str': '414097393', + 'title': '', + 'user_id': 1610430, + 'width': 3764 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3274, + 'img_id': 454860640, + 'img_id_str': '454860640', + 'title': '', + 'user_id': 1610430, + 'width': 2182 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 54763481, + 'img_id_str': '54763481', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 76587007, + 'img_id_str': '76587007', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 164339510, + 'img_id_str': '164339510', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 378445839, + 'img_id_str': '378445839', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 458399543, + 'img_id_str': '458399543', + 'title': '', + 'user_id': 1610430, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 168140799, + 'img_id_str': '168140799', + 'title': '', + 'user_id': 1610430, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 155229797, + 'img_id_str': '155229797', + 'title': '', + 'user_id': 1610430, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 583048808, + 'img_id_str': '583048808', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 200777577, + 'img_id_str': '200777577', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5479, + 'img_id': 655269494, + 'img_id_str': '655269494', + 'title': '', + 'user_id': 1610430, + 'width': 3653 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7026, + 'img_id': 456564501, + 'img_id_str': '456564501', + 'title': '', + 'user_id': 1610430, + 'width': 4684 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 611164379, + 'img_id_str': '611164379', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 63676566, + 'img_id_str': '63676566', + 'title': '', + 'user_id': 1610430, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 45457199, + 'img_id_str': '45457199', + 'title': '', + 'user_id': 1610430, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3071, + 'img_id': 106078135, + 'img_id_str': '106078135', + 'title': '', + 'user_id': 1610430, + 'width': 2047 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 553885355, + 'img_id_str': '553885355', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 113745466, + 'img_id_str': '113745466', + 'title': '', + 'user_id': 1610430, + 'width': 5760 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '2019年09月07日', + 'post_id': 51881812, + 'published_at': '2019-09-07 15:06:10', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '8', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 3437, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1610430_6', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '咖啡爱上猫', + 'site_id': '1610430', + 'type': 'user', + 'url': 'https://tuchong.com/1610430/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1610430', + 'sites': [], + 'tags': ['人像', '夜景', '日常'], + 'title': '夜', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1610430/51881812/', + 'views': 16717 + }, + { + 'author_id': '1720380', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': 'cos.王者荣耀甄姬 游园惊梦', + 'created_at': '2019-12-12 20:09:15', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '上海人像圈子', + '古风摄影研习社', + '约拍馆摄影作品投稿', + 'Cosplay摄影集中地', + '同济大学摄影圈', + '高颜值女神聚集地' + ], + 'excerpt': 'cos.王者荣耀甄姬 游园惊梦', + 'favorite_list_prefix': [], + 'favorites': 404, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 74105654, + 'img_id_str': '74105654', + 'title': '1682071', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 652722852, + 'img_id_str': '652722852', + 'title': '1804463', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 581551277, + 'img_id_str': '581551277', + 'title': '1804527', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 110805896, + 'img_id_str': '110805896', + 'title': '1804466', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 297714174, + 'img_id_str': '297714174', + 'title': '1804464', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 163693932, + 'img_id_str': '163693932', + 'title': '1804462', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 195281649, + 'img_id_str': '195281649', + 'title': '1804468', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 286835473, + 'img_id_str': '286835473', + 'title': '1804467', + 'user_id': 1720380, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 94749708, + 'img_id_str': '94749708', + 'title': '1804465', + 'user_id': 1720380, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '22', + 'passed_time': '2019年12月12日', + 'post_id': 60324475, + 'published_at': '2019-12-12 20:09:15', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 14, + 'site': { + 'description': '人像摄影', + 'domain': '', + 'followers': 420, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1720380_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '姹姹', + 'site_id': '1720380', + 'type': 'user', + 'url': 'https://tuchong.com/1720380/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1720380', + 'sites': [], + 'tags': [ + '上海人像圈子', + '古风摄影研习社', + '约拍馆摄影作品投稿', + 'Cosplay摄影集中地', + '同济大学摄影圈', + '高颜值女神聚集地' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1720380/60324475/', + 'views': 20735 + }, + { + 'author_id': '1409920', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 29, + 'content': '长沙长沙', + 'created_at': '2019-10-20 23:00:59', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['第三届京东摄影金像奖'], + 'excerpt': '长沙长沙', + 'favorite_list_prefix': [], + 'favorites': 325, + 'image_count': 18, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 526299544, + 'img_id_str': '526299544', + 'title': '001', + 'user_id': 1409920, + 'width': 3918 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5696, + 'img_id': 176796218, + 'img_id_str': '176796218', + 'title': '001', + 'user_id': 1409920, + 'width': 3800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3800, + 'img_id': 277787203, + 'img_id_str': '277787203', + 'title': '001', + 'user_id': 1409920, + 'width': 5796 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6042, + 'img_id': 554610777, + 'img_id_str': '554610777', + 'title': '001', + 'user_id': 1409920, + 'width': 3900 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 526299545, + 'img_id_str': '526299545', + 'title': '001', + 'user_id': 1409920, + 'width': 7295 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7952, + 'img_id': 88191057, + 'img_id_str': '88191057', + 'title': '001', + 'user_id': 1409920, + 'width': 5304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 296399784, + 'img_id_str': '296399784', + 'title': '001', + 'user_id': 1409920, + 'width': 4732 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3500, + 'img_id': 180401285, + 'img_id_str': '180401285', + 'title': '001', + 'user_id': 1409920, + 'width': 5647 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5835, + 'img_id': 115259200, + 'img_id_str': '115259200', + 'title': '001', + 'user_id': 1409920, + 'width': 3799 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5056, + 'img_id': 533507089, + 'img_id_str': '533507089', + 'title': '001', + 'user_id': 1409920, + 'width': 7041 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6500, + 'img_id': 346533193, + 'img_id_str': '346533193', + 'title': '001', + 'user_id': 1409920, + 'width': 4336 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3800, + 'img_id': 483767028, + 'img_id_str': '483767028', + 'title': '001', + 'user_id': 1409920, + 'width': 5456 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4583, + 'img_id': 390703961, + 'img_id_str': '390703961', + 'title': '001', + 'user_id': 1409920, + 'width': 7249 + }, + { + 'description': '', + 'excerpt': '', + 'height': 7547, + 'img_id': 561687784, + 'img_id_str': '561687784', + 'title': '001', + 'user_id': 1409920, + 'width': 4591 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4630, + 'img_id': 509914898, + 'img_id_str': '509914898', + 'title': '001', + 'user_id': 1409920, + 'width': 7179 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5304, + 'img_id': 295938718, + 'img_id_str': '295938718', + 'title': '001', + 'user_id': 1409920, + 'width': 7952 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3700, + 'img_id': 41726357, + 'img_id_str': '41726357', + 'title': '001', + 'user_id': 1409920, + 'width': 5546 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5080, + 'img_id': 215396998, + 'img_id_str': '215396998', + 'title': '001', + 'user_id': 1409920, + 'width': 7380 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '25', + 'passed_time': '2019年10月20日', + 'post_id': 56505427, + 'published_at': '2019-10-20 23:00:59', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 31, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 7398, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1409920_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '老白屹_', + 'site_id': '1409920', + 'type': 'user', + 'url': 'https://tuchong.com/1409920/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1409920', + 'sites': [], + 'tags': ['第三届京东摄影金像奖', 'JD看城市', '建筑物', '安全'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1409920/56505427/', + 'views': 13338 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 68, + 'content': '分享一下我的客人', + 'created_at': '2019-10-18 21:21:11', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上“首页推荐位”'], + 'excerpt': '分享一下我的客人', + 'favorite_list_prefix': [], + 'favorites': 2297, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 111391874, + 'img_id_str': '111391874', + 'title': '814114', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 344438049, + 'img_id_str': '344438049', + 'title': '814113', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 468497222, + 'img_id_str': '468497222', + 'title': '814112', + 'user_id': 3738183, + 'width': 3500 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5250, + 'img_id': 539276352, + 'img_id_str': '539276352', + 'title': '814111', + 'user_id': 3738183, + 'width': 3500 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '67', + 'passed_time': '2019年10月18日', + 'post_id': 56261682, + 'published_at': '2019-10-18 21:21:11', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 77, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['我要上“首页推荐位”', '人像', '日系', '写真'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/56261682/', + 'views': 77745 + }, + { + 'author_id': '2600543', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 46, + 'content': '出境:@迷你鹿er', + 'created_at': '2019-10-15 17:36:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['Cosplay摄影集中地', '让摄影穿破次元壁', '人像写真精选', '第三届京东摄影金像奖'], + 'excerpt': '出境:@迷你鹿er', + 'favorite_list_prefix': [], + 'favorites': 1155, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 581087865, + 'img_id_str': '581087865', + 'title': '', + 'user_id': 2600543, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 453686242, + 'img_id_str': '453686242', + 'title': '', + 'user_id': 2600543, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 212316674, + 'img_id_str': '212316674', + 'title': '', + 'user_id': 2600543, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 473609234, + 'img_id_str': '473609234', + 'title': '', + 'user_id': 2600543, + 'width': 2070 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3290, + 'img_id': 320647903, + 'img_id_str': '320647903', + 'title': '', + 'user_id': 2600543, + 'width': 2164 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3290, + 'img_id': 56537924, + 'img_id_str': '56537924', + 'title': '', + 'user_id': 2600543, + 'width': 2160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 137343615, + 'img_id_str': '137343615', + 'title': '', + 'user_id': 2600543, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2176, + 'img_id': 636203808, + 'img_id_str': '636203808', + 'title': '', + 'user_id': 2600543, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2176, + 'img_id': 35304620, + 'img_id_str': '35304620', + 'title': '', + 'user_id': 2600543, + 'width': 3264 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '44', + 'passed_time': '2019年10月15日', + 'post_id': 55974541, + 'published_at': '2019-10-15 17:36:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 35, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'sanyue015.tuchong.com', + 'followers': 13819, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2600543_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '叁月life', + 'site_id': '2600543', + 'type': 'user', + 'url': 'https://sanyue015.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2600543', + 'sites': [], + 'tags': ['Cosplay摄影集中地', '让摄影穿破次元壁', '人像写真精选', '第三届京东摄影金像奖', '人像', '写真'], + 'title': '#碧蓝航线 #爱宕 #婚纱', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://sanyue015.tuchong.com/55974541/', + 'views': 50221 + }, + { + 'author_id': '1531311', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 28, + 'content': '', + 'created_at': '2019-09-07 12:48:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 727, + 'image_count': 27, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2572, + 'img_id': 534224989, + 'img_id_str': '534224989', + 'title': '', + 'user_id': 1531311, + 'width': 1819 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 373923671, + 'img_id_str': '373923671', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 306225262, + 'img_id_str': '306225262', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 372744054, + 'img_id_str': '372744054', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 242065047, + 'img_id_str': '242065047', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 171614454, + 'img_id_str': '171614454', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 647667568, + 'img_id_str': '647667568', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 96051097, + 'img_id_str': '96051097', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 472424279, + 'img_id_str': '472424279', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 572563178, + 'img_id_str': '572563178', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 229744458, + 'img_id_str': '229744458', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 422289696, + 'img_id_str': '422289696', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 257072920, + 'img_id_str': '257072920', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 612867701, + 'img_id_str': '612867701', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 85958365, + 'img_id_str': '85958365', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 492544224, + 'img_id_str': '492544224', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 126656450, + 'img_id_str': '126656450', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 435396430, + 'img_id_str': '435396430', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 107060925, + 'img_id_str': '107060925', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 533897252, + 'img_id_str': '533897252', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3072, + 'img_id': 450797352, + 'img_id_str': '450797352', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 549822329, + 'img_id_str': '549822329', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 215916404, + 'img_id_str': '215916404', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2048, + 'img_id': 630300505, + 'img_id_str': '630300505', + 'title': '', + 'user_id': 1531311, + 'width': 3072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 323461182, + 'img_id_str': '323461182', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 420323351, + 'img_id_str': '420323351', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2867, + 'img_id': 307077283, + 'img_id_str': '307077283', + 'title': '', + 'user_id': 1531311, + 'width': 2048 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '26', + 'passed_time': '2019年09月07日', + 'post_id': 51870732, + 'published_at': '2019-09-07 12:48:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 25, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'wangyimeng.tuchong.com', + 'followers': 11125, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1531311_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '王艺萌', + 'site_id': '1531311', + 'type': 'user', + 'url': 'https://wangyimeng.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1531311', + 'sites': [], + 'tags': ['佳能', '小清新', '日系', '少女', '校园', 'JK'], + 'title': '开学季', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://wangyimeng.tuchong.com/51870732/', + 'views': 20208 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 185, + 'content': '送给自己20岁的礼物', + 'created_at': '2019-08-28 23:32:23', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我要上开屏'], + 'excerpt': '送给自己20岁的礼物', + 'favorite_list_prefix': [], + 'favorites': 2676, + 'image_count': 7, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 222337530, + 'img_id_str': '222337530', + 'title': '571459', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 551525167, + 'img_id_str': '551525167', + 'title': '571456', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 431332232, + 'img_id_str': '431332232', + 'title': '571457', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 118855879, + 'img_id_str': '118855879', + 'title': '571454', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 224369416, + 'img_id_str': '224369416', + 'title': '571455', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 315136277, + 'img_id_str': '315136277', + 'title': '571458', + 'user_id': 3738183, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1334, + 'img_id': 170367481, + 'img_id_str': '170367481', + 'title': '571460', + 'user_id': 3738183, + 'width': 750 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '145', + 'passed_time': '2019年08月28日', + 'post_id': 50964588, + 'published_at': '2019-08-28 23:32:23', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '2', + 'rqt_id': '', + 'shares': 129, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['我要上开屏', '服装', '毛衣', '工作室'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/50964588/', + 'views': 92898 + }, + { + 'author_id': '1325971', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 36, + 'content': '', + 'created_at': '2019-08-01 12:47:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1249, + 'image_count': 12, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 322535808, + 'img_id_str': '322535808', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 621183700, + 'img_id_str': '621183700', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 110789079, + 'img_id_str': '110789079', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 454918521, + 'img_id_str': '454918521', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 249856378, + 'img_id_str': '249856378', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 122126933, + 'img_id_str': '122126933', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 365723634, + 'img_id_str': '365723634', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 484803120, + 'img_id_str': '484803120', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1067, + 'img_id': 315654586, + 'img_id_str': '315654586', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 364020196, + 'img_id_str': '364020196', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 619151737, + 'img_id_str': '619151737', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2400, + 'img_id': 73171533, + 'img_id_str': '73171533', + 'title': '', + 'user_id': 1325971, + 'width': 1600 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '36', + 'passed_time': '2019年08月01日', + 'post_id': 47181699, + 'published_at': '2019-08-01 12:47:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 25, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2852, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1325971_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '西萌阿兵', + 'site_id': '1325971', + 'type': 'user', + 'url': 'https://tuchong.com/1325971/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1325971', + 'sites': [], + 'tags': ['人像', '少女', '美女', '50mm'], + 'title': '早安,乖乖', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1325971/47181699/', + 'views': 58999 + }, + { + 'author_id': '406880', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 112, + 'content': '', + 'created_at': '2019-07-23 05:49:43', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1605, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 313817664, + 'img_id_str': '313817664', + 'title': '001', + 'user_id': 406880, + 'width': 958 + }, + { + 'description': '', + 'excerpt': '', + 'height': 958, + 'img_id': 519928406, + 'img_id_str': '519928406', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 958, + 'img_id': 426277499, + 'img_id_str': '426277499', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 185694895, + 'img_id_str': '185694895', + 'title': '001', + 'user_id': 406880, + 'width': 958 + }, + { + 'description': '', + 'excerpt': '', + 'height': 958, + 'img_id': 214661447, + 'img_id_str': '214661447', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 34568659, + 'img_id_str': '34568659', + 'title': '001', + 'user_id': 406880, + 'width': 958 + }, + { + 'description': '', + 'excerpt': '', + 'height': 958, + 'img_id': 448821613, + 'img_id_str': '448821613', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 251034022, + 'img_id_str': '251034022', + 'title': '001', + 'user_id': 406880, + 'width': 958 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 399669718, + 'img_id_str': '399669718', + 'title': '001', + 'user_id': 406880, + 'width': 958 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '91', + 'passed_time': '2019年07月23日', + 'post_id': 45795564, + 'published_at': '2019-07-23 05:49:43', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 67, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 24454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_406880_9', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '风-vision', + 'site_id': '406880', + 'type': 'user', + 'url': 'https://tuchong.com/406880/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '406880', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/406880/45795564/', + 'views': 105946 + }, + { + 'author_id': '1317325', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 26, + 'content': '', + 'created_at': '2020-01-01 19:19:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 424, + 'image_count': 156, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 352765572, + 'img_id_str': '352765572', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3596, + 'img_id': 383371796, + 'img_id_str': '383371796', + 'title': '', + 'user_id': 1317325, + 'width': 2406 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 379569663, + 'img_id_str': '379569663', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 574669812, + 'img_id_str': '574669812', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2393, + 'img_id': 494978624, + 'img_id_str': '494978624', + 'title': '', + 'user_id': 1317325, + 'width': 3577 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 37930860, + 'img_id_str': '37930860', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 103204635, + 'img_id_str': '103204635', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 166381707, + 'img_id_str': '166381707', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3553, + 'img_id': 573818737, + 'img_id_str': '573818737', + 'title': '', + 'user_id': 1317325, + 'width': 2377 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 123586311, + 'img_id_str': '123586311', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 307676886, + 'img_id_str': '307676886', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 551994176, + 'img_id_str': '551994176', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2360, + 'img_id': 549373649, + 'img_id_str': '549373649', + 'title': '', + 'user_id': 1317325, + 'width': 3528 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 90228497, + 'img_id_str': '90228497', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 119129777, + 'img_id_str': '119129777', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3473, + 'img_id': 649250029, + 'img_id_str': '649250029', + 'title': '', + 'user_id': 1317325, + 'width': 2323 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 185648300, + 'img_id_str': '185648300', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 381470422, + 'img_id_str': '381470422', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 554616169, + 'img_id_str': '554616169', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 248235000, + 'img_id_str': '248235000', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2385, + 'img_id': 396805517, + 'img_id_str': '396805517', + 'title': '', + 'user_id': 1317325, + 'width': 3519 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2402, + 'img_id': 284477221, + 'img_id_str': '284477221', + 'title': '', + 'user_id': 1317325, + 'width': 3590 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 615761151, + 'img_id_str': '615761151', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 507758030, + 'img_id_str': '507758030', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2405, + 'img_id': 252167834, + 'img_id_str': '252167834', + 'title': '', + 'user_id': 1317325, + 'width': 3595 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 225363509, + 'img_id_str': '225363509', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 504939606, + 'img_id_str': '504939606', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 643614191, + 'img_id_str': '643614191', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 448120233, + 'img_id_str': '448120233', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 264357223, + 'img_id_str': '264357223', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 522766113, + 'img_id_str': '522766113', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 133809889, + 'img_id_str': '133809889', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 408798835, + 'img_id_str': '408798835', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 418694238, + 'img_id_str': '418694238', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 81839611, + 'img_id_str': '81839611', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 110610285, + 'img_id_str': '110610285', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2382, + 'img_id': 299484439, + 'img_id_str': '299484439', + 'title': '', + 'user_id': 1317325, + 'width': 3561 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 42976581, + 'img_id_str': '42976581', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 530236923, + 'img_id_str': '530236923', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 431867053, + 'img_id_str': '431867053', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 296404131, + 'img_id_str': '296404131', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2420, + 'img_id': 95864239, + 'img_id_str': '95864239', + 'title': '', + 'user_id': 1317325, + 'width': 3617 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 619497093, + 'img_id_str': '619497093', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 186173411, + 'img_id_str': '186173411', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 500090433, + 'img_id_str': '500090433', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 315868907, + 'img_id_str': '315868907', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 34064578, + 'img_id_str': '34064578', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 109561871, + 'img_id_str': '109561871', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3388, + 'img_id': 436061879, + 'img_id_str': '436061879', + 'title': '', + 'user_id': 1317325, + 'width': 2400 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2396, + 'img_id': 375309969, + 'img_id_str': '375309969', + 'title': '', + 'user_id': 1317325, + 'width': 3581 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 346015876, + 'img_id_str': '346015876', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 369936245, + 'img_id_str': '369936245', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2416, + 'img_id': 540591705, + 'img_id_str': '540591705', + 'title': '', + 'user_id': 1317325, + 'width': 3612 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 92522097, + 'img_id_str': '92522097', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 203933044, + 'img_id_str': '203933044', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2424, + 'img_id': 613795454, + 'img_id_str': '613795454', + 'title': '', + 'user_id': 1317325, + 'width': 3623 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 561760119, + 'img_id_str': '561760119', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 352306970, + 'img_id_str': '352306970', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2248, + 'img_id': 602523163, + 'img_id_str': '602523163', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 428918388, + 'img_id_str': '428918388', + 'title': '', + 'user_id': 1317325, + 'width': 3608 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 209241612, + 'img_id_str': '209241612', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 249545977, + 'img_id_str': '249545977', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2419, + 'img_id': 580436941, + 'img_id_str': '580436941', + 'title': '', + 'user_id': 1317325, + 'width': 3616 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 279561482, + 'img_id_str': '279561482', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 594986424, + 'img_id_str': '594986424', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 397068049, + 'img_id_str': '397068049', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 398771826, + 'img_id_str': '398771826', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 131188270, + 'img_id_str': '131188270', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 71484751, + 'img_id_str': '71484751', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 227591926, + 'img_id_str': '227591926', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 307217569, + 'img_id_str': '307217569', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 144622952, + 'img_id_str': '144622952', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 615499199, + 'img_id_str': '615499199', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2360, + 'img_id': 410961410, + 'img_id_str': '410961410', + 'title': '', + 'user_id': 1317325, + 'width': 3528 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 61850928, + 'img_id_str': '61850928', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2415, + 'img_id': 523224107, + 'img_id_str': '523224107', + 'title': '', + 'user_id': 1317325, + 'width': 3610 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 627296025, + 'img_id_str': '627296025', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 438290115, + 'img_id_str': '438290115', + 'title': '', + 'user_id': 1317325, + 'width': 2218 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 313837011, + 'img_id_str': '313837011', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 483640695, + 'img_id_str': '483640695', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 628344320, + 'img_id_str': '628344320', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 533448448, + 'img_id_str': '533448448', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 638371104, + 'img_id_str': '638371104', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 639550758, + 'img_id_str': '639550758', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 603964690, + 'img_id_str': '603964690', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 617203501, + 'img_id_str': '617203501', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 389924354, + 'img_id_str': '389924354', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 145934013, + 'img_id_str': '145934013', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 641189901, + 'img_id_str': '641189901', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 604751276, + 'img_id_str': '604751276', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 38192268, + 'img_id_str': '38192268', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 459851283, + 'img_id_str': '459851283', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 341755791, + 'img_id_str': '341755791', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 644335322, + 'img_id_str': '644335322', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 234538530, + 'img_id_str': '234538530', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3402, + 'img_id': 239585095, + 'img_id_str': '239585095', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 407094569, + 'img_id_str': '407094569', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 132630014, + 'img_id_str': '132630014', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 170640695, + 'img_id_str': '170640695', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2365, + 'img_id': 458278360, + 'img_id_str': '458278360', + 'title': '', + 'user_id': 1317325, + 'width': 3535 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 44549357, + 'img_id_str': '44549357', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 450676510, + 'img_id_str': '450676510', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3595, + 'img_id': 276808607, + 'img_id_str': '276808607', + 'title': '', + 'user_id': 1317325, + 'width': 2405 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 239126308, + 'img_id_str': '239126308', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 467650276, + 'img_id_str': '467650276', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 189973714, + 'img_id_str': '189973714', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2133, + 'img_id': 581289264, + 'img_id_str': '581289264', + 'title': '', + 'user_id': 1317325, + 'width': 3551 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 254592462, + 'img_id_str': '254592462', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2398, + 'img_id': 335528862, + 'img_id_str': '335528862', + 'title': '', + 'user_id': 1317325, + 'width': 3584 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2169, + 'img_id': 100124175, + 'img_id_str': '100124175', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 282249200, + 'img_id_str': '282249200', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 253347188, + 'img_id_str': '253347188', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 451003729, + 'img_id_str': '451003729', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 257213902, + 'img_id_str': '257213902', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 149865822, + 'img_id_str': '149865822', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2307, + 'img_id': 321701103, + 'img_id_str': '321701103', + 'title': '', + 'user_id': 1317325, + 'width': 3636 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 589285324, + 'img_id_str': '589285324', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 134923539, + 'img_id_str': '134923539', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 412140623, + 'img_id_str': '412140623', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 477218709, + 'img_id_str': '477218709', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 322946462, + 'img_id_str': '322946462', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 376424066, + 'img_id_str': '376424066', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 124635337, + 'img_id_str': '124635337', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 600557124, + 'img_id_str': '600557124', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 452445555, + 'img_id_str': '452445555', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 568706479, + 'img_id_str': '568706479', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 587711871, + 'img_id_str': '587711871', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 622446192, + 'img_id_str': '622446192', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 375637657, + 'img_id_str': '375637657', + 'title': '', + 'user_id': 1317325, + 'width': 2107 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 277333329, + 'img_id_str': '277333329', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 138200407, + 'img_id_str': '138200407', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 344966443, + 'img_id_str': '344966443', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2391, + 'img_id': 449955449, + 'img_id_str': '449955449', + 'title': '', + 'user_id': 1317325, + 'width': 3574 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 199018289, + 'img_id_str': '199018289', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 204850479, + 'img_id_str': '204850479', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 152225040, + 'img_id_str': '152225040', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2250, + 'img_id': 633587058, + 'img_id_str': '633587058', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3637, + 'img_id': 551405599, + 'img_id_str': '551405599', + 'title': '', + 'user_id': 1317325, + 'width': 2433 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 187221289, + 'img_id_str': '187221289', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 476693827, + 'img_id_str': '476693827', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 79021769, + 'img_id_str': '79021769', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2385, + 'img_id': 572245468, + 'img_id_str': '572245468', + 'title': '', + 'user_id': 1317325, + 'width': 3565 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2402, + 'img_id': 261473805, + 'img_id_str': '261473805', + 'title': '', + 'user_id': 1317325, + 'width': 3590 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2403, + 'img_id': 601277868, + 'img_id_str': '601277868', + 'title': '', + 'user_id': 1317325, + 'width': 3592 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 404014479, + 'img_id_str': '404014479', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2433, + 'img_id': 329893049, + 'img_id_str': '329893049', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2305, + 'img_id': 587056675, + 'img_id_str': '587056675', + 'title': '', + 'user_id': 1317325, + 'width': 3637 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3318, + 'img_id': 152487179, + 'img_id_str': '152487179', + 'title': '', + 'user_id': 1317325, + 'width': 2279 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 444581362, + 'img_id_str': '444581362', + 'title': '', + 'user_id': 1317325, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 631358883, + 'img_id_str': '631358883', + 'title': '', + 'user_id': 1317325, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2156, + 'img_id': 514442644, + 'img_id_str': '514442644', + 'title': '', + 'user_id': 1317325, + 'width': 3303 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2279, + 'img_id': 407815364, + 'img_id_str': '407815364', + 'title': '', + 'user_id': 1317325, + 'width': 3318 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3255, + 'img_id': 574669813, + 'img_id_str': '574669813', + 'title': '', + 'user_id': 1317325, + 'width': 2236 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2233, + 'img_id': 624018956, + 'img_id_str': '624018956', + 'title': '', + 'user_id': 1317325, + 'width': 3251 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3242, + 'img_id': 324716075, + 'img_id_str': '324716075', + 'title': '', + 'user_id': 1317325, + 'width': 2227 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2390, + 'img_id': 622249495, + 'img_id_str': '622249495', + 'title': '', + 'user_id': 1317325, + 'width': 3573 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '26', + 'passed_time': '01月01日', + 'post_id': 61292051, + 'published_at': '2020-01-01 19:19:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 16657, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1317325_6', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '蔡九记', + 'site_id': '1317325', + 'type': 'user', + 'url': 'https://tuchong.com/1317325/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1317325', + 'sites': [], + 'tags': [], + 'title': '冲吧冲吧', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1317325/61292051/', + 'views': 21184 + }, + { + 'author_id': '406880', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 40, + 'content': '冬至\n出镜:轩轩', + 'created_at': '2019-12-28 11:07:44', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '冬至\n出镜:轩轩', + 'favorite_list_prefix': [], + 'favorites': 492, + 'image_count': 14, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 551339442, + 'img_id_str': '551339442', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 111199699, + 'img_id_str': '111199699', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 90948976, + 'img_id_str': '90948976', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 574407786, + 'img_id_str': '574407786', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 140363214, + 'img_id_str': '140363214', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 71943897, + 'img_id_str': '71943897', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 616088906, + 'img_id_str': '616088906', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 59622563, + 'img_id_str': '59622563', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 170837482, + 'img_id_str': '170837482', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 304006409, + 'img_id_str': '304006409', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 217761014, + 'img_id_str': '217761014', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 204326157, + 'img_id_str': '204326157', + 'title': '001', + 'user_id': 406880, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 570017156, + 'img_id_str': '570017156', + 'title': '001', + 'user_id': 406880, + 'width': 960 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1440, + 'img_id': 552256976, + 'img_id_str': '552256976', + 'title': '001', + 'user_id': 406880, + 'width': 960 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '35', + 'passed_time': '2019年12月28日', + 'post_id': 61083981, + 'published_at': '2019-12-28 11:07:44', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 13, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 24454, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_406880_9', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '风-vision', + 'site_id': '406880', + 'type': 'user', + 'url': 'https://tuchong.com/406880/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '406880', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/406880/61083981/', + 'views': 30677 + }, + { + 'author_id': '529822', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 40, + 'content': '那一天 \n你几乎带走我 \n所有 的从前\n故事里\n不再出现与你相关\n 的画面\n一个人的幸福 \n 怎么编', + 'created_at': '2019-12-14 12:36:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '2019胶片摄影赛', + '我要上开屏', + '对短发姑娘没有任何抵抗力!', + '分享神仙颜值', + '人像爱好者', + '陕西人像摄影' + ], + 'excerpt': '那一天 \n你几乎带走我 \n所有 的从前\n故事里\n不再出现与你相关\n 的画面\n一个人的幸福 \n 怎么编', + 'favorite_list_prefix': [], + 'favorites': 513, + 'image_count': 15, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 387236717, + 'img_id_str': '387236717', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 270451562, + 'img_id_str': '270451562', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2632, + 'img_id': 102810135, + 'img_id_str': '102810135', + 'title': '', + 'user_id': 529822, + 'width': 4680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 546096033, + 'img_id_str': '546096033', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 361808681, + 'img_id_str': '361808681', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 201704487, + 'img_id_str': '201704487', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 500810605, + 'img_id_str': '500810605', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 155960315, + 'img_id_str': '155960315', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 217564354, + 'img_id_str': '217564354', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 199214191, + 'img_id_str': '199214191', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 54575694, + 'img_id_str': '54575694', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 504021967, + 'img_id_str': '504021967', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 255771657, + 'img_id_str': '255771657', + 'title': '', + 'user_id': 529822, + 'width': 3120 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2767, + 'img_id': 98027132, + 'img_id_str': '98027132', + 'title': '', + 'user_id': 529822, + 'width': 4680 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4680, + 'img_id': 144819348, + 'img_id_str': '144819348', + 'title': '', + 'user_id': 529822, + 'width': 3120 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年12月14日', + 'post_id': 60410711, + 'published_at': '2019-12-14 12:36:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'guchengshijue.tuchong.com', + 'followers': 15440, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_529822_12', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '孤城视觉', + 'site_id': '529822', + 'type': 'user', + 'url': 'https://guchengshijue.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '529822', + 'sites': [], + 'tags': [ + '2019胶片摄影赛', + '我要上开屏', + '对短发姑娘没有任何抵抗力!', + '分享神仙颜值', + '人像爱好者', + '陕西人像摄影' + ], + 'title': '一点点', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://guchengshijue.tuchong.com/60410711/', + 'views': 18044 + }, + { + 'author_id': '2342168', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': '阳光透过窗口\n洒进一帘幽梦\n我愿白纱遮眼\n以梦为马\n像一朵云\n掠过风\n掠过树\n掠过你', + 'created_at': '2019-11-20 21:33:25', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['日系集'], + 'excerpt': '阳光透过窗口\n洒进一帘幽梦\n我愿白纱遮眼\n以梦为马\n像一朵云\n掠过风\n掠过树\n掠过你', + 'favorite_list_prefix': [], + 'favorites': 621, + 'image_count': 17, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 496156621, + 'img_id_str': '496156621', + 'title': '', + 'user_id': 2342168, + 'width': 2688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2523, + 'img_id': 450281452, + 'img_id_str': '450281452', + 'title': '', + 'user_id': 2342168, + 'width': 1802 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 394706451, + 'img_id_str': '394706451', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1673, + 'img_id': 447921749, + 'img_id_str': '447921749', + 'title': '', + 'user_id': 2342168, + 'width': 1673 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 311869234, + 'img_id_str': '311869234', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 213696474, + 'img_id_str': '213696474', + 'title': '', + 'user_id': 2342168, + 'width': 2688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 510312121, + 'img_id_str': '510312121', + 'title': '', + 'user_id': 2342168, + 'width': 1371 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2197, + 'img_id': 541441751, + 'img_id_str': '541441751', + 'title': '', + 'user_id': 2342168, + 'width': 1569 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1371, + 'img_id': 154321150, + 'img_id_str': '154321150', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1892, + 'img_id': 373211787, + 'img_id_str': '373211787', + 'title': '', + 'user_id': 2342168, + 'width': 2648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 595378132, + 'img_id_str': '595378132', + 'title': '', + 'user_id': 2342168, + 'width': 2688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2688, + 'img_id': 309248041, + 'img_id_str': '309248041', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2880, + 'img_id': 69844831, + 'img_id_str': '69844831', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1741, + 'img_id': 190234450, + 'img_id_str': '190234450', + 'title': '', + 'user_id': 2342168, + 'width': 1741 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1638, + 'img_id': 381140255, + 'img_id_str': '381140255', + 'title': '', + 'user_id': 2342168, + 'width': 1638 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 603438903, + 'img_id_str': '603438903', + 'title': '', + 'user_id': 2342168, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2263, + 'img_id': 38321965, + 'img_id_str': '38321965', + 'title': '', + 'user_id': 2342168, + 'width': 1617 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '22', + 'passed_time': '2019年11月20日', + 'post_id': 58964959, + 'published_at': '2019-11-20 21:33:25', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4477, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2342168_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄手座DA', + 'site_id': '2342168', + 'type': 'user', + 'url': 'https://tuchong.com/2342168/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2342168', + 'sites': [], + 'tags': ['日系集', '人像', '美女'], + 'title': '以梦为马', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/2342168/58964959/', + 'views': 28795 + }, + { + 'author_id': '3733034', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 16, + 'content': 'FGO正片', + 'created_at': '2019-11-05 15:07:18', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': 'FGO正片', + 'favorite_list_prefix': [], + 'favorites': 670, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3200, + 'img_id': 273922646, + 'img_id_str': '273922646', + 'title': '001', + 'user_id': 3733034, + 'width': 4800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 539212695, + 'img_id_str': '539212695', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 634764122, + 'img_id_str': '634764122', + 'title': '001', + 'user_id': 3733034, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 595508309, + 'img_id_str': '595508309', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 93895026, + 'img_id_str': '93895026', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 509000141, + 'img_id_str': '509000141', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 66501570, + 'img_id_str': '66501570', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 213826272, + 'img_id_str': '213826272', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 241285957, + 'img_id_str': '241285957', + 'title': '001', + 'user_id': 3733034, + 'width': 3200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5472, + 'img_id': 330873154, + 'img_id_str': '330873154', + 'title': '001', + 'user_id': 3733034, + 'width': 3648 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4800, + 'img_id': 335198645, + 'img_id_str': '335198645', + 'title': '001', + 'user_id': 3733034, + 'width': 3200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '16', + 'passed_time': '2019年11月05日', + 'post_id': 57859682, + 'published_at': '2019-11-05 15:07:18', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '9', + 'rqt_id': '', + 'shares': 20, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 6387, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3733034_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影愛倫同学', + 'site_id': '3733034', + 'type': 'user', + 'url': 'https://tuchong.com/3733034/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3733034', + 'sites': [], + 'tags': ['Cosplay'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3733034/57859682/', + 'views': 27369 + }, + { + 'author_id': '2976763', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 81, + 'content': 'Photographer:顾小白Hala\nModel:琳琳\nOrganizer:文珺Ronnie', + 'created_at': '2019-10-10 17:15:50', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '高颜值女神聚集地', + '分享神仙颜值', + '人像爱好者', + '糖水人像小组', + '暖色调人像', + '写真人像摄影', + '人像摄影集', + '佳能器材党', + '我们都爱日系摄影', + '我要上开屏', + '绝不停止记录的2019', + '周末好时光' + ], + 'excerpt': 'Photographer:顾小白Hala\nModel:琳琳\nOrganizer:文珺Ronnie', + 'favorite_list_prefix': [], + 'favorites': 1506, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6006, + 'img_id': 196653493, + 'img_id_str': '196653493', + 'title': '', + 'user_id': 2976763, + 'width': 4004 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6288, + 'img_id': 410038363, + 'img_id_str': '410038363', + 'title': '', + 'user_id': 2976763, + 'width': 4192 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 482193776, + 'img_id_str': '482193776', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6384, + 'img_id': 130330669, + 'img_id_str': '130330669', + 'title': '', + 'user_id': 2976763, + 'width': 4256 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 410890704, + 'img_id_str': '410890704', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5970, + 'img_id': 377597824, + 'img_id_str': '377597824', + 'title': '', + 'user_id': 2976763, + 'width': 3980 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 633778207, + 'img_id_str': '633778207', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 48541967, + 'img_id_str': '48541967', + 'title': '', + 'user_id': 2976763, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 538489154, + 'img_id_str': '538489154', + 'title': '', + 'user_id': 2976763, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6198, + 'img_id': 629977420, + 'img_id_str': '629977420', + 'title': '', + 'user_id': 2976763, + 'width': 4132 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '76', + 'passed_time': '2019年10月10日', + 'post_id': 55477651, + 'published_at': '2019-10-10 17:15:50', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 35, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'gxbhala.tuchong.com', + 'followers': 39077, + 'has_everphoto_note': false, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2976763_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '顾小白Hala', + 'site_id': '2976763', + 'type': 'user', + 'url': 'https://gxbhala.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2976763', + 'sites': [], + 'tags': ['高颜值女神聚集地', '分享神仙颜值', '人像爱好者', '糖水人像小组', '暖色调人像', '写真人像摄影'], + 'title': '杨花落尽子规啼', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://gxbhala.tuchong.com/55477651/', + 'views': 67104 + }, + { + 'author_id': '1349328', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 47, + 'content': '光,落在你脸上,可爱一如往常。', + 'created_at': '2019-09-18 17:35:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '光,落在你脸上,可爱一如往常。', + 'favorite_list_prefix': [], + 'favorites': 920, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 198746991, + 'img_id_str': '198746991', + 'title': '', + 'user_id': 1349328, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2309, + 'img_id': 516400918, + 'img_id_str': '516400918', + 'title': '', + 'user_id': 1349328, + 'width': 1539 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2888, + 'img_id': 86550008, + 'img_id_str': '86550008', + 'title': '', + 'user_id': 1349328, + 'width': 1926 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2778, + 'img_id': 203137947, + 'img_id_str': '203137947', + 'title': '', + 'user_id': 1349328, + 'width': 1852 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3142, + 'img_id': 359441827, + 'img_id_str': '359441827', + 'title': '', + 'user_id': 1349328, + 'width': 2095 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3165, + 'img_id': 380150695, + 'img_id_str': '380150695', + 'title': '', + 'user_id': 1349328, + 'width': 2110 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2882, + 'img_id': 92841318, + 'img_id_str': '92841318', + 'title': '', + 'user_id': 1349328, + 'width': 1921 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3107, + 'img_id': 532849699, + 'img_id_str': '532849699', + 'title': '', + 'user_id': 1349328, + 'width': 2072 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3360, + 'img_id': 482780953, + 'img_id_str': '482780953', + 'title': '', + 'user_id': 1349328, + 'width': 2240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2452, + 'img_id': 359441826, + 'img_id_str': '359441826', + 'title': '', + 'user_id': 1349328, + 'width': 1635 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '43', + 'passed_time': '2019年09月18日', + 'post_id': 52928737, + 'published_at': '2019-09-18 17:35:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 41, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 7901, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1349328_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '壹梵i', + 'site_id': '1349328', + 'type': 'user', + 'url': 'https://tuchong.com/1349328/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1349328', + 'sites': [], + 'tags': ['人像', '佳能', '日系'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1349328/52928737/', + 'views': 28980 + }, + { + 'author_id': '982513', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 20, + 'content': '', + 'created_at': '2019-11-06 19:18:24', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 412, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 406895151, + 'img_id_str': '406895151', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 471906623, + 'img_id_str': '471906623', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 182041329, + 'img_id_str': '182041329', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 237091693, + 'img_id_str': '237091693', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 64207408, + 'img_id_str': '64207408', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 113556549, + 'img_id_str': '113556549', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 114998014, + 'img_id_str': '114998014', + 'title': '', + 'user_id': 982513, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5907, + 'img_id': 215465014, + 'img_id_str': '215465014', + 'title': '', + 'user_id': 982513, + 'width': 3938 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 580762709, + 'img_id_str': '580762709', + 'title': '', + 'user_id': 982513, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '19', + 'passed_time': '2019年11月06日', + 'post_id': 57952462, + 'published_at': '2019-11-06 19:18:24', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 13, + 'site': { + 'description': 'QQ/微信: 341215 欢迎交流/约拍.', + 'domain': '', + 'followers': 4219, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_982513_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'ゞ灵魂', + 'site_id': '982513', + 'type': 'user', + 'url': 'https://tuchong.com/982513/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '982513', + 'sites': [], + 'tags': ['人像', '城市', '美女', '高尔夫'], + 'title': '摄影是件让人愉快的事---Monica', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/982513/57952462/', + 'views': 22268 + }, + { + 'author_id': '1509808', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 59, + 'content': '想立刻搬进你眼中', + 'created_at': '2019-10-24 10:10:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['分享神仙颜值'], + 'excerpt': '想立刻搬进你眼中', + 'favorite_list_prefix': [], + 'favorites': 1251, + 'image_count': 13, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 360364066, + 'img_id_str': '360364066', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 210744687, + 'img_id_str': '210744687', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 532854206, + 'img_id_str': '532854206', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 293058488, + 'img_id_str': '293058488', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 177190943, + 'img_id_str': '177190943', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 240825653, + 'img_id_str': '240825653', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 259044765, + 'img_id_str': '259044765', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 379696723, + 'img_id_str': '379696723', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 348108282, + 'img_id_str': '348108282', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 433829334, + 'img_id_str': '433829334', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 645379451, + 'img_id_str': '645379451', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 417772776, + 'img_id_str': '417772776', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1800, + 'img_id': 549303940, + 'img_id_str': '549303940', + 'title': '001', + 'user_id': 1509808, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '59', + 'passed_time': '2019年10月24日', + 'post_id': 56790650, + 'published_at': '2019-10-24 10:10:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 73, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 4600, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1509808_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '远远Ayn', + 'site_id': '1509808', + 'type': 'user', + 'url': 'https://tuchong.com/1509808/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1509808', + 'sites': [], + 'tags': ['分享神仙颜值', '人像', '摄影', '少女'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1509808/56790650/', + 'views': 53227 + }, + { + 'author_id': '1733468', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 54, + 'content': '白蛇传之红颜旧', + 'created_at': '2019-09-16 10:11:47', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '白蛇传之红颜旧', + 'favorite_list_prefix': [], + 'favorites': 581, + 'image_count': 16, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2316, + 'img_id': 167814617, + 'img_id_str': '167814617', + 'title': '', + 'user_id': 1733468, + 'width': 1537 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2371, + 'img_id': 604873978, + 'img_id_str': '604873978', + 'title': '', + 'user_id': 1733468, + 'width': 1517 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2287, + 'img_id': 243639424, + 'img_id_str': '243639424', + 'title': '', + 'user_id': 1733468, + 'width': 1443 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2266, + 'img_id': 193701130, + 'img_id_str': '193701130', + 'title': '', + 'user_id': 1733468, + 'width': 1435 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2291, + 'img_id': 481469255, + 'img_id_str': '481469255', + 'title': '', + 'user_id': 1733468, + 'width': 1495 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1482, + 'img_id': 366191715, + 'img_id_str': '366191715', + 'title': '', + 'user_id': 1733468, + 'width': 2357 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1449, + 'img_id': 260744411, + 'img_id_str': '260744411', + 'title': '', + 'user_id': 1733468, + 'width': 2410 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1462, + 'img_id': 622437256, + 'img_id_str': '622437256', + 'title': '', + 'user_id': 1733468, + 'width': 2357 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2323, + 'img_id': 292397797, + 'img_id_str': '292397797', + 'title': '', + 'user_id': 1733468, + 'width': 1484 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1493, + 'img_id': 301966448, + 'img_id_str': '301966448', + 'title': '', + 'user_id': 1733468, + 'width': 2363 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2291, + 'img_id': 486909087, + 'img_id_str': '486909087', + 'title': '', + 'user_id': 1733468, + 'width': 1520 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2268, + 'img_id': 156869367, + 'img_id_str': '156869367', + 'title': '', + 'user_id': 1733468, + 'width': 1511 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1760, + 'img_id': 579642113, + 'img_id_str': '579642113', + 'title': '', + 'user_id': 1733468, + 'width': 1744 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2356, + 'img_id': 316121666, + 'img_id_str': '316121666', + 'title': '', + 'user_id': 1733468, + 'width': 1426 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1446, + 'img_id': 342401844, + 'img_id_str': '342401844', + 'title': '', + 'user_id': 1733468, + 'width': 2357 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2262, + 'img_id': 64070460, + 'img_id_str': '64070460', + 'title': '', + 'user_id': 1733468, + 'width': 1522 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '50', + 'passed_time': '2019年09月16日', + 'post_id': 52743756, + 'published_at': '2019-09-16 10:11:47', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 35, + 'site': { + 'description': '', + 'domain': '', + 'followers': 4350, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1733468_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '心是自在A', + 'site_id': '1733468', + 'type': 'user', + 'url': 'https://tuchong.com/1733468/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1733468', + 'sites': [], + 'tags': ['人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1733468/52743756/', + 'views': 41356 + }, + { + 'author_id': '1303010', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 37, + 'content': '', + 'created_at': '2019-08-31 08:29:37', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 771, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 356555965, + 'img_id_str': '356555965', + 'title': '', + 'user_id': 1303010, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1125, + 'img_id': 591961520, + 'img_id_str': '591961520', + 'title': '', + 'user_id': 1303010, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 296328686, + 'img_id_str': '296328686', + 'title': '', + 'user_id': 1303010, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 549165862, + 'img_id_str': '549165862', + 'title': '', + 'user_id': 1303010, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 422288829, + 'img_id_str': '422288829', + 'title': '', + 'user_id': 1303010, + 'width': 2000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 63216338, + 'img_id_str': '63216338', + 'title': '', + 'user_id': 1303010, + 'width': 1320 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 503553070, + 'img_id_str': '503553070', + 'title': '', + 'user_id': 1303010, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 560962303, + 'img_id_str': '560962303', + 'title': '', + 'user_id': 1303010, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2000, + 'img_id': 305372418, + 'img_id_str': '305372418', + 'title': '', + 'user_id': 1303010, + 'width': 1333 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1333, + 'img_id': 220110471, + 'img_id_str': '220110471', + 'title': '', + 'user_id': 1303010, + 'width': 2000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '34', + 'passed_time': '2019年08月31日', + 'post_id': 51190423, + 'published_at': '2019-08-31 08:29:37', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 12, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': 'devilkman.tuchong.com', + 'followers': 4653, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1303010_3', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '咕哒囧子', + 'site_id': '1303010', + 'type': 'user', + 'url': 'https://devilkman.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1303010', + 'sites': [], + 'tags': [], + 'title': '去年花博会拍的', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://devilkman.tuchong.com/51190423/', + 'views': 27040 + }, + { + 'author_id': '3274149', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 21, + 'content': '秘密花园\n摄影后期:此岸', + 'created_at': '2019-08-14 15:57:26', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '秘密花园\n摄影后期:此岸', + 'favorite_list_prefix': [], + 'favorites': 815, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 198086385, + 'img_id_str': '198086385', + 'title': '001', + 'user_id': 3274149, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 350195257, + 'img_id_str': '350195257', + 'title': '001', + 'user_id': 3274149, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 166629262, + 'img_id_str': '166629262', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 458919916, + 'img_id_str': '458919916', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 404787189, + 'img_id_str': '404787189', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 512790192, + 'img_id_str': '512790192', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 563384313, + 'img_id_str': '563384313', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6000, + 'img_id': 251760421, + 'img_id_str': '251760421', + 'title': '001', + 'user_id': 3274149, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 484347701, + 'img_id_str': '484347701', + 'title': '001', + 'user_id': 3274149, + 'width': 6000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年08月14日', + 'post_id': 49145624, + 'published_at': '2019-08-14 15:57:26', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 13, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 20450, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3274149_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '方叉子', + 'site_id': '3274149', + 'type': 'user', + 'url': 'https://tuchong.com/3274149/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3274149', + 'sites': [], + 'tags': [], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3274149/49145624/', + 'views': 49961 + }, + { + 'author_id': '3262232', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 33, + 'content': '王羽衫', + 'created_at': '2019-07-30 17:18:42', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '王羽衫', + 'favorite_list_prefix': [], + 'favorites': 968, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6463, + 'img_id': 448168437, + 'img_id_str': '448168437', + 'title': '001', + 'user_id': 3262232, + 'width': 4310 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 328630832, + 'img_id_str': '328630832', + 'title': '001', + 'user_id': 3262232, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 85557701, + 'img_id_str': '85557701', + 'title': '001', + 'user_id': 3262232, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 642547982, + 'img_id_str': '642547982', + 'title': '001', + 'user_id': 3262232, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6401, + 'img_id': 540639695, + 'img_id_str': '540639695', + 'title': '001', + 'user_id': 3262232, + 'width': 4267 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 408191476, + 'img_id_str': '408191476', + 'title': '001', + 'user_id': 3262232, + 'width': 4480 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '27', + 'passed_time': '2019年07月30日', + 'post_id': 46927932, + 'published_at': '2019-07-30 17:18:42', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '28', + 'rqt_id': '', + 'shares': 17, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 16485, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3262232_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师刘逸凡', + 'site_id': '3262232', + 'type': 'user', + 'url': 'https://tuchong.com/3262232/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3262232', + 'sites': [], + 'tags': ['人像', '佳能', '少女', '小清新', '日系', '可爱'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3262232/46927932/', + 'views': 39785 + }, + { + 'author_id': '1311838', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': 'PHOTO BY ANDYWAN', + 'created_at': '2020-01-08 02:40:46', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['古典蓝晒作品征集'], + 'excerpt': 'PHOTO BY ANDYWAN', + 'favorite_list_prefix': [], + 'favorites': 33, + 'image_count': 11, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5448, + 'img_id': 603505967, + 'img_id_str': '603505967', + 'title': '', + 'user_id': 1311838, + 'width': 3632 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 608486957, + 'img_id_str': '608486957', + 'title': '', + 'user_id': 1311838, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3073, + 'img_id': 548718112, + 'img_id_str': '548718112', + 'title': '', + 'user_id': 1311838, + 'width': 3073 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3840, + 'img_id': 479119563, + 'img_id_str': '479119563', + 'title': '', + 'user_id': 1311838, + 'width': 5760 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3767, + 'img_id': 572376494, + 'img_id_str': '572376494', + 'title': '', + 'user_id': 1311838, + 'width': 5651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3771, + 'img_id': 361613159, + 'img_id_str': '361613159', + 'title': '', + 'user_id': 1311838, + 'width': 5656 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3479, + 'img_id': 162121031, + 'img_id_str': '162121031', + 'title': '', + 'user_id': 1311838, + 'width': 5218 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3689, + 'img_id': 53593512, + 'img_id_str': '53593512', + 'title': '', + 'user_id': 1311838, + 'width': 5533 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3555, + 'img_id': 412468559, + 'img_id_str': '412468559', + 'title': '', + 'user_id': 1311838, + 'width': 5332 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5476, + 'img_id': 653379260, + 'img_id_str': '653379260', + 'title': '', + 'user_id': 1311838, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 357877258, + 'img_id_str': '357877258', + 'title': '', + 'user_id': 1311838, + 'width': 3840 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月08日', + 'post_id': 61504851, + 'published_at': '2020-01-08 02:40:46', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'andywan.tuchong.com', + 'followers': 682, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1311838_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '安迪andywan', + 'site_id': '1311838', + 'type': 'user', + 'url': 'https://andywan.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1311838', + 'sites': [], + 'tags': ['古典蓝晒作品征集', '人像', '色彩', '女孩', '写真'], + 'title': '沉醉于深蓝之海', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://andywan.tuchong.com/61504851/', + 'views': 1193 + }, + { + 'author_id': '388420', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 69, + 'content': '璀璨入梦,星光入海。\n出镜:鲸鱼\n出品:有映画工作室', + 'created_at': '2019-12-05 16:37:29', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '璀璨入梦,星光入海。\n出镜:鲸鱼\n出品:有映画工作室', + 'favorite_list_prefix': [], + 'favorites': 985, + 'image_count': 17, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 250397277, + 'img_id_str': '250397277', + 'title': '', + 'user_id': 388420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 215007504, + 'img_id_str': '215007504', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 245547635, + 'img_id_str': '245547635', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 434291176, + 'img_id_str': '434291176', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 221430317, + 'img_id_str': '221430317', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 337298007, + 'img_id_str': '337298007', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 223723662, + 'img_id_str': '223723662', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 200065785, + 'img_id_str': '200065785', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 209568402, + 'img_id_str': '209568402', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 46187254, + 'img_id_str': '46187254', + 'title': '', + 'user_id': 388420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 309576983, + 'img_id_str': '309576983', + 'title': '', + 'user_id': 388420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 238142088, + 'img_id_str': '238142088', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 359449438, + 'img_id_str': '359449438', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 226476611, + 'img_id_str': '226476611', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 263963612, + 'img_id_str': '263963612', + 'title': '', + 'user_id': 388420, + 'width': 1200 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1199, + 'img_id': 454279699, + 'img_id_str': '454279699', + 'title': '', + 'user_id': 388420, + 'width': 800 + }, + { + 'description': '', + 'excerpt': '', + 'height': 800, + 'img_id': 135315905, + 'img_id_str': '135315905', + 'title': '', + 'user_id': 388420, + 'width': 1200 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '55', + 'passed_time': '2019年12月05日', + 'post_id': 59924656, + 'published_at': '2019-12-05 16:37:29', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 30, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'zwyoyi.tuchong.com', + 'followers': 9535, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_388420_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '游弋yoyi', + 'site_id': '388420', + 'type': 'user', + 'url': 'https://zwyoyi.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '388420', + 'sites': [], + 'tags': ['人像', '美女', '海边', '日落', '烟花'], + 'title': '【有映画】星海', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://zwyoyi.tuchong.com/59924656/', + 'views': 32745 + }, + { + 'author_id': '2574940', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 44, + 'content': '', + 'created_at': '2019-11-08 12:27:50', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 1062, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 591706813, + 'img_id_str': '591706813', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 287881850, + 'img_id_str': '287881850', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4333, + 'img_id': 351910885, + 'img_id_str': '351910885', + 'title': '', + 'user_id': 2574940, + 'width': 6499 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6558, + 'img_id': 614972223, + 'img_id_str': '614972223', + 'title': '', + 'user_id': 2574940, + 'width': 4372 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 148945675, + 'img_id_str': '148945675', + 'title': '', + 'user_id': 2574940, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 257997289, + 'img_id_str': '257997289', + 'title': '', + 'user_id': 2574940, + 'width': 6720 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6720, + 'img_id': 293387692, + 'img_id_str': '293387692', + 'title': '', + 'user_id': 2574940, + 'width': 4480 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3188, + 'img_id': 434944824, + 'img_id_str': '434944824', + 'title': '', + 'user_id': 2574940, + 'width': 4813 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4928, + 'img_id': 338869040, + 'img_id_str': '338869040', + 'title': '', + 'user_id': 2574940, + 'width': 3264 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '42', + 'passed_time': '2019年11月08日', + 'post_id': 58071420, + 'published_at': '2019-11-08 12:27:50', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '19', + 'rqt_id': '', + 'shares': 40, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'mixmico.tuchong.com', + 'followers': 48506, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2574940_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'MixMico米扣', + 'site_id': '2574940', + 'type': 'user', + 'url': 'https://mixmico.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2574940', + 'sites': [], + 'tags': ['人像', '色彩', '写真', '少女', '女孩', '小清新'], + 'title': '少女A', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://mixmico.tuchong.com/58071420/', + 'views': 60357 + }, + { + 'author_id': '3738183', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 96, + 'content': '分享一下我的客人', + 'created_at': '2019-10-24 19:17:17', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['高颜值女神聚集地'], + 'excerpt': '分享一下我的客人', + 'favorite_list_prefix': [], + 'favorites': 2113, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 188594039, + 'img_id_str': '188594039', + 'title': '821493', + 'user_id': 3738183, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1504, + 'img_id': 184137181, + 'img_id_str': '184137181', + 'title': '836714', + 'user_id': 3738183, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1620, + 'img_id': 157333128, + 'img_id_str': '157333128', + 'title': '821491', + 'user_id': 3738183, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1504, + 'img_id': 630503029, + 'img_id_str': '630503029', + 'title': '821492', + 'user_id': 3738183, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '91', + 'passed_time': '2019年10月24日', + 'post_id': 56829592, + 'published_at': '2019-10-24 19:17:17', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 83, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 15518, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3738183_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '钟月月', + 'site_id': '3738183', + 'type': 'user', + 'url': 'https://tuchong.com/3738183/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3738183', + 'sites': [], + 'tags': ['高颜值女神聚集地', '人像', '日系'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3738183/56829592/', + 'views': 88274 + }, + { + 'author_id': '1827482', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '', + 'created_at': '2019-10-01 01:55:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['胶片是种情怀'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 415, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 283749100, + 'img_id_str': '283749100', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2067, + 'img_id': 530688758, + 'img_id_str': '530688758', + 'title': '', + 'user_id': 1827482, + 'width': 2067 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 412855019, + 'img_id_str': '412855019', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 281717486, + 'img_id_str': '281717486', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 649178099, + 'img_id_str': '649178099', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 213953472, + 'img_id_str': '213953472', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4875, + 'img_id': 284470057, + 'img_id_str': '284470057', + 'title': '', + 'user_id': 1827482, + 'width': 3250 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 102935246, + 'img_id_str': '102935246', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5477, + 'img_id': 464169886, + 'img_id_str': '464169886', + 'title': '', + 'user_id': 1827482, + 'width': 3651 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '2019年10月01日', + 'post_id': 54102726, + 'published_at': '2019-10-01 01:55:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 6, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'j-leonardo.tuchong.com', + 'followers': 6303, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1827482_5', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '空镜Titanium', + 'site_id': '1827482', + 'type': 'user', + 'url': 'https://j-leonardo.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1827482', + 'sites': [], + 'tags': ['胶片是种情怀', '色彩', '人像', '胶片', '复古'], + 'title': '【鱼】', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://j-leonardo.tuchong.com/54102726/', + 'views': 17417 + }, + { + 'author_id': '3262232', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 22, + 'content': '王羽衫', + 'created_at': '2019-08-03 17:59:18', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '王羽衫', + 'favorite_list_prefix': [], + 'favorites': 700, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2176, + 'img_id': 300975187, + 'img_id_str': '300975187', + 'title': '001', + 'user_id': 3262232, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 46957875, + 'img_id_str': '46957875', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2176, + 'img_id': 327058864, + 'img_id_str': '327058864', + 'title': '001', + 'user_id': 3262232, + 'width': 3264 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 637961569, + 'img_id_str': '637961569', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 589399637, + 'img_id_str': '589399637', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 291734632, + 'img_id_str': '291734632', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 359957699, + 'img_id_str': '359957699', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 99255536, + 'img_id_str': '99255536', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3264, + 'img_id': 384730558, + 'img_id_str': '384730558', + 'title': '001', + 'user_id': 3262232, + 'width': 2176 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '20', + 'passed_time': '2019年08月03日', + 'post_id': 47505333, + 'published_at': '2019-08-03 17:59:18', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '15', + 'rqt_id': '', + 'shares': 20, + 'site': { + 'description': '资深Cosplay摄影师', + 'domain': '', + 'followers': 16485, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_3262232_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师刘逸凡', + 'site_id': '3262232', + 'type': 'user', + 'url': 'https://tuchong.com/3262232/', + 'verification_list': [ + {'verification_reason': '资深Cosplay摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '3262232', + 'sites': [], + 'tags': ['人像', '佳能', '色彩', '少女', '小清新', '日系'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/3262232/47505333/', + 'views': 26897 + }, + { + 'author_id': '10592504', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 60, + 'content': '夜空', + 'created_at': '2019-08-01 21:52:54', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '夜空', + 'favorite_list_prefix': [], + 'favorites': 1296, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 2304, + 'img_id': 151290718, + 'img_id_str': '151290718', + 'title': '001', + 'user_id': 10592504, + 'width': 2304 + }, + { + 'description': '', + 'excerpt': '', + 'height': 613, + 'img_id': 147424094, + 'img_id_str': '147424094', + 'title': '001', + 'user_id': 10592504, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1152, + 'img_id': 211846183, + 'img_id_str': '211846183', + 'title': '001', + 'user_id': 10592504, + 'width': 1728 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1428, + 'img_id': 255361990, + 'img_id_str': '255361990', + 'title': '001', + 'user_id': 10592504, + 'width': 2540 + }, + { + 'description': '', + 'excerpt': '', + 'height': 813, + 'img_id': 297698021, + 'img_id_str': '297698021', + 'title': '001', + 'user_id': 10592504, + 'width': 1518 + }, + { + 'description': '', + 'excerpt': '', + 'height': 972, + 'img_id': 507216814, + 'img_id_str': '507216814', + 'title': '001', + 'user_id': 10592504, + 'width': 1728 + }, + { + 'description': '', + 'excerpt': '', + 'height': 960, + 'img_id': 635404931, + 'img_id_str': '635404931', + 'title': '001', + 'user_id': 10592504, + 'width': 1440 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1152, + 'img_id': 147162286, + 'img_id_str': '147162286', + 'title': '001', + 'user_id': 10592504, + 'width': 1152 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1152, + 'img_id': 343901477, + 'img_id_str': '343901477', + 'title': '001', + 'user_id': 10592504, + 'width': 1152 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '59', + 'passed_time': '2019年08月01日', + 'post_id': 47259435, + 'published_at': '2019-08-01 21:52:54', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 34, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12006, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_10592504_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '摄影师陌年', + 'site_id': '10592504', + 'type': 'user', + 'url': 'https://tuchong.com/10592504/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '10592504', + 'sites': [], + 'tags': ['人像', '海滩', '写真', '美女人像', '人像摄影', '夜景人像'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/10592504/47259435/', + 'views': 58292 + }, + { + 'author_id': '1413882', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 20, + 'content': 'girl and snack', + 'created_at': '2019-11-30 12:04:28', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '驚鴻·一眸', + '写真人像摄影', + '成都约拍圈子', + '成都人像爱好者', + '高颜值女神聚集地', + '日系集', + '分享神仙颜值' + ], + 'excerpt': 'girl and snack', + 'favorite_list_prefix': [], + 'favorites': 335, + 'image_count': 6, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3666, + 'img_id': 469352787, + 'img_id_str': '469352787', + 'title': '001', + 'user_id': 1413882, + 'width': 5499 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5320, + 'img_id': 412205535, + 'img_id_str': '412205535', + 'title': '001', + 'user_id': 1413882, + 'width': 3547 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5186, + 'img_id': 638763146, + 'img_id_str': '638763146', + 'title': '001', + 'user_id': 1413882, + 'width': 3457 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5688, + 'img_id': 186237318, + 'img_id_str': '186237318', + 'title': '001', + 'user_id': 1413882, + 'width': 3792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 508281036, + 'img_id_str': '508281036', + 'title': '001', + 'user_id': 1413882, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4513, + 'img_id': 221691930, + 'img_id_str': '221691930', + 'title': '001', + 'user_id': 1413882, + 'width': 3009 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '20', + 'passed_time': '2019年11月30日', + 'post_id': 59609903, + 'published_at': '2019-11-30 12:04:28', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 7, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 2548, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1413882_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': 'Batkid', + 'site_id': '1413882', + 'type': 'user', + 'url': 'https://tuchong.com/1413882/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1413882', + 'sites': [], + 'tags': ['驚鴻·一眸', '写真人像摄影', '成都约拍圈子', '成都人像爱好者', '高颜值女神聚集地', '日系集'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1413882/59609903/', + 'views': 13186 + }, + { + 'author_id': '490904', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 37, + 'content': '星河滚烫,你是人间理想', + 'created_at': '2019-11-17 19:57:57', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '冷色调人像', + '有温度的人像', + '人像写真摄影约拍', + '分享神仙颜值', + '驚鴻·一眸', + '约拍馆摄影作品投稿', + '糖水人像小组', + '人像爱好者', + '河北摄影圈', + '高颜值女神聚集地' + ], + 'excerpt': '星河滚烫,你是人间理想', + 'favorite_list_prefix': [], + 'favorites': 1266, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 461749811, + 'img_id_str': '461749811', + 'title': '1130431', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 583122316, + 'img_id_str': '583122316', + 'title': '1130433', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 234274446, + 'img_id_str': '234274446', + 'title': '1130425', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 111394458, + 'img_id_str': '111394458', + 'title': '1130428', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 177782842, + 'img_id_str': '177782842', + 'title': '1130427', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 154779232, + 'img_id_str': '154779232', + 'title': '1130430', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 85704816, + 'img_id_str': '85704816', + 'title': '1130426', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 443989844, + 'img_id_str': '443989844', + 'title': '1130432', + 'user_id': 490904, + 'width': 1000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1500, + 'img_id': 42188213, + 'img_id_str': '42188213', + 'title': '1130429', + 'user_id': 490904, + 'width': 1000 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '37', + 'passed_time': '2019年11月17日', + 'post_id': 58769071, + 'published_at': '2019-11-17 19:57:57', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 48, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 12649, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_490904_8', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '摄影师CAT', + 'site_id': '490904', + 'type': 'user', + 'url': 'https://tuchong.com/490904/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '490904', + 'sites': [], + 'tags': ['冷色调人像', '有温度的人像', '人像写真摄影约拍', '分享神仙颜值', '驚鴻·一眸', '约拍馆摄影作品投稿'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/490904/58769071/', + 'views': 39431 + }, + { + 'author_id': '1124419', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 19, + 'content': '', + 'created_at': '2019-10-28 15:43:07', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 397, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5792, + 'img_id': 364426855, + 'img_id_str': '364426855', + 'title': '', + 'user_id': 1124419, + 'width': 8688 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 135444506, + 'img_id_str': '135444506', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4930, + 'img_id': 273397522, + 'img_id_str': '273397522', + 'title': '', + 'user_id': 1124419, + 'width': 7395 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 317896303, + 'img_id_str': '317896303', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5615, + 'img_id': 412727302, + 'img_id_str': '412727302', + 'title': '', + 'user_id': 1124419, + 'width': 8423 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 469808894, + 'img_id_str': '469808894', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 306755106, + 'img_id_str': '306755106', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 281131082, + 'img_id_str': '281131082', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8688, + 'img_id': 601798555, + 'img_id_str': '601798555', + 'title': '', + 'user_id': 1124419, + 'width': 5792 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '19', + 'passed_time': '2019年10月28日', + 'post_id': 57176330, + 'published_at': '2019-10-28 15:43:07', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 9, + 'site': { + 'description': '资深人像摄影师', + 'domain': '215447352.tuchong.com', + 'followers': 9016, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1124419_3', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '夏雨天的X视界', + 'site_id': '1124419', + 'type': 'user', + 'url': 'https://215447352.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1124419', + 'sites': [], + 'tags': ['美腿', '长腿', '红色高跟鞋', '旗袍', '适马', '135art'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://215447352.tuchong.com/57176330/', + 'views': 11392 + }, + { + 'author_id': '1844143', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 10, + 'content': '#contracted#', + 'created_at': '2019-10-23 15:33:31', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '#contracted#', + 'favorite_list_prefix': [], + 'favorites': 301, + 'image_count': 5, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 491959937, + 'img_id_str': '491959937', + 'title': '3686306', + 'user_id': 1844143, + 'width': 2984 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3922, + 'img_id': 362656734, + 'img_id_str': '362656734', + 'title': '3686305', + 'user_id': 1844143, + 'width': 2812 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 82818717, + 'img_id_str': '82818717', + 'title': '3686317', + 'user_id': 1844143, + 'width': 2984 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 465745930, + 'img_id_str': '465745930', + 'title': '3686319', + 'user_id': 1844143, + 'width': 2984 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4480, + 'img_id': 268940861, + 'img_id_str': '268940861', + 'title': '3686318', + 'user_id': 1844143, + 'width': 2984 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '10', + 'passed_time': '2019年10月23日', + 'post_id': 56729678, + 'published_at': '2019-10-23 15:33:31', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 8, + 'site': { + 'description': '', + 'domain': '', + 'followers': 3469, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1844143_4', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'Glong_Q', + 'site_id': '1844143', + 'type': 'user', + 'url': 'https://tuchong.com/1844143/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1844143', + 'sites': [], + 'tags': ['优雅', '女人', '女孩', '人像', '工作室', '时尚'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1844143/56729678/', + 'views': 10300 + }, + { + 'author_id': '1409920', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 93, + 'content': '武汉武汉', + 'created_at': '2019-10-20 23:14:52', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['第三届京东摄影金像奖'], + 'excerpt': '武汉武汉', + 'favorite_list_prefix': [], + 'favorites': 1237, + 'image_count': 28, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 493921208, + 'img_id_str': '493921208', + 'title': '001', + 'user_id': 1409920, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3325, + 'img_id': 617965156, + 'img_id_str': '617965156', + 'title': '001', + 'user_id': 1409920, + 'width': 3197 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5168, + 'img_id': 455350227, + 'img_id_str': '455350227', + 'title': '001', + 'user_id': 1409920, + 'width': 4000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3640, + 'img_id': 348497315, + 'img_id_str': '348497315', + 'title': '001', + 'user_id': 1409920, + 'width': 2675 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 579253774, + 'img_id_str': '579253774', + 'title': '001', + 'user_id': 1409920, + 'width': 4051 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5328, + 'img_id': 433491816, + 'img_id_str': '433491816', + 'title': '001', + 'user_id': 1409920, + 'width': 3161 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5186, + 'img_id': 201624800, + 'img_id_str': '201624800', + 'title': '001', + 'user_id': 1409920, + 'width': 3312 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4489, + 'img_id': 522750244, + 'img_id_str': '522750244', + 'title': '001', + 'user_id': 1409920, + 'width': 2918 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3510, + 'img_id': 418799358, + 'img_id_str': '418799358', + 'title': '001', + 'user_id': 1409920, + 'width': 5260 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4927, + 'img_id': 42770833, + 'img_id_str': '42770833', + 'title': '001', + 'user_id': 1409920, + 'width': 2867 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8249, + 'img_id': 171285733, + 'img_id_str': '171285733', + 'title': '001', + 'user_id': 1409920, + 'width': 2732 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4129, + 'img_id': 331326047, + 'img_id_str': '331326047', + 'title': '001', + 'user_id': 1409920, + 'width': 6037 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4571, + 'img_id': 106344646, + 'img_id_str': '106344646', + 'title': '001', + 'user_id': 1409920, + 'width': 3179 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4948, + 'img_id': 332695939, + 'img_id_str': '332695939', + 'title': '001', + 'user_id': 1409920, + 'width': 2718 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8352, + 'img_id': 445035368, + 'img_id_str': '445035368', + 'title': '001', + 'user_id': 1409920, + 'width': 2993 + }, + { + 'description': '', + 'excerpt': '', + 'height': 9343, + 'img_id': 592360546, + 'img_id_str': '592360546', + 'title': '001', + 'user_id': 1409920, + 'width': 2671 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3640, + 'img_id': 390952117, + 'img_id_str': '390952117', + 'title': '001', + 'user_id': 1409920, + 'width': 4699 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3806, + 'img_id': 263353245, + 'img_id_str': '263353245', + 'title': '001', + 'user_id': 1409920, + 'width': 6240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3000, + 'img_id': 220555895, + 'img_id_str': '220555895', + 'title': '001', + 'user_id': 1409920, + 'width': 1026 + }, + { + 'description': '', + 'excerpt': '', + 'height': 8192, + 'img_id': 191870954, + 'img_id_str': '191870954', + 'title': '001', + 'user_id': 1409920, + 'width': 2501 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3454, + 'img_id': 347321582, + 'img_id_str': '347321582', + 'title': '001', + 'user_id': 1409920, + 'width': 4044 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6511, + 'img_id': 477345535, + 'img_id_str': '477345535', + 'title': '001', + 'user_id': 1409920, + 'width': 2458 + }, + { + 'description': '', + 'excerpt': '', + 'height': 4000, + 'img_id': 68465710, + 'img_id_str': '68465710', + 'title': '001', + 'user_id': 1409920, + 'width': 6000 + }, + { + 'description': '', + 'excerpt': '', + 'height': 541, + 'img_id': 155694356, + 'img_id_str': '155694356', + 'title': '001', + 'user_id': 1409920, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 536, + 'img_id': 252294658, + 'img_id_str': '252294658', + 'title': '001', + 'user_id': 1409920, + 'width': 750 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3745, + 'img_id': 123052725, + 'img_id_str': '123052725', + 'title': '001', + 'user_id': 1409920, + 'width': 5445 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5199, + 'img_id': 392017197, + 'img_id_str': '392017197', + 'title': '001', + 'user_id': 1409920, + 'width': 3167 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6047, + 'img_id': 568239704, + 'img_id_str': '568239704', + 'title': '001', + 'user_id': 1409920, + 'width': 4160 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '87', + 'passed_time': '2019年10月20日', + 'post_id': 56507376, + 'published_at': '2019-10-20 23:14:52', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 56, + 'site': { + 'description': '资深风光摄影师', + 'domain': '', + 'followers': 7398, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1409920_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '老白屹_', + 'site_id': '1409920', + 'type': 'user', + 'url': 'https://tuchong.com/1409920/', + 'verification_list': [ + {'verification_reason': '资深风光摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '1409920', + 'sites': [], + 'tags': ['第三届京东摄影金像奖', 'JD看城市'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1409920/56507376/', + 'views': 33253 + }, + { + 'author_id': '2661362', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 45, + 'content': '小言', + 'created_at': '2019-09-26 21:14:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['上海外拍活动'], + 'excerpt': '小言', + 'favorite_list_prefix': [], + 'favorites': 834, + 'image_count': 15, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 480617808, + 'img_id_str': '480617808', + 'title': '001', + 'user_id': 2661362, + 'width': 1239 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1231, + 'img_id': 381986107, + 'img_id_str': '381986107', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 387163067, + 'img_id_str': '387163067', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1260, + 'img_id': 346727742, + 'img_id_str': '346727742', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 134718765, + 'img_id_str': '134718765', + 'title': '001', + 'user_id': 2661362, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1286, + 'img_id': 172991992, + 'img_id_str': '172991992', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 450668015, + 'img_id_str': '450668015', + 'title': '001', + 'user_id': 2661362, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 484484422, + 'img_id_str': '484484422', + 'title': '001', + 'user_id': 2661362, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1281, + 'img_id': 346792956, + 'img_id_str': '346792956', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 301966715, + 'img_id_str': '301966715', + 'title': '001', + 'user_id': 2661362, + 'width': 1306 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 652060066, + 'img_id_str': '652060066', + 'title': '001', + 'user_id': 2661362, + 'width': 1281 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 42247717, + 'img_id_str': '42247717', + 'title': '001', + 'user_id': 2661362, + 'width': 1241 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1315, + 'img_id': 287024176, + 'img_id_str': '287024176', + 'title': '001', + 'user_id': 2661362, + 'width': 1920 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 266511650, + 'img_id_str': '266511650', + 'title': '001', + 'user_id': 2661362, + 'width': 1202 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1920, + 'img_id': 68069170, + 'img_id_str': '68069170', + 'title': '001', + 'user_id': 2661362, + 'width': 1281 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '40', + 'passed_time': '2019年09月26日', + 'post_id': 53649839, + 'published_at': '2019-09-26 21:14:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 20, + 'site': { + 'description': '资深人像摄影师', + 'domain': '18921935500.tuchong.com', + 'followers': 4499, + 'has_everphoto_note': false, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_2661362_2', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '克林', + 'site_id': '2661362', + 'type': 'user', + 'url': 'https://18921935500.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '2661362', + 'sites': [], + 'tags': ['上海外拍活动', '小言', '人像', '美女', '时尚', '黑白'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://18921935500.tuchong.com/53649839/', + 'views': 34955 + }, + { + 'author_id': '35928', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 25, + 'content': '', + 'created_at': '2019-08-03 11:38:14', + 'data_type': 'post', + 'delete': false, + 'event_tags': [], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 643, + 'image_count': 9, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 851, + 'img_id': 353011283, + 'img_id_str': '353011283', + 'title': '', + 'user_id': 35928, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 792, + 'img_id': 126387603, + 'img_id_str': '126387603', + 'title': '', + 'user_id': 35928, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1294, + 'img_id': 607552474, + 'img_id_str': '607552474', + 'title': '', + 'user_id': 35928, + 'width': 859 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1297, + 'img_id': 261064348, + 'img_id_str': '261064348', + 'title': '', + 'user_id': 35928, + 'width': 859 + }, + { + 'description': '', + 'excerpt': '', + 'height': 851, + 'img_id': 178816002, + 'img_id_str': '178816002', + 'title': '', + 'user_id': 35928, + 'width': 1280 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1293, + 'img_id': 452428911, + 'img_id_str': '452428911', + 'title': '', + 'user_id': 35928, + 'width': 975 + }, + { + 'description': '', + 'excerpt': '', + 'height': 756, + 'img_id': 516260924, + 'img_id_str': '516260924', + 'title': '', + 'user_id': 35928, + 'width': 1132 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1297, + 'img_id': 91129279, + 'img_id_str': '91129279', + 'title': '', + 'user_id': 35928, + 'width': 856 + }, + { + 'description': '', + 'excerpt': '', + 'height': 852, + 'img_id': 308249876, + 'img_id_str': '308249876', + 'title': '', + 'user_id': 35928, + 'width': 1280 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '21', + 'passed_time': '2019年08月03日', + 'post_id': 47456212, + 'published_at': '2019-08-03 11:38:14', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 18, + 'site': { + 'description': '资深人像摄影师', + 'domain': 'bubblegirl.tuchong.com', + 'followers': 4235, + 'has_everphoto_note': true, + 'icon': + 'https://sf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_35928_11', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': 'FAYE-HSU', + 'site_id': '35928', + 'type': 'user', + 'url': 'https://bubblegirl.tuchong.com/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '35928', + 'sites': [], + 'tags': ['人像'], + 'title': '小功写真', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://bubblegirl.tuchong.com/47456212/', + 'views': 29048 + }, + { + 'author_id': '15957713', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '延安乾坤湾', + 'created_at': '2020-01-19 15:41:43', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['最满意的风光照'], + 'excerpt': '延安乾坤湾', + 'favorite_list_prefix': [], + 'favorites': 12, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 843, + 'img_id': 654559599, + 'img_id_str': '654559599', + 'title': '001', + 'user_id': 15957713, + 'width': 1125 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '2', + 'passed_time': '01月19日', + 'post_id': 61839750, + 'published_at': '2020-01-19 15:41:43', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '爱摄影的小工程师', + 'domain': '', + 'followers': 19, + 'has_everphoto_note': true, + 'icon': + 'https://lf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15957713_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '萱鲍勃', + 'site_id': '15957713', + 'type': 'user', + 'url': 'https://tuchong.com/15957713/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15957713', + 'sites': [], + 'tags': ['最满意的风光照'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15957713/61839750/', + 'views': 645 + }, + { + 'author_id': '15948532', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '枝繁,叶茂', + 'created_at': '2020-01-19 10:53:34', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['极简主义,少即是多'], + 'excerpt': '枝繁,叶茂', + 'favorite_list_prefix': [], + 'favorites': 11, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1184, + 'img_id': 247383812, + 'img_id_str': '247383812', + 'title': '001', + 'user_id': 15948532, + 'width': 1776 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月19日', + 'post_id': 61833716, + 'published_at': '2020-01-19 10:53:34', + 'recommend': true, + 'recom_type': '', + 'rewardable': false, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '一个脱离了高级趣味的人', + 'domain': '', + 'followers': 14, + 'has_everphoto_note': true, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15948532_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '子跳儿', + 'site_id': '15948532', + 'type': 'user', + 'url': 'https://tuchong.com/15948532/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15948532', + 'sites': [], + 'tags': ['极简主义,少即是多', '静物'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15948532/61833716/', + 'views': 574 + }, + { + 'author_id': '15172887', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 5, + 'content': '', + 'created_at': '2020-01-18 21:42:58', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['河北摄影圈'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 26, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3002, + 'img_id': 138331852, + 'img_id_str': '138331852', + 'title': '16673', + 'user_id': 15172887, + 'width': 4503 + }, + { + 'description': '', + 'excerpt': '', + 'height': 3087, + 'img_id': 594134774, + 'img_id_str': '594134774', + 'title': '16672', + 'user_id': 15172887, + 'width': 4630 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2848, + 'img_id': 163170258, + 'img_id_str': '163170258', + 'title': '16674', + 'user_id': 15172887, + 'width': 4272 + }, + { + 'description': '', + 'excerpt': '', + 'height': 799, + 'img_id': 640403303, + 'img_id_str': '640403303', + 'title': '16675', + 'user_id': 15172887, + 'width': 571 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '5', + 'passed_time': '01月18日', + 'post_id': 61822228, + 'published_at': '2020-01-18 21:42:58', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '河北石家庄(东方森林)', + 'domain': '', + 'followers': 153, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15172887_1', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '东方森林1', + 'site_id': '15172887', + 'type': 'user', + 'url': 'https://tuchong.com/15172887/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15172887', + 'sites': [], + 'tags': ['河北摄影圈'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15172887/61822228/', + 'views': 1069 + }, + { + 'author_id': '1016626', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 6, + 'content': '我在唐古拉山,你呢?(唐古拉山口,此时海拨5000米以上。摄于2016年夏。)', + 'created_at': '2020-01-18 20:28:01', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '南京航空航天大学摄影', + '福建摄影圈', + '极简主义,少即是多', + '驚鴻·一眸', + '火烛一花精品摄影', + '南京大学摄影圈', + '晒晒旅行打卡照', + '行摄部落', + '人像爱好者', + '河北摄影圈' + ], + 'excerpt': '我在唐古拉山,你呢?(唐古拉山口,此时海拨5000米以上。摄于2016年夏。)', + 'favorite_list_prefix': [], + 'favorites': 32, + 'image_count': 2, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 5760, + 'img_id': 182175906, + 'img_id_str': '182175906', + 'title': '001', + 'user_id': 1016626, + 'width': 3840 + }, + { + 'description': '', + 'excerpt': '', + 'height': 5532, + 'img_id': 35243734, + 'img_id_str': '35243734', + 'title': '001', + 'user_id': 1016626, + 'width': 3681 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '3', + 'passed_time': '01月18日', + 'post_id': 61820096, + 'published_at': '2020-01-18 20:28:01', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '不是在路上,就是准备去远方。', + 'domain': '', + 'followers': 47, + 'has_everphoto_note': false, + 'icon': + 'https://lf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_1016626_4', + 'is_bind_everphoto': true, + 'is_following': false, + 'name': '杨乐乐哥', + 'site_id': '1016626', + 'type': 'user', + 'url': 'https://tuchong.com/1016626/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '1016626', + 'sites': [], + 'tags': [ + '南京航空航天大学摄影', + '福建摄影圈', + '极简主义,少即是多', + '驚鴻·一眸', + '火烛一花精品摄影', + '南京大学摄影圈' + ], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/1016626/61820096/', + 'views': 1301 + }, + { + 'author_id': '15946105', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 1, + 'content': '适合郊游的好天气', + 'created_at': '2020-01-18 18:15:24', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['我们都爱日系摄影', '生活小确幸', '云上的日子'], + 'excerpt': '适合郊游的好天气', + 'favorite_list_prefix': [], + 'favorites': 15, + 'image_count': 4, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 4160, + 'img_id': 489670452, + 'img_id_str': '489670452', + 'title': '2155899', + 'user_id': 15946105, + 'width': 6240 + }, + { + 'description': '', + 'excerpt': '', + 'height': 6240, + 'img_id': 95798826, + 'img_id_str': '95798826', + 'title': '2155902', + 'user_id': 15946105, + 'width': 4160 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 565036511, + 'img_id_str': '565036511', + 'title': '2227302', + 'user_id': 15946105, + 'width': 3968 + }, + { + 'description': '', + 'excerpt': '', + 'height': 2976, + 'img_id': 472302966, + 'img_id_str': '472302966', + 'title': '2227300', + 'user_id': 15946105, + 'width': 3968 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61816866, + 'published_at': '2020-01-18 18:15:24', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': 'wb:-青-森', + 'domain': '', + 'followers': 9, + 'has_everphoto_note': true, + 'icon': + 'https://sf3-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15946105_2', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '青森-', + 'site_id': '15946105', + 'type': 'user', + 'url': 'https://tuchong.com/15946105/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15946105', + 'sites': [], + 'tags': ['我们都爱日系摄影', '生活小确幸', '云上的日子', '季节', '公园', '树'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15946105/61816866/', + 'views': 597 + }, + { + 'author_id': '15952461', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 2, + 'content': '', + 'created_at': '2020-01-18 16:55:13', + 'data_type': 'post', + 'delete': false, + 'event_tags': [ + '浙江摄影俱乐部', + '华为摄影爱好者', + '图虫旅行摄影圈子', + '风光摄影圈', + '生活小确幸', + '最满意的风光照', + '杭州风光圈子' + ], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 19, + 'image_count': 1, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 3648, + 'img_id': 63686594, + 'img_id_str': '63686594', + 'title': '896574', + 'user_id': 15952461, + 'width': 2736 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '1', + 'passed_time': '01月18日', + 'post_id': 61815151, + 'published_at': '2020-01-18 16:55:13', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '0', + 'rqt_id': '', + 'shares': 0, + 'site': { + 'description': '', + 'domain': '', + 'followers': 9, + 'has_everphoto_note': true, + 'icon': + 'https://lf1-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_15952461_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '我可是邓紫棋的宝贝呢', + 'site_id': '15952461', + 'type': 'user', + 'url': 'https://tuchong.com/15952461/', + 'verification_list': [], + 'verifications': 0, + 'verified': false + }, + 'site_id': '15952461', + 'sites': [], + 'tags': ['浙江摄影俱乐部', '华为摄影爱好者', '图虫旅行摄影圈子', '风光摄影圈', '生活小确幸', '最满意的风光照'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/15952461/61815151/', + 'views': 778 + }, + { + 'author_id': '7381082', + 'collected': false, + 'comment_list_prefix': [], + 'comments': 44, + 'content': '', + 'created_at': '2019-08-23 09:31:48', + 'data_type': 'post', + 'delete': false, + 'event_tags': ['度假就要去海滩'], + 'excerpt': '', + 'favorite_list_prefix': [], + 'favorites': 958, + 'image_count': 10, + 'images': [ + { + 'description': '', + 'excerpt': '', + 'height': 1611, + 'img_id': 349476280, + 'img_id_str': '349476280', + 'title': '726910', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1617, + 'img_id': 192386263, + 'img_id_str': '192386263', + 'title': '726920', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1603, + 'img_id': 166762337, + 'img_id_str': '166762337', + 'title': '726921', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1598, + 'img_id': 565483041, + 'img_id_str': '565483041', + 'title': '726922', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1614, + 'img_id': 605656784, + 'img_id_str': '605656784', + 'title': '726923', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 708, + 'img_id': 443651882, + 'img_id_str': '443651882', + 'title': '726926', + 'user_id': 7381082, + 'width': 1063 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1599, + 'img_id': 121542087, + 'img_id_str': '121542087', + 'title': '726928', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1613, + 'img_id': 231904857, + 'img_id_str': '231904857', + 'title': '726925', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 703, + 'img_id': 545625928, + 'img_id_str': '545625928', + 'title': '726924', + 'user_id': 7381082, + 'width': 1080 + }, + { + 'description': '', + 'excerpt': '', + 'height': 1608, + 'img_id': 394696269, + 'img_id_str': '394696269', + 'title': '726927', + 'user_id': 7381082, + 'width': 1080 + } + ], + 'is_favorite': false, + 'last_read': null, + 'parent_comments': '40', + 'passed_time': '2019年08月23日', + 'post_id': 50291665, + 'published_at': '2019-08-23 09:31:48', + 'recommend': true, + 'recom_type': '', + 'rewardable': true, + 'reward_list_prefix': [], + 'rewards': '1', + 'rqt_id': '', + 'shares': 24, + 'site': { + 'description': '资深人像摄影师', + 'domain': '', + 'followers': 1885, + 'has_everphoto_note': true, + 'icon': + 'https://sf6-tccdn-tos.pstatp.com/obj/tuchong-avatar/ll_7381082_1', + 'is_bind_everphoto': false, + 'is_following': false, + 'name': '原来是姜雯呀', + 'site_id': '7381082', + 'type': 'user', + 'url': 'https://tuchong.com/7381082/', + 'verification_list': [ + {'verification_reason': '资深人像摄影师', 'verification_type': 13} + ], + 'verifications': 1, + 'verified': true + }, + 'site_id': '7381082', + 'sites': [], + 'tags': ['度假就要去海滩', '瓦特·清新滤镜'], + 'title': '', + 'title_image': null, + 'type': 'multi-photo', + 'update': false, + 'url': 'https://tuchong.com/7381082/50291665/', + 'views': 54356 + } + ], + 'is_history': false, + 'message': '添加成功', + 'more': true, + 'result': 'SUCCESS' +}; + +TuChongSource _mockSource = TuChongSource.fromJson(_mock); +TuChongSource get mockSource => _mockSource; diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_repository.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_repository.dart new file mode 100644 index 0000000..af50cd2 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_repository.dart @@ -0,0 +1,91 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:flutter/foundation.dart'; +import 'package:http_client_helper/http_client_helper.dart'; +import 'package:loading_more_list_library/loading_more_list_library.dart'; + +import 'mock_data.dart'; +import 'tu_chong_source.dart'; + +Future onLikeButtonTap(bool isLiked, TuChongItem item) { + ///send your request here + return Future.delayed(const Duration(milliseconds: 50), () { + item.isFavorite = !item.isFavorite!; + item.favorites = + item.isFavorite! ? item.favorites! + 1 : item.favorites! - 1; + return item.isFavorite!; + }); +} + +class TuChongRepository extends LoadingMoreBase { + TuChongRepository({this.maxLength = 300}); + int _pageIndex = 1; + bool _hasMore = true; + @override + bool get hasMore => _hasMore && length < maxLength; + final int maxLength; + + @override + Future refresh([bool notifyStateChanged = false]) async { + _hasMore = true; + _pageIndex = 1; + + final bool result = await super.refresh(true); + return result; + } + + @override + Future loadData([bool isLoadMoreAction = false]) async { + String url = ''; + if (isEmpty) { + url = 'https://api.tuchong.com/feed-app'; + } else { + final int? lastPostId = this[length - 1].postId; + url = + 'https://api.tuchong.com/feed-app?post_id=$lastPostId&page=$_pageIndex&type=loadmore'; + } + bool isSuccess = false; + try { + //to show loading more clearly, in your app,remove this + // await Future.delayed(const Duration(seconds: 2)); + List? feedList; + if (!kIsWeb) { + final Response result = + await HttpClientHelper.get(Uri.parse(url)) as Response; + feedList = TuChongSource.fromJson( + json.decode(result.body) as Map) + .feedList; + } else { + feedList = mockSource.feedList!.getRange(length, length + 20).toList(); + } + + if (_pageIndex == 1) { + clear(); + } + + for (final TuChongItem item in feedList!) { + if (item.hasImage && !contains(item) && hasMore) { + add(item); + } + } + + _hasMore = feedList.isNotEmpty; + _pageIndex++; + isSuccess = true; + } catch (exception, stack) { + isSuccess = false; + if (kDebugMode) { + print(exception); + + print(stack); + } + } + return isSuccess; + } + + // @override + // Iterable wrapData(Iterable source) { + // return source.where((TuChongItem element) => element.imageCount == 1); + // } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_source.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_source.dart new file mode 100644 index 0000000..bde9c2e --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/data/tu_chong_source.dart @@ -0,0 +1,559 @@ +import 'dart:convert' show json; +import 'dart:math'; +import 'package:flutter/rendering.dart'; + +void tryCatch(Function f) { + try { + f.call(); + } catch (e, stack) { + debugPrint('$e'); + debugPrint('$stack'); + } +} + +T? asT(dynamic value) { + if (value is T) { + return value; + } + if (value != null) { + final String valueS = value.toString(); + if (0 is T) { + return int.tryParse(valueS) as T?; + } else if (0.0 is T) { + return double.tryParse(valueS) as T?; + } else if ('' is T) { + return valueS as T; + } else if (false is T) { + if (valueS == '0' || valueS == '1') { + return (valueS == '1') as T; + } + return (valueS == 'true') as T; + } + } + return null; +} + +class TuChongSource { + TuChongSource({ + this.counts, + this.feedList, + this.isHistory, + this.message, + this.more, + this.result, + }); + + factory TuChongSource.fromJson(Map jsonRes) { + final List? feedList = + jsonRes['feedList'] is List ? [] : null; + if (feedList != null) { + for (final dynamic item in jsonRes['feedList']) { + if (item != null) { + tryCatch(() { + feedList + .add(TuChongItem.fromJson(asT>(item)!)); + }); + } + } + } + + return TuChongSource( + counts: asT(jsonRes['counts']), + feedList: feedList, + isHistory: asT(jsonRes['is_history']), + message: asT(jsonRes['message']), + more: asT(jsonRes['more']), + result: asT(jsonRes['result']), + ); + } + + final int? counts; + final List? feedList; + final bool? isHistory; + final String? message; + final bool? more; + final String? result; + + Map toJson() => { + 'counts': counts, + 'feedList': feedList, + 'is_history': isHistory, + 'message': message, + 'more': more, + 'result': result, + }; + + @override + String toString() { + return json.encode(this); + } +} + +class TuChongItem { + TuChongItem({ + this.authorId, + this.collected, + this.commentListPrefix, + this.comments, + this.content, + this.createdAt, + this.dataType, + this.delete, + this.eventTags, + this.excerpt, + this.favoriteListPrefix, + this.favorites, + this.imageCount, + this.images, + this.isFavorite, + this.parentComments, + this.passedTime, + this.postId, + this.publishedAt, + this.recommend, + this.recomType, + this.rewardable, + this.rewardListPrefix, + this.rewards, + this.rqtId, + this.shares, + this.site, + this.siteId, + this.sites, + this.tags, + this.title, + this.titleImage, + this.type, + this.update, + this.url, + this.views, + this.tagColors, + }); + + factory TuChongItem.fromJson(Map jsonRes) { + final List? commentListPrefix = + jsonRes['comment_list_prefix'] is List ? [] : null; + if (commentListPrefix != null) { + for (final dynamic item in jsonRes['comment_list_prefix']) { + if (item != null) { + tryCatch(() { + commentListPrefix.add(asT(item)); + }); + } + } + } + + final List? eventTags = + jsonRes['event_tags'] is List ? [] : null; + if (eventTags != null) { + for (final dynamic item in jsonRes['event_tags']) { + if (item != null) { + tryCatch(() { + eventTags.add(asT(item)); + }); + } + } + } + + final List? favoriteListPrefix = + jsonRes['favorite_list_prefix'] is List ? [] : null; + if (favoriteListPrefix != null) { + for (final dynamic item in jsonRes['favorite_list_prefix']) { + if (item != null) { + tryCatch(() { + favoriteListPrefix.add(asT(item)); + }); + } + } + } + + final List? images = + jsonRes['images'] is List ? [] : null; + if (images != null) { + for (final dynamic item in jsonRes['images']) { + if (item != null) { + tryCatch(() { + images.add(ImageItem.fromJson(asT>(item)!)); + }); + } + } + } + + final List? rewardListPrefix = + jsonRes['reward_list_prefix'] is List ? [] : null; + if (rewardListPrefix != null) { + for (final dynamic item in jsonRes['reward_list_prefix']) { + if (item != null) { + tryCatch(() { + rewardListPrefix.add(asT(item)); + }); + } + } + } + + final List? sites = jsonRes['sites'] is List ? [] : null; + if (sites != null) { + for (final dynamic item in jsonRes['sites']) { + if (item != null) { + tryCatch(() { + sites.add(asT(item)); + }); + } + } + } + final List tagColors = []; + final List? tags = jsonRes['tags'] is List ? [] : null; + if (tags != null) { + const int maxNum = 6; + for (final dynamic item in jsonRes['tags']) { + if (item != null) { + tryCatch(() { + tags.add(asT(item)); + tagColors.add(Color.fromARGB(255, Random.secure().nextInt(255), + Random.secure().nextInt(255), Random.secure().nextInt(255))); + }); + } + if (tags.length == maxNum) { + break; + } + } + } + + return TuChongItem( + authorId: asT(jsonRes['author_id']), + collected: asT(jsonRes['collected']), + commentListPrefix: commentListPrefix, + comments: asT(jsonRes['comments']), + content: asT(jsonRes['content']), + createdAt: asT(jsonRes['created_at']), + dataType: asT(jsonRes['data_type']), + delete: asT(jsonRes['delete']), + eventTags: eventTags, + excerpt: asT(jsonRes['excerpt']), + favoriteListPrefix: favoriteListPrefix, + favorites: asT(jsonRes['favorites']), + imageCount: asT(jsonRes['image_count']), + images: images, + isFavorite: asT(jsonRes['is_favorite']), + parentComments: asT(jsonRes['parent_comments']), + passedTime: asT(jsonRes['passed_time']), + postId: asT(jsonRes['post_id']), + publishedAt: asT(jsonRes['published_at']), + recommend: asT(jsonRes['recommend']), + recomType: asT(jsonRes['recom_type']), + rewardable: asT(jsonRes['rewardable']), + rewardListPrefix: rewardListPrefix, + rewards: asT(jsonRes['rewards']), + rqtId: asT(jsonRes['rqt_id']), + shares: asT(jsonRes['shares']), + site: Site.fromJson(asT>(jsonRes['site'])!), + siteId: asT(jsonRes['site_id']), + sites: sites, + tags: tags, + tagColors: tagColors, + title: asT(jsonRes['title']), + titleImage: asT(jsonRes['title_image']), + type: asT(jsonRes['type']), + update: asT(jsonRes['update']), + url: asT(jsonRes['url']), + views: asT(jsonRes['views']), + ); + } + + final String? authorId; + final bool? collected; + final List? commentListPrefix; + final int? comments; + final String? content; + final String? createdAt; + final String? dataType; + final bool? delete; + final List? eventTags; + final String? excerpt; + final List? favoriteListPrefix; + int? favorites; + final int? imageCount; + final List? images; + bool? isFavorite; + final String? parentComments; + final String? passedTime; + final int? postId; + final String? publishedAt; + final bool? recommend; + final String? recomType; + final bool? rewardable; + final List? rewardListPrefix; + final String? rewards; + final String? rqtId; + final int? shares; + final Site? site; + final String? siteId; + final List? sites; + final List? tags; + final String? title; + final Object? titleImage; + final String? type; + final bool? update; + final String? url; + final int? views; + final List? tagColors; + bool get hasImage { + return images != null && images!.isNotEmpty; + } + + Size? imageRawSize; + + Size get imageSize { + if (!hasImage) { + return const Size(0, 0); + } + return Size(images![0].width!.toDouble(), images![0].height!.toDouble()); + } + + String get imageUrl { + if (!hasImage) { + return ''; + } + return 'https://photo.tuchong.com/${images![0].userId}/f/${images![0].imgId}.jpg'; + } + + String? get avatarUrl => site!.icon; + + String? get imageTitle { + if (!hasImage) { + return title; + } + + return images![0].title; + } + + String? get imageDescription { + if (!hasImage) { + return content; + } + + return images![0].description; + } + + Map toJson() => { + 'author_id': authorId, + 'collected': collected, + 'comment_list_prefix': commentListPrefix, + 'comments': comments, + 'content': content, + 'created_at': createdAt, + 'data_type': dataType, + 'delete': delete, + 'event_tags': eventTags, + 'excerpt': excerpt, + 'favorite_list_prefix': favoriteListPrefix, + 'favorites': favorites, + 'image_count': imageCount, + 'images': images, + 'is_favorite': isFavorite, + 'parent_comments': parentComments, + 'passed_time': passedTime, + 'post_id': postId, + 'published_at': publishedAt, + 'recommend': recommend, + 'recom_type': recomType, + 'rewardable': rewardable, + 'reward_list_prefix': rewardListPrefix, + 'rewards': rewards, + 'rqt_id': rqtId, + 'shares': shares, + 'site': site, + 'site_id': siteId, + 'sites': sites, + 'tags': tags, + 'title': title, + 'title_image': titleImage, + 'type': type, + 'update': update, + 'url': url, + 'views': views, + }; + + @override + String toString() { + return json.encode(this); + } +} + +class ImageItem { + ImageItem({ + this.description, + this.excerpt, + this.height, + this.imgId, + this.imgIdStr, + this.title, + this.userId, + this.width, + }); + + factory ImageItem.fromJson(Map jsonRes) => ImageItem( + description: asT(jsonRes['description']), + excerpt: asT(jsonRes['excerpt']), + height: asT(jsonRes['height']), + imgId: asT(jsonRes['img_id']), + imgIdStr: asT(jsonRes['img_id_str']), + title: asT(jsonRes['title']), + userId: asT(jsonRes['user_id']), + width: asT(jsonRes['width']), + ); + + final String? description; + final String? excerpt; + final int? height; + final int? imgId; + final String? imgIdStr; + final String? title; + final int? userId; + final int? width; + String get imageUrl { + return 'https://photo.tuchong.com/$userId/f/$imgId.jpg'; + } + // ImageProvider createNetworkImage() { + // return ExtendedNetworkImageProvider(imageUrl); + // } + + // ImageProvider createResizeImage() { + // return ResizeImage(ExtendedNetworkImageProvider(imageUrl), + // width: width ~/ 5, height: height ~/ 5); + // } + + // void clearCache() { + // createNetworkImage().evict(); + // createResizeImage().evict(); + // } + Map toJson() => { + 'description': description, + 'excerpt': excerpt, + 'height': height, + 'img_id': imgId, + 'img_id_str': imgIdStr, + 'title': title, + 'user_id': userId, + 'width': width, + }; + + @override + String toString() { + return json.encode(this); + } +} + +class Site { + Site({ + this.description, + this.domain, + this.followers, + this.hasEverphotoNote, + this.icon, + this.isBindEverphoto, + this.isFollowing, + this.name, + this.siteId, + this.type, + this.url, + this.verificationList, + this.verifications, + this.verified, + }); + + factory Site.fromJson(Map jsonRes) { + final List? verificationList = + jsonRes['verification_list'] is List ? [] : null; + if (verificationList != null) { + for (final dynamic item in jsonRes['verification_list']) { + if (item != null) { + tryCatch(() { + verificationList.add( + VerificationList.fromJson(asT>(item)!)); + }); + } + } + } + + return Site( + description: asT(jsonRes['description']), + domain: asT(jsonRes['domain']), + followers: asT(jsonRes['followers']), + hasEverphotoNote: asT(jsonRes['has_everphoto_note']), + icon: asT(jsonRes['icon']), + isBindEverphoto: asT(jsonRes['is_bind_everphoto']), + isFollowing: asT(jsonRes['is_following']), + name: asT(jsonRes['name']), + siteId: asT(jsonRes['site_id']), + type: asT(jsonRes['type']), + url: asT(jsonRes['url']), + verificationList: verificationList, + verifications: asT(jsonRes['verifications']), + verified: asT(jsonRes['verified']), + ); + } + + final String? description; + final String? domain; + int? followers; + final bool? hasEverphotoNote; + final String? icon; + final bool? isBindEverphoto; + bool? isFollowing; + final String? name; + final String? siteId; + final String? type; + final String? url; + final List? verificationList; + final int? verifications; + final bool? verified; + + Map toJson() => { + 'description': description, + 'domain': domain, + 'followers': followers, + 'has_everphoto_note': hasEverphotoNote, + 'icon': icon, + 'is_bind_everphoto': isBindEverphoto, + 'is_following': isFollowing, + 'name': name, + 'site_id': siteId, + 'type': type, + 'url': url, + 'verification_list': verificationList, + 'verifications': verifications, + 'verified': verified, + }; + + @override + String toString() { + return json.encode(this); + } +} + +class VerificationList { + VerificationList({ + this.verificationReason, + this.verificationType, + }); + + factory VerificationList.fromJson(Map jsonRes) => + VerificationList( + verificationReason: asT(jsonRes['verification_reason']), + verificationType: asT(jsonRes['verification_type']), + ); + + final String? verificationReason; + final int? verificationType; + + Map toJson() => { + 'verification_reason': verificationReason, + 'verification_type': verificationType, + }; + + @override + String toString() { + return json.encode(this); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/example_route.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/example_route.dart new file mode 100644 index 0000000..5abbbd5 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/example_route.dart @@ -0,0 +1,118 @@ +// GENERATED CODE - DO NOT MODIFY MANUALLY +// ************************************************************************** +// Auto generated by https://github.com/fluttercandies/ff_annotation_route +// ************************************************************************** +// fast mode: true +// version: 10.0.9 +// ************************************************************************** +// ignore_for_file: prefer_const_literals_to_create_immutables,unused_local_variable,unused_import,unnecessary_import,unused_shown_name,implementation_imports,duplicate_import +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/widgets.dart'; + +import 'pages/complex/text_demo.dart'; +import 'pages/main_page.dart'; +import 'pages/simple/custom_toolbar.dart'; +import 'pages/simple/no_keyboard.dart'; +import 'pages/simple/selectable_text.dart'; +import 'pages/simple/widget_span.dart'; + +/// Get route settings base on route name, auto generated by https://github.com/fluttercandies/ff_annotation_route +FFRouteSettings getRouteSettings({ + required String name, + Map? arguments, + PageBuilder? notFoundPageBuilder, +}) { + final Map safeArguments = + arguments ?? const {}; + switch (name) { + case 'fluttercandies://CustomToolBar': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => CustomToolBar(), + routeName: 'custom toolbar', + description: 'custom selection toolbar and handles for text field', + exts: { + 'group': 'Simple', + 'order': 0, + }, + ); + case 'fluttercandies://NoKeyboard': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => NoSystemKeyboardDemo( + key: asT( + safeArguments['key'], + ), + ), + routeName: 'no system Keyboard', + description: + 'show how to ignore system keyboard and show custom keyboard', + exts: { + 'group': 'Simple', + 'order': 2, + }, + ); + case 'fluttercandies://SelectableTextDemo': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => SelectableTextDemo(), + routeName: 'SelectableText', + description: 'support SelectableText', + exts: { + 'group': 'Simple', + 'order': 3, + }, + ); + case 'fluttercandies://TextDemo': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => TextDemo(), + routeName: 'text', + description: 'build special text and inline image in text field', + exts: { + 'group': 'Complex', + 'order': 0, + }, + ); + case 'fluttercandies://WidgetSpanDemo': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => WidgetSpanDemo(), + routeName: 'widget span', + description: 'mailbox demo with widgetSpan', + exts: { + 'group': 'Simple', + 'order': 1, + }, + ); + case 'fluttercandies://demogrouppage': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => DemoGroupPage( + keyValue: asT>>( + safeArguments['keyValue'], + )!, + ), + routeName: 'DemoGroupPage', + ); + case 'fluttercandies://mainpage': + return FFRouteSettings( + name: name, + arguments: arguments, + builder: () => MainPage(), + routeName: 'MainPage', + ); + default: + return FFRouteSettings( + name: FFRoute.notFoundName, + routeName: FFRoute.notFoundRouteName, + builder: notFoundPageBuilder ?? () => Container(), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/example_routes.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/example_routes.dart new file mode 100644 index 0000000..36a04db --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/example_routes.dart @@ -0,0 +1,108 @@ +// GENERATED CODE - DO NOT MODIFY MANUALLY +// ************************************************************************** +// Auto generated by https://github.com/fluttercandies/ff_annotation_route +// ************************************************************************** +// fast mode: true +// version: 10.0.9 +// ************************************************************************** +// ignore_for_file: prefer_const_literals_to_create_immutables,unused_local_variable,unused_import,unnecessary_import,unused_shown_name,implementation_imports,duplicate_import +/// The routeNames auto generated by https://github.com/fluttercandies/ff_annotation_route +const List routeNames = [ + 'fluttercandies://CustomToolBar', + 'fluttercandies://NoKeyboard', + 'fluttercandies://SelectableTextDemo', + 'fluttercandies://TextDemo', + 'fluttercandies://WidgetSpanDemo', + 'fluttercandies://demogrouppage', + 'fluttercandies://mainpage', +]; + +/// The routes auto generated by https://github.com/fluttercandies/ff_annotation_route +class Routes { + const Routes._(); + + /// 'custom selection toolbar and handles for text field' + /// + /// [name] : 'fluttercandies://CustomToolBar' + /// + /// [routeName] : 'custom toolbar' + /// + /// [description] : 'custom selection toolbar and handles for text field' + /// + /// [exts] : {'group': 'Simple', 'order': 0} + static const String fluttercandiesCustomToolBar = + 'fluttercandies://CustomToolBar'; + + /// 'show how to ignore system keyboard and show custom keyboard' + /// + /// [name] : 'fluttercandies://NoKeyboard' + /// + /// [routeName] : 'no system Keyboard' + /// + /// [description] : 'show how to ignore system keyboard and show custom keyboard' + /// + /// [constructors] : + /// + /// NoSystemKeyboardDemo : [Key? key] + /// + /// [exts] : {'group': 'Simple', 'order': 2} + static const String fluttercandiesNoKeyboard = 'fluttercandies://NoKeyboard'; + + /// 'support SelectableText' + /// + /// [name] : 'fluttercandies://SelectableTextDemo' + /// + /// [routeName] : 'SelectableText' + /// + /// [description] : 'support SelectableText' + /// + /// [exts] : {'group': 'Simple', 'order': 3} + static const String fluttercandiesSelectableTextDemo = + 'fluttercandies://SelectableTextDemo'; + + /// 'build special text and inline image in text field' + /// + /// [name] : 'fluttercandies://TextDemo' + /// + /// [routeName] : 'text' + /// + /// [description] : 'build special text and inline image in text field' + /// + /// [exts] : {'group': 'Complex', 'order': 0} + static const String fluttercandiesTextDemo = 'fluttercandies://TextDemo'; + + /// 'mailbox demo with widgetSpan' + /// + /// [name] : 'fluttercandies://WidgetSpanDemo' + /// + /// [routeName] : 'widget span' + /// + /// [description] : 'mailbox demo with widgetSpan' + /// + /// [exts] : {'group': 'Simple', 'order': 1} + static const String fluttercandiesWidgetSpanDemo = + 'fluttercandies://WidgetSpanDemo'; + + /// 'DemoGroupPage' + /// + /// [name] : 'fluttercandies://demogrouppage' + /// + /// [routeName] : 'DemoGroupPage' + /// + /// [constructors] : + /// + /// DemoGroupPage : [MapEntry>(required) keyValue] + static const String fluttercandiesDemogrouppage = + 'fluttercandies://demogrouppage'; + + /// 'MainPage' + /// + /// [name] : 'fluttercandies://mainpage' + /// + /// [routeName] : 'MainPage' + /// + /// [constructors] : + /// + /// MainPage : [] + static const String fluttercandiesMainpage = 'fluttercandies://mainpage'; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/generated_plugin_registrant.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/generated_plugin_registrant.dart new file mode 100644 index 0000000..40a0d00 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/generated_plugin_registrant.dart @@ -0,0 +1,17 @@ +// +// Generated file. Do not edit. +// + +// ignore_for_file: directives_ordering +// ignore_for_file: lines_longer_than_80_chars +// ignore_for_file: depend_on_referenced_packages + +import 'package:url_launcher_web/url_launcher_web.dart'; + +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +// ignore: public_member_api_docs +void registerPlugins(Registrar registrar) { + UrlLauncherPlugin.registerWith(registrar); + registrar.registerMessageHandler(); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/main.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/main.dart new file mode 100644 index 0000000..da0258f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/main.dart @@ -0,0 +1,38 @@ +import 'package:example/pages/simple/no_keyboard.dart'; +import 'package:extended_keyboard/extended_keyboard.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; +import 'package:oktoast/oktoast.dart'; +import 'example_route.dart'; +import 'example_routes.dart'; + +Future main() async { + CustomKeyboarBinding(); + await SystemKeyboard().init(); + runApp(MyApp()); +} + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + //EditableText + //TextField + return OKToast( + child: MaterialApp( + title: 'extended_text_field demo', + debugShowCheckedModeBanner: false, + theme: ThemeData( + primarySwatch: Colors.blue, + ), + initialRoute: Routes.fluttercandiesMainpage, + onGenerateRoute: (RouteSettings settings) { + return onGenerateRoute( + settings: settings, + getRouteSettings: getRouteSettings, + ); + }, + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/complex/text_demo.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/complex/text_demo.dart new file mode 100644 index 0000000..fa2a720 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/complex/text_demo.dart @@ -0,0 +1,424 @@ +import 'package:example/common/toggle_button.dart'; +import 'package:example/data/tu_chong_repository.dart'; +import 'package:example/data/tu_chong_source.dart'; +import 'package:example/special_text/at_text.dart'; +import 'package:example/special_text/dollar_text.dart'; +import 'package:example/special_text/emoji_text.dart' as emoji; +import 'package:example/special_text/my_extended_text_selection_controls.dart'; +import 'package:example/special_text/my_special_text_span_builder.dart'; +import 'package:extended_image/extended_image.dart'; +import 'package:extended_keyboard/extended_keyboard.dart'; +import 'package:extended_list/extended_list.dart'; +import 'package:extended_text/extended_text.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:loading_more_list/loading_more_list.dart'; +import 'package:url_launcher/url_launcher.dart'; + +enum KeyboardPanelType { + system, + emoji, + image, + at, + dollar, +} + +@FFRoute( + name: 'fluttercandies://TextDemo', + routeName: 'text', + description: 'build special text and inline image in text field', + exts: { + 'group': 'Complex', + 'order': 0, + }, +) +class TextDemo extends StatefulWidget { + @override + _TextDemoState createState() => _TextDemoState(); +} + +class _TextDemoState extends State { + KeyboardPanelType _keyboardPanelType = KeyboardPanelType.system; + final TextEditingController _textEditingController = TextEditingController(); + final MyTextSelectionControls _myExtendedMaterialTextSelectionControls = + MyTextSelectionControls(); + final GlobalKey _key = + GlobalKey(); + final MySpecialTextSpanBuilder _mySpecialTextSpanBuilder = + MySpecialTextSpanBuilder(); + late TuChongRepository imageList = TuChongRepository(maxLength: 100); + final FocusNode _focusNode = FocusNode(); + + List sessions = [ + '[44] @Dota2 CN dota best dota', + 'yes, you are right [36].', + '大家好,我是拉面,很萌很新 [12].', + '\$Flutter\$. CN dev best dev', + '\$Dota2 Ti9\$. Shanghai,I\'m coming.', + 'error 0 [45] warning 0', + ]; + + Duration duration = const Duration(milliseconds: 300); + + final ScrollController _controller = ScrollController(); + + final CustomKeyboardController _customKeyboardController = + CustomKeyboardController(KeyboardType.system); + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: AppBar( + title: const Text('special text'), + actions: [ + TextButton( + child: const Icon( + Icons.backspace, + color: Colors.white, + ), + onPressed: manualDelete, + ) + ], + ), + body: SafeArea( + bottom: true, + child: GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + _customKeyboardController.unfocus(); + }, + child: KeyboardBuilder( + controller: _customKeyboardController, + resizeToAvoidBottomInset: true, + bodyBuilder: (bool readOnly) => Column( + children: [ + Expanded( + child: ExtendedListView.builder( + extendedListDelegate: const ExtendedListDelegate( + closeToTrailing: true, + ), + controller: _controller, + itemBuilder: (BuildContext context, int index) { + final bool left = index % 2 == 0; + final Image logo = Image.asset( + 'assets/flutter_candies_logo.png', + width: 30.0, + height: 30.0, + ); + //print(sessions[index]); + final Widget text = ExtendedText( + sessions[index], + textAlign: left ? TextAlign.left : TextAlign.right, + specialTextSpanBuilder: _mySpecialTextSpanBuilder, + onSpecialTextTap: (dynamic value) { + if (value.toString().startsWith('\$')) { + launchUrl( + Uri.parse('https://github.com/fluttercandies')); + } else if (value.toString().startsWith('@')) { + launchUrl(Uri.parse('mailto:zmtzawqlp@live.com')); + } + }, + ); + List list = [ + logo, + Expanded(child: text), + Container( + width: 30.0, + ) + ]; + if (!left) { + list = list.reversed.toList(); + } + return Row( + children: list, + ); + }, + padding: const EdgeInsets.only(bottom: 10.0), + reverse: true, + itemCount: sessions.length, + )), + Container( + padding: const EdgeInsets.all(5), + decoration: const BoxDecoration( + border: Border( + top: BorderSide( + color: Colors.blue, + ), + bottom: BorderSide( + color: Colors.blue, + ), + ), + ), + child: Column( + children: [ + ExtendedTextField( + key: _key, + minLines: 1, + maxLines: 2, + showCursor: true, + readOnly: readOnly, + + // StrutStyle get strutStyle { + // if (_strutStyle == null) { + // return StrutStyle.fromTextStyle(style, forceStrutHeight: true); + // } + // return _strutStyle!.inheritFromTextStyle(style); + // } + // default strutStyle is not good for WidgetSpan + strutStyle: const StrutStyle(), + specialTextSpanBuilder: MySpecialTextSpanBuilder( + showAtBackground: true, + ), + controller: _textEditingController, + selectionControls: + _myExtendedMaterialTextSelectionControls, + extendedContextMenuBuilder: + MyTextSelectionControls.defaultContextMenuBuilder, + focusNode: _focusNode, + decoration: InputDecoration( + border: InputBorder.none, + suffixIcon: GestureDetector( + onTap: () { + sendMessage(_textEditingController.text); + _textEditingController.clear(); + }, + child: const Icon(Icons.send), + ), + contentPadding: const EdgeInsets.all(12.0), + ), + onTap: () { + _customKeyboardController.showSystemKeyboard(); + }, + //textDirection: TextDirection.rtl, + ), + Container(height: 1, color: Colors.grey.withOpacity(0.3)), + KeyboardTypeBuilder( + builder: ( + BuildContext context, + CustomKeyboardController controller, + ) => + Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + createToolButton( + Icons.sentiment_very_satisfied, + KeyboardPanelType.emoji, + controller, + ), + createToolButton( + Icons.image, + KeyboardPanelType.image, + controller, + ), + createToolButton( + Icons.call_end, + KeyboardPanelType.at, + controller, + ), + createToolButton( + Icons.attach_money, + KeyboardPanelType.dollar, + controller, + ), + ], + ), + ), + ], + ), + ), + ], + ), + builder: (BuildContext context, double? systemKeyboardHeight) { + return _buildCustomKeyboard(context, systemKeyboardHeight); + }, + ), + ), + ), + ); + } + + Widget createToolButton( + IconData icon, + KeyboardPanelType keyboardPanelType, + CustomKeyboardController controller, + ) { + return ToggleButton( + builder: (bool active) => Icon( + icon, + color: active ? Colors.orange : null, + ), + activeChanged: (bool active) { + _keyboardPanelType = keyboardPanelType; + if (active) { + controller.showCustomKeyboard(); + if (!_focusNode.hasFocus) { + SchedulerBinding.instance + .addPostFrameCallback((Duration timeStamp) { + _focusNode.requestFocus(); + }); + } + } else { + controller.showSystemKeyboard(); + } + }, + active: controller.isCustom && _keyboardPanelType == keyboardPanelType, + ); + } + + void insertText(String text) { + _textEditingController.insertText(text); + + SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { + _key.currentState?.bringIntoView(_textEditingController.selection.base); + }); + } + + void manualDelete() { + final TextSpan oldTextSpan = + _mySpecialTextSpanBuilder.build(_textEditingController.text); + + final TextEditingValue value = + ExtendedTextLibraryUtils.handleSpecialTextSpanDelete( + _textEditingController.deleteText(), + _textEditingController.value, + oldTextSpan, + null, + ); + _textEditingController.value = value; + } + + void sendMessage(String text) { + if (text.isEmpty) { + return; + } + setState(() { + sessions.insert(0, text); + }); + SchedulerBinding.instance.addPostFrameCallback((Duration timeStamp) { + _controller.animateTo( + _controller.position.minScrollExtent, + duration: const Duration(milliseconds: 200), + curve: Curves.easeInOut, + ); + }); + } + + Widget _buildCustomKeyboard( + BuildContext context, + double? systemKeyboardHeight, + ) { + systemKeyboardHeight ??= 346; + + switch (_keyboardPanelType) { + case KeyboardPanelType.emoji: + return SizedBox( + height: systemKeyboardHeight, + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 8, + crossAxisSpacing: 10.0, + mainAxisSpacing: 10.0), + itemBuilder: (BuildContext context, int index) { + return GestureDetector( + child: Image.asset( + emoji.EmojiUitl.instance.emojiMap['[${index + 1}]']!), + behavior: HitTestBehavior.translucent, + onTap: () { + insertText('[${index + 1}]'); + }, + ); + }, + itemCount: emoji.EmojiUitl.instance.emojiMap.length, + padding: const EdgeInsets.all(5.0), + ), + ); + case KeyboardPanelType.image: + return SizedBox( + height: systemKeyboardHeight, + child: LoadingMoreList( + ListConfig( + sourceList: imageList, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 10.0, + mainAxisSpacing: 10.0, + ), + itemBuilder: (BuildContext context, TuChongItem item, int index) { + final String url = item.imageUrl; + return GestureDetector( + behavior: HitTestBehavior.translucent, + onTap: () { + // + + sendMessage( + ""); + }, + child: ExtendedImage.network( + url, + ), + ); + }, + padding: const EdgeInsets.all(5.0), + ), + ), + ); + case KeyboardPanelType.at: + return SizedBox( + height: systemKeyboardHeight, + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 10.0, + mainAxisSpacing: 10.0), + itemBuilder: (BuildContext context, int index) { + final String text = atList[index]; + return GestureDetector( + child: Align( + child: Text(text), + ), + behavior: HitTestBehavior.translucent, + onTap: () { + insertText(text); + }, + ); + }, + itemCount: atList.length, + padding: const EdgeInsets.all(5.0), + ), + ); + case KeyboardPanelType.dollar: + return SizedBox( + height: systemKeyboardHeight, + child: GridView.builder( + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount( + crossAxisCount: 3, + crossAxisSpacing: 10.0, + mainAxisSpacing: 10.0), + itemBuilder: (BuildContext context, int index) { + final String text = dollarList[index]; + return GestureDetector( + child: Align( + child: Text(text.replaceAll('\$', '')), + ), + behavior: HitTestBehavior.translucent, + onTap: () { + insertText(text); + }, + ); + }, + itemCount: dollarList.length, + padding: const EdgeInsets.all(5.0), + ), + ); + default: + return Container(); + } + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/main_page.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/main_page.dart new file mode 100644 index 0000000..eb077b4 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/main_page.dart @@ -0,0 +1,172 @@ +import 'package:collection/collection.dart'; +import 'package:example/example_routes.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +import '../example_route.dart'; +import '../example_routes.dart' as example_routes; + +@FFRoute( + name: 'fluttercandies://mainpage', + routeName: 'MainPage', +) +class MainPage extends StatelessWidget { + MainPage() { + final List routeNames = []; + routeNames.addAll(example_routes.routeNames); + routeNames.remove(Routes.fluttercandiesMainpage); + routeNames.remove(Routes.fluttercandiesDemogrouppage); + routesGroup.addAll(groupBy( + routeNames + .map((String name) => getRouteSettings(name: name)) + .where((FFRouteSettings element) => element.exts != null) + .map((FFRouteSettings e) => DemoRouteResult(e)) + .toList() + ..sort((DemoRouteResult a, DemoRouteResult b) => + b.group!.compareTo(a.group!)), + (DemoRouteResult x) => x.group)); + } + final Map> routesGroup = + >{}; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + // Here we take the value from the MyHomePage object that was created by + // the App.build method, and use it to set our appbar title. + title: const Text('extended_text_field'), + actions: [ + ButtonTheme( + minWidth: 0.0, + padding: const EdgeInsets.symmetric(horizontal: 10.0), + child: TextButton( + child: const Text( + 'Github', + style: TextStyle( + decorationStyle: TextDecorationStyle.solid, + decoration: TextDecoration.underline, + color: Colors.white, + ), + ), + onPressed: () { + launchUrl(Uri.parse( + 'https://github.com/fluttercandies/extended_text_field')); + }, + ), + ), + if (!kIsWeb) + ButtonTheme( + padding: const EdgeInsets.only(right: 10.0), + minWidth: 0.0, + child: TextButton( + child: Image.network( + 'https://pub.idqqimg.com/wpa/images/group.png'), + onPressed: () { + launchUrl(Uri.parse('https://jq.qq.com/?_wv=1027&k=5bcc0gy')); + }, + ), + ) + ], + ), + body: ListView.builder( + itemBuilder: (BuildContext c, int index) { + // final RouteResult page = routes[index]; + final String type = routesGroup.keys.toList()[index]!; + return Container( + margin: const EdgeInsets.all(20.0), + child: GestureDetector( + behavior: HitTestBehavior.translucent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + (index + 1).toString() + '.' + type, + //style: TextStyle(inherit: false), + ), + Text( + '$type demos of extended_text_field', + //page.description, + style: const TextStyle(color: Colors.grey), + ) + ], + ), + onTap: () { + Navigator.pushNamed( + context, + Routes.fluttercandiesDemogrouppage, + arguments: { + 'keyValue': routesGroup.entries.toList()[index], + }, + ); + }, + )); + }, + itemCount: routesGroup.length, + ), + ); + } +} + +@FFRoute( + name: 'fluttercandies://demogrouppage', + routeName: 'DemoGroupPage', +) +class DemoGroupPage extends StatelessWidget { + DemoGroupPage({required MapEntry> keyValue}) + : routes = keyValue.value + ..sort((DemoRouteResult a, DemoRouteResult b) => + a.order!.compareTo(b.order!)), + group = keyValue.key!; + final List routes; + final String group; + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('$group demos'), + ), + body: ListView.builder( + itemBuilder: (BuildContext context, int index) { + final DemoRouteResult page = routes[index]; + return Container( + margin: const EdgeInsets.all(20.0), + child: GestureDetector( + behavior: HitTestBehavior.translucent, + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + (index + 1).toString() + '.' + page.routeResult.routeName!, + //style: TextStyle(inherit: false), + ), + Text( + page.routeResult.description!, + style: const TextStyle(color: Colors.grey), + ) + ], + ), + onTap: () { + Navigator.pushNamed(context, page.routeResult.name!); + }, + ), + ); + }, + itemCount: routes.length, + ), + ); + } +} + +class DemoRouteResult { + DemoRouteResult( + this.routeResult, + ) : order = routeResult.exts!['order'] as int?, + group = routeResult.exts!['group'] as String?; + + final int? order; + final String? group; + final FFRouteSettings routeResult; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/custom_toolbar.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/custom_toolbar.dart new file mode 100644 index 0000000..a9e989b --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/custom_toolbar.dart @@ -0,0 +1,141 @@ +// ignore_for_file: always_put_control_body_on_new_line + +import 'package:example/special_text/my_extended_text_selection_controls.dart'; +import 'package:example/special_text/my_special_text_span_builder.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; + +/// +/// create by zmtzawqlp on 2019/7/31 +/// + +@FFRoute( + name: 'fluttercandies://CustomToolBar', + routeName: 'custom toolbar', + description: 'custom selection toolbar and handles for text field', + exts: { + 'group': 'Simple', + 'order': 0, + }, +) +class CustomToolBar extends StatefulWidget { + @override + _CustomToolBarState createState() => _CustomToolBarState(); +} + +class _CustomToolBarState extends State { + final MyTextSelectionControls _myExtendedMaterialTextSelectionControls = + MyTextSelectionControls(); + final MySpecialTextSpanBuilder _mySpecialTextSpanBuilder = + MySpecialTextSpanBuilder(); + TextEditingController controller = TextEditingController() + ..text = + '[33]Extended text field help you to build rich text quickly. any special text you will have with extended text. this is demo to show how to create custom toolbar and handles.' + '\n\nIt\'s my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[36]' + '\n\nif you meet any problem, please let me konw @zmtzawqlp .[44]'; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('custom selection toolbar handles'), + ), + body: Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Center( + child: ExtendedTextField( + selectionControls: _myExtendedMaterialTextSelectionControls, + specialTextSpanBuilder: _mySpecialTextSpanBuilder, + extendedContextMenuBuilder: + MyTextSelectionControls.defaultContextMenuBuilder, + controller: controller, + maxLines: null, + // StrutStyle get strutStyle { + // if (_strutStyle == null) { + // return StrutStyle.fromTextStyle(style, forceStrutHeight: true); + // } + // return _strutStyle!.inheritFromTextStyle(style); + // } + // default strutStyle is not good for WidgetSpan + strutStyle: const StrutStyle(), + // shouldShowSelectionHandles: _shouldShowSelectionHandles, + // textSelectionGestureDetectorBuilder: ({ + // required ExtendedTextSelectionGestureDetectorBuilderDelegate + // delegate, + // required Function showToolbar, + // required Function hideToolbar, + // required Function? onTap, + // required BuildContext context, + // required Function? requestKeyboard, + // }) { + // return MyCommonTextSelectionGestureDetectorBuilder( + // delegate: delegate, + // showToolbar: showToolbar, + // hideToolbar: hideToolbar, + // onTap: onTap, + // context: context, + // requestKeyboard: requestKeyboard, + // ); + // }, + ), + ), + ), + ); + } + +// bool _shouldShowSelectionHandles( +// SelectionChangedCause? cause, +// CommonTextSelectionGestureDetectorBuilder selectionGestureDetectorBuilder, +// TextEditingValue editingValue, +// ) { +// // When the text field is activated by something that doesn't trigger the +// // selection overlay, we shouldn't show the handles either. + +// // +// // if (!selectionGestureDetectorBuilder.shouldShowSelectionToolbar) +// // return false; + +// if (cause == SelectionChangedCause.keyboard) return false; + +// // if (widget.readOnly && _effectiveController.selection.isCollapsed) +// // return false; + +// // if (!_isEnabled) return false; + +// if (cause == SelectionChangedCause.longPress) return true; + +// if (editingValue.text.isNotEmpty) return true; + +// return false; +// } +} + +// class MyCommonTextSelectionGestureDetectorBuilder +// extends CommonTextSelectionGestureDetectorBuilder { +// MyCommonTextSelectionGestureDetectorBuilder( +// {required ExtendedTextSelectionGestureDetectorBuilderDelegate delegate, +// required Function showToolbar, +// required Function hideToolbar, +// required Function? onTap, +// required BuildContext context, +// required Function? requestKeyboard}) +// : super( +// delegate: delegate, +// showToolbar: showToolbar, +// hideToolbar: hideToolbar, +// onTap: onTap, +// context: context, +// requestKeyboard: requestKeyboard, +// ); +// @override +// void onTapDown(TapDragDownDetails details) { +// super.onTapDown(details); + +// /// always show toolbar +// shouldShowSelectionToolbar = true; +// } + +// @override +// bool get showToolbarInWeb => true; +// } diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/no_keyboard.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/no_keyboard.dart new file mode 100644 index 0000000..49d755b --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/no_keyboard.dart @@ -0,0 +1,430 @@ +import 'package:extended_keyboard/extended_keyboard.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:oktoast/oktoast.dart'; + +class CustomKeyboarBinding extends TextInputBinding with KeyboardBindingMixin { + @override + // ignore: unnecessary_overrides + bool ignoreTextInputShow() { + // you can override it base on your case + // if NoKeyboardFocusNode is not enough + return super.ignoreTextInputShow(); + } +} + +@FFRoute( + name: 'fluttercandies://NoKeyboard', + routeName: 'no system Keyboard', + description: 'show how to ignore system keyboard and show custom keyboard', + exts: { + 'group': 'Simple', + 'order': 2, + }, +) +class NoSystemKeyboardDemo extends StatelessWidget { + const NoSystemKeyboardDemo({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('no system Keyboard'), + ), + body: GestureDetector( + behavior: HitTestBehavior.opaque, + onTap: () { + FocusManager.instance.primaryFocus?.unfocus(); + }, + child: const Padding( + padding: EdgeInsets.all(8.0), + child: Column(children: [ + Text('ExtendedTextField'), + ExtendedTextFieldCase(), + Text('CustomTextField'), + TextFieldCase(), + ]), + ), + ), + ); + } +} + +class ExtendedTextFieldCase extends StatefulWidget { + const ExtendedTextFieldCase({Key? key}) : super(key: key); + + @override + State createState() => _ExtendedTextFieldCaseState(); +} + +class _ExtendedTextFieldCaseState extends State + with CustomKeyboardShowStateMixin { + @override + Widget build(BuildContext context) { + return ExtendedTextField( + // you must use TextInputFocusNode + focusNode: _focusNode..debugLabel = 'ExtendedTextField', + // if your custom keyboard can be close without unfocus + // you can show custom keyboard when TextField onTap + controller: _controller, + maxLines: null, + inputFormatters: _inputFormatters, + ); + } +} + +class TextFieldCase extends StatefulWidget { + const TextFieldCase({Key? key}) : super(key: key); + @override + State createState() => TextFieldCaseState(); +} + +class TextFieldCaseState extends State + with CustomKeyboardShowStateMixin { + @override + Widget build(BuildContext context) { + return TextField( + // you must use TextInputFocusNode + focusNode: _focusNode..debugLabel = 'CustomTextField', + // if your custom keyboard can be close without unfocus + // you can show custom keyboard when TextField onTap + onTap: _onTextFiledTap, + controller: _controller, + inputFormatters: _inputFormatters, + maxLines: null, + ); + } +} + +@optionalTypeArgs +mixin CustomKeyboardShowStateMixin on State { + final TextInputFocusNode _focusNode = TextInputFocusNode(); + final TextEditingController _controller = TextEditingController(); + PersistentBottomSheetController? _bottomSheetController; + + final List _inputFormatters = [ + // digit or decimal + FilteringTextInputFormatter.allow(RegExp(r'[1-9]{1}[0-9.]*')), + // only one decimal + TextInputFormatter.withFunction( + (TextEditingValue oldValue, TextEditingValue newValue) => + newValue.text.indexOf('.') != newValue.text.lastIndexOf('.') + ? oldValue + : newValue), + ]; + + @override + void initState() { + super.initState(); + _focusNode.addListener(_handleFocusChanged); + } + + void _onTextFiledTap() { + if (_bottomSheetController == null) { + _handleFocusChanged(); + } + } + + void _handleFocusChanged() { + if (_focusNode.hasFocus) { + // just demo, you can define your custom keyboard as you want + _bottomSheetController = showBottomSheet( + context: FocusManager.instance.primaryFocus!.context!, + // set false, if don't want to drag to close custom keyboard + enableDrag: true, + builder: (BuildContext b) { + final MediaQueryData mediaQueryData = MediaQuery.of(b); + + return Material( + //shadowColor: Colors.grey, + color: Colors.grey.withOpacity(0.3), + //elevation: 8, + child: Padding( + padding: EdgeInsets.only( + left: 10, + right: 10, + top: 20, + bottom: mediaQueryData.viewPadding.bottom / + mediaQueryData.devicePixelRatio, + ), + child: IntrinsicHeight( + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Expanded( + flex: 15, + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Row( + children: [ + Expanded( + flex: 5, + child: NumberButton( + number: 1, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 2, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 3, + insertText: insertText, + ), + ), + ], + ), + Row( + children: [ + Expanded( + flex: 5, + child: NumberButton( + number: 4, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 5, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 6, + insertText: insertText, + ), + ), + ], + ), + Row( + children: [ + Expanded( + flex: 5, + child: NumberButton( + number: 7, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 8, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 9, + insertText: insertText, + ), + ), + ], + ), + Row( + children: [ + Expanded( + flex: 5, + child: CustomButton( + child: const Text('.'), + onTap: () { + insertText('.'); + }, + ), + ), + Expanded( + flex: 5, + child: NumberButton( + number: 0, + insertText: insertText, + ), + ), + Expanded( + flex: 5, + child: CustomButton( + child: const Icon(Icons.arrow_downward), + onTap: () { + _focusNode.unfocus(); + }, + ), + ), + ], + ), + ], + ), + ), + Expanded( + flex: 7, + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Expanded( + child: CustomButton( + child: const Icon(Icons.backspace), + onTap: () { + manualDelete(); + }, + )), + Expanded( + child: CustomButton( + child: const Icon(Icons.keyboard_return), + onTap: () { + showToast('onSubmitted: ${_controller.text}'); + }, + )) + ], + ), + ), + ], + ), + ), + ), + ); + }); + // maybe drag close + _bottomSheetController?.closed.whenComplete(() { + _bottomSheetController = null; + }); + } else { + _bottomSheetController?.close(); + _bottomSheetController = null; + } + } + + @override + void dispose() { + _focusNode.removeListener(_handleFocusChanged); + super.dispose(); + } + + void insertText(String text) { + final TextEditingValue oldValue = _controller.value; + TextEditingValue newValue = oldValue; + final int start = oldValue.selection.baseOffset; + int end = oldValue.selection.extentOffset; + if (oldValue.selection.isValid) { + String newText = ''; + if (oldValue.selection.isCollapsed) { + if (end > 0) { + newText += oldValue.text.substring(0, end); + } + newText += text; + if (oldValue.text.length > end) { + newText += oldValue.text.substring(end, oldValue.text.length); + } + } else { + newText = oldValue.text.replaceRange(start, end, text); + end = start; + } + + newValue = oldValue.copyWith( + text: newText, + selection: oldValue.selection.copyWith( + baseOffset: end + text.length, extentOffset: end + text.length)); + } else { + newValue = TextEditingValue( + text: text, + selection: + TextSelection.fromPosition(TextPosition(offset: text.length))); + } + for (final TextInputFormatter inputFormatter in _inputFormatters) { + newValue = inputFormatter.formatEditUpdate(oldValue, newValue); + } + + _controller.value = newValue; + } + + void manualDelete() { + //delete by code + final TextEditingValue _value = _controller.value; + final TextSelection selection = _value.selection; + if (!selection.isValid) { + return; + } + + TextEditingValue value; + final String actualText = _value.text; + if (selection.isCollapsed && selection.start == 0) { + return; + } + final int start = + selection.isCollapsed ? selection.start - 1 : selection.start; + final int end = selection.end; + + value = TextEditingValue( + text: actualText.replaceRange(start, end, ''), + selection: TextSelection.collapsed(offset: start), + ); + + _controller.value = value; + } +} + +class NumberButton extends StatelessWidget { + const NumberButton({ + Key? key, + required this.number, + required this.insertText, + }) : super(key: key); + final int number; + final Function(String text) insertText; + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: () { + insertText('$number'); + }, + child: Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + height: 50, + child: Text( + '$number', + ), + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(8), + ), + ), + ); + } +} + +class CustomButton extends StatelessWidget { + const CustomButton({ + Key? key, + required this.child, + required this.onTap, + }) : super(key: key); + final Widget child; + final GestureTapCallback onTap; + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTap, + child: Container( + margin: const EdgeInsets.all(5), + alignment: Alignment.center, + height: 50, + child: child, + decoration: BoxDecoration( + border: Border.all(color: Colors.grey), + borderRadius: BorderRadius.circular(8), + ), + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/selectable_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/selectable_text.dart new file mode 100644 index 0000000..b24aef0 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/selectable_text.dart @@ -0,0 +1,33 @@ +import 'package:example/special_text/my_special_text_span_builder.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; + +@FFRoute( + name: 'fluttercandies://SelectableTextDemo', + routeName: 'SelectableText', + description: 'support SelectableText', + exts: { + 'group': 'Simple', + 'order': 3, + }, +) +class SelectableTextDemo extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('SelectableText'), + ), + body: Container( + padding: const EdgeInsets.all(20.0), + child: ExtendedSelectableText( + '[17]Extended text help you to build rich text quickly. any special text you will have with extended text. ' + '\n\nIt\'s my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[17]' + '\n\nif you meet any problem, please let me know @zmtzawqlp .[36]', + specialTextSpanBuilder: MySpecialTextSpanBuilder(), + ), + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/widget_span.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/widget_span.dart new file mode 100644 index 0000000..b60b5c4 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/pages/simple/widget_span.dart @@ -0,0 +1,194 @@ +import 'package:example/special_text/email_span_builder.dart'; +import 'package:example/special_text/my_special_text_span_builder.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:ff_annotation_route_library/ff_annotation_route_library.dart'; +import 'package:flutter/material.dart'; + +/// +/// create by zmtzawqlp on 2019/8/4 +/// +@FFRoute( + name: 'fluttercandies://WidgetSpanDemo', + routeName: 'widget span', + description: 'mailbox demo with widgetSpan', + exts: { + 'group': 'Simple', + 'order': 1, + }, +) +class WidgetSpanDemo extends StatefulWidget { + @override + _WidgetSpanDemoState createState() => _WidgetSpanDemoState(); +} + +class _WidgetSpanDemoState extends State { + TextEditingController controller = TextEditingController(); + TextEditingController controller1 = TextEditingController(); + TextEditingController controller2 = TextEditingController() + ..text = + '[33]Extended text field help you to build rich text quickly. any special text you will have with extended text field. this is demo to show how to create special text with widget span.' + '\n\nIt\'s my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[36]' + '\n\nif you meet any problem, please let me konw @zmtzawqlp .[44]'; + EmailSpanBuilder? _emailSpanBuilder; + @override + void initState() { + _emailSpanBuilder = EmailSpanBuilder(controller, context); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('E-mail'), + actions: [ + IconButton( + icon: const Icon(Icons.send), + onPressed: () {}, + ) + ], + ), + body: Column( + children: [ + Row( + children: [ + Container( + child: const Text('To : '), + width: 60.0, + padding: const EdgeInsets.only( + left: 10.0, + ), + ), + Expanded( + child: ExtendedTextField( + controller: controller, + specialTextSpanBuilder: _emailSpanBuilder, + maxLines: null, + // StrutStyle get strutStyle { + // if (_strutStyle == null) { + // return StrutStyle.fromTextStyle(style, forceStrutHeight: true); + // } + // return _strutStyle!.inheritFromTextStyle(style); + // } + // default strutStyle is not good for WidgetSpan + strutStyle: const StrutStyle(), + decoration: InputDecoration( + suffixIcon: IconButton( + icon: const Icon(Icons.add), + onPressed: () { + final TextSelection selection = + controller.selection.copyWith(); + showDialog( + context: context, + barrierDismissible: true, + builder: (BuildContext c) { + return Column( + children: [ + Flexible( + child: Container(), + ), + Expanded( + child: Material( + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + TextButton( + onPressed: () { + insertEmail( + 'zmtzawqlp@live.com ', + selection); + Navigator.pop(context); + }, + child: const Text( + 'zmtzawqlp@live.com')), + TextButton( + onPressed: () { + insertEmail( + '410496936@qq.com ', + selection); + Navigator.pop(context); + }, + child: const Text( + '410496936@qq.com')), + ], + ), + )), + ), + Flexible( + child: Container(), + ) + ], + ); + }); + }, + ), + border: InputBorder.none, + hintText: 'input receiver here'), + ), + ), + ], + ), + const Divider(), + Row( + children: [ + Container( + child: const Text('Topic : '), + width: 60.0, + padding: const EdgeInsets.only(left: 10.0), + ), + Expanded( + child: ExtendedTextField( + controller: controller1, + maxLines: null, + decoration: const InputDecoration( + border: InputBorder.none, hintText: 'input topic here'), + ), + ) + ], + ), + const Divider(), + Expanded( + child: ExtendedTextField( + controller: controller2, + maxLines: null, + specialTextSpanBuilder: MySpecialTextSpanBuilder(), + decoration: const InputDecoration( + border: InputBorder.none, contentPadding: EdgeInsets.all(10)), + ), + ) + ], + ), + ); + } + + void insertEmail(String text, TextSelection selection) { + final TextEditingValue value = controller.value; + final int start = selection.baseOffset; + int end = selection.extentOffset; + if (selection.isValid) { + String newText = ''; + if (value.selection.isCollapsed) { + if (end > 0) { + newText += value.text.substring(0, end); + } + newText += text; + if (value.text.length > end) { + newText += value.text.substring(end, value.text.length); + } + } else { + newText = value.text.replaceRange(start, end, text); + end = start; + } + controller.value = value.copyWith( + text: newText, + selection: selection.copyWith( + baseOffset: end + text.length, extentOffset: end + text.length)); + } else { + controller.value = TextEditingValue( + text: text, + selection: + TextSelection.fromPosition(TextPosition(offset: text.length))); + } + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/at_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/at_text.dart new file mode 100644 index 0000000..d80ab3e --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/at_text.dart @@ -0,0 +1,62 @@ +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +class AtText extends SpecialText { + AtText(TextStyle? textStyle, SpecialTextGestureTapCallback? onTap, + {this.showAtBackground = false, this.start}) + : super(flag, ' ', textStyle, onTap: onTap); + static const String flag = '@'; + final int? start; + + /// whether show background for @somebody + final bool showAtBackground; + + @override + InlineSpan finishText() { + final TextStyle? textStyle = + this.textStyle?.copyWith(color: Colors.blue, fontSize: 16.0); + + final String atText = toString(); + + return showAtBackground + ? BackgroundTextSpan( + background: Paint()..color = Colors.blue.withOpacity(0.15), + text: atText, + actualText: atText, + start: start!, + + ///caret can move into special text + deleteAll: true, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) { + onTap!(atText); + } + })) + : SpecialTextSpan( + text: atText, + actualText: atText, + start: start!, + style: textStyle, + recognizer: (TapGestureRecognizer() + ..onTap = () { + if (onTap != null) { + onTap!(atText); + } + })); + } +} + +List atList = [ + '@Nevermore ', + '@Dota2 ', + '@Biglao ', + '@艾莉亚·史塔克 ', + '@丹妮莉丝 ', + '@HandPulledNoodles ', + '@Zmtzawqlp ', + '@FaDeKongJian ', + '@CaiJingLongDaLao ', +]; diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/dollar_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/dollar_text.dart new file mode 100644 index 0000000..989feae --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/dollar_text.dart @@ -0,0 +1,43 @@ +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; + +class DollarText extends SpecialText { + DollarText(TextStyle? textStyle, SpecialTextGestureTapCallback? onTap, + {this.start}) + : super(flag, flag, textStyle, onTap: onTap); + static const String flag = '\$'; + final int? start; + @override + InlineSpan finishText() { + final String text = getContent(); + + return SpecialTextSpan( + text: text, + actualText: toString(), + start: start!, + + ///caret can move into special text + deleteAll: true, + style: textStyle?.copyWith(color: Colors.orange), + recognizer: TapGestureRecognizer() + ..onTap = () { + if (onTap != null) { + onTap!(toString()); + } + }); + } +} + +List dollarList = [ + '\$Dota2\$', + '\$Dota2 Ti9\$', + '\$CN dota best dota\$', + '\$Flutter\$', + '\$CN dev best dev\$', + '\$UWP\$', + '\$Nevermore\$', + '\$FlutterCandies\$', + '\$ExtendedImage\$', + '\$ExtendedText\$', +]; diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_span_builder.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_span_builder.dart new file mode 100644 index 0000000..06aab1c --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_span_builder.dart @@ -0,0 +1,32 @@ +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/material.dart'; + +import 'email_text.dart'; + +/// +/// create by zmtzawqlp on 2019/8/4 +/// + +class EmailSpanBuilder extends SpecialTextSpanBuilder { + EmailSpanBuilder(this.controller, this.context); + final TextEditingController controller; + final BuildContext context; + @override + SpecialText? createSpecialText(String flag, + {TextStyle? textStyle, + SpecialTextGestureTapCallback? onTap, + int? index}) { + if (flag == '') { + return null; + } + + if (!flag.startsWith(' ') && !flag.startsWith('@')) { + return EmailText(textStyle!, onTap, + start: index, + context: context, + controller: controller, + startFlag: flag); + } + return null; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_text.dart new file mode 100644 index 0000000..47c47cb --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/email_text.dart @@ -0,0 +1,115 @@ +import 'dart:ui' as ui show PlaceholderAlignment; +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/material.dart'; + +class EmailText extends SpecialText { + EmailText(TextStyle textStyle, SpecialTextGestureTapCallback? onTap, + {this.start, this.controller, this.context, required String startFlag}) + : super(startFlag, ' ', textStyle, onTap: onTap); + final TextEditingController? controller; + final int? start; + final BuildContext? context; + @override + bool isEnd(String value) { + final int index = value.indexOf('@'); + final int index1 = value.indexOf('.'); + + return index >= 0 && + index1 >= 0 && + index1 > index + 1 && + super.isEnd(value); + } + + @override + InlineSpan finishText() { + final String text = toString(); + + return ExtendedWidgetSpan( + actualText: text, + start: start!, + alignment: ui.PlaceholderAlignment.middle, + child: GestureDetector( + child: Padding( + padding: const EdgeInsets.only(right: 5.0, top: 2.0, bottom: 2.0), + child: ClipRRect( + borderRadius: const BorderRadius.all(Radius.circular(5.0)), + child: Container( + padding: const EdgeInsets.all(5.0), + color: Colors.orange, + child: Row( + mainAxisAlignment: MainAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + Text( + text.trim(), + //style: textStyle?.copyWith(color: Colors.orange), + ), + const SizedBox( + width: 5.0, + ), + InkWell( + child: const Icon( + Icons.close, + size: 15.0, + ), + onTap: () { + controller!.value = controller!.value.copyWith( + text: controller!.text + .replaceRange(start!, start! + text.length, ''), + selection: TextSelection.fromPosition( + TextPosition(offset: start!))); + }, + ) + ], + ), + )), + ), + onTap: () { + showDialog( + context: context!, + barrierDismissible: true, + builder: (BuildContext c) { + final TextEditingController textEditingController = + TextEditingController()..text = text.trim(); + return Column( + children: [ + Expanded( + child: Container(), + ), + Material( + child: Padding( + padding: const EdgeInsets.all(10.0), + child: TextField( + controller: textEditingController, + decoration: InputDecoration( + suffixIcon: TextButton( + child: const Text('OK'), + onPressed: () { + controller!.value = controller!.value.copyWith( + text: controller!.text.replaceRange( + start!, + start! + text.length, + textEditingController.text + ' '), + selection: TextSelection.fromPosition( + TextPosition( + offset: start! + + (textEditingController.text + ' ') + .length))); + + Navigator.pop(context!); + }, + )), + ), + )), + Expanded( + child: Container(), + ) + ], + ); + }); + }, + ), + deleteAll: true, + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/emoji_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/emoji_text.dart new file mode 100644 index 0000000..8181291 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/emoji_text.dart @@ -0,0 +1,52 @@ +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/material.dart'; + +///emoji/image text +class EmojiText extends SpecialText { + EmojiText(TextStyle? textStyle, {this.start}) + : super(EmojiText.flag, ']', textStyle); + static const String flag = '['; + final int? start; + @override + InlineSpan finishText() { + final String key = toString(); + + if (EmojiUitl.instance.emojiMap.containsKey(key)) { + double size = 18; + + if (textStyle?.fontSize != null) { + size = textStyle!.fontSize! * 1.15; + } + + return ImageSpan( + AssetImage( + EmojiUitl.instance.emojiMap[key]!, + ), + actualText: key, + imageWidth: size, + imageHeight: size, + start: start!, + //fit: BoxFit.fill, + margin: const EdgeInsets.all(2)); + } + + return TextSpan(text: toString(), style: textStyle); + } +} + +class EmojiUitl { + EmojiUitl._() { + for (int i = 1; i < 49; i++) { + _emojiMap['[$i]'] = '$_emojiFilePath/$i.png'; + } + } + + final Map _emojiMap = {}; + + Map get emojiMap => _emojiMap; + + final String _emojiFilePath = 'assets'; + + static EmojiUitl? _instance; + static EmojiUitl get instance => _instance ??= EmojiUitl._(); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/image_text.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/image_text.dart new file mode 100644 index 0000000..07c0520 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/image_text.dart @@ -0,0 +1,88 @@ +import 'dart:math'; + +import 'package:extended_image/extended_image.dart'; +import 'package:extended_text_field/extended_text_field.dart'; +import 'package:flutter/material.dart' hide Element; +import 'package:html/dom.dart' hide Text; +import 'package:html/parser.dart'; + +class ImageText extends SpecialText { + ImageText(TextStyle? textStyle, + {this.start, SpecialTextGestureTapCallback? onTap}) + : super( + ImageText.flag, + '/>', + textStyle, + onTap: onTap, + ); + + static const String flag = ' _imageUrl; + @override + InlineSpan finishText() { + ///content already has endflag '/' + final String text = toString(); + + ///'' +// var index1 = text.indexOf(''') + 1; +// var index2 = text.indexOf(''', index1); +// +// var url = text.substring(index1, index2); +// + ////'' + final Document html = parse(text); + + final Element img = html.getElementsByTagName('img').first; + final String url = img.attributes['src']!; + _imageUrl = url; + + //fontsize id define image height + //size = 30.0/26.0 * fontSize + double? width = 60.0; + double? height = 60.0; + const BoxFit fit = BoxFit.cover; + const double num300 = 60.0; + const double num400 = 80.0; + + height = num300; + width = num400; + const bool knowImageSize = true; + if (knowImageSize) { + height = double.tryParse(img.attributes['height']!); + width = double.tryParse(img.attributes['width']!); + final double n = height! / width!; + if (n >= 4 / 3) { + width = num300; + height = num400; + } else if (4 / 3 > n && n > 3 / 4) { + final double maxValue = max(width, height); + height = num400 * height / maxValue; + width = num400 * width / maxValue; + } else if (n <= 3 / 4) { + width = num400; + height = num300; + } + } + + ///fontSize 26 and text height =30.0 + //final double fontSize = 26.0; + + return ExtendedWidgetSpan( + start: start!, + actualText: text, + child: GestureDetector( + onTap: () { + onTap?.call(url); + }, + child: ExtendedImage.network( + url, + width: width, + height: height, + fit: fit, + ), + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_extended_text_selection_controls.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_extended_text_selection_controls.dart new file mode 100644 index 0000000..48d4ad7 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_extended_text_selection_controls.dart @@ -0,0 +1,106 @@ +import 'dart:math' as math; +import 'package:extended_text_field/extended_text_field.dart'; + +import 'package:flutter/material.dart'; +import 'package:url_launcher/url_launcher.dart'; + +/// +/// create by zmtzawqlp on 2019/8/3 +/// + +const double _kHandleSize = 22.0; + +/// Android Material styled text selection controls. +class MyTextSelectionControls extends TextSelectionControls + with TextSelectionHandleControls { + static Widget defaultContextMenuBuilder( + BuildContext context, ExtendedEditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.buttonItems( + buttonItems: [ + ...editableTextState.contextMenuButtonItems, + ContextMenuButtonItem( + onPressed: () { + launchUrl( + Uri.parse( + 'mailto:xxx@live.com?subject=extended_text_share&body=${editableTextState.textEditingValue.text}', + ), + ); + editableTextState.hideToolbar(true); + editableTextState.textEditingValue + .copyWith(selection: const TextSelection.collapsed(offset: 0)); + }, + type: ContextMenuButtonType.custom, + label: 'like', + ), + ], + anchors: editableTextState.contextMenuAnchors, + ); + // return AdaptiveTextSelectionToolbar.editableText( + // editableTextState: editableTextState, + // ); + } + + /// Returns the size of the Material handle. + @override + Size getHandleSize(double textLineHeight) => + const Size(_kHandleSize, _kHandleSize); + + /// Builder for material-style text selection handles. + @override + Widget buildHandle( + BuildContext context, TextSelectionHandleType type, double textLineHeight, + [VoidCallback? onTap, double? startGlyphHeight, double? endGlyphHeight]) { + final Widget handle = SizedBox( + width: _kHandleSize, + height: _kHandleSize, + child: Image.asset( + 'assets/40.png', + ), + ); + + // [handle] is a circle, with a rectangle in the top left quadrant of that + // circle (an onion pointing to 10:30). We rotate [handle] to point + // straight up or up-right depending on the handle type. + switch (type) { + case TextSelectionHandleType.left: // points up-right + return Transform.rotate( + angle: math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.right: // points up-left + return Transform.rotate( + angle: -math.pi / 4.0, + child: handle, + ); + case TextSelectionHandleType.collapsed: // points up + return handle; + } + } + + /// Gets anchor for material-style text selection handles. + /// + /// See [TextSelectionControls.getHandleAnchor]. + @override + Offset getHandleAnchor(TextSelectionHandleType type, double textLineHeight, + [double? startGlyphHeight, double? endGlyphHeight]) { + switch (type) { + case TextSelectionHandleType.left: + return const Offset(_kHandleSize, 0); + case TextSelectionHandleType.right: + return Offset.zero; + default: + return const Offset(_kHandleSize / 2, -4); + } + } + + @override + bool canSelectAll(TextSelectionDelegate delegate) { + // Android allows SelectAll when selection is not collapsed, unless + // everything has already been selected. + final TextEditingValue value = delegate.textEditingValue; + return delegate.selectAllEnabled && + value.text.isNotEmpty && + !(value.selection.start == 0 && + value.selection.end == value.text.length); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_special_text_span_builder.dart b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_special_text_span_builder.dart new file mode 100644 index 0000000..ae1bbe7 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/lib/special_text/my_special_text_span_builder.dart @@ -0,0 +1,45 @@ +import 'package:example/special_text/image_text.dart'; +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/material.dart'; + +import 'at_text.dart'; +import 'dollar_text.dart'; +import 'emoji_text.dart'; + +class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder { + MySpecialTextSpanBuilder({this.showAtBackground = false}); + + /// whether show background for @somebody + final bool showAtBackground; + + @override + SpecialText? createSpecialText(String flag, + {TextStyle? textStyle, + SpecialTextGestureTapCallback? onTap, + int? index}) { + if (flag == '') { + return null; + } + + ///index is end index of start flag, so text start index should be index-(flag.length-1) + if (isStart(flag, EmojiText.flag)) { + return EmojiText(textStyle, start: index! - (EmojiText.flag.length - 1)); + } else if (isStart(flag, ImageText.flag)) { + return ImageText(textStyle, + start: index! - (ImageText.flag.length - 1), onTap: onTap); + } else if (isStart(flag, AtText.flag)) { + return AtText( + textStyle, + onTap, + start: index! - (AtText.flag.length - 1), + showAtBackground: showAtBackground, + ); + } else if (isStart(flag, EmojiText.flag)) { + return EmojiText(textStyle, start: index! - (EmojiText.flag.length - 1)); + } else if (isStart(flag, DollarText.flag)) { + return DollarText(textStyle, onTap, + start: index! - (DollarText.flag.length - 1)); + } + return null; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Debug.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 0000000..4b81f9b --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Release.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 0000000..5caa9d1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/GeneratedPluginRegistrant.swift b/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/GeneratedPluginRegistrant.swift new file mode 100644 index 0000000..8236f57 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Flutter/GeneratedPluginRegistrant.swift @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +import FlutterMacOS +import Foundation + +import url_launcher_macos + +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile b/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile new file mode 100644 index 0000000..049abe2 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile @@ -0,0 +1,40 @@ +platform :osx, '10.14' + +# 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/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile.lock b/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile.lock new file mode 100644 index 0000000..eb85594 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Podfile.lock @@ -0,0 +1,22 @@ +PODS: + - FlutterMacOS (1.0.0) + - url_launcher_macos (0.0.1): + - FlutterMacOS + +DEPENDENCIES: + - FlutterMacOS (from `Flutter/ephemeral`) + - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`) + +EXTERNAL SOURCES: + FlutterMacOS: + :path: Flutter/ephemeral + url_launcher_macos: + :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos + +SPEC CHECKSUMS: + FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24 + url_launcher_macos: c04e4fa86382d4f94f6b38f14625708be3ae52e2 + +PODFILE CHECKSUM: 353c8bcc5d5b0994e508d035b5431cfe18c1dea7 + +COCOAPODS: 1.11.2 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.pbxproj b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ce99738 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,633 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 54; + 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 */; }; + 7AF4D8477C1FAF78892E7B47 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F20835456926299CD3CDCE5 /* 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 = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; + 8A07DB08724BE1ACDF26F964 /* 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 = ""; }; + 9F20835456926299CD3CDCE5 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + D7B7FF68CC01EE21C6512FAA /* 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 = ""; }; + FABA45EBEEAD51CFF206571D /* 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 = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 33CC10EA2044A3C60003C045 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7AF4D8477C1FAF78892E7B47 /* 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 */, + E5F3109C001394DBA2121E0A /* 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 = ""; + }; + D73912EC22F37F3D000D13A0 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9F20835456926299CD3CDCE5 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + E5F3109C001394DBA2121E0A /* Pods */ = { + isa = PBXGroup; + children = ( + FABA45EBEEAD51CFF206571D /* Pods-Runner.debug.xcconfig */, + 8A07DB08724BE1ACDF26F964 /* Pods-Runner.release.xcconfig */, + D7B7FF68CC01EE21C6512FAA /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 33CC10EC2044A3C60003C045 /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 3EF585B484D5C35B2252DA86 /* [CP] Check Pods Manifest.lock */, + 33CC10E92044A3C60003C045 /* Sources */, + 33CC10EA2044A3C60003C045 /* Frameworks */, + 33CC10EB2044A3C60003C045 /* Resources */, + 33CC110E2044A8840003C045 /* Bundle Framework */, + 3399D490228B24CF009A79C7 /* ShellScript */, + BF4155FDD3B79E6AF9E31812 /* [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 */ + 3399D490228B24CF009A79C7 /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; + 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"; + }; + 3EF585B484D5C35B2252DA86 /* [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; + }; + BF4155FDD3B79E6AF9E31812 /* [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; + }; +/* 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.14; + 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.14; + 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.14; + 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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme new file mode 100644 index 0000000..fb7259e --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/contents.xcworkspacedata b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..21a3cc1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/AppDelegate.swift b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/AppDelegate.swift new file mode 100644 index 0000000..d53ef64 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a2ec33f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png new file mode 100644 index 0000000000000000000000000000000000000000..3c4935a7ca84f0976aca34b7f2895d65fb94d1ea GIT binary patch literal 46993 zcmZ5|3p`X?`~OCwR3s6~xD(})N~M}fiXn6%NvKp3QYhuNN0*apqmfHdR7#ShNQ99j zQi+P9nwlXbmnktZ_WnO>bl&&<{m*;O=RK!cd#$zCdM@AR`#jH%+2~+BeX7b-48x|= zZLBt9*d+MZNtpCx_&asa{+CselLUV<<&ceQ5QfRjLjQDSL-t4eq}5znmIXDtfA|D+VRV$*2jxU)JopC)!37FtD<6L^&{ia zgVf1p(e;c3|HY;%uD5<-oSFkC2JRh- z&2RTL)HBG`)j5di8ys|$z_9LSm^22*uH-%MmUJs|nHKLHxy4xTmG+)JoA`BN7#6IN zK-ylvs+~KN#4NWaH~o5Wuwd@W?H@diExdcTl0!JJq9ZOA24b|-TkkeG=Q(pJw7O;i z`@q+n|@eeW7@ z&*NP+)wOyu^5oNJ=yi4~s_+N)#M|@8nfw=2#^BpML$~dJ6yu}2JNuq!)!;Uwxic(z zM@Wa-v|U{v|GX4;P+s#=_1PD7h<%8ey$kxVsS1xt&%8M}eOF98&Rx7W<)gY(fCdmo{y*FPC{My!t`i=PS1cdV7DD=3S1J?b2<5BevW7!rWJ%6Q?D9UljULd*7SxX05PP^5AklWu^y` z-m9&Oq-XNSRjd|)hZ44DK?3>G%kFHSJ8|ZXbAcRb`gH~jk}Iwkl$@lqg!vu)ihSl= zjhBh%%Hq|`Vm>T7+SYyf4bI-MgiBq4mZlZmsKv+S>p$uAOoNxPT)R6owU%t*#aV}B z5@)X8nhtaBhH=={w;Du=-S*xvcPz26EI!gt{(hf;TllHrvku`^8wMj7-9=By>n{b= zHzQ?Wn|y=;)XM#St@o%#8idxfc`!oVz@Lv_=y(t-kUC`W)c0H2TX}Lop4121;RHE(PPHKfe_e_@DoHiPbVP%JzNudGc$|EnIv`qww1F5HwF#@l(=V zyM!JQO>Rt_PTRF1hI|u^2Uo#w*rdF*LXJky0?|fhl4-M%zN_2RP#HFhSATE3&{sos zIE_?MdIn!sUH*vjs(teJ$7^7#|M_7m`T>r>qHw>TQh?yhhc8=TJk2B;KNXw3HhnQs za(Uaz2VwP;82rTy(T3FJNKA86Y7;L(K=~BW_Q=jjRh=-k_=wh-$`nY+#au+v^C4VV z)U?X(v-_#i=3bAylP1S*pM_y*DB z2fR!imng6Dk$>dl*K@AIj<~zw_f$T!-xLO8r{OkE(l?W#W<={460Y02*K#)O4xp?W zAN+isO}!*|mN7B#jUt&!KNyFOpUxv&ybM>jmkfn8z^llBslztv!!`TBEPwu;#eR3d z@_VDa)|ByvXx1V=^Up4{;M8ji3FC7gm(C7Ty-#1gs+U<{Ouc(iV67{< zam#KwvR&s=k4W<13`}DxzJ9{TUa97N-cgWkCDc+C339)EEnC@^HQK6OvKDSCvNz(S zOFAF_6omgG!+zaPC8fBO3kH8YVBx9_AoM?->pv~@$saf(Myo|e@onD`a=;kO*Utem ze=eUH&;JB2I4}?Pm@=VnE+yb$PD~sA5+)|iH3bi|s?ExIePeoAMd(Z4Z%$mCu{t;B9(sgdG~Q}0ShAwe!l8nw0tJn zJ+m?ogrgty$3=T&6+JJa!1oS3AtQQ1gJ z3gR1<=hXU>{SB-zq!okl4c+V9N;vo4{fyGeqtgBIt%TPC1P&k!pR-GZ7O8b}9=%>3 zQrV%FQdB+CcCRKK)0}v>U25rbQk(1^9Ax|WcAo5?L(H&H@%zAoT2RH$iN6boyXpsYqME}WJZI6T%OMlkWXK>R`^7AHG&31 z&MIU}igQ7$;)7AEm#dXA+!I&6ymb7n6D;F7c$tO3Ql(`ht z1sFrzIk_q5#=!#D(e~#SdWz5K;tPF*R883Yu>*@jTeOGUjQekw zM+7HlfP{y8p}jA9bLfyKC_Ti8k#;AVp@RML^9MQp-E+Ns-Y zKA!aAZV-sfm<23fy#@TZZlQVQxH%R7rD}00LxHPUF!Yg3%OX ziDe4m<4fp{7ivBS?*AlJz$~vw5m)Ei8`|+~xOSqJ$waA0+Yys$z$9iN9TIXu8 zaYacjd09uRAsU|)g|03w`F|b1Xg#K~*Mp2X^K^)r3P^juoc}-me&YhkW3#G|H<~jK zoKD?lE@jOw7>4cpKkh!8qU!bF(i~Oa8a!EGy-j46eZYbKUvF=^^nq`EtWFK}gwrsB zeu<6~?mk+;+$whP)8ud8vjqh+NofU+Nu`~|pb&CN1y_idxxf6cGbT=fBZR_hl&G)GgnW$*oDrN-zz;cKs18n+dAn95w z)Y>l6!5eYpebJGw7it~Q5m}8$7@%p&KS=VtydFj4HPJ{xqUVS_Ih}c(^4nUdwG|0% zw8Fnm{IT`8MqoL(1BNtu_#7alS@3WSUUOFT@U*`V!zrPIeCbbO=pE%|g92$EU|lw; z^;^AqMVWVf-R5^OI79TzIyYf}HX%0Y)=aYH;EKo}?=R~ZM&s&F;W>u%hFUfNafb;- z8OkmkK3k||J#3`xdLuMJAhj9oPI?Cjt}cDN7hw26n7irWS0hsy`fs&Y?Y&(QF*Nu! z!p`NggHXaBU6$P42LkqnKsPG@363DHYGXg{!|z6VMAQt??>FK1B4x4{j;iY8A+7o% z*!0qt&w+w#Ob@pQp;q)u0;v^9FlY=AK>2!qku)!%TO<^lNBr!6R8X)iXgXi^1p`T8 z6sU@Y_Fsp6E89E1*jz~Tm2kF=mjYz_q99r^v0h-l7SP6azzL%woM6!7>IFWyizrNwAqoia3nN0q343q zFztMPh0)?ugQg5Izbk{5$EGcMzt*|=S8ZFK%O&^YV@V;ZRL>f!iG?s5z{(*Xq20c^ z(hkk~PljBo%U`$q>mz!ir7chKlE-oHA2&0i@hn4O5scsI&nIWsM>sYg;Ph5IO~VpT z%c-3_{^N>4kECzk?2~Z@V|jWio&a&no;boiNxqXOpS;ph)gEDFJ6E=zPJ$>y5w`U0 z;h9_6ncIEY?#j1+IDUuixRg&(hw+QSSEmFi%_$ua$^K%(*jUynGU@FlvsyThxqMRw z7_ALpqTj~jOSu2_(@wc_Z?>X&(5jezB6w-@0X_34f&cZ=cA-t%#}>L7Q3QRx1$qyh zG>NF=Ts>)wA)fZIlk-kz%Xa;)SE(PLu(oEC8>9GUBgd$(^_(G6Y((Hi{fsV; zt*!IBWx_$5D4D&ezICAdtEU!WS3`YmC_?+o&1RDSfTbuOx<*v`G<2SP;5Q4TqFV&q zJL=90Lcm^TL7a9xck}XPMRnQ`l0%w-fi@bRI&c*VDj!W4nj=qaQd$2U?^9RTT{*qS_)Q9OL>s}2P3&da^Pf(*?> z#&2bt;Q7N2`P{{KH@>)Tf5&za?crRmQ%8xZi<9f=EV3={K zwMet=oA0-@`8F;u`8j-!8G~0TiH5yKemY+HU@Zw3``1nT>D ziK465-m?Nm^~@G@RW2xH&*C#PrvCWU)#M4jQ`I*>_^BZB_c!z5Wn9W&eCBE(oc1pw zmMr)iu74Xl5>pf&D7Ml>%uhpFGJGyj6Mx=t#`}Mt3tDZQDn~K`gp0d)P>>4{FGiP$sPK*ExVs!1)aGgAX z6eA;-9@@Muti3xYv$8U{?*NxlHxs?)(6%!Iw&&l79K86h+Z8;)m9+(zzX?cS zH*~)yk)X^H1?AfL!xctY-8T0G0Vh~kcP=8%Wg*zZxm*;eb)TEh&lGuNkqJib_}i;l z*35qQ@}I#v;EwCGM2phE1{=^T4gT63m`;UEf5x2Get-WSWmt6%T6NJM`|tk-~4<#HHwCXuduB4+vW!BywlH8murH@|32CNxx7} zAoF?Gu02vpSl|q1IFO0tNEvKwyH5V^3ZtEO(su1sIYOr{t@Tr-Ot@&N*enq;Je38} zOY+C1bZ?P~1=Qb%oStI-HcO#|WHrpgIDR0GY|t)QhhTg*pMA|%C~>;R4t_~H1J3!i zyvQeDi&|930wZlA$`Wa9)m(cB!lPKD>+Ag$5v-}9%87`|7mxoNbq7r^U!%%ctxiNS zM6pV6?m~jCQEKtF3vLnpag``|bx+eJ8h=(8b;R+8rzueQvXgFhAW*9y$!DgSJgJj% zWIm~}9(R6LdlXEg{Y3g_i7dP^98=-3qa z$*j&xC_$5btF!80{D&2*mp(`rNLAM$JhkB@3al3s=1k^Ud6HHontlcZw&y?`uPT#a za8$RD%e8!ph8Ow7kqI@_vd7lgRhkMvpzp@4XJ`9dA@+Xk1wYf`0Dk!hIrBxhnRR(_ z%jd(~x^oqA>r>`~!TEyhSyrwNA(i}={W+feUD^8XtX^7^Z#c7att{ot#q6B;;t~oq zct7WAa?UK0rj0yhRuY$7RPVoO29JV$o1Z|sJzG5<%;7pCu%L-deUon-X_wAtzY@_d z6S}&5xXBtsf8TZ13chR&vOMYs0F1?SJcvPn>SFe#+P3r=6=VIqcCU7<6-vxR*BZUm zO^DkE{(r8!e56)2U;+8jH4tuD2c(ptk0R{@wWK?%Wz?fJckr9vpIU27^UN*Q$}VyHWx)reWgmEls}t+2#Zm z_I5?+htcQl)}OTqF<`wht89>W*2f6e)-ewk^XU5!sW2A2VtaI=lggR&I z;Rw{xd)WMqw`VUPbhrx!!1Eg_*O0Si6t@ny)~X^Gu8wZZDockr)5)6tm+<=z+rYu? zCof+;!nq6r9MAfh zp4|^2w^-3vFK~{JFX|F5BIWecBJkkEuE%iP8AZ z^&e|C+VEH&i(4Y|oWPCa#C3T$129o5xaJa=y8f(!k&q+x=M|rq{?Zw_n?1X-bt&bP zD{*>Io`F4(i+5eE2oEo6iF}jNAZ52VN&Cp>LD{MyB=mCeiwP+v#gRvr%W)}?JBTMY z_hc2r8*SksC%(pp$KGmWSa|fx;r^9c;~Q(Jqw1%;$#azZf}#Fca9NZOh{*YxV9(1ivVA^2Wz>!A&Xvmm-~{y8n!^Jdl8c>`J#=2~!P{ zC1g_5Ye3={{fB`R%Q|%9<1p1;XmPo5lH5PHvX$bCIYzQhGqj7hZ?@P4M0^mkejD|H zVzARm7LRy|8`jSG^GpxRIs=aD>Y{Cb>^IwGEKCMd5LAoI;b{Q<-G}x*e>86R8dNAV z<@jb1q%@QQanW1S72kOQ$9_E#O?o}l{mHd=%Dl{WQcPio$baXZN!j{2m)TH1hfAp{ zM`EQ=4J`fMj4c&T+xKT!I0CfT^UpcgJK22vC962ulgV7FrUrII5!rx1;{@FMg(dIf zAC}stNqooiVol%%TegMuWnOkWKKA}hg6c)ssp~EnTUVUI98;a}_8UeTgT|<%G3J=n zKL;GzAhIQ_@$rDqqc1PljwpfUwiB)w!#cLAkgR_af;>}(BhnC9N zqL|q8-?jsO&Srv54TxVuJ=rfcX=C7{JNV zSmW@s0;$(#!hNuU0|YyXLs{9$_y2^fRmM&g#toh}!K8P}tlJvYyrs6yjTtHU>TB0} zNy9~t5F47ocE_+%V1(D!mKNBQc{bnrAbfPC2KO?qdnCv8DJzEBeDbW}gd!g2pyRyK`H6TVU^~K# z488@^*&{foHKthLu?AF6l-wEE&g1CTKV|hN7nP+KJnkd0sagHm&k{^SE-woW9^fYD z7y?g*jh+ELt;$OgP>Se3o#~w9qS}!%#vBvB?|I-;GM63oYrJ}HFRW6D+{54v@PN8K z2kG8`!VVc+DHl^8y#cevo4VCnTaPTzCB%*)sr&+=p{Hh#(MwaJbeuvvd!5fd67J_W za`oKxTR=mtM7P}i2qHG8=A(39l)_rHHKduDVA@^_Ueb7bq1A5#zHAi**|^H@fD`_W z#URdSG86hhQ#&S-Vf_8b`TIAmM55XhaHX7}Ci-^(ZDs*yb-WrWV&(oAQu3vMv%u$5 zc;!ADkeNBN_@47r!;%G3iFzo;?k)xTS-;1D-YeS5QXN7`p2PzGK~e6ib;8COBa5)p zfMn}dA--&A12~zr&GVk?qnBGfIEo`5yir;-Q;ZLn{Fimdrk;e!)q`sAkYh^~^>4Q@ zN5RT>s38+`V{|6@k&vZW!W0*BEqV&~34d+Ev8h)ObYL7Bd_hgbUzjdJaXP=S@Dp6X z)i013q3K4Gr5d%2YIp>218pYK!xwH;k)j?uUrT-yVKLg*L3y~=a+qd!RWGTL`z>29 z-Zb4Y{%pT%`R-iA#?T58c-i@?jf-Ckol9O>HAZPUxN%Z=<4ad9BL7n`_kH0i#E(m& zaNb039+z~ONUCLsf_a|x*&ptU?`=R*n}rm-tOdCDrS!@>>xBg)B3Sy8?x^e=U=i8< zy7H-^BPfM}$hf*d_`Qhk_V$dRYZw<)_mbC~gPPxf0$EeXhl-!(ZH3rkDnf`Nrf4$+ zh?jsRS+?Zc9Cx7Vzg?q53ffpp43po22^8i1Obih&$oBufMR;cT2bHlSZ#fDMZZr~u zXIfM5SRjBj4N1}#0Ez|lHjSPQoL&QiT4mZn=SxHJg~R`ZjP!+hJ?&~tf$N!spvKPi zfY;x~laI9X`&#i#Z}RJ`0+MO_j^3#3TQJu2r;A-maLD8xfI+2Y*iDf4LsQ$9xiu?~ z?^wHEf^qlgtjdj(u_(W5sbGx1;maVPDHvI-76u2uUywf;>()=e>0le;bO0LIvs)iy z*lJTO+7gyf^)2uS-PhS_O-+RToQmc6VT>ej^y^stNkwIxUg?E|YMAAwQ}U!dC&cXL ziXKU?zT~xbh6C};rICGbdX~;8Z%L~Jdg|`senVEJo-CiDsX47Kc`;EiXWO<9o)(`4 zGj(9@c+Me=F~y(HUehcAy!tkoM&e1y#(qqCkE(0lik_U>wg8vOhGR(=gBGFSbR`mh zn-%j3VTD4 zwA1Kqw!OSgi_v0;6?=Bk4Z{l-7Fl4`ZT535OC{73{rBwpNHMPH>((4G`sh zZhr!v{zM@4Q$5?8)Jm;v$A2v$Yp9qFG7y`9j7O-zhzC+7wr3Cb8sS$O{yOFOODdL) zV2pU{=nHne51{?^kh%a$WEro~o(rKQmM!p?#>5Pt`;!{0$2jkmVzsl|Nr^UF^IHxG z8?HmZEVMY~ec%Ow6hjfg6!9hCC4xY?V;5Ipo-myV=3TmfT^@XkKME`+=_inm4h7ki z->K~a+20?)zic^zc&7h=0)T{Aa24FU_}(O|9DMW3Bf>MW=O%~8{unFxp4}B+>>_KN zU%rKs3Va&&27&OX4-o&y2ie|sN2p-=S^V<2wa2NUQ4)?0e|hgna*1R7(#R_ys3xmG zE#(ry+q=O~&t|RX@ZMD`-)0QmE*x%SBc(Yvq60JtCQ4RL(gdA(@=}0rYo5yKz36bW zkvLOosP6I?7qH!rce(}q@cH-{oM2ThKV2RZe+{{25hkc?T>=Tky12xHr0jmfH@SZi zLHPJ@^Oo^Zo%`gZk_hrbCzS+t|=O!Bt zWi|>M8mz~sD|Z>C1ZPf_Cs&R!S5E2qK+@j*UpP>;5_|+h+y{gb=zub7#QKSUabet# zFH2H0ul;zO+uc+V=W_W@_Ig-791T7J9&=5)wrBE?JEHS_A6P~VQ)u6s1)Pu|VxP(aYJV*(e<)(42R zm3AK>dr1QLbC1RMoQ|M5k+TWBjY9q+_vY=K-tUte35m4RWl51A<4O0ptqV3)KzL7U z0gpp-I1)|zvtA8V7-e-o9H)lB_Rx6;Bu7A2yE)6)SuDqWDs}~Ojfk?DFwI% z3E1(>LbbB7I(&E@B7nlulhvY=Wa1mGXD@ijD7WF^y@L1e55h)-hzoq}eWe!fh9m3V{)x^6F8?ed1z>+4;qW6A4hYYj zZCYP=c#I8+$pAIVyiY*#%!j3ySAnH`tp|=^lh{)#JimWaP_rXK40A0WcsEUj`G1}O zG?XQ~qK4F!lqauv6-BL_Up3+-l1=kVfD;D*C)yr>o9>W=%mIyATtn_OBLK+h@p)j5jRAb;m&Ok?TZH-5Q)~#UwdYFp~rEE{judWa9E)z zE>135C-xMdHYY&AZGR)tb`K}s0CK9 z1!))p^ZaUC*e50t`sL+)@`)#kJ}?C_cCMH@k{f4wh~0`OFnGQ2nzUuuu;=r4BYRcI z){G#a6Y$S(mIc6B#YS;jFcU{0`c)Raa$nG+hV(K|2|^ZWOI566zlF0N;t~$jD<_AX zjnD?HN-G>xRmHwtL3BcJX7)Q^YGfc?cS4Nj=yYl5MB(uBD?r@VTB|mIYs=au$e)e{ zLHWd!+EN*v2*(=y%G1JzyQdY&%|?~R5NPb)`S2dw1AJW8O;L=p?yVxJs=X?U#-l1O zk6xh8yyY;OTR7aF{P=kQ>y`*EFivnw%rQioA-I67WS+~hVamG4_sI)(Jo4vHS|@F@ zqrBHbxHd_Y8+?8Gfq=Z1O^Fs5moGayCHVUHY^8)^j)Aj*RB!S2-FA?4#-`puwBW`` zJ_6OQj(FGo8DotHYRKq;;$4xDn9=4rgw}5xvxhi)?n?W5{*%4%h9Tg)zlQl&fN~Z1)gL(Dn7X!P428I zwA+U-x5!cQ57g1N=2bLqAWF z!&cbvsD)dvYoqP5vaQz%rL@kv*J>0AMzWAKn~Mxi5g2GlI7qvVZo)Z5oj=#O!M&*O z`3O3)uvrjNTeremC}nW@(m%#E-sITB>j-!yBM#(=FN`~c#@XjL3e)SjR9&%QO%tUg zzGv=SLH()`ZIt?Ayym;9VG1Muq+a+7Zo+59?SuRu_`k>@S4!yS3roMnq+SDO?`C7V#2 z8vHf4&0k;{kLT)fa==7EILSu3e|ZnxtFO;1 zGqP-;Xo(>_QKcYUhsi-X72BqH#7Zb-TsiNIF>G9xOHT3XoA*qX^10+#XCU0)UO4_%A_s_vO=uDd3_Q%D{OsvLMW9wGvuuRnF52{2vH06D~7N672!bIMt@it_D}& zwjZ7gV!RzZ86*wbEB5cnMJRbEqMM{G!K)bfJjyPH^9nGnrOI9S{~!dm4~P#&b*~)h zCMwM8mR+y5i~E5*JAopwZ>F`=ORfA&IF%O8(aS<}^H6wcY1g^=lYLPtFpyvW9F z3;FCS-TGFYPr#Y$ue>}?rTYrmWr^VbUu>!eL$cEdh1e>5_UDnZ@Mu$l*KVo_NDEu^ zBn*!qVnzYv>t|<(>nt8%CoNPhN!qGP|sANRN^#+2YSSYHa>R1mss->c0f=#g@U58@? zA4sUbrA7)&KrTddS0M6pTSRaz)wqUgsT3&8-0eG|d;ULOUztdaiD3~>!10H`rRHWY z1iNu6=UaA8LUBoaH9G*;m`Mzm6d1d+A#I8sdkl*zfvbmV0}+u` zDMv=HJJm?IOwbP;f~yn|AI_J7`~+5&bPq6Iv?ILo2kk$%vIlGsI0%nf1z9Mth8cy! zWumMn=RL1O9^~bVEFJ}QVvss?tHIwci#ldC`~&KFS~DU5K5zzneq_Q91T~%-SVU4S zJ6nVI5jeqfh~*2{AY#b(R*Ny95RQBGIp^fxDK{I9nG0uHCqc-Ib;pUUh$t0-4wX*< z=RzW~;iR3xfRnW<>5Jr5O1MP)brA3+ei@H8Hjkt7yuYIpd7c-4j%U=8vn8HD#TPJo zSe+7~Db}4U3Y^4dl1)4XuKZ67f(ZP;?TYg9te>hbAr4R_0K$oq3y5m-gb?fR$UtF9 zS~S^=aDyFSE}9W2;Okj%uoG-Um^&Qo^bB#!W?|%=6+P>``bumeA2E7ti7Aj%Fr~qm z2gbOY{WTyX$!s5_0jPGPQQ0#&zQ0Zj0=_74X8|(#FMzl`&9G_zX*j$NMf?i3M;FCU z6EUr4vnUOnZd`*)Uw#6yI!hSIXr%OF5H z5QlF8$-|yjc^Y89Qfl!Er_H$@khM6&N*VKjIZ15?&DB?);muI`r;7r0{mI03v9#31 z#4O*vNqb=1b}TjLY`&ww@u^SE{4ZiO=jOP3!|6cKUV2*@kI9Aw0ASwn-OAV~0843$1_FGl7}eF6C57dJb3grW)*jtoUd zpqXvfJSCIv4G*_@XZE?> z4Lt=jTSc*hG3`qVq!PVMR2~G-1P{%amYoIg!8Odf4~nv6wnEVrBt-R5Au=g~4=X|n zHRJGVd|$>4@y#w;g!wz>+z%x?XM^xY%iw%QoqY@`vSqg0c>n_}g^lrV))+9n$zGOP zs%d&JWT2Jjxaz`_V%XtANP$#kLLlW=OG2?!Q%#ThY#Sj}*XzMsYis2HiU2OlfeC>d z8n8j-{Npr1ri$Jv2E_QqKsbc$6vedBiugD~S`_0QjTTtX(mS}j6)6e;xdh*sp5U0aMpuN}qTP=^_Qn zh~0padPWs&aXmf6b~}{7Raglc)$~p?G89N4)&a}`izf|bA)IUmFLQ8UM$T!6siQxr z=%)pPsWYXWCNdGMS3fK6cxVuhp7>mug|>DVtxGd~O8v@NFz<+l`8^#e^KS3})bovWb^ zILp4a_9#%Y*b6m$VH8#)2NL@6a9|q!@#XOXyU-oAe)RR$Auj6?p2LEp*lD!KP{%(- z@5}`S$R)Kxf@m68b}Tr7eUTO=dh2wBjlx;PuO~gbbS2~9KK1szxbz$R|Frl8NqGn= z2RDp@$u5Obk&sxp!<;h=C=ZKPZB+jk zBxrCc_gxabNnh6Gl;RR6>Yt8c$vkv>_o@KDMFW1bM-3krWm|>RG>U`VedjCz2lAB1 zg(qb_C@Z~^cR=_BmGB@f;-Is3Z=*>wR2?r({x}qymVe?YnczkKG%k?McZ2v3OVpT* z(O$vnv}*Tle9WVK_@X@%tR^Z!3?FT_3s@jb3KBVf#)4!p~AFGgmn%1fBbZe3T53$_+UX_A!@Kz63qSLeH@8(augJDJ;RA>6rNxQYkd6t(sqK=*zv4j;O#N(%*2cdD z3FjN6`owjbF%UFbCO=haP<;Y1KozVgUy(nnnoV7{_l5OYK>DKEgy%~)Rjb0meL49X z7Fg;d!~;Wh63AcY--x{1XWn^J%DQMg*;dLKxs$;db`_0so$qO!>~yPDNd-CrdN!ea zMgHt24mD%(w>*7*z-@bNFaTJlz;N0SU4@J(zDH*@!0V00y{QfFTt>Vx7y5o2Mv9*( z1J#J27gHPEI3{!^cbKr^;T8 z{knt%bS@nrExJq1{mz2x~tc$Dm+yw=~vZD|A3q>d534za^{X9e7qF29H5yu};J)vlJkKq}< zXObu*@ioXGp!F=WVG3eUtfIA$GGgv0N?d&3C47`Zo)ms*qO}A9BAEke!nh#AfQ0d_ z&_N)E>5BsoR0rPqZb)YN}b~6Ppjyev;MMis-HkWF!az%G? z#&it84hv!%_Q>bnwch!nZKxB05M=jgiFaB^M=e-sj1xR?dPYUzZ#jua`ggyCAcWY> z-L$r#a{=;JP5X}9(ZPC&PdG~h5>_8SueX($_)Qu(;()N3*ZQH(VGnkWq^C}0r)~G3_?a10y*LsFz zokU5AKsW9DUr-ylK61shLS#4@vPcteK-Ga9xvRnPq=xSD_zC=Q_%6IuM?GpL(9aDx z|8d_;^6_D4{IQ1ndMAcFz5ZaT+Ww0wWN`xP(U#^=POs(BpKm;(H(lmYp+XCb7Kaw0 z;LT945Ev3IkhP6$lQBiMgr+vAL}{8xO&IObqJBEP4Y^x&V?iGC=1lVIbH^Z!eXxr@ zz)D7Fon`z~N|Pq>Bsue&_T9d;G+d8#@k^cq~F^I8ETsZ*cGOf*gZ4ghlAzW|aZ;WA13^B!Tlr0sWA zosgXD-%zvO-*GLU@hVV(bbQ`s@f~Ux=4}(@7O)%o5EH((gYflccBC@jbLF3IgPozv zglX2IL}kL1rtn4mu~`J(MMY83Rz6gc1}cX4RB+tZO2~;3FI# z@dU(xa5J_KvL0)oSkvwz9|!QcEA$jKR@a-4^SU3O449TrO+x$1fkBU<<=E_IHnF6> zPmZ7I2E+9A_>j6og$>Nih~b2F_^@6ef|Hm-K2(>`6ag{Vpd`g35n`yW|Jme78-cSy z2Jz7V#5=~u#0eLSh3U4uM3Smk31>xEh^-Os%&5tK6hSAX83jJi%5l!MmL4E?=FerNG#3lj^;-F1VISY!4E)__J~gY zP{o~Xo!8DW{5lsBFKL~OJiQoH>yBZ+b^};UL&UUs!Hbu7Gsf<9sLAsOPD4?-3CP{Q zIDu8jLk6(U3VQPyTP{Esf)1-trW5Mi#zfpgoc-!H>F$J#8uDRwDwOaohB(_I%SuHg zGP)11((V9rRAG>80NrW}d`=G(Kh>nzPa1M?sP;UNfGQaOMG1@_D0EMIWhIn#$u2_$ zlG-ED(PU+v<1Dd?q-O#bsA)LwrwL>q#_&75H)_X4sJK{n%SGvVsWH7@1QZqq|LM`l zDhX8m%Pe5`p1qR{^wuQ&>A+{{KWhXs<4RD< z=qU6)+btESL>kZWH8w}Q%=>NJTj=b%SKV3q%jSW>r*Qv1j$bX>}sQ%KO7Il zm?7>4%Q6Nk!2^z})Kchu%6lv-7i=rS26q7)-02q?2$yNt7Y={z<^<+wy6ja-_X6P4 zoqZ1PW#`qSqD4qH&UR57+z0-hm1lRO2-*(xN-42|%wl2i^h8I{d8lS+b=v9_>2C2> zz(-(%#s*fpe18pFi+EIHHeQvxJT*^HFj2QyP0cHJw?Kg+hC?21K&4>=jmwcu-dOqEs{%c+yaQ z2z6rB>nPdwuUR*j{BvM-)_XMd^S1U|6kOQ$rR`lHO3z~*QZ71(y(42g`csRZ1M@K7 zGeZ27hWA%v`&zQExDnc@cm9?ZO?$?0mWaO7E(Js|3_MAlXFB$^4#Zpo;x~xOEbay( zq=N;ZD9RVV7`dZNzz+p@YqH@dW*ij8g053Cbd=Mo!Ad8*L<5m1c4Kk ziuca5CyQ05z7gOMecqu!vU=y93p+$+;m=;s-(45taf_P(2%vER<8q3}actBuhfk)( zf7nccmO{8zL?N5oynmJM4T?8E))e;;+HfHZHr` zdK}~!JG}R#5Bk%M5FlTSPv}Eb9qs1r0ZH{tSk@I{KB|$|16@&`0h3m7S+)$k*3QbQ zasW2`9>hwc)dVNgx46{Io zZ}aJHHNf1?!K|P;>g7(>TefcLJk%!vM`gH8V3!b= z>YS+)1nw9U(G&;7;PV4eIl{=6DT^Vw<2Elnox;u@xF5ad*9Fo|yKgq<>*?C$jaG2j z|29>K)fI^U!v?55+kQ*d2#3}*libC4>Dl4 zIo3Jvsk?)edMnpH<|*l<*0Pf{2#KedIt>~-QiB{4+KEpSjUAYOhGDpn3H_N9$lxaP ztZwagSRY~x@81bqe^3fb;|_A7{FmMBvwHN*Xu006qKo{1i!RbN__2q!Q*A;U*g-Mz zg)-3FZ`VJdognZ~WrWW^2J$ArQAr1&jl~kWhn+osG5wAlE5W&V%GI{8iMQ!5lmV~# zeb3SKZ@?7p;?7{uviY6`Oz16t0=B70`im=`D@xJa16j2eHoCtElU*~7={YUzN41sE z#Th>DvJq-#UwEpJGKx;;wfDhShgO0cM|e!Ej){RX#~>a?)c2|7Hjhh2d=)VUVJL<^Aq|>_df4DX>b9W2$_DM zTjF#j(9?Co`yor?pK<16@{h#F&F8~1PG|qQNZPX^b!L*L&?PH#W8za0c~v6I2W($Jderl%4gufl z#s;C*7APQJP46xHqw;mUyKp3}W^hjJ-Dj>h%`^XS7WAab^C^aRu1?*vh-k2df&y9E z=0p*sn0<83UL4w30FqnZ0EvXCBIMVSY9Zf?H1%IrwQybOvn~4*NKYubcyVkBZ4F$z zkqcP*S>k6!_MiTKIdGlG+pfw>o{ni`;Z7pup#g z4tDx3Kl$)-msHd1r(YpVz7`VW=fx9{ zP}U8rJ-IP)m}~5t&0Y$~Quyjflm!-eXC?_LMGCkZtNDZf0?w<{f^zp&@U@sQxcPOZ zBbfQTFDWL_>HytC*QQG_=K7ZRbL!`q{m8IjE0cz(t`V0Ee}v!C74^!Fy~-~?@}rdn zABORRmgOLz8{r!anhFgghZc>0l7EpqWKU|tG$`VM=141@!EQ$=@Zmjc zTs`)!A&yNGY6WfKa?)h>zHn!)=Jd73@T^(m_j|Z;f?avJ{EOr~O~Q2gox6dkyY@%M zBU+#=T?P8tvGG|D5JTR}XXwjgbH(uwnW%W?9<-OQU9|6H{09v#+jmnxwaQ-V;q{v% zA8srmJX7Fn@7mr*ZQ@)haPjWVN@e3K z_`+@X$k*ocx*uF^_mTqJpwpuhBX~CSu=zPE(Sy%fYz&lzZmz3xo4~-xBBvU0Ao?;I-81*Z%8Do+*}pqg>bt^{w-`V6Sj>{Znj+ z70GS2evXinf|S#9=NNoXoS;$BTW*G0!xuTSZUY45yPE+~*&a-XC+3_YPqhd*&aQ>f z$oMUq^jjA;x#?iJKrpAqa<2<21h*_lx9a}VMib;a6c$~=PJOj6XJXJ|+rc7O7PEN5uE7!4n9nllo@BI4$VW2Nf_jqnkz%cvU4O4umV z#n6oXGWOt3tuIjmX*b!!$t~94@a@QgybLpQo3icAyU`iNbY~XNAArFAn$nFJ()d-U zFaO#nxxVF-%J{UB**uRo0*+?S>=^il)1m7v-u`PDy*ln%|3E-{3U~R=QcE&zhiG_c zDnGMgf1}3h1gWz8IV0Oc7FmEt>6W?Eva;J`(!;IIny}PvD?vztz`F6su_tUO`M%K5 z%C#=nXbX})#uE!zcq2mB;hPUVU1!`9^2K303XfOIVS{mlnMqJyt}FV=$&fgoquO+N zU6!gWoL%3N1kyrhd^3!u>?l6|cIl*t4$Z$=ihyzD7FFY~U~{RaZmfyO4+$kC7+m zo+-*f-VwpUjTi_Idyl~efx)!$GpE!h+in4G1WQkoUr<#2BtxLNn*2A>a-2BL#z%QO@w0v^{s=`*I6=ew2nUj1=mvi%^U@2#Wf& zs1@q6l8WqrqGm!)Yr|*``||#A+4#du6`mR^_#?CymIr}O!8Zm?(XY$u-RGH;?HFMGIEYVuA1& z`3RlG_y0%Mo5w@-_W$E&#>g6j5|y1)2$hg(6k<{&NsACgQQ0c8&8Tdth-{@srKE*I zAW64%AvJJ+Z-|I~8`+eWv&+k8vhdJk5%jolc%e`^%_vul0~U8t)>=bU&^ z6qXW&GDP%~1{L1-nKK>IsFgDJrh>!wr3?Vu-cmi#wn`;F`$GNc_>D|>RSuC8Vh21N z|G;J1%1YxwLZDD400Ggw+FirsoXVWYtOwg-srm}6woBb!8@OIc`P$!?kH>E55zbMB z8rdpODYfVmf>cF`1;>9N>Fl(Rov!pm=okW>I(GNJoNZ6jfIunKna-h6zXZPoZ9E2PythpyYk3HRN%xhq2c?gT$?4}Ybl42kip$QiA+ab zf-!EqBXkT1OLW>C4;|irG4sMfh;hYVSD_t6!MISn-IW)w#8kgY0cI>A`yl?j@x)hc z=wMU^=%71lcELG|Q-og8R{RC9cZ%6f7a#815zaPmyWPN*LS3co#vcvJ%G+>a3sYE`9Xc&ucfU0bB}c_3*W#V7btcG|iC>LctSZUfMOK zlIUt>NBmx6Ed}w_WQARG+9fLiRjS1;g49srN1Xi&DRd|r+zz*OPLWOu>M?V>@!i49 zPLZ3Q(99%(t|l%5=+9=t$slX0Pq(K@S`^n|MKTZL_Sj+DUZY?GU8sG=*6xu)k5V3v zd-flrufs*;j-rU9;qM zyJMlz(uBh0IkV<(HkUxJ747~|gDR6xFu?QvXn`Kr|IWY-Y!UsDCEqsE#Jp*RQpnc# z8y3RX%c2lY9D*aL!VS`xgQ^u0rvl#61yjg03CBER7-#t7Z++5h_4pw{ZZ~j0n_S_g zR=eVrlZDiH4y2}EZMq2(0#uU|XHnU!+}(H*l~J&)BUDN~&$ju@&a=s$tH5L`_wLeB z944k;)JIH^T9GEFlXiNJ6JRymqtLGZc?#Mqk2XIWMuGIt#z#*kJtnk+uS;Gp}zp$(O%LOC|U4ibw%ce-6>id$j5^y?wv zp1At~Sp7Fp_z24oIbOREU!Mji-M;a|15$#ZnBpa^h+HS&4TCU-ul0{^n1aPzkSi1i zuGcMSC@(3Ac6tdQ&TkMI|5n7(6P4(qUTCr)vt5F&iIj9_%tlb|fQ{DyVu!X(gn<3c zCN6?RwFjgCJ2EfV&6mjcfgKQ^rpUedLTsEu8z7=q;WsYb>)E}8qeLhxjhj9K**-Ti z9Z2A=gg+}6%r9HXF!Z~du|jPz&{zgWHpcE+j@p0WhyHpkA6`@q{wXl6g6rL5Z|j~G zbBS~X7QXr3Pq0$@mUH1Snk^1WJ0Fx2nTyCGkWKok$bJZV0*W?kjT|mkUpK<)_!_K^OoTjMc+CWc^~{ZP8vgm`f&=ppzKtw}cxwV^gppu}^df1|va7Q?@=(076-( z4KJVmu?l(aQwmQ*y_mke>YLW^^Rsj@diLY$uUBHL3yGMwNwb7OR3VD%%4tDW(nC984jBWCd90yY(GEdE8s(j>(uPfknLwh!i6*LX}@vvrRCG`c?EdB8uYU zqgsI4=akCeC+&iMNpVu56Fj2xZQHs6SdWssIF#Q@u@f9kab0&y*PlG+PynjHy`}GT zg%aTjRs2+7CknhTQKI%YZhFq1quSM{u24Oy2As@4g(bpbi%y1i0^TwI)%1Whpa~qE zX4MD(PgFEK@jZBPXkFd437aL6#COs$WrNT#U=er-X1FX{{v9!0AS$HR{!_u;zldwY zKko!`w2u@($c&k_3uLFE0Z*2vms?uw1A{AqZw^jwg$|D7jAY20j`s*l##=4Ne_K5) zOtu6_kziEF@vPsS7+@UwqOW6>OUwF$j{r4=nOSf-{UC(rEKidie7IUn>5`UoNJ9k) zxJXXEBQifng+Pte3mPQ76pVlZ<`jnI##F1*YFA*)ZCEncvgF-%)0dUXV*pXTT^L`n zL=?A5Vty#{R9W4K)m$`me~*_(&a88M?Eon$P-YdVG}#Gq4=hh#w=`>8f`9}}zhv;~ za?I=Gb3v$Ln?-SDTBow0J5Tt&xPlw|%`*VTyVee1Oh<-&;mA|;$ zoPl;^f7Q~}km#_#HT2|!;LEqORn%~KJaM)r#x_{PstSGOiZ!zX2c}^!ea3+HSWrwE z=6SJ!7sNDPdbVr#vnUf}hr&g@7_Yj&=sY=q(v^BwLKQm|oSB}172GpPlj?a3GqX#B zJko4zRRttIY>Fv#2b#A<_DLx=T@eUj+f}!u?p)hmN)u4(Jp(`9j58ze{&~rV?WVbP z%A=|J96mQjtD037%>=yk3lkF5EOIYwcE;uQ5J6wRfI^P3{9U$(b>BlcJF$2O;>-{+a1l4;FSlb z_LRpoy$L%S<&ATf#SE z;L?-lQlUDX_s&jz;Q1Lr@5>p_RPPReGnBNxgpD!5R#3)#thAI3ufgc^L)u%Rr+Hlb zT(pLDt%wP7<%z(utq=l%1M78jveI@T$dF#su(&>JkE(#=f4;D54l*%(-^(nfbCUQe)FV9non9F%K+KZ(4_`uOciy82CO)OolxisUd0m^cqueIRnY< z;BgA4S1&XC3uUP?U$}4o&r|0VCC7fkuMZBa|2n4asR>*5`zBaOJPWT$bNn(W_CK%L$c2AsfSlwq?A8Q6 zhK&USSV=^-4vZ^5<}pnAOb&IKseHNxv_!|B{g@d^&w%{?x;i3iSo)+vt^VnMmS!v) zM)W)05vXqzH5^hOWWw~$#&7HoIw}}DD3bCQgc=I8Rv|G5fM8O^58?--_-*>%Nwk)j zIfvfok0n05!w%tZ=-dpffezI7(+}yX5XhwYk#0@KW%PkR;%#t|P6Ze_K*N6ns%jOt zNeW(bRsv0BK7ah~9U~UBAVA_L34F+;14x6-;I|o=%>?sS3@dpRv|GKxilsa#7N#@! z!RX~>&JX&r{A^^>S~n_hPKkPR_(~~g>SuPj5Kx6VI%8BOa(Iit&xSMU8B#EY-Wr?9 zOaRPw0PEbVSW@Wk{8kkVn34;D1pV2mUXnXWp{V-M9+d}|qfb6F`!a9JQO_-wlH?zf z4Sn0F4-q-tzkaJ?1fV0+cJBF$f0g6*DL6U3y`Tr`1wzCiwY#muw7Q-Ki)uN}{MoCWP%tQ@~J4}tyr1^_bV9PScNKQHK=BZFV!`0gRe?mVxhcA4hW5?p0B<5oK+?vG^NM%B%NDOvu0FMq#)u&zt_-g&2 z7?z%~p&32OAUSQV{<=pc_j2^<;)`8$zxCEomh=rvMiliShS?ahdYI1grE-M&+qkK_ zD=5Hexi<&8qb4hgtgj81OD(tfX3EJSqy9KFcxpeBerG`apI4!#93xpEFT??vLt>kf zac28;86CpMu=BWIe$NOT~+Es!y#+$ zvm2s*c`J9Gy*ERvLSI<9<=j*O=0xUG>7rYh^R4bGsvz;j-SBO|P^OQ1>G9_akF}D; zlRmB@k3c5!s|Vz3OMZ8M*n0AMTiSt5ZpRy+R1|ckna&w`UQjklt9f&0Z~=->XImVA zLXizO2h=<|wM~w>%}3q1!E{oSq7LBPwQ~93p-peDq-W?wCm8NOKgTSz-P)|cm}S5&HBsx#C@Ba5;hzi#Yw@y-kC~)@u4}Rf?KV0$lPjv}} zcFpNy=YJfsS||9&!-JFjw=@NU96ESzU^gme0_oNy?})II`>Sy>bUCHs_(m&)vn^&isCl+`F~qu8elAO z)-ZP7`gYE2H(1)5tKalz&NJbcutAU&&JFV~$Jrai31^j>vZ|HV1f}#C1<5>F8 zS1RWIzM%b{@2dAF^$+i4p>TC8-weiLAPN+Aa#(bxXo9%Vz2NEkgF&s#_>V?YPye^_ z`` z-h3Cv^m6K%28I$e2i=cFdhZN?JTWhqJC{Q9mg0Vg|FiPEWDl&K)_;Bz_K`jH7W7QX^d$WQF*iF@#4_P*D36w9&iJr2E{w?LRFapwZIIVHGH ziTp*5>T{=;(E}z{1VL4;_H`BAXA~&zpeWX!gN9m|AfcJ{`!XVz48O^&+0Gd|w;udP zzU|DbGTS|7qZoEoDZEH9Kb0%DZvCaWDzuJ=8jZz}pqPn+I!c_+*~>m>BQqN2560*< z$6sx_y8WRqj$SugYGip+et$;iJ!SQAx=HgVSh_3e)MOFHuXD@sg>Yi_p8Sh`{lP=5 zo?AFv1h;KqR`Yj!8Pjji3lr+qae2|a1GmlxE*su%_V)K0Xu0(#2LcO!*k11w*V12$ z;f~i{kI#9PzvFLZ3pz@d558HeK2BTvk*JvS^J8L^_?q4q z);;4Z!DsV!P*M>F>FiF*{|p_nUgy;pDh?J8vwO;emgOAAcxrgDXiSDS5ag?0l*jj< z(khZ3-)>eiwPwpb6T9meeL)!2C-K@z9fF`0j|t@;^f5+dx86R3ZM{bnx9Hm1O$s)N zk$OvZR0u2`Z^QP8V%{8sEhW~_xbZMad2jtz&0+ekxmp;9`ae;_f%-ltk5E%)VT*a6 zRbMnpCLPnalu+1TafJ4M0xNV8g}U4Mjk{le6MA|0y0rk)is}M%Z9tUU22SvIAh7`w zTysd{Pztfkk=jD^*!lA+rBcqb)Fx`A5iaU2tl&XdL1D)U@pLEXdu%#YB*ol1N?4ti zHBQcU#_%UqiQ1)J^u-ovU@-7l?`YzYFvA2#tM0mEh3?CpyEh_NUuVajD16t zyg$C*5du9R=K~6mCJ`W+dFI$9WZZauO)p2H)*SKpHVsIu2CxfJvi2>; zcit#57RP7DpSwMF-VBm|4V5d=tRgX7RM9%KQ0JRo6d<)RmiIPWe2zh6tmswP`fs^) zwy};#jk|NXMqCSfwIR3QZ#W2`(%sJ>qvk=53CYoLmQt9q|2Gm$sB;rEuBqGJA1OUM zoyl4Wy-HYn0J6L=cad8o)R!Ea^;`rSMg9hYo3?Fw6B9dUq75a-MSb56n8~AAsS(JP zZ!1khPu}!GRpsj+jvl`N1tDD8m1myJCI3c-c<9U-1Vg`xJO~}5_wvPXYh^=Boo^|V z3Tp}|lH!9m4Ipa_$p;b8fjUd=zc4iO7vr)M&Xs0_m$fgY@+hB9%K~4*9$p0d)m2bO ze5JH`W0fnIKdcW!oO#^g1YceSQ4u->{>u@>tLi!fky)o&$h(=he?Fe_6?}O~iSf(F zV&(P~*5h>BW{3e1H%8*7#_%L1#>W97b0@jHtliES^w6w5oldI7QL+?I(Pl$DaN>~d5nXx z;CO1E+S?3E2PLq~)-?ygkHAO1m&hOYmj7?;2XM!$D^f0l9K4P{n}mgb{CoYH6RJ8o ztydc6dNqA)`CG?=Gd~EIbi`UM)eyzGF^+i?&TOdyW~mFH_^Gye(D}clDVFQ@V2Tvy z7rQIaq8Xx`kC;AO-_{k%VI2e6X@bIy^mupEX%{u0=KDUGu~r6lS*7GOeppy{&I&Ly zjOTz=9~jC|qWXznRbrfjg!1`cE!Hzyjzw6l{%>X)TK(UEGi9Uy3f9D6bbn0gT-s`< z8%$Msh!^8WidX7S;)n2jh_n1-QCtSyOAKcPQc(Xlf0*Q|5CSBjo(I-u!R0GJgzTkL z|6QdQRrUMbUO|q0dQ%+d^4)*Mjbm$R}RUcz(7|E0Bq-bAYY@)OsM<+2>}CV zzPBgeD~kBHE(Y+@l2orJrdtV7XXq_V8IETas%7OCYo`oi)+h&v#YN!Qpp7drXFS>6 z?r-q7px+(rIy+bo1uU#I2A5s@ASe01FgGMbouFkhbkm-9yZ8Q2@Q1vuhDQ3D3L+zA z(uz8^rc24VmE5r0Gbd;yOrXnQKAEBfa3@T7fcF$#QYv^00)VZPYehpSc@?^8we}o{ zlX0~o_I<`xSfI8xF(WXO-DX1>wJ`XN?4rw@}_RLD*${$}UaXL=oM(=SDMIxZj1Ji#jAcrH7nYG`r z#ewodj>F5Bf9j(j`a;>)=*2j_ZN}vf!~Hq`2Eyt;9UH1_(yjq1OUO(1M0lI3FZ2j-fU9)L59v&OiQ>5$;d!jg?Fo{Svf5t5FCZbb?)* zJN=Q!?2BztV$7)CWtG0MO~Lr4E5>aoHD5N4(+@~gQEbZTc4s3HrIl_G23PCng4Y3f zbLZK1A-x9x!)WwuI=UBkQ5QyE^&Nrw?@fsRKK41G9-xq=#VyO%CEo`{_eioDj%M!3x=>I zfOPFiFX{1t-|+3E@?UuK=0miGN04hW0=JnJrEyWw{Bg-jMvAA}cg<5LN1c5BQdrIZ z#+bxj9Jbu`11@IUjU|RKfL(UzRlVB4XT ze|(WaxL$KiRqkgCr3^Al(19!_Y7b=E(4Xm7LCO$y5+k;Fu6B#=OSzW`-7p{zRv-_) zPr!|km?8aF}+3hm)QG92YaI+jctX&5IrvTUGf{Y$)TK6)s9v!SMhU=HIpEC~2 z4>o14mG$El2sTA(Ct?xS!l*x7^)oo}|3+BF8QNe;bBHcqdHVmb?#cbS*NqZ%mYS~z z`KLoq7B#KULt%9a#DE%VTEo4TV03T2nr`FK5jUTA$FP0JH6F9oD*|0z1Yf2b5?H0_ zD|K|_5Zk`uu?ZN0U! z_mL>>F;mnHU=@to!Vv*s4;TQr9y)L@1BXXz^a85NSifPTL4h6I>+m_S3~FkXB{N?E zS<3ue_(wqaIS5;4e9{HB`Okl9Y}iFiju+oTqb)BY)QT?~3Oag7nGu-NB5VCOFsiRs zs@m%Ruwl^FuJ1b}g^=*_R?=SYJQ@7o>c9j>)1HgB zyN9LI9ifwu{Shlb6QO2#MWhxq~IG!U^I!6%5}(sbi>=bq8!8@s;4Iaun#kvh7NPwX34Rjbp2f!D)cF&sNIO%9~;C`cs&ZY2=d@c3PpN$YZjUT}X7rY`dlWX$yc znw(7=fzWapI=KzQnJ(6!o0K_aDk!^dZ#)pSTif+jQtQXga$bPApM z=);jZ5c*?*GoeGMnV0=RrZucRRYBjx>tx`A3OuY)#tp2w7mh}&kj)SKoAvbbf;uO! z?+RItUow0xc*6StuO4D--+qY!o}Isy}s;ts5aM5X~eJUZoLOq@dGv=a4hHJD<* z5q{dZSN{bv_(Vj#pFm7Q<$C;MwL|Qizm~QCFx~xQyJoCOZ$`sYD}}q>PwRZjb<=E< zAeMP?qVfM>xu2}Il2xT6={KBdDIstxY-`5IWXN zUiWV&Oiy5R_=2X9Y$ug9Ee=ZSCaza!>dWBMYWrq7uqp>25`btLn^@ydwz?+v?-?2V z?yVwD=rAO!JEABUU1hQ|cY+_OZ14Hb-Ef`qemxp+ZSK?Z;r!gDkJ}&ayJBx+7>#~^ zTm<>LzxR^t-P;1x3$h;-xzQgveY$^C28?jNM6@8$uJiY81sCwNi~+F=78qJZ@bIsz1CO! zgtPM~p6kaCR~-M>zpRCpQI}kUfaiZS`ez6%P6%*!$YCfF=sn}dg!593GFRw>OV2nQ ztTF6uB&}1J`r>gJuBP(z%KW{I^Uz%(^r5#$SK~%w1agl)Gg9Zy9fSK0kyLE24Z(34 zYtihZMQO^*=eY=<5R6LztHaB1AcuIrXoFuQ=7&C}L{c?Z$rto$%n=!whqoqG>#vvC z2%J5LVkU%Ta8hoM($p1WqN}wurA!d@#mQGU5Nb>~#XC84EYH)Zf&DZR!uY+-;VqS< z@q?$ggdX#auS#%%%oS^EN)?JhSR4JYpSgGRQZD<9!YvvF+zp0>C#$!x*x}l8U|Bb& zv?v*im5Bq_(5Wi40b1^nKun$XTST(a8yOAcqQZmKTgGLo)Ig6JuEh5J9NnqJXin@Gxzz-k6xXWYJ&@=JZw=$+ zFPGde%HsR`gI+y`rtiPaMYwbtyp!sVb!pX~;c3zLoPO0eaZSV+O_z z%9H@UhqNowzBTPcMfL6kC>LRaFF6KVaSv1R@%4}rtleX!EMnL`rethYrhTLj1x$tj z;)H!fKo08&T(;i|FT&rPgZ*D0d=B2dXuO_(Uaoi9+vEhs4%{AD{Fl@4^|`X=PvH(s zI7$6bWJiWndP$;&!kSCIR1l57F2?yzmZm~lA5%JKVb;1rQwj*O=^WW~`+n*+fQkK0 zydInOU1Be2`jhA!rnk1iRWR=1SOZpzFoU5{OPpc&A#j6Oc?D&>fAw=>x@H7?SN;d^ z-o&}WR;E|OR`QKItu(y4mT)%Pgqju-3uyH?Y@5>oSLO2Y(0(P!?_xOL=@5+R7rWw# z3J8%Hb@%Pzf^`=J6fEJ_aG6+e7>OUnhaO1(R1<6>f}L z?d@Wnqw9?^;2?q(b@?Wd=T6r_8a@Z4)*_@Q7A`+ zW3w?j!HW0KbhxF%D`9d2HpvIrBxM!36W3Yh5=8_0qYfnHm*yiLB?Ay|V10N%F9XYq zanaDtDk$rS+|_H_r|a${C}C7b{E)Ii20-a?Grff$E?&|gWF<#Ern2GqhCiS0~Y%knIi8zY^lE4qLaR-3M;_Rkz(s;wu z9207W1PXIe#4h4Zw}dvdV&FYcnUlD5_C4hzJ@bPSBVBLpl$&52mi+wwH;svyVIzAB zoA+NQ;Hpqh?A}^Et~xhl>YQNQwh20!muW{ zq}|Pg3jHZWnDBN?r1KhiVG$%Sm-4+=Q2MZzlNr3{#Abqb9j}KK%sHZj{Vr2y4~GIQ zA3Mz1DjQ3q(CC~OyCaZn0M2!){)S!!L~t>-wA&%01?-*H5?nzW?LJB`{r&)vLB4!K zrSm({8SeZ0w(bL9%ZZAZ*^jf=8mAjK^ZR0q9004|3%73z#`-Npqx*X^Ozbja!C1MW z-M~84#=rU1r>p{+h9JU<#K_x$eWqJ+aP%e?7KTSK&1>dlxwhQmkr69uG~0iD@y|L- zlY0vSR2|IhZoS6PpfUai_AhKo2HfdD&mhv#k51CX;T z*sU)XbDyfKjxYC$*_^(U)2-c0>GJ(zVm$CihHKlFSw&1A$mq$vsRt-!$jJe3GTaZ6 z3GcVvmwZ0D>`U+f3i*pQ>${p1UeyF~G9g~g-n{ThVOuC#9=ok`Zgz@qKCSN!1&P`N z=pdlGNwal%9;)ujwWH*#K6CQG*fJDAQiKlO2vKJHeA1lj&WQC+VU^@ea8$#~UOX$*Q!V^8L- zL0$W5(Y3=??%&j_WUq6*x>=?BfmI*d8fmDF*-!XVvxL8p7$r+}Igd_(&`|D*;Z#GE zqm{tHx&aHBpXw&~l6>7-FlyiSPJtTJblAjLU5Ho$FeN0mDguFAq?r+6^~o6|b+rfE zGVcZ&O-X~tE3liGcdI~hHSCT+&F&uH8rr&f{6pr^1y5061`fu~=^_|Idrgti5+*U7 zQOb9G?Rz$j-G0Y}x+i{HB0!4ZmKzykB<0;Rbmo2)T4|VdcwujI_otLG@@8OOKg3kw zP|0ST0D4@zT?O=(0Pikp)Rpwxw_VsmW4!^j^sFd6r5l zw}SG_HQPs>ae%Bq{sye_SaBX%|F-}&^)Wz@Xi<)YNbO?lPs7z@3c;$b^Aw@>E%mOj zW^c%IdtC(Kk@s*}9NbKxEf8SZtP+32ZTxjnrNWS7;W&D~ft{QY?oqOmxlV7JP!kW!Yj`Ur{QbbM1h=0KMaIAmWiISb7TKd4=gMeo+Tcz2>e#NihnOV%iNdx` zeiuoOK^{}D+M+p(Y7EC=&-`$B0F< zQ=zHaM;&QQR4jM$sG=N&sqOvD_Bx*drQ6c@u0()g05cwl`Xm{!S_Nuaa2KlL*rmmk z51yPE)q?Bl$sNM474Y!=zZ zc{EVGpdJ!Su{Qq%llR5O6#zK8l(ld*UVl87@|iaH@C3+*;XBxjEg&fsQrzpMo3EEG zv*Tpms7a;7!|iz8WY7={0a$0ItO-(ajXl;wX_$$yzEF5k9nc>L3wv!p{8h2)G0W?h z{v6vH=7+>$Ho^+)9hDtCd+S_yh8pzS9$)hYev-=eDu?lGIR;-fgz+dr+wcmM-^dZp z9}`&kAf$~z1ovF)>Hgxc!Xe3cju-jQRluCm;c_1=PYQygb?Oxe z!QG0L3sT_k=WpfOPL#|EPlD^t;ENCC39O?tHd<(kfx7SOcxl+E#;ff19_+{vbkZSvbS$I{#>31KZj^$n%ayX0jj}EvsgnHg16P z_A6Y)pdp>kLW<;PtR*Vs#mVb%)ao7AXw{O&hBDmD;?mc3iMH;Ac@rZZ_BQa8CQ~|0 z&d1L{in-z--lBO|pxqc%bqy^~LAGv=E*eaVU~OeuVV{d`Vv#-_W7EYdTDzVraG9H+LC_dWcgZMn~KcP)XvKWbcr5&d+=a>{*(Ha6Y1$==bR z{O-?$7H;`2dt0B%Vm?6`_?ZOjJkyu9ZJsh^WH*+es&^@KDcR%Zej%3PJ*XovgyhTbaH(!H1H_OF~=*f55Jr8A%uW zz5IoAB~1e2-tDGp9}`MnavAMy?jgPM5F%y`%$}dFLrz_* zIrO=afT8+AkK5B1s3{ZDVP$g6y$-*U*=?-fh!cNyn3q6YhNhfRxW&GLIJ2#>9bYMD7-F%{|Iw%@a=DoAAU;3k9p$`V zImKm{5HU~wq|nQFwab)_7lNckW#1z2$|oW5x7vDbBURVjw8674P?L1ogMKpHoV>;# zO%*1OwI|($UOr#hL(*M~qsn3PF%_|15uc%Hy9@D>_~N|?<%lig6yKX0a#1s$o(^Laj8bF#5fGPOFMGmMiUaxSwE}Qf#SG_f79d2Iv=TFBXzTpr$^avJ?=|arh2<+ce}&248Kw0} zhlva`wD6X~s7|37la4FnFOgIHhBiFo`lw~?lSbk{>)P(3jyVhM4O)a=GX3(sW1vIC zz0mJ>;J{!eN5#nf2>$u=3Kq>`7u9QnChi8>CjONBN-b+W_UQIuN#{N$Q<$}IOvpQP zB&5ZrY{V&D=4)voh;6<1U`PFA>V%XUW73S9D^J>cQYfzIyIV5i35WNb5K9c^|M}=* zN_C3rnjCZP1^v{;EaGK7Tp5z~B#?f5NZaAsFUOLK)mI~bJTaL8DF_eRikE{%^J?y9-n_U32EKHPCkB^ZN2*zk{bC=GM%_I z61}nkr+Plg6S0V=mY>H_KQU&)P~=y3$#$*U8FunXkb_e1O-7t@m$5re%u!_G%^?_| zRIJzg+lX$}+ba|qx)Ec6c^ip;`_QfQrD~SPa4MoyRUOtX&~^XWcO^a}KBkXK9J{ZFOA~rovYa0!7btTC*=xNQrwJ)$Eu`TT$;%V&2@y@$ISdNn ztbM7|nO+U9r;ae{{;QiNEYpe4nrFq_x3 z4Tvf^b(I@_3odwhVe!aC0X&~inrYFu# zh)+eF__8ly&nLr4KlLWl%B_ZMo=zCH2QfO^$lJ zBvU*LQ#M(5HQ}2Z9_^y~i@C#h)1C*?N3v68pY+7DD09nxowdG#_AAM5z&*|-9NcB{ z_xKUY>Ya7>TO#Bat}yM}o(~8Ck^!QHnIj8N9}c*uyIs}IEqGn`xP;q3vhW6gsqUe>`m1 z)~ad@y1=?H`1SNl?ANCs5ZD`8tG&Hi=j|R%pP(%gB8pd)Q--E?hWU@)e?>SLV4s(- z!_I^oVC0x97@I(;cnEm$ttKBnI3gXE>>`K?vAq~SK?0YSBsx{@s1ZdiKfFb|zf}ju z7@rJb3mC{U`$R`YS(Z#KyxQx_*nU`kf;}QL%bw17%5~6!mMao^-{FFmX}|ItFuR~F zAAvTF%f4XKYo>2-PJ~ro@Ly#t@Sf69CrA+rmMRpihqH7V&SXX+$Sw`HZF`I*_3Vjz z%kPMyN0J3sl>X{-h12)j&XRhAAI;Aou%%z}gI>G+32z*qpZg{m`CezFrzg#&yc<1` z%j~}PN!F5Ddq(>R{+t0v{j6v^0XwWGu@5+`-$m`_>pCzM`r}wz*8Qv=$|P0R$%tJp z>D+N4GZ|Tg>XL<6XP9_wQRGDs^1icY*5GP4>*7mGMr;V zI%kT_^_SQml6$#uRE4Ps>}?ES)_XI8m-%GN{o^itb^S7e_bM$-wo_Ws)W? zx4_6#*X;T$n2N==N0#xzb~BQU#%^NF6|~898JGDbQxjK(ex;Q}_Qn@?Y>!kkUYUeY z&VclG1#eDPU78K@^p3tAUvZi1(nFfk6AAVHWt)Wbi7dPbjA4isOY~?*1&asp!wg#Q zSpSI6*!TGn3|-%vuJE<9V_1EKkz_0%z}Mb7;E!uz)+0^k;@x+<5tzj5 z!InbRtc`YwNCbCac{plY&Y}hWp#PC{o@5UsBj#tv3f^ns^`;$MVN?>q!pW+MYeC7= zkWr1kAX(0xVQ<{qny&CO*|g1{Mk_yE>1t}_YT<5#p8P7QXf;o|s>XQ#SoA&!ddE+8 zOM&VsxsRGS(Spli?P$^pK7Ty{v86RP_6h|MU^J z`J>vn0|BG3Vf!uR0zM|GwtiTPZNb;a@@1+V5+$P4GI_&$%6m!YRGL=lz5kh?z#5f55 z76COi1`R(5p69;ThuQnJ$R3w?I?jigai2arApagd=^tT~oMUWp^u|H_@zXBjpI)Dv zEFc^_`mVu5U*;ClT?x-t9{#fto_+92GF^dotz0sFWTDwZ`s40AY@mv+Qh5c-Ts8Zp z!(v7!zPvFhUZ-xkR!IvaW`{PqN|k)L4*anbtmK+UU&K*awl?DhxRalbtmDw`$#VzK zYFaG}?$F)1j`Qx7wbn|XzMJ&g@3Ai#u5M?%CLPghk;lD^)-|21{Sr+M(suBU4}6CMTMxc_tD;X;z<1-{FeHte=kh1B9O6Hl z!v2i$d1VFC&z&58zU0`G#7^K3Cs@9LYN16O%Vz)?-iQL!G6&sg6aaX>DBZmm@lFrRJpcL{K3(;+`$9GDFDw62Mud@LZjabzVC=w$dx>TQa}U z-{dhKYTYx*C=Fio`ez@wrzx+p%Fk3i&v?6ENXMb3p^?;_&huLLueDwr zpRqHbU%i;9TmexFxCS8F1rPo-ea3!}!ew7{(($76Rdnfa`~$9{8H@f7U&0&HjZ3TZ zuBc||%FljS_e&wNZ$1ezT$*})XAfm??$_cY_?13vM^tT0EKY2ptb+v5P10}a%aTk_ zh8@_T{ns2@jTFhv`)-Vxh}u(0DiL0MUi(We_eic$;gCoqj(T_S{jDo^PahnKJUp3@ zMOk+%weP*c%K6VFXR2icY`J~-&fVMYUg6fsFI->jlA|9`+07y~$Fsz}^;w;mNk$ms zu?y)VA@QH__tvYDudhEWuDD20H&uvrf_boY{($?5{s-SDjyRxSC%%2Xs5d2dpjdk$ zU*NURD#ovwIfd^H{fXR@UuaooJtQr7$d0+(K+1UEwtG9_T?sb$ExV$e-bpf}a@YUe zuzInI59w!x;<)>Be;a7ukLW>V=8~J6nKU<0@H+SQ!Be;1Za_pw#hiuW_PMPBo8W2G z*WDtiIAN<>HQOmh)DMi{s-0H^GmV3QMf4Zu(zXT!-c;2)uv4gUwt(-}-N*|KUOo$h z+Ak^R)h8yB5UD8 zsSjHgY}KguNi?xV=tdCWqJR!~dDpFQoRJOwxrWH^vfRq4%)v;sDfIjsLXF^)uy>!i z*S8Njd7yfa`+7(|8H9j73Rh|TwFpF(8H-p;RLLIU>k<*qI%A*SL{u$%<=X@Jm1QFe zVkQ(X8P4Tohl?_tSO__^aqaI?k$CC8uNLv2mp_zD@4oDaZfEN5;3#XY!L{8B!;Dtt zb~Zge@JF|#Gsk^5$-|(OPI73po|WZh<`UxaH#Y2!&p05Ph?H)d3Bc3J4sDi$f(6K`?&D&~eHVuE@_Prkt>_&8&aq=OzoN!ANkvho;qIX(g|d#EKQbJ@;-%_iARmgSF1fEK z@B4W@5mDME7AzfL**c&2#B7xO9>rA4x$rM{N=%0=goumK1kL{TF@CSk0yvqR2oo&m z)?nyiL$9~Jt(qnEuWt9Hc_duim%|zJQYiaF*~orVNDvJB;`%ZW_2x%Uu01LeX-JP& zD&fas6d3=igAgcfeki79{5!XPHHYR#nfLYRKv^wkv~cnEbLHMwQ8%yCZI^rK!D2qT zk40Vg;e!_!3d56&umIuidN?6MTZFzHot}AdqKzDh#w0s`)cV!2A74RSH1@lDXtC38 z+UhO4A9?oZEOV{bIgGd1{2qMR&xT+}q!=I8m)W23v!W2WPC?Tf!F!e%_(m^lQZtq* zYwi}gY(KZ*Y^OWRNj$Ph#uEEBM+wtN8QFQ@^`GDOln^ioNrmtvzNNi*qS5lPHxI96#sMil*teLVaa%$msF>@5p#SjT%q8|<4ZOUB#!-kG+|eFSED z!|3c8fXaym9qH`L;pmqTWcG}WE$(h1sZ3seM>)E3ptoP<;~h~qe6XA)lGVanf&->P zjZwi;_;Dt+bYdAeD_XSQ-DgXRXqLv`3Wcgl}myA-JlzBBIh zWq4Q*9#(zjAk_H8VS_AJ`?OS*^gB-rp|~qt;v(C5ef=SErv;~zL64hW`#g!UZQcvZ zF6Ra@S@YhVSkSWVAY=Z1w)w-hfJDRwKTUH0o-OG5TlW0HDH36hIjnP=?A+8u1)Qyy5U8Gi$! zt^!vy|f=YHfQ`ZRK?D zXXn*kItRg50vr2+_hV5kjOleg#s~z(J2p#`=1Tq4#JS`MC^e4p&s7Ir=3m(K$LW#` z=ULCoWtna!so+QQ*JHb~6Ps9_&Ag>9qsUskp0pKbi`n?(u3&@QT!?}N}rXn z>1eHi6(@LicU*AR1obe+nbzTCD#VTJ`PFLRT(nc$NWrhsgRwFni*D(#?W^x=J6?|b zENSc^D}s>Y55)PzFs2d_2;yh89E0ZIgs&>6JV=pL6k9g_(`$04EoY+Zjn}}8e#n83 zJ=zB>BU<253Erdo$wE4^+@QQJFZyAj#(InFlN;!UGg96R@{Y&%OlGG;dM)^X8=Ddw@&2Vx?zui$tO z-{zgaU7&F!xs=e`Mn}r+xrdIAmkraRN_7P1?qu1|TZ%1QR(Mn?k+pq`Xys2v9Gs=a z?r@g&;UKcM#?36r9k*eVD(}9qe8?irotsn0+eHH8*4 zPX@Lusr)$J%8jarx5ssEJ?twFyu4kAbrf`96_z{6at^&UkyDzFa69RXP>PeK+dAWqE5<5P+aHa zs<<*+OO_2ObTXau%y)Nn{(p5`XIPWlvi|asjYcui;E@)Ig{YKBXi}spqC!-P5owwL z3L*+9;0C0G!xoN;4KNfDaElv>1#DMDglI&MAVoK2+c2Pr8&sl*1dYj=^>NRS`{O&%YV25@5*eoOvpD_(xdKsnqb^`T}bm;n0BN9ben1Ynyi*OOf;qLpf^ z!T{}GzkXSszN_Xqzp>}S*Im)_Y8~2|B*ybw(U=Q)5_NcMkT;)1&52YQJB)Tn%kPK! z@3;^AI){B(&UOv<{v9KKJrInkdcXV0%O1%1=7vYV*j?v(Kp~arZio$#(A@$kYB3aM zRdm4!^Je15%66($EkCIWGhi@=kNAyLJ3ydlJnCpPuxH0+OA}J)+t8d7nT->##Nz4w-L=S7ExQt=Rx}S*mpT91(>t~qe7tM%e|O)TIO^dP zfo61GNS=cJbLutqUh84?7X#bq)bv57s&D_zm{+xNv7vHjb=_}j-Lrj-Ss*pcD@ts$ z)5Dol8Z_&*1@JdAQE7SL$*!TXI|YE7q=YGkIiUeLvT0)14Q-ivs|+cqeT6DTi9eQ)h?Pu9pqmH51B* zFMd|;l2@D4*56|EhMFlDxl2i<8qq=c+AhMYS3(A28#3DZ;_Ln>RA3q#IAdJq7M#N> zTZ8t=_>lq0=W&w|bdQ^sy&m^@KR)mNi3|1<6|OL(0KLtP#I6ix$2b{-Y9GP5I7 z8AJUSCnlia5vWawX%ZLWTC2UV$cn^sfv68W!6)QO;ZjnX=7#`$ZPRG~irfl)ZUJ^D z{lUk?(*SU7XIiS^H{Lpxn%542#PgxdeG)Ociej#(uvX)z;Z3)<16Yhd z-sv?qQ5D4a)ZYoYPRep2Zvom@U)HKq*54ZEwdaEq^FZG#(CyG!=Vw(0j8CCmP~`_z z=OR^i&WkDCf2cLvWm@d?)mEgme{hA(o#xAL023LZ3(82SGRg6jJF7$kZ4! z6*FTm4y6v~CP!3$+fxg{QeFo24<3iucgI!oyjV|9Dsx}r~4X@lt^VaH$u zD?87}1Jh=?G8OYg*ts2k;X9{f*Za?yu8IUUfyuQ**wbcWT+KncjD^qQ3h&w2+S(Mj zZM~?Ot%ggTIHwkBkL-4&jI5R=B+MCOR42bKzC2M>l?1%x2Iv7amIfQ1B#wwfD`z|m z+E?G+o(tde*Ws?;Wo4p#Yy>Nnf|*b<nj@-s(rZ)-U@ z(Xe(qZ1(_dH|J3yWu|bAPINK}DwF(kZ>FKx(?ZmU^KFC6*bh$;FKGh~pH1 zozA+kgcIk9@2aAwEJ=VYizT!sxDXX$N?XDiGKaaT-OU@Ib=~4DmgEk&{2D@IvyjF* zuF@sDcuuqx_FAgx;B@@8gqjMh!kQeEKA*y4+q+^4&uc0|>M;$Xb+ z@X%eUx1m%$WSP}Qchx68NQ?dO!h`6;Quq+A1(RORsQ-;6bZ90vj#^0(7>cLR+-_;9 zCd@b~B5V>$tpjkQU#BD%9^zu7-l>U8nzt+XuX5cYDCHYaX5t~~3?lpa;)Mr>q;5XW zu(Th;fr}-GkP`K)u97(#UB|L3f;H7Cd#Pox+auV`=m?a=mSv1v)(V!E=$%gkIJZ;` zZj{Lb@bhs%bRa znZw9cD$cDFVHPtpXwY1K)wys@LS~;!qdqkR>@&RtP>?M^>xe{4N#EtZy4zZ5Ar$ZF zV=X=(!xin-58MC<+b~;jk8Q|3B3THGIA$cM8Bg)Yd6ygP#i?4VrX3OvP_k5i{Cppw z-{$XwrJ-+X$ccJ(Q{|?T@U9=-?qlsfA43%8t247KZn?`+C4e`b-e^(df*iW66=Oc2 z3w9UhohfdY@pH1MZ}vc<1osV(2CGG)Ree$E-T;8>$zw*>x-505b&4(shMGIjbAfLS zEZ3ys(`SmCWc(75)^=aKer}>67qj^nGKtCK{35I|tA}wQa!uM!suX%Gb~ylORGGc( ze^|m|N!}G0#Ph|;wSXz`SByQM>lPM#8>mdSQs`7RxkXaSAADYA24u6xWqkIXY?o%z z%TEFL+wNW^&nrvaA1_#P%&Hbzrjl!*hIft>F0@g0IVydUU4MJgS3_3Js8{*>|G2jC z4%n#cOy9b2Xf&Pw=14;0Dtf00C^Z$I-v05OqtvN9>sAC&oV1Tk;;ku7VR`sQK4oFq zQ8)yoZNuTwV$t13|GCUIC{ID_r7M5&R*zhsxbrkg;EgMtL|9ne=^}BM!dxV!KDeXkWA^MfQTkQEt8~t>JznNh%ULvn@dbQ2cyf} z|C%ns#NJU}SHU(7Pg$<&8uDK>d5GZJ&`;CcfGP(~b-#UusXevc^q!km1X6_wVMqGk z^m&ZS6#42?p4c_t1TA$_+}h1L2c<<=$k%;v+D!<@j5hs|{>d18>~~v#oq4yGyS@QP zgTX2oJbEy@eJbo-f{ZQ>-nmB-#AqWcHbMQXFi*T)0n!(HIexz=pp<(O*DMh7CMupX z)ei1ZYuIW~E={-ND*nD;okiZdm!?^|LjLZhs*FHZvWld5TDj zcvWB)`-1Me9bu`*4M=CO6ye=pMgxlgYvsh2rV#5Z$hFKw0GX30%oufb=hJ0BFIJH` z+Fii4gQ+7!)8K^yc*PVEW^#f!|BW0Q5*`IewQ5YDFh?{x1L7tlaUAX@3Y+D>6FPVf zJzOGex~H34`8eq+TL$FsHm+27RS>3$CG;>0Jj4*1ukX$za})*b^S5p}I2jbFCHLsA zzYwAyftMz`uo2c8ieQcy-p&9iP3fMk(uRw+OlBPm`KCLei6g!|Vnk*-kjs>A25MTE z5GLDMV$70AC0j-tx*0sCruvKh{fSM)3X}13U>m|KeaOb`9^}v^44!$`06-JHf@L4EKyxV)M!8cL zi5p9kF97RiAT92!e?%9CP=qX3wyv^A8q!w%07d(9f-U))uDgsr4FDVL;|%r)fw}-@ zlB$F79X^EKYF%8J7mU?3VzJoYQ0<;NczW1jH4=4kEh_)q|^9wj zIsn-SsmRx0_EJ7(6WypwptIwZ)-T<__UgUu?BXt zoIf|a!5`?&JEb$w2PZSqhA>J;GIA^rJ-Cpz8MKX~bcqZNOUzPtu|NMvEP>+cO;V*W zNQ8YPENkr!)lN+tlxB79RUD20$)+_P6Jc`+4q@%Kno{F+#1qR*zrj%T>nTSceO?a5 zyqGDa59#G6k*RXu6+#=e=e!~i1Y&15!cHmE6sLh_K%Ppv$tFE-Le3RQs-nx5LB>gy z5A))kwkxWSy73{@I{%{DY8X+2o{CLJb~R$3r=oT^P~Xo$2lKz8?Z!3QLn$5l#L2k2 zb1=?UT&c<8!&9gW1M&jI!5%dhJbD3nQXpaeNJ>=zR+EL!4iY(nMBQI+|2J+Hw-WMr z08Mt9h8(PGbY?zKtk=cqw(yW}1A#htn* z8&}5Y>$uc>Lv!bSuWQ5UB&ct7*jiZAFpxz|%xO&5kg zzlf?6xy7H3G^*wvP5scW*Wf(<&eP!YIUf%&HT?K)RWmKg$G^=mSoi~;&9dU%{o}WV z#BX;9+q)fpVU`>Vdo~AtYK)`7z*H;dc-e|q6Qt;3J0APUL!~g&Q literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png new file mode 100644 index 0000000000000000000000000000000000000000..ed4cc16421680a50164ba74381b4b35ceaa0ccfc GIT binary patch literal 3276 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 N;OXk;vd$@?2>?>Ex^Vyi literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png new file mode 100644 index 0000000000000000000000000000000000000000..bcbf36df2f2aaaa0a63c7dabc94e600184229d0d GIT binary patch literal 5933 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 f$KZHO*s&vt|9^w-6P?|#0pRK8NSwWJ?9znhg z3{`3j3=J&|48MRv4KElNN(~qoUL`OvSj}Ky5HFasE6@fg!ItFh?!xdN1Q+aGJ{c&& zS>O>_%)r1c48n{Iv*t(u1=&kHeO=ifbFy+6aSK)V_AxLppYn8Z42d|rc6w}vOsL55 z`t&mC&y2@JTEyg!eDiFX^k#CC!jq%>erB=yHqUP0XcDOTw6ko}L zX;EmMrq(fKk*eygEuA616;0)>@A{TK|55PV@70 z$OfzS*(VJxQev3J?yY?O=ul(v`fp}?u9z`JK3ugibK>)DyCwImZOF4d{xK%%Ks1*} zv$oa)9anR%lXIBUqYnhLmT>VOzHfNP?ZwJNZ!5$s9M08RynIvaXw>@G^T9@r9^KH1 zVy??F&uuk)bH9Y4pQY!hP58i_H6 znl-NcuCpLV6ZWU;4C zu@9exF&OZi`Bovq_m%T+WhU2kvkz@^_LpycBvqm3bMpLw8X-Or5sL>0AKE1$(k_L=_Zc=CUq#=x1-QZf)G7nHu@fmsQ1eN_N3+nTEz`4HI4Z6uVlE zJH+X&det8JU?tO?upcM4Z=cV!JV;yF>FfL5Q$M|W_2Z!P`S=}Wzp|_1^#d%e?_H`> zV@%vA$+bFVqhw9`U;TfP|5|PD{||OiYdor8P*i??|NJcb%kzT_73*7WE?Ua5hAnR2 z=7WE=PhTlJ#ZeRznjTUb;`E(wkMZrj4e|Hilz-mK>9cZHQY**5TUPw~u}k;u73KI}xAx!0m-)GVia|x^d3p~s_9gh83jA&Ra<8rM%`>U3x69t&NzbwWY}7Ar?)FK#IZ0z|d0H0EkRO w3{9;}4Xg|ebq&m|3=9_N6z8I7$jwj5OsmAL;bP(Gi$Dzwp00i_>zopr02+f8CIA2c literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png new file mode 100644 index 0000000000000000000000000000000000000000..e71a726136a47ed24125c7efc79d68a4a01961b4 GIT binary patch literal 14800 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 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/AppInfo.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/AppInfo.xcconfig new file mode 100644 index 0000000..8b42559 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Debug.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Debug.xcconfig new file mode 100644 index 0000000..36b0fd9 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Debug.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Debug.xcconfig" +#include "Warnings.xcconfig" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Release.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Release.xcconfig new file mode 100644 index 0000000..dff4f49 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Release.xcconfig @@ -0,0 +1,2 @@ +#include "../../Flutter/Flutter-Release.xcconfig" +#include "Warnings.xcconfig" diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Warnings.xcconfig b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Configs/Warnings.xcconfig new file mode 100644 index 0000000..42bcbf4 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/DebugProfile.entitlements b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/DebugProfile.entitlements new file mode 100644 index 0000000..dcf4060 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/DebugProfile.entitlements @@ -0,0 +1,14 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.cs.allow-jit + + com.apple.security.network.server + + com.apple.security.network.client + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Info.plist b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Info.plist new file mode 100644 index 0000000..4789daa --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/MainFlutterWindow.swift b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/MainFlutterWindow.swift new file mode 100644 index 0000000..2722837 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/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/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Release.entitlements b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Release.entitlements new file mode 100644 index 0000000..1f6330d --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/macos/Runner/Release.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.network.client + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/pubspec.yaml b/local_packages/extended_text_field-16.0.2-patched/example/pubspec.yaml new file mode 100644 index 0000000..62233ad --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/pubspec.yaml @@ -0,0 +1,99 @@ +name: example +description: A new Flutter application. +publish_to: none +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: '>=3.4.0 <4.0.0' + flutter: ">=3.22.0" +dependencies: + + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + + + cupertino_icons: ^1.0.4 + + ff_annotation_route_library: ^3.0.0 + extended_text: ^14.0.1 + # extended_text: + # version: ^11.0.0-dev.1 + # hosted: "https://pub.dev" + flutter: + sdk: flutter + html: ^0.15.0 + loading_more_list: ^7.1.0 + oktoast: ^3.1.5 + url_launcher: ^6.0.17 + extended_keyboard: ^0.0.3 + extended_image: any + +dev_dependencies: + flutter_test: + sdk: flutter +dependency_overrides: + extended_text_field: + path: ../ + + #extended_text: + # git: + # url: https://github.com/fluttercandies/extended_text.git + # ref: refactor + #path: ../../extended_text + #extended_text_library: + # git: + # url: https://github.com/fluttercandies/extended_text_library.git + # ref: refactor + #path: ../../extended_text_library +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + assets: + - assets/ + # To add assets to your application, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.dev/assets-and-images/#resolution-aware. + + # For details regarding adding assets from package dependencies, see + # https://flutter.dev/assets-and-images/#from-packages + + # To add custom fonts to your application, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts from package dependencies, + # see https://flutter.dev/custom-fonts/#from-packages diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/favicon.png b/local_packages/extended_text_field-16.0.2-patched/example/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-192.png b/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-512.png b/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-192.png b/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-512.png b/local_packages/extended_text_field-16.0.2-patched/example/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/index.html b/local_packages/extended_text_field-16.0.2-patched/example/web/index.html new file mode 100644 index 0000000..b6b9dd2 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/web/index.html @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + example + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/web/manifest.json b/local_packages/extended_text_field-16.0.2-patched/example/web/manifest.json new file mode 100644 index 0000000..096edf8 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "example", + "short_name": "example", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/CMakeLists.txt b/local_packages/extended_text_field-16.0.2-patched/example/windows/CMakeLists.txt new file mode 100644 index 0000000..abf9040 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/CMakeLists.txt @@ -0,0 +1,95 @@ +cmake_minimum_required(VERSION 3.15) +project(example LANGUAGES CXX) + +set(BINARY_NAME "example") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Configure build options. +get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) +if(IS_MULTICONFIG) + set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" + CACHE STRING "" FORCE) +else() + 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() +endif() + +set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") +set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") +set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") +set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") + +# Use Unicode for all projects. +add_definitions(-DUNICODE -D_UNICODE) + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") + target_compile_options(${TARGET} PRIVATE /EHsc) + target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") + target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + + +# === Installation === +# Support files are copied into place next to the executable, so that it can +# run in place. This is done instead of making a separate bundle (as on Linux) +# so that building and running from within Visual Studio will work. +set(BUILD_BUNDLE_DIR "$") +# Make the "install" step default, as it's required to run. +set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") + +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) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# 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. +install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + CONFIGURATIONS Profile;Release + COMPONENT Runtime) diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/CMakeLists.txt b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/CMakeLists.txt new file mode 100644 index 0000000..744f08a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/CMakeLists.txt @@ -0,0 +1,102 @@ +cmake_minimum_required(VERSION 3.15) + +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. +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# === Flutter Library === +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") + +# 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/windows/app.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_windows.h" + "flutter_messenger.h" + "flutter_plugin_registrar.h" +) +list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app 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. +set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") +set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) +add_custom_command( + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${PHONY_OUTPUT} + COMMAND ${CMAKE_COMMAND} -E env + ${FLUTTER_TOOL_ENVIRONMENT} + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" + windows-x64 $ + VERBATIM +) +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.cc b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.cc new file mode 100644 index 0000000..4f78848 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.cc @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + UrlLauncherWindowsRegisterWithRegistrar( + registry->GetRegistrarForPlugin("UrlLauncherWindows")); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugin_registrant.h new file mode 100644 index 0000000..dc139d8 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/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 RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugins.cmake b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugins.cmake new file mode 100644 index 0000000..88b22e5 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/flutter/generated_plugins.cmake @@ -0,0 +1,24 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + url_launcher_windows +) + +list(APPEND FLUTTER_FFI_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows 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}/windows plugins/${ffi_plugin}) + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) +endforeach(ffi_plugin) diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/CMakeLists.txt b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/CMakeLists.txt new file mode 100644 index 0000000..977e38b --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/CMakeLists.txt @@ -0,0 +1,18 @@ +cmake_minimum_required(VERSION 3.15) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} WIN32 + "flutter_window.cpp" + "main.cpp" + "run_loop.cpp" + "utils.cpp" + "win32_window.cpp" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" + "Runner.rc" + "runner.exe.manifest" +) +apply_standard_settings(${BINARY_NAME}) +target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/Runner.rc b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/Runner.rc new file mode 100644 index 0000000..944329a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/Runner.rc @@ -0,0 +1,121 @@ +// Microsoft Visual C++ generated resource script. +// +#pragma code_page(65001) +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (United States) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_APP_ICON ICON "resources\\app_icon.ico" + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +#ifdef FLUTTER_BUILD_NUMBER +#define VERSION_AS_NUMBER FLUTTER_BUILD_NUMBER +#else +#define VERSION_AS_NUMBER 1,0,0 +#endif + +#ifdef FLUTTER_BUILD_NAME +#define VERSION_AS_STRING #FLUTTER_BUILD_NAME +#else +#define VERSION_AS_STRING "1.0.0" +#endif + +VS_VERSION_INFO VERSIONINFO + FILEVERSION VERSION_AS_NUMBER + PRODUCTVERSION VERSION_AS_NUMBER + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "com.example" "\0" + VALUE "FileDescription", "A new Flutter project." "\0" + VALUE "FileVersion", VERSION_AS_STRING "\0" + VALUE "InternalName", "example" "\0" + VALUE "LegalCopyright", "Copyright (C) 2020 com.example. All rights reserved." "\0" + VALUE "OriginalFilename", "example.exe" "\0" + VALUE "ProductName", "example" "\0" + VALUE "ProductVersion", VERSION_AS_STRING "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // English (United States) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.cpp b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.cpp new file mode 100644 index 0000000..c422723 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.cpp @@ -0,0 +1,64 @@ +#include "flutter_window.h" + +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project) + : run_loop_(run_loop), project_(project) {} + +FlutterWindow::~FlutterWindow() {} + +bool FlutterWindow::OnCreate() { + if (!Win32Window::OnCreate()) { + return false; + } + + RECT frame = GetClientArea(); + + // The size here must match the window dimensions to avoid unnecessary surface + // creation / destruction in the startup path. + flutter_controller_ = std::make_unique( + frame.right - frame.left, frame.bottom - frame.top, project_); + // Ensure that basic setup of the controller was successful. + if (!flutter_controller_->engine() || !flutter_controller_->view()) { + return false; + } + RegisterPlugins(flutter_controller_->engine()); + run_loop_->RegisterFlutterInstance(flutter_controller_->engine()); + SetChildContent(flutter_controller_->view()->GetNativeWindow()); + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_controller_) { + run_loop_->UnregisterFlutterInstance(flutter_controller_->engine()); + flutter_controller_ = nullptr; + } + + Win32Window::OnDestroy(); +} + +LRESULT +FlutterWindow::MessageHandler(HWND hwnd, UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + // Give Flutter, including plugins, an opporutunity to handle window messages. + if (flutter_controller_) { + std::optional result = + flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, + lparam); + if (result) { + return *result; + } + } + + switch (message) { + case WM_FONTCHANGE: + flutter_controller_->engine()->ReloadSystemFonts(); + break; + } + + return Win32Window::MessageHandler(hwnd, message, wparam, lparam); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.h new file mode 100644 index 0000000..b663ddd --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/flutter_window.h @@ -0,0 +1,39 @@ +#ifndef RUNNER_FLUTTER_WINDOW_H_ +#define RUNNER_FLUTTER_WINDOW_H_ + +#include +#include + +#include + +#include "run_loop.h" +#include "win32_window.h" + +// A window that does nothing but host a Flutter view. +class FlutterWindow : public Win32Window { + public: + // Creates a new FlutterWindow driven by the |run_loop|, hosting a + // Flutter view running |project|. + explicit FlutterWindow(RunLoop* run_loop, + const flutter::DartProject& project); + virtual ~FlutterWindow(); + + protected: + // Win32Window: + bool OnCreate() override; + void OnDestroy() override; + LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, + LPARAM const lparam) noexcept override; + + private: + // The run loop driving events for this window. + RunLoop* run_loop_; + + // The project to run. + flutter::DartProject project_; + + // The Flutter instance hosted by this window. + std::unique_ptr flutter_controller_; +}; + +#endif // RUNNER_FLUTTER_WINDOW_H_ diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/main.cpp b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/main.cpp new file mode 100644 index 0000000..fc17fec --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/main.cpp @@ -0,0 +1,36 @@ +#include +#include +#include + +#include "flutter_window.h" +#include "run_loop.h" +#include "utils.h" + +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, + _In_ wchar_t *command_line, _In_ int show_command) { + // Attach to console when present (e.g., 'flutter run') or create a + // new console when running with a debugger. + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { + CreateAndAttachConsole(); + } + + // Initialize COM, so that it is available for use in the library and/or + // plugins. + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); + + RunLoop run_loop; + + flutter::DartProject project(L"data"); + FlutterWindow window(&run_loop, project); + Win32Window::Point origin(10, 10); + Win32Window::Size size(1280, 720); + if (!window.CreateAndShow(L"example", origin, size)) { + return EXIT_FAILURE; + } + window.SetQuitOnClose(true); + + run_loop.Run(); + + ::CoUninitialize(); + return EXIT_SUCCESS; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resource.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resource.h new file mode 100644 index 0000000..66a65d1 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by Runner.rc +// +#define IDI_APP_ICON 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resources/app_icon.ico b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/resources/app_icon.ico new file mode 100644 index 0000000000000000000000000000000000000000..c04e20caf6370ebb9253ad831cc31de4a9c965f6 GIT binary patch literal 33772 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 literal 0 HcmV?d00001 diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.cpp b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.cpp new file mode 100644 index 0000000..2d6636a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.cpp @@ -0,0 +1,66 @@ +#include "run_loop.h" + +#include + +#include + +RunLoop::RunLoop() {} + +RunLoop::~RunLoop() {} + +void RunLoop::Run() { + bool keep_running = true; + TimePoint next_flutter_event_time = TimePoint::clock::now(); + while (keep_running) { + std::chrono::nanoseconds wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - TimePoint::clock::now()); + ::MsgWaitForMultipleObjects( + 0, nullptr, FALSE, static_cast(wait_duration.count() / 1000), + QS_ALLINPUT); + bool processed_events = false; + MSG message; + // All pending Windows messages must be processed; MsgWaitForMultipleObjects + // won't return again for items left in the queue after PeekMessage. + while (::PeekMessage(&message, nullptr, 0, 0, PM_REMOVE)) { + processed_events = true; + if (message.message == WM_QUIT) { + keep_running = false; + break; + } + ::TranslateMessage(&message); + ::DispatchMessage(&message); + // Allow Flutter to process messages each time a Windows message is + // processed, to prevent starvation. + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + // If the PeekMessage loop didn't run, process Flutter messages. + if (!processed_events) { + next_flutter_event_time = + std::min(next_flutter_event_time, ProcessFlutterMessages()); + } + } +} + +void RunLoop::RegisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.insert(flutter_instance); +} + +void RunLoop::UnregisterFlutterInstance( + flutter::FlutterEngine* flutter_instance) { + flutter_instances_.erase(flutter_instance); +} + +RunLoop::TimePoint RunLoop::ProcessFlutterMessages() { + TimePoint next_event_time = TimePoint::max(); + for (auto instance : flutter_instances_) { + std::chrono::nanoseconds wait_duration = instance->ProcessMessages(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, TimePoint::clock::now() + wait_duration); + } + } + return next_event_time; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.h new file mode 100644 index 0000000..000d362 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/run_loop.h @@ -0,0 +1,40 @@ +#ifndef RUNNER_RUN_LOOP_H_ +#define RUNNER_RUN_LOOP_H_ + +#include + +#include +#include + +// A runloop that will service events for Flutter instances as well +// as native messages. +class RunLoop { + public: + RunLoop(); + ~RunLoop(); + + // Prevent copying + RunLoop(RunLoop const&) = delete; + RunLoop& operator=(RunLoop const&) = delete; + + // Runs the run loop until the application quits. + void Run(); + + // Registers the given Flutter instance for event servicing. + void RegisterFlutterInstance( + flutter::FlutterEngine* flutter_instance); + + // Unregisters the given Flutter instance from event servicing. + void UnregisterFlutterInstance( + flutter::FlutterEngine* flutter_instance); + + private: + using TimePoint = std::chrono::steady_clock::time_point; + + // Processes all currently pending messages for registered Flutter instances. + TimePoint ProcessFlutterMessages(); + + std::set flutter_instances_; +}; + +#endif // RUNNER_RUN_LOOP_H_ diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/runner.exe.manifest b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/runner.exe.manifest new file mode 100644 index 0000000..c977c4a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/runner.exe.manifest @@ -0,0 +1,20 @@ + + + + + PerMonitorV2 + + + + + + + + + + + + + + + diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.cpp b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.cpp new file mode 100644 index 0000000..37501e5 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.cpp @@ -0,0 +1,22 @@ +#include "utils.h" + +#include +#include +#include +#include + +#include + +void CreateAndAttachConsole() { + if (::AllocConsole()) { + FILE *unused; + if (freopen_s(&unused, "CONOUT$", "w", stdout)) { + _dup2(_fileno(stdout), 1); + } + if (freopen_s(&unused, "CONOUT$", "w", stderr)) { + _dup2(_fileno(stdout), 2); + } + std::ios::sync_with_stdio(); + FlutterDesktopResyncOutputStreams(); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.h new file mode 100644 index 0000000..d792603 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/utils.h @@ -0,0 +1,8 @@ +#ifndef RUNNER_UTILS_H_ +#define RUNNER_UTILS_H_ + +// Creates a console for the process, and redirects stdout and stderr to +// it for both the runner and the Flutter library. +void CreateAndAttachConsole(); + +#endif // RUNNER_UTILS_H_ diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.cpp b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.cpp new file mode 100644 index 0000000..efc3eb9 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.cpp @@ -0,0 +1,244 @@ +#include "win32_window.h" + +#include + +#include "resource.h" + +namespace { + +constexpr const wchar_t kWindowClassName[] = L"FLUTTER_RUNNER_WIN32_WINDOW"; + +// The number of Win32Window objects that currently exist. +static int g_active_window_count = 0; + +using EnableNonClientDpiScaling = BOOL __stdcall(HWND hwnd); + +// Scale helper to convert logical scaler values to physical using passed in +// scale factor +int Scale(int source, double scale_factor) { + return static_cast(source * scale_factor); +} + +// Dynamically loads the |EnableNonClientDpiScaling| from the User32 module. +// This API is only needed for PerMonitor V1 awareness mode. +void EnableFullDpiSupportIfAvailable(HWND hwnd) { + HMODULE user32_module = LoadLibraryA("User32.dll"); + if (!user32_module) { + return; + } + auto enable_non_client_dpi_scaling = + reinterpret_cast( + GetProcAddress(user32_module, "EnableNonClientDpiScaling")); + if (enable_non_client_dpi_scaling != nullptr) { + enable_non_client_dpi_scaling(hwnd); + FreeLibrary(user32_module); + } +} + +} // namespace + +// Manages the Win32Window's window class registration. +class WindowClassRegistrar { + public: + ~WindowClassRegistrar() = default; + + // Returns the singleton registar instance. + static WindowClassRegistrar* GetInstance() { + if (!instance_) { + instance_ = new WindowClassRegistrar(); + } + return instance_; + } + + // Returns the name of the window class, registering the class if it hasn't + // previously been registered. + const wchar_t* GetWindowClass(); + + // Unregisters the window class. Should only be called if there are no + // instances of the window. + void UnregisterWindowClass(); + + private: + WindowClassRegistrar() = default; + + static WindowClassRegistrar* instance_; + + bool class_registered_ = false; +}; + +WindowClassRegistrar* WindowClassRegistrar::instance_ = nullptr; + +const wchar_t* WindowClassRegistrar::GetWindowClass() { + if (!class_registered_) { + WNDCLASS window_class{}; + window_class.hCursor = LoadCursor(nullptr, IDC_ARROW); + window_class.lpszClassName = kWindowClassName; + window_class.style = CS_HREDRAW | CS_VREDRAW; + window_class.cbClsExtra = 0; + window_class.cbWndExtra = 0; + window_class.hInstance = GetModuleHandle(nullptr); + window_class.hIcon = + LoadIcon(window_class.hInstance, MAKEINTRESOURCE(IDI_APP_ICON)); + window_class.hbrBackground = 0; + window_class.lpszMenuName = nullptr; + window_class.lpfnWndProc = Win32Window::WndProc; + RegisterClass(&window_class); + class_registered_ = true; + } + return kWindowClassName; +} + +void WindowClassRegistrar::UnregisterWindowClass() { + UnregisterClass(kWindowClassName, nullptr); + class_registered_ = false; +} + +Win32Window::Win32Window() { + ++g_active_window_count; +} + +Win32Window::~Win32Window() { + --g_active_window_count; + Destroy(); +} + +bool Win32Window::CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size) { + Destroy(); + + const wchar_t* window_class = + WindowClassRegistrar::GetInstance()->GetWindowClass(); + + const POINT target_point = {static_cast(origin.x), + static_cast(origin.y)}; + HMONITOR monitor = MonitorFromPoint(target_point, MONITOR_DEFAULTTONEAREST); + UINT dpi = FlutterDesktopGetDpiForMonitor(monitor); + double scale_factor = dpi / 96.0; + + HWND window = CreateWindow( + window_class, title.c_str(), WS_OVERLAPPEDWINDOW | WS_VISIBLE, + Scale(origin.x, scale_factor), Scale(origin.y, scale_factor), + Scale(size.width, scale_factor), Scale(size.height, scale_factor), + nullptr, nullptr, GetModuleHandle(nullptr), this); + + if (!window) { + return false; + } + + return OnCreate(); +} + +// static +LRESULT CALLBACK Win32Window::WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + if (message == WM_NCCREATE) { + auto window_struct = reinterpret_cast(lparam); + SetWindowLongPtr(window, GWLP_USERDATA, + reinterpret_cast(window_struct->lpCreateParams)); + + auto that = static_cast(window_struct->lpCreateParams); + EnableFullDpiSupportIfAvailable(window); + that->window_handle_ = window; + } else if (Win32Window* that = GetThisFromHandle(window)) { + return that->MessageHandler(window, message, wparam, lparam); + } + + return DefWindowProc(window, message, wparam, lparam); +} + +LRESULT +Win32Window::MessageHandler(HWND hwnd, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept { + switch (message) { + case WM_DESTROY: + window_handle_ = nullptr; + Destroy(); + if (quit_on_close_) { + PostQuitMessage(0); + } + return 0; + + case WM_DPICHANGED: { + auto newRectSize = reinterpret_cast(lparam); + LONG newWidth = newRectSize->right - newRectSize->left; + LONG newHeight = newRectSize->bottom - newRectSize->top; + + SetWindowPos(hwnd, nullptr, newRectSize->left, newRectSize->top, newWidth, + newHeight, SWP_NOZORDER | SWP_NOACTIVATE); + + return 0; + } + case WM_SIZE: + RECT rect = GetClientArea(); + if (child_content_ != nullptr) { + // Size and position the child window. + MoveWindow(child_content_, rect.left, rect.top, rect.right - rect.left, + rect.bottom - rect.top, TRUE); + } + return 0; + + case WM_ACTIVATE: + if (child_content_ != nullptr) { + SetFocus(child_content_); + } + return 0; + } + + return DefWindowProc(window_handle_, message, wparam, lparam); +} + +void Win32Window::Destroy() { + OnDestroy(); + + if (window_handle_) { + DestroyWindow(window_handle_); + window_handle_ = nullptr; + } + if (g_active_window_count == 0) { + WindowClassRegistrar::GetInstance()->UnregisterWindowClass(); + } +} + +Win32Window* Win32Window::GetThisFromHandle(HWND const window) noexcept { + return reinterpret_cast( + GetWindowLongPtr(window, GWLP_USERDATA)); +} + +void Win32Window::SetChildContent(HWND content) { + child_content_ = content; + SetParent(content, window_handle_); + RECT frame = GetClientArea(); + + MoveWindow(content, frame.left, frame.top, frame.right - frame.left, + frame.bottom - frame.top, true); + + SetFocus(child_content_); +} + +RECT Win32Window::GetClientArea() { + RECT frame; + GetClientRect(window_handle_, &frame); + return frame; +} + +HWND Win32Window::GetHandle() { + return window_handle_; +} + +void Win32Window::SetQuitOnClose(bool quit_on_close) { + quit_on_close_ = quit_on_close; +} + +bool Win32Window::OnCreate() { + // No-op; provided for subclasses. + return true; +} + +void Win32Window::OnDestroy() { + // No-op; provided for subclasses. +} diff --git a/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.h b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.h new file mode 100644 index 0000000..17ba431 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/example/windows/runner/win32_window.h @@ -0,0 +1,98 @@ +#ifndef RUNNER_WIN32_WINDOW_H_ +#define RUNNER_WIN32_WINDOW_H_ + +#include + +#include +#include +#include + +// A class abstraction for a high DPI-aware Win32 Window. Intended to be +// inherited from by classes that wish to specialize with custom +// rendering and input handling +class Win32Window { + public: + struct Point { + unsigned int x; + unsigned int y; + Point(unsigned int x, unsigned int y) : x(x), y(y) {} + }; + + struct Size { + unsigned int width; + unsigned int height; + Size(unsigned int width, unsigned int height) + : width(width), height(height) {} + }; + + Win32Window(); + virtual ~Win32Window(); + + // Creates and shows a win32 window with |title| and position and size using + // |origin| and |size|. New windows are created on the default monitor. Window + // sizes are specified to the OS in physical pixels, hence to ensure a + // consistent size to will treat the width height passed in to this function + // as logical pixels and scale to appropriate for the default monitor. Returns + // true if the window was created successfully. + bool CreateAndShow(const std::wstring& title, + const Point& origin, + const Size& size); + + // Release OS resources associated with window. + void Destroy(); + + // Inserts |content| into the window tree. + void SetChildContent(HWND content); + + // Returns the backing Window handle to enable clients to set icon and other + // window properties. Returns nullptr if the window has been destroyed. + HWND GetHandle(); + + // If true, closing this window will quit the application. + void SetQuitOnClose(bool quit_on_close); + + // Return a RECT representing the bounds of the current client area. + RECT GetClientArea(); + + protected: + // Processes and route salient window messages for mouse handling, + // size change and DPI. Delegates handling of these to member overloads that + // inheriting classes can handle. + virtual LRESULT MessageHandler(HWND window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Called when CreateAndShow is called, allowing subclass window-related + // setup. Subclasses should return false if setup fails. + virtual bool OnCreate(); + + // Called when Destroy is called. + virtual void OnDestroy(); + + private: + friend class WindowClassRegistrar; + + // OS callback called by message pump. Handles the WM_NCCREATE message which + // is passed when the non-client area is being created and enables automatic + // non-client DPI scaling so that the non-client area automatically + // responsponds to changes in DPI. All other messages are handled by + // MessageHandler. + static LRESULT CALLBACK WndProc(HWND const window, + UINT const message, + WPARAM const wparam, + LPARAM const lparam) noexcept; + + // Retrieves a class instance pointer for |window| + static Win32Window* GetThisFromHandle(HWND const window) noexcept; + + bool quit_on_close_ = false; + + // window handle for top level window. + HWND window_handle_ = nullptr; + + // window handle for hosted content. + HWND child_content_ = nullptr; +}; + +#endif // RUNNER_WIN32_WINDOW_H_ diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/extended_text_field.dart b/local_packages/extended_text_field-16.0.2-patched/lib/extended_text_field.dart new file mode 100644 index 0000000..a15ade0 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/extended_text_field.dart @@ -0,0 +1,9 @@ +library extended_text_field; + +export 'package:extended_text_library/extended_text_library.dart'; + +export 'src/extended/cupertino/spell_check_suggestions_toolbar.dart'; +export 'src/extended/material/spell_check_suggestions_toolbar.dart'; +export 'src/extended/widgets/text_field.dart'; +export 'src/keyboard/binding.dart'; +export 'src/keyboard/focus_node.dart'; diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/cupertino/spell_check_suggestions_toolbar.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/cupertino/spell_check_suggestions_toolbar.dart new file mode 100644 index 0000000..49c585a --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/cupertino/spell_check_suggestions_toolbar.dart @@ -0,0 +1,167 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:extended_text_field/src/extended/widgets/text_field.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart' + show SelectionChangedCause, SuggestionSpan; + +/// iOS only shows 3 spell check suggestions in the toolbar. +const int _kMaxSuggestions = 3; + +/// The default spell check suggestions toolbar for iOS. +/// +/// Tries to position itself below the [anchors], but if it doesn't fit, then it +/// readjusts to fit above bottom view insets. +/// +/// See also: +/// * [SpellCheckSuggestionsToolbar], which is similar but for both the +/// Material and Cupertino libraries. +/// [CupertinoSpellCheckSuggestionsToolbar] +class ExtendedCupertinoSpellCheckSuggestionsToolbar extends StatelessWidget { + /// Constructs a [ExtendedCupertinoSpellCheckSuggestionsToolbar]. + /// + /// [buttonItems] must not contain more than three items. + const ExtendedCupertinoSpellCheckSuggestionsToolbar({ + super.key, + required this.anchors, + required this.buttonItems, + }) : assert(buttonItems.length <= _kMaxSuggestions); + + /// Constructs a [ExtendedCupertinoSpellCheckSuggestionsToolbar] with the default + /// children for an [EditableText]. + /// + /// See also: + /// * [SpellCheckSuggestionsToolbar.editableText], which is similar but + /// builds an Android-style toolbar. + ExtendedCupertinoSpellCheckSuggestionsToolbar.editableText({ + super.key, + // zmtzawqlp + required ExtendedEditableTextState editableTextState, + }) : buttonItems = + buildButtonItems(editableTextState) ?? [], + anchors = editableTextState.contextMenuAnchors; + + /// The location on which to anchor the menu. + final TextSelectionToolbarAnchors anchors; + + /// The [ContextMenuButtonItem]s that will be turned into the correct button + /// widgets and displayed in the spell check suggestions toolbar. + /// + /// Must not contain more than three items. + /// + /// See also: + /// + /// * [AdaptiveTextSelectionToolbar.buttonItems], the list of + /// [ContextMenuButtonItem]s that are used to build the buttons of the + /// text selection toolbar. + /// * [SpellCheckSuggestionsToolbar.buttonItems], the list of + /// [ContextMenuButtonItem]s used to build the Material style spell check + /// suggestions toolbar. + final List buttonItems; + + /// Builds the button items for the toolbar based on the available + /// spell check suggestions. + static List? buildButtonItems( + ExtendedEditableTextState editableTextState, + ) { + // Determine if composing region is misspelled. + final SuggestionSpan? spanAtCursorIndex = + editableTextState.findSuggestionSpanAtCursorIndex( + editableTextState.currentTextEditingValue.selection.baseOffset, + ); + + if (spanAtCursorIndex == null) { + return null; + } + if (spanAtCursorIndex.suggestions.isEmpty) { + assert(debugCheckHasCupertinoLocalizations(editableTextState.context)); + final CupertinoLocalizations localizations = + CupertinoLocalizations.of(editableTextState.context); + return [ + ContextMenuButtonItem( + onPressed: null, + label: localizations.noSpellCheckReplacementsLabel, + ) + ]; + } + + final List buttonItems = []; + + // Build suggestion buttons. + for (final String suggestion + in spanAtCursorIndex.suggestions.take(_kMaxSuggestions)) { + buttonItems.add(ContextMenuButtonItem( + onPressed: () { + if (!editableTextState.mounted) { + return; + } + _replaceText( + editableTextState, + suggestion, + spanAtCursorIndex.range, + ); + }, + label: suggestion, + )); + } + return buttonItems; + } + + // zmtzawqlp + static void _replaceText(ExtendedEditableTextState editableTextState, + String text, TextRange replacementRange) { + // Replacement cannot be performed if the text is read only or obscured. + assert(!editableTextState.widget.readOnly && + !editableTextState.widget.obscureText); + + final TextEditingValue newValue = editableTextState.textEditingValue + .replaced( + replacementRange, + text, + ) + .copyWith( + selection: TextSelection.collapsed( + offset: replacementRange.start + text.length, + ), + ); + editableTextState.userUpdateTextEditingValue( + newValue, SelectionChangedCause.toolbar); + + // Schedule a call to bringIntoView() after renderEditable updates. + SchedulerBinding.instance.addPostFrameCallback((Duration duration) { + if (editableTextState.mounted) { + editableTextState + .bringIntoView(editableTextState.textEditingValue.selection.extent); + } + }, debugLabel: 'SpellCheckSuggestions.bringIntoView'); + editableTextState.hideToolbar(); + } + + /// Builds the toolbar buttons based on the [buttonItems]. + List _buildToolbarButtons(BuildContext context) { + return buttonItems.map((ContextMenuButtonItem buttonItem) { + return CupertinoTextSelectionToolbarButton.buttonItem( + buttonItem: buttonItem, + ); + }).toList(); + } + + @override + Widget build(BuildContext context) { + if (buttonItems.isEmpty) { + return const SizedBox.shrink(); + } + + final List children = _buildToolbarButtons(context); + return CupertinoTextSelectionToolbar( + anchorAbove: anchors.primaryAnchor, + anchorBelow: anchors.secondaryAnchor == null + ? anchors.primaryAnchor + : anchors.secondaryAnchor!, + children: children, + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/selectable_text.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/selectable_text.dart new file mode 100644 index 0000000..3b847b9 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/selectable_text.dart @@ -0,0 +1,290 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [SelectableText] +class ExtendedSelectableText extends _SelectableText { + const ExtendedSelectableText( + super.data, { + super.key, + super.focusNode, + super.style, + super.strutStyle, + super.textAlign, + super.textDirection, + super.textScaler, + super.showCursor = false, + super.autofocus = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + super.toolbarOptions, + super.minLines, + super.maxLines, + super.cursorWidth = 2.0, + super.cursorHeight, + super.cursorRadius, + super.cursorColor, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.dragStartBehavior = DragStartBehavior.start, + super.enableInteractiveSelection = true, + super.selectionControls, + super.onTap, + super.scrollPhysics, + super.semanticsLabel, + super.textHeightBehavior, + super.textWidthBasis, + super.onSelectionChanged, + // super.contextMenuBuilder = _defaultContextMenuBuilder, + this.extendedContextMenuBuilder = + ExtendedTextField._defaultContextMenuBuilder, + super.magnifierConfiguration, + this.specialTextSpanBuilder, + }); + + const ExtendedSelectableText.rich( + TextSpan textSpan, { + super.key, + super.focusNode, + super.style, + super.strutStyle, + super.textAlign, + super.textDirection, + super.textScaler, + super.showCursor = false, + super.autofocus = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + super.toolbarOptions, + super.minLines, + super.maxLines, + super.cursorWidth = 2.0, + super.cursorHeight, + super.cursorRadius, + super.cursorColor, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.dragStartBehavior = DragStartBehavior.start, + super.enableInteractiveSelection = true, + super.selectionControls, + super.onTap, + super.scrollPhysics, + super.semanticsLabel, + super.textHeightBehavior, + super.textWidthBasis, + super.onSelectionChanged, + // super.contextMenuBuilder = _defaultContextMenuBuilder, + this.extendedContextMenuBuilder = + ExtendedTextField._defaultContextMenuBuilder, + super.magnifierConfiguration, + this.specialTextSpanBuilder, + }) : super.rich(textSpan); + + /// build your ccustom text span + final SpecialTextSpanBuilder? specialTextSpanBuilder; + + /// {@template flutter.widgets.EditableText.contextMenuBuilder} + /// Builds the text selection toolbar when requested by the user. + /// + /// `primaryAnchor` is the desired anchor position for the context menu, while + /// `secondaryAnchor` is the fallback location if the menu doesn't fit. + /// + /// `buttonItems` represents the buttons that would be built by default for + /// this widget. + /// + /// {@tool dartpad} + /// This example shows how to customize the menu, in this case by keeping the + /// default buttons for the platform but modifying their appearance. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.0.dart ** + /// {@end-tool} + /// + /// {@tool dartpad} + /// This example shows how to show a custom button only when an email address + /// is currently selected. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.1.dart ** + /// {@end-tool} + /// + /// See also: + /// * [AdaptiveTextSelectionToolbar], which builds the default text selection + /// toolbar for the current platform, but allows customization of the + /// buttons. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given + /// [ContextMenuButtonItem]s. + /// * [BrowserContextMenu], which allows the browser's context menu on web + /// to be disabled and Flutter-rendered context menus to appear. + /// {@endtemplate} + /// + /// If not provided, no context menu will be shown. + final ExtendedEditableTextContextMenuBuilder? extendedContextMenuBuilder; + + @override + State<_SelectableText> createState() => _ExtendedSelectableTextState(); +} + +class _ExtendedSelectableTextState extends _SelectableTextState { + ExtendedSelectableText get extendedSelectableText => + widget as ExtendedSelectableText; + @override + Widget build(BuildContext context) { + // TODO(garyq): Assert to block WidgetSpans from being used here are removed, + // but we still do not yet have nice handling of things like carets, clipboard, + // and other features. We should add proper support. Currently, caret handling + // is blocked on SkParagraph switch and https://github.com/flutter/engine/pull/27010 + // should be landed in SkParagraph after the switch is complete. + assert(debugCheckHasMediaQuery(context)); + assert(debugCheckHasDirectionality(context)); + assert( + !(widget.style != null && + !widget.style!.inherit && + (widget.style!.fontSize == null || + widget.style!.textBaseline == null)), + 'inherit false style must supply fontSize and textBaseline', + ); + + final ThemeData theme = Theme.of(context); + final DefaultSelectionStyle selectionStyle = + DefaultSelectionStyle.of(context); + final FocusNode focusNode = _effectiveFocusNode; + + TextSelectionControls? textSelectionControls = widget.selectionControls; + final bool paintCursorAboveText; + final bool cursorOpacityAnimates; + Offset? cursorOffset; + final Color cursorColor; + final Color selectionColor; + Radius? cursorRadius = widget.cursorRadius; + + switch (theme.platform) { + case TargetPlatform.iOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = true; + textSelectionControls ??= cupertinoTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates = true; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + + case TargetPlatform.macOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = false; + textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates = true; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + + case TargetPlatform.android: + case TargetPlatform.fuchsia: + forcePressEnabled = false; + textSelectionControls ??= materialTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates = false; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + + case TargetPlatform.linux: + case TargetPlatform.windows: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates = false; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + } + + final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context); + TextStyle? effectiveTextStyle = widget.style; + if (effectiveTextStyle == null || effectiveTextStyle.inherit) { + effectiveTextStyle = defaultTextStyle.style + .merge(widget.style ?? _controller._textSpan.style); + } + final Widget child = RepaintBoundary( + // zmtzawqlp + child: ExtendedEditableText( + key: editableTextKey, + style: effectiveTextStyle, + readOnly: true, + toolbarOptions: widget.toolbarOptions, + textWidthBasis: + widget.textWidthBasis ?? defaultTextStyle.textWidthBasis, + textHeightBehavior: + widget.textHeightBehavior ?? defaultTextStyle.textHeightBehavior, + showSelectionHandles: _showSelectionHandles, + showCursor: widget.showCursor, + controller: _controller, + focusNode: focusNode, + strutStyle: widget.strutStyle ?? const StrutStyle(), + textAlign: + widget.textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start, + textDirection: widget.textDirection, + textScaler: widget.textScaler, + autofocus: widget.autofocus, + forceLine: false, + minLines: widget.minLines, + maxLines: widget.maxLines ?? defaultTextStyle.maxLines, + selectionColor: selectionColor, + selectionControls: + widget.selectionEnabled ? textSelectionControls : null, + onSelectionChanged: _handleSelectionChanged, + onSelectionHandleTapped: _handleSelectionHandleTapped, + rendererIgnoresPointer: true, + cursorWidth: widget.cursorWidth, + cursorHeight: widget.cursorHeight, + cursorRadius: cursorRadius, + cursorColor: cursorColor, + selectionHeightStyle: widget.selectionHeightStyle, + selectionWidthStyle: widget.selectionWidthStyle, + cursorOpacityAnimates: cursorOpacityAnimates, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + backgroundCursorColor: CupertinoColors.inactiveGray, + enableInteractiveSelection: widget.enableInteractiveSelection, + magnifierConfiguration: widget.magnifierConfiguration ?? + TextMagnifier.adaptiveMagnifierConfiguration, + dragStartBehavior: widget.dragStartBehavior, + scrollPhysics: widget.scrollPhysics, + autofillHints: null, + // zmtzawqlp + // contextMenuBuilder: widget.contextMenuBuilder, + extendedContextMenuBuilder: + extendedSelectableText.extendedContextMenuBuilder, + specialTextSpanBuilder: extendedSelectableText.specialTextSpanBuilder, + ), + ); + + return Semantics( + label: widget.semanticsLabel, + excludeSemantics: widget.semanticsLabel != null, + onLongPress: () { + _effectiveFocusNode.requestFocus(); + }, + child: _selectionGestureDetectorBuilder.buildGestureDetector( + behavior: HitTestBehavior.translucent, + child: child, + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/spell_check_suggestions_toolbar.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/spell_check_suggestions_toolbar.dart new file mode 100644 index 0000000..39a7a7f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/material/spell_check_suggestions_toolbar.dart @@ -0,0 +1,269 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +import 'package:extended_text_field/src/extended/widgets/text_field.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart' + show SelectionChangedCause, SuggestionSpan; + +// The default height of the SpellCheckSuggestionsToolbar, which +// assumes there are the maximum number of spell check suggestions available, 3. +// Size eyeballed on Pixel 4 emulator running Android API 31. +const double _kDefaultToolbarHeight = 193.0; + +/// The maximum number of suggestions in the toolbar is 3, plus a delete button. +const int _kMaxSuggestions = 3; + +/// The default spell check suggestions toolbar for Android. [SpellCheckSuggestionsToolbar] +/// +/// Tries to position itself below the [anchor], but if it doesn't fit, then it +/// readjusts to fit above bottom view insets. +/// +/// See also: +/// +/// * [CupertinoSpellCheckSuggestionsToolbar], which is similar but builds an +/// iOS-style spell check toolbar. +/// [SpellCheckSuggestionsToolbar] +class ExtendedSpellCheckSuggestionsToolbar extends StatelessWidget { + /// Constructs a [ExtendedSpellCheckSuggestionsToolbar]. + /// + /// [buttonItems] must not contain more than four items, generally three + /// suggestions and one delete button. + const ExtendedSpellCheckSuggestionsToolbar({ + super.key, + required this.anchor, + required this.buttonItems, + }) : assert(buttonItems.length <= _kMaxSuggestions + 1); + + /// Constructs a [ExtendedSpellCheckSuggestionsToolbar] with the default children for + /// an [EditableText]. + /// + /// See also: + /// * [CupertinoSpellCheckSuggestionsToolbar.editableText], which is similar + /// but builds an iOS-style toolbar. + ExtendedSpellCheckSuggestionsToolbar.editableText({ + super.key, + // zmtzawqlp + required ExtendedEditableTextState editableTextState, + }) : buttonItems = + buildButtonItems(editableTextState) ?? [], + anchor = getToolbarAnchor(editableTextState.contextMenuAnchors); + + /// {@template flutter.material.SpellCheckSuggestionsToolbar.anchor} + /// The focal point below which the toolbar attempts to position itself. + /// {@endtemplate} + final Offset anchor; + + /// The [ContextMenuButtonItem]s that will be turned into the correct button + /// widgets and displayed in the spell check suggestions toolbar. + /// + /// Must not contain more than four items, typically three suggestions and a + /// delete button. + /// + /// See also: + /// + /// * [AdaptiveTextSelectionToolbar.buttonItems], the list of + /// [ContextMenuButtonItem]s that are used to build the buttons of the + /// text selection toolbar. + /// * [CupertinoSpellCheckSuggestionsToolbar.buttonItems], the list of + /// [ContextMenuButtonItem]s used to build the Cupertino style spell check + /// suggestions toolbar. + final List buttonItems; + + /// Builds the button items for the toolbar based on the available + /// spell check suggestions. + static List? buildButtonItems( + ExtendedEditableTextState editableTextState, + ) { + // Determine if composing region is misspelled. + final SuggestionSpan? spanAtCursorIndex = + editableTextState.findSuggestionSpanAtCursorIndex( + editableTextState.currentTextEditingValue.selection.baseOffset, + ); + + if (spanAtCursorIndex == null) { + return null; + } + + final List buttonItems = []; + + // Build suggestion buttons. + for (final String suggestion + in spanAtCursorIndex.suggestions.take(_kMaxSuggestions)) { + buttonItems.add(ContextMenuButtonItem( + onPressed: () { + if (!editableTextState.mounted) { + return; + } + _replaceText( + editableTextState, + suggestion, + spanAtCursorIndex.range, + ); + }, + label: suggestion, + )); + } + + // Build delete button. + final ContextMenuButtonItem deleteButton = ContextMenuButtonItem( + onPressed: () { + if (!editableTextState.mounted) { + return; + } + _replaceText( + editableTextState, + '', + editableTextState.currentTextEditingValue.composing, + ); + }, + type: ContextMenuButtonType.delete, + ); + buttonItems.add(deleteButton); + + return buttonItems; + } + + // zmtzawqlp + static void _replaceText(ExtendedEditableTextState editableTextState, + String text, TextRange replacementRange) { + // Replacement cannot be performed if the text is read only or obscured. + assert(!editableTextState.widget.readOnly && + !editableTextState.widget.obscureText); + + final TextEditingValue newValue = + editableTextState.textEditingValue.replaced( + replacementRange, + text, + ); + editableTextState.userUpdateTextEditingValue( + newValue, SelectionChangedCause.toolbar); + + // Schedule a call to bringIntoView() after renderEditable updates. + SchedulerBinding.instance.addPostFrameCallback((Duration duration) { + if (editableTextState.mounted) { + editableTextState + .bringIntoView(editableTextState.textEditingValue.selection.extent); + } + }, debugLabel: 'SpellCheckerSuggestionsToolbar.bringIntoView'); + editableTextState.hideToolbar(); + } + + /// Determines the Offset that the toolbar will be anchored to. + static Offset getToolbarAnchor(TextSelectionToolbarAnchors anchors) { + // Since this will be positioned below the anchor point, use the secondary + // anchor by default. + return anchors.secondaryAnchor == null + ? anchors.primaryAnchor + : anchors.secondaryAnchor!; + } + + /// Builds the toolbar buttons based on the [buttonItems]. + List _buildToolbarButtons(BuildContext context) { + return buttonItems.map((ContextMenuButtonItem buttonItem) { + final TextSelectionToolbarTextButton button = + TextSelectionToolbarTextButton( + padding: const EdgeInsets.fromLTRB(20, 0, 0, 0), + onPressed: buttonItem.onPressed, + alignment: Alignment.centerLeft, + child: Text( + AdaptiveTextSelectionToolbar.getButtonLabel(context, buttonItem), + style: buttonItem.type == ContextMenuButtonType.delete + ? const TextStyle(color: Colors.blue) + : null, + ), + ); + + if (buttonItem.type != ContextMenuButtonType.delete) { + return button; + } + return DecoratedBox( + decoration: const BoxDecoration( + border: Border(top: BorderSide(color: Colors.grey))), + child: button, + ); + }).toList(); + } + + @override + Widget build(BuildContext context) { + if (buttonItems.isEmpty) { + return const SizedBox.shrink(); + } + + // Adjust toolbar height if needed. + final double spellCheckSuggestionsToolbarHeight = + _kDefaultToolbarHeight - (48.0 * (4 - buttonItems.length)); + // Incorporate the padding distance between the content and toolbar. + final MediaQueryData mediaQueryData = MediaQuery.of(context); + final double softKeyboardViewInsetsBottom = + mediaQueryData.viewInsets.bottom; + final double paddingAbove = mediaQueryData.padding.top + + CupertinoTextSelectionToolbar.kToolbarScreenPadding; + // Makes up for the Padding. + final Offset localAdjustment = Offset( + CupertinoTextSelectionToolbar.kToolbarScreenPadding, + paddingAbove, + ); + + return Padding( + padding: EdgeInsets.fromLTRB( + CupertinoTextSelectionToolbar.kToolbarScreenPadding, + paddingAbove, + CupertinoTextSelectionToolbar.kToolbarScreenPadding, + CupertinoTextSelectionToolbar.kToolbarScreenPadding + + softKeyboardViewInsetsBottom, + ), + child: CustomSingleChildLayout( + delegate: SpellCheckSuggestionsToolbarLayoutDelegate( + anchor: anchor - localAdjustment, + ), + child: AnimatedSize( + // This duration was eyeballed on a Pixel 2 emulator running Android + // API 28 for the Material TextSelectionToolbar. + duration: const Duration(milliseconds: 140), + child: _SpellCheckSuggestionsToolbarContainer( + height: spellCheckSuggestionsToolbarHeight, + children: [..._buildToolbarButtons(context)], + ), + ), + ), + ); + } +} + +/// The Material-styled toolbar outline for the spell check suggestions +/// toolbar. +class _SpellCheckSuggestionsToolbarContainer extends StatelessWidget { + const _SpellCheckSuggestionsToolbarContainer({ + required this.height, + required this.children, + }); + + final double height; + final List children; + + @override + Widget build(BuildContext context) { + return Material( + // This elevation was eyeballed on a Pixel 4 emulator running Android + // API 31 for the SpellCheckSuggestionsToolbar. + elevation: 2.0, + type: MaterialType.card, + child: SizedBox( + // This width was eyeballed on a Pixel 4 emulator running Android + // API 31 for the SpellCheckSuggestionsToolbar. + width: 165.0, + height: height, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.stretch, + children: children, + ), + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/rendering/editable.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/rendering/editable.dart new file mode 100644 index 0000000..c3de0c3 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/rendering/editable.dart @@ -0,0 +1,199 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [RenderEditable] +class ExtendedRenderEditable extends _RenderEditable { + ExtendedRenderEditable({ + super.text, + required super.textDirection, + super.textAlign = TextAlign.start, + super.cursorColor, + super.backgroundCursorColor, + super.showCursor, + super.hasFocus, + required super.startHandleLayerLink, + required super.endHandleLayerLink, + super.maxLines = 1, + super.minLines, + super.expands = false, + super.strutStyle, + super.selectionColor, + super.textScaler = TextScaler.noScaling, + super.selection, + required super.offset, + super.ignorePointer = false, + super.readOnly = false, + super.forceLine = true, + super.textHeightBehavior, + super.textWidthBasis = TextWidthBasis.parent, + super.obscuringCharacter = '•', + super.obscureText = false, + super.locale, + super.cursorWidth = 1.0, + super.cursorHeight, + super.cursorRadius, + super.paintCursorAboveText = false, + super.cursorOffset = Offset.zero, + super.devicePixelRatio = 1.0, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.enableInteractiveSelection, + super.floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), + super.promptRectRange, + super.promptRectColor, + super.clipBehavior = Clip.hardEdge, + required super.textSelectionDelegate, + super.painter, + super.foregroundPainter, + super.children, + this.supportSpecialText = false, + }) { + _findSpecialInlineSpanBase(text); + } + + bool supportSpecialText = false; + bool _hasSpecialInlineSpanBase = false; + bool get hasSpecialInlineSpanBase => + supportSpecialText && _hasSpecialInlineSpanBase; + + void _findSpecialInlineSpanBase(InlineSpan? span) { + _hasSpecialInlineSpanBase = false; + span?.visitChildren((InlineSpan span) { + if (span is SpecialInlineSpanBase) { + _hasSpecialInlineSpanBase = true; + return false; + } + return true; + }); + } + + @override + set text(InlineSpan? value) { + if (_textPainter.text == value) { + return; + } + _findSpecialInlineSpanBase(value); + super.text = value; + } + + @override + String get plainText { + return ExtendedTextLibraryUtils.textSpanToActualText(_textPainter.text!); + } + + /// Move the selection to the beginning or end of a word. + /// + /// {@macro flutter.rendering.RenderEditable.selectPosition} + @override + void selectWordEdge({required SelectionChangedCause cause}) { + _computeTextMetricsIfNeeded(); + assert(_lastTapDownPosition != null); + final TextPosition position = _textPainter.getPositionForOffset( + globalToLocal(_lastTapDownPosition!) - _paintOffset); + final TextRange word = _textPainter.getWordBoundary(position); + late TextSelection newSelection; + if (position.offset <= word.start) { + newSelection = TextSelection.collapsed(offset: word.start); + } else { + newSelection = TextSelection.collapsed( + offset: word.end, affinity: TextAffinity.upstream); + } + + /// zmtzawqlp + newSelection = hasSpecialInlineSpanBase + ? ExtendedTextLibraryUtils + .convertTextPainterSelectionToTextInputSelection( + text!, newSelection) + : newSelection; + _setSelection(newSelection, cause); + } + + @override + + /// Select text between the global positions [from] and [to]. + /// + /// [from] corresponds to the [TextSelection.baseOffset], and [to] corresponds + /// to the [TextSelection.extentOffset]. + void selectPositionAt( + {required Offset from, + Offset? to, + required SelectionChangedCause cause}) { + _computeTextMetricsIfNeeded(); + TextPosition fromPosition = + _textPainter.getPositionForOffset(globalToLocal(from) - _paintOffset); + TextPosition? toPosition = to == null + ? null + : _textPainter.getPositionForOffset(globalToLocal(to) - _paintOffset); + // zmtzawqlp + if (hasSpecialInlineSpanBase) { + fromPosition = + ExtendedTextLibraryUtils.convertTextPainterPostionToTextInputPostion( + text!, fromPosition)!; + toPosition = + ExtendedTextLibraryUtils.convertTextPainterPostionToTextInputPostion( + text!, toPosition); + } + final int baseOffset = fromPosition.offset; + final int extentOffset = toPosition?.offset ?? fromPosition.offset; + + final TextSelection newSelection = TextSelection( + baseOffset: baseOffset, + extentOffset: extentOffset, + affinity: fromPosition.affinity, + ); + + _setSelection(newSelection, cause); + } + + @override + TextSelection getWordAtOffset(TextPosition position) { + final TextSelection selection = super.getWordAtOffset(position); + + /// zmt + return hasSpecialInlineSpanBase + ? ExtendedTextLibraryUtils + .convertTextPainterSelectionToTextInputSelection(text!, selection, + selectWord: true) + : selection; + } + + @override + List getEndpointsForSelection(TextSelection selection) { + // zmtzawqlp + if (hasSpecialInlineSpanBase) { + selection = ExtendedTextLibraryUtils + .convertTextInputSelectionToTextPainterSelection(text!, selection); + } + + return super.getEndpointsForSelection(selection); + } + + @override + set selection(TextSelection? value) { + if (_selection == value) { + return; + } + _selection = value; + _selectionPainter.highlightedRange = getActualSelection(); + markNeedsPaint(); + markNeedsSemanticsUpdate(); + } + + @override + void setPromptRectRange(TextRange? newRange) { + _autocorrectHighlightPainter.highlightedRange = + getActualSelection(newRange: newRange); + } + + TextSelection? getActualSelection({TextRange? newRange}) { + TextSelection? value = selection; + if (newRange != null) { + value = + TextSelection(baseOffset: newRange.start, extentOffset: newRange.end); + } + + return hasSpecialInlineSpanBase + ? ExtendedTextLibraryUtils + .convertTextInputSelectionToTextPainterSelection(text!, value!) + : value; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/utils.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/utils.dart new file mode 100644 index 0000000..32b57a3 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/utils.dart @@ -0,0 +1,14 @@ +import 'package:flutter/material.dart'; + +extension TextEditingControllerEx on TextEditingController { + /// Check that the [selection] is inside of the bounds of [text]. + bool isSelectionWithinTextBounds(TextSelection selection) { + return selection.start <= text.length && selection.end <= text.length; + } + + /// Check that the [selection] is inside of the composing range. + bool isSelectionWithinComposingRange(TextSelection selection) { + return selection.start >= value.composing.start && + selection.end <= value.composing.end; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/editable_text.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/editable_text.dart new file mode 100644 index 0000000..22a5a82 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/editable_text.dart @@ -0,0 +1,1087 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// Signature for a widget builder that builds a context menu for the given +/// [EditableTextState]. +/// +/// See also: +/// +/// * [SelectableRegionContextMenuBuilder], which performs the same role for +/// [SelectableRegion]. +typedef ExtendedEditableTextContextMenuBuilder = Widget Function( + BuildContext context, + ExtendedEditableTextState editableTextState, +); + +/// [EditableText] +/// +class ExtendedEditableText extends _EditableText { + ExtendedEditableText({ + super.key, + required super.controller, + required super.focusNode, + super.readOnly = false, + super.obscuringCharacter = '•', + super.obscureText = false, + super.autocorrect = true, + super.smartDashesType, + super.smartQuotesType, + super.enableSuggestions = true, + required super.style, + super.strutStyle, + required super.cursorColor, + required super.backgroundCursorColor, + super.textAlign = TextAlign.start, + super.textDirection, + super.locale, + super.textScaler, + super.maxLines = 1, + super.minLines, + super.expands = false, + super.forceLine = true, + super.textHeightBehavior, + super.textWidthBasis = TextWidthBasis.parent, + super.autofocus = false, + super.showCursor, + super.showSelectionHandles = false, + super.selectionColor, + super.selectionControls, + super.keyboardType, + super.textInputAction, + super.textCapitalization = TextCapitalization.none, + super.onChanged, + super.onEditingComplete, + super.onSubmitted, + super.onAppPrivateCommand, + super.onSelectionChanged, + super.onSelectionHandleTapped, + super.groupId = EditableText, + super.onTapOutside, + super.inputFormatters, + super.mouseCursor, + super.rendererIgnoresPointer = false, + super.cursorWidth = 2.0, + super.cursorHeight, + super.cursorRadius, + super.cursorOpacityAnimates = false, + super.cursorOffset, + super.paintCursorAboveText = false, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.scrollPadding = const EdgeInsets.all(20.0), + super.keyboardAppearance = Brightness.light, + super.dragStartBehavior = DragStartBehavior.start, + super.enableInteractiveSelection, + super.scrollController, + super.scrollPhysics, + super.autocorrectionTextRectColor, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + ToolbarOptions? toolbarOptions, + super.autofillHints = const [], + super.autofillClient, + super.clipBehavior = Clip.hardEdge, + super.restorationId, + super.scrollBehavior, + super.scribbleEnabled = true, + super.enableIMEPersonalizedLearning = true, + super.contentInsertionConfiguration, + // super.contextMenuBuilder, + // super.spellCheckConfiguration, + this.extendedContextMenuBuilder, + this.extendedSpellCheckConfiguration, + super.magnifierConfiguration = TextMagnifierConfiguration.disabled, + super.undoController, + this.specialTextSpanBuilder, + }); + + /// build your ccustom text span + final SpecialTextSpanBuilder? specialTextSpanBuilder; + + /// {@template flutter.widgets.EditableText.contextMenuBuilder} + /// Builds the text selection toolbar when requested by the user. + /// + /// `primaryAnchor` is the desired anchor position for the context menu, while + /// `secondaryAnchor` is the fallback location if the menu doesn't fit. + /// + /// `buttonItems` represents the buttons that would be built by default for + /// this widget. + /// + /// {@tool dartpad} + /// This example shows how to customize the menu, in this case by keeping the + /// default buttons for the platform but modifying their appearance. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.0.dart ** + /// {@end-tool} + /// + /// {@tool dartpad} + /// This example shows how to show a custom button only when an email address + /// is currently selected. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.1.dart ** + /// {@end-tool} + /// + /// See also: + /// * [AdaptiveTextSelectionToolbar], which builds the default text selection + /// toolbar for the current platform, but allows customization of the + /// buttons. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given + /// [ContextMenuButtonItem]s. + /// * [BrowserContextMenu], which allows the browser's context menu on web + /// to be disabled and Flutter-rendered context menus to appear. + /// {@endtemplate} + /// + /// If not provided, no context menu will be shown. + final ExtendedEditableTextContextMenuBuilder? extendedContextMenuBuilder; + + /// {@template flutter.widgets.EditableText.spellCheckConfiguration} + /// Configuration that details how spell check should be performed. + /// + /// Specifies the [SpellCheckService] used to spell check text input and the + /// [TextStyle] used to style text with misspelled words. + /// + /// If the [SpellCheckService] is left null, spell check is disabled by + /// default unless the [DefaultSpellCheckService] is supported, in which case + /// it is used. It is currently supported only on Android and iOS. + /// + /// If this configuration is left null, then spell check is disabled by default. + /// {@endtemplate} + final ExtendedSpellCheckConfiguration? extendedSpellCheckConfiguration; + @override + _EditableTextState createState() { + return ExtendedEditableTextState(); + } +} + +class ExtendedEditableTextState extends _EditableTextState { + ExtendedEditableText get extendedEditableText => + widget as ExtendedEditableText; + ExtendedSpellCheckConfiguration get extendedSpellCheckConfiguration => + _spellCheckConfiguration as ExtendedSpellCheckConfiguration; + + /// whether to support build SpecialText + bool get supportSpecialText => + extendedEditableText.specialTextSpanBuilder != null && + !widget.obscureText && + _textDirection == TextDirection.ltr; + + // State lifecycle: + + @override + void initState() { + super.initState(); + _spellCheckConfiguration = _inferSpellCheckConfiguration( + extendedEditableText.extendedSpellCheckConfiguration); + } + + /// Infers the [_SpellCheckConfiguration] used to perform spell check. + /// + /// If spell check is enabled, this will try to infer a value for + /// the [SpellCheckService] if left unspecified. + static _SpellCheckConfiguration _inferSpellCheckConfiguration( + ExtendedSpellCheckConfiguration? configuration) { + final SpellCheckService? spellCheckService = + configuration?.spellCheckService; + final bool spellCheckAutomaticallyDisabled = configuration == null || + configuration == const ExtendedSpellCheckConfiguration.disabled(); + final bool spellCheckServiceIsConfigured = spellCheckService != null || + spellCheckService == null && + WidgetsBinding + .instance.platformDispatcher.nativeSpellCheckServiceDefined; + if (spellCheckAutomaticallyDisabled || !spellCheckServiceIsConfigured) { + // Only enable spell check if a non-disabled configuration is provided + // and if that configuration does not specify a spell check service, + // a native spell checker must be supported. + assert(() { + if (!spellCheckAutomaticallyDisabled && + !spellCheckServiceIsConfigured) { + FlutterError.reportError( + FlutterErrorDetails( + exception: FlutterError( + 'Spell check was enabled with spellCheckConfiguration, but the ' + 'current platform does not have a supported spell check ' + 'service, and none was provided. Consider disabling spell ' + 'check for this platform or passing a SpellCheckConfiguration ' + 'with a specified spell check service.', + ), + library: 'widget library', + stack: StackTrace.current, + ), + ); + } + return true; + }()); + return const ExtendedSpellCheckConfiguration.disabled(); + } + + return configuration.copyWith( + spellCheckService: spellCheckService ?? DefaultSpellCheckService()); + } + + // zmtzawqlp + @override + Widget build(BuildContext context) { + assert(debugCheckHasMediaQuery(context)); + super.build(context); // See AutomaticKeepAliveClientMixin. + + final TextSelectionControls? controls = widget.selectionControls; + double? textScaleFactor; + final TextScaler effectiveTextScaler = switch (( + widget.textScaler, textScaleFactor //widget.textScaleFactor + )) { + (final TextScaler textScaler, _) => textScaler, + (null, final double textScaleFactor) => + TextScaler.linear(textScaleFactor), + (null, null) => MediaQuery.textScalerOf(context), + }; + + return _CompositionCallback( + compositeCallback: _compositeCallback, + enabled: _hasInputConnection, + child: TextFieldTapRegion( + groupId: widget.groupId, + onTapOutside: + _hasFocus ? widget.onTapOutside ?? _defaultOnTapOutside : null, + debugLabel: kReleaseMode ? null : 'ExtendedEditableText', + child: MouseRegion( + cursor: widget.mouseCursor ?? SystemMouseCursors.text, + child: Actions( + actions: _actions, + child: UndoHistory( + value: widget.controller, + onTriggered: (TextEditingValue value) { + userUpdateTextEditingValue( + value, SelectionChangedCause.keyboard); + }, + shouldChangeUndoStack: + (TextEditingValue? oldValue, TextEditingValue newValue) { + if (!newValue.selection.isValid) { + return false; + } + + if (oldValue == null) { + return true; + } + + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + // Composing text is not counted in history coalescing. + if (!widget.controller.value.composing.isCollapsed) { + return false; + } + case TargetPlatform.android: + // Gboard on Android puts non-CJK words in composing regions. Coalesce + // composing text in order to allow the saving of partial words in that + // case. + break; + } + + return oldValue.text != newValue.text || + oldValue.composing != newValue.composing; + }, + undoStackModifier: (TextEditingValue value) { + // On Android we should discard the composing region when pushing + // a new entry to the undo stack. This prevents the TextInputPlugin + // from restarting the input on every undo/redo when the composing + // region is changed by the framework. + return defaultTargetPlatform == TargetPlatform.android + ? value.copyWith(composing: TextRange.empty) + : value; + }, + focusNode: widget.focusNode, + controller: widget.undoController, + child: Focus( + focusNode: widget.focusNode, + includeSemantics: false, + debugLabel: kReleaseMode ? null : 'EditableText', + child: NotificationListener( + onNotification: (ScrollNotification notification) { + _handleContextMenuOnScroll(notification); + _scribbleCacheKey = null; + return false; + }, + child: Scrollable( + key: _scrollableKey, + excludeFromSemantics: true, + axisDirection: + _isMultiline ? AxisDirection.down : AxisDirection.right, + controller: _scrollController, + physics: widget.scrollPhysics, + dragStartBehavior: widget.dragStartBehavior, + restorationId: widget.restorationId, + // If a ScrollBehavior is not provided, only apply scrollbars when + // multiline. The overscroll indicator should not be applied in + // either case, glowing or stretching. + scrollBehavior: widget.scrollBehavior ?? + ScrollConfiguration.of(context).copyWith( + scrollbars: _isMultiline, + overscroll: false, + ), + viewportBuilder: + (BuildContext context, ViewportOffset offset) { + return CompositedTransformTarget( + link: _toolbarLayerLink, + child: Semantics( + onCopy: _semanticsOnCopy(controls), + onCut: _semanticsOnCut(controls), + onPaste: _semanticsOnPaste(controls), + child: _ScribbleFocusable( + focusNode: widget.focusNode, + editableKey: _editableKey, + enabled: widget.scribbleEnabled, + updateSelectionRects: () { + _openInputConnection(); + _updateSelectionRects(force: true); + }, + child: SizeChangedLayoutNotifier( + child: _ExtendedEditable( + key: _editableKey, + startHandleLayerLink: _startHandleLayerLink, + endHandleLayerLink: _endHandleLayerLink, + inlineSpan: buildTextSpan(), + value: _value, + cursorColor: _cursorColor, + backgroundCursorColor: + widget.backgroundCursorColor, + showCursor: _cursorVisibilityNotifier, + forceLine: widget.forceLine, + readOnly: widget.readOnly, + hasFocus: _hasFocus, + maxLines: widget.maxLines, + minLines: widget.minLines, + expands: widget.expands, + strutStyle: widget.strutStyle, + selectionColor: _selectionOverlay + ?.spellCheckToolbarIsVisible ?? + false + ? _spellCheckConfiguration + .misspelledSelectionColor ?? + widget.selectionColor + : widget.selectionColor, + textScaler: effectiveTextScaler, + textAlign: widget.textAlign, + textDirection: _textDirection, + locale: widget.locale, + textHeightBehavior: widget.textHeightBehavior ?? + DefaultTextHeightBehavior.maybeOf(context), + textWidthBasis: widget.textWidthBasis, + obscuringCharacter: widget.obscuringCharacter, + obscureText: widget.obscureText, + offset: offset, + rendererIgnoresPointer: + widget.rendererIgnoresPointer, + cursorWidth: widget.cursorWidth, + cursorHeight: widget.cursorHeight, + cursorRadius: widget.cursorRadius, + cursorOffset: + widget.cursorOffset ?? Offset.zero, + selectionHeightStyle: + widget.selectionHeightStyle, + selectionWidthStyle: widget.selectionWidthStyle, + paintCursorAboveText: + widget.paintCursorAboveText, + enableInteractiveSelection: + widget._userSelectionEnabled, + textSelectionDelegate: this, + devicePixelRatio: _devicePixelRatio, + promptRectRange: _currentPromptRectRange, + promptRectColor: + widget.autocorrectionTextRectColor, + clipBehavior: widget.clipBehavior, + supportSpecialText: supportSpecialText, + ), + ), + ), + ), + ); + }, + ), + ), + ), + ), + ), + ), + ), + ); + } + + /// Shows toolbar with spell check suggestions of misspelled words that are + /// available for click-and-replace. + @override + bool showSpellCheckSuggestionsToolbar() { + // Spell check suggestions toolbars are intended to be shown on non-web + // platforms. Additionally, the Cupertino style toolbar can't be drawn on + // the web with the HTML renderer due to + // https://github.com/flutter/flutter/issues/123560. + + if (!spellCheckEnabled || + _webContextMenuEnabled || + widget.readOnly || + _selectionOverlay == null || + !_spellCheckResultsReceived || + findSuggestionSpanAtCursorIndex( + textEditingValue.selection.extentOffset) == + null) { + // Only attempt to show the spell check suggestions toolbar if there + // is a toolbar specified and spell check suggestions available to show. + return false; + } + + assert( + _spellCheckConfiguration.spellCheckSuggestionsToolbarBuilder != null, + 'spellCheckSuggestionsToolbarBuilder must be defined in ' + 'SpellCheckConfiguration to show a toolbar with spell check ' + 'suggestions', + ); + + // zmtzawqlp + _selectionOverlay!.showSpellCheckSuggestionsToolbar( + (BuildContext context) { + // zmtzawqlp + return extendedSpellCheckConfiguration + .extendedSpellCheckSuggestionsToolbarBuilder!( + context, + this, + ); + }, + ); + return true; + } + + @override + _TextSelectionOverlay _createSelectionOverlay() { + final ExtendedTextSelectionOverlay selectionOverlay = + ExtendedTextSelectionOverlay( + clipboardStatus: clipboardStatus, + context: context, + value: _value, + debugRequiredFor: widget, + toolbarLayerLink: _toolbarLayerLink, + startHandleLayerLink: _startHandleLayerLink, + endHandleLayerLink: _endHandleLayerLink, + renderObject: renderEditable, + selectionControls: widget.selectionControls, + selectionDelegate: this, + dragStartBehavior: widget.dragStartBehavior, + onSelectionHandleTapped: widget.onSelectionHandleTapped, + // zmtzawqlp + contextMenuBuilder: + extendedEditableText.extendedContextMenuBuilder == null || + _webContextMenuEnabled + ? null + : (BuildContext context) { + return extendedEditableText.extendedContextMenuBuilder!( + context, + this, + ); + }, + magnifierConfiguration: widget.magnifierConfiguration, + ); + + return selectionOverlay; + } + + /// Builds [TextSpan] from current editing value. + /// + /// By default makes text in composing range appear as underlined. + /// Descendants can override this method to customize appearance of text. + @override + TextSpan buildTextSpan() { + if (widget.obscureText) { + String text = _value.text; + text = widget.obscuringCharacter * text.length; + // Reveal the latest character in an obscured field only on mobile. + // Newer versions of iOS (iOS 15+) no longer reveal the most recently + // entered character. + const Set mobilePlatforms = { + TargetPlatform.android, + TargetPlatform.fuchsia, + }; + final bool brieflyShowPassword = + WidgetsBinding.instance.platformDispatcher.brieflyShowPassword && + mobilePlatforms.contains(defaultTargetPlatform); + if (brieflyShowPassword) { + final int? o = + _obscureShowCharTicksPending > 0 ? _obscureLatestCharIndex : null; + if (o != null && o >= 0 && o < text.length) { + text = text.replaceRange(o, o + 1, _value.text.substring(o, o + 1)); + } + } + return TextSpan(style: _style, text: text); + } + + // zmtzawqlp + if (_value.composing.isValid && !widget.readOnly) { + final TextStyle composingStyle = widget.style.merge( + const TextStyle(decoration: TextDecoration.underline), + ); + final String beforeText = _value.composing.textBefore(_value.text); + final String insideText = _value.composing.textInside(_value.text); + final String afterText = _value.composing.textAfter(_value.text); + + if (supportSpecialText) { + final TextSpan before = extendedEditableText.specialTextSpanBuilder! + .build(beforeText, textStyle: widget.style); + final TextSpan after = extendedEditableText.specialTextSpanBuilder! + .build(afterText, textStyle: widget.style); + + final List children = []; + + children.add(before); + + children.add(TextSpan( + style: composingStyle, + text: insideText, + )); + + children.add(after); + + return TextSpan(style: widget.style, children: children); + } + + return TextSpan(style: widget.style, children: [ + TextSpan(text: beforeText), + TextSpan( + style: composingStyle, + text: insideText, + ), + TextSpan(text: afterText), + ]); + } + + if (supportSpecialText) { + final TextSpan? specialTextSpan = extendedEditableText + .specialTextSpanBuilder + ?.build(_value.text, textStyle: widget.style); + if (specialTextSpan != null) { + return specialTextSpan; + } + } + + if (_placeholderLocation >= 0 && + _placeholderLocation <= _value.text.length) { + final List<_ScribblePlaceholder> placeholders = <_ScribblePlaceholder>[]; + final int placeholderLocation = _value.text.length - _placeholderLocation; + if (_isMultiline) { + // The zero size placeholder here allows the line to break and keep the caret on the first line. + placeholders.add(const _ScribblePlaceholder( + child: SizedBox.shrink(), size: Size.zero)); + placeholders.add(_ScribblePlaceholder( + child: const SizedBox.shrink(), + size: Size(renderEditable.size.width, 0.0))); + } else { + placeholders.add(const _ScribblePlaceholder( + child: SizedBox.shrink(), size: Size(100.0, 0.0))); + } + return TextSpan( + style: _style, + children: [ + TextSpan(text: _value.text.substring(0, placeholderLocation)), + ...placeholders, + TextSpan(text: _value.text.substring(placeholderLocation)), + ], + ); + } + final bool withComposing = !widget.readOnly && _hasFocus; + if (_spellCheckResultsReceived) { + // If the composing range is out of range for the current text, ignore it to + // preserve the tree integrity, otherwise in release mode a RangeError will + // be thrown and this EditableText will be built with a broken subtree. + assert(!_value.composing.isValid || + !withComposing || + _value.isComposingRangeValid); + + final bool composingRegionOutOfRange = + !_value.isComposingRangeValid || !withComposing; + + return buildTextSpanWithSpellCheckSuggestions( + _value, + composingRegionOutOfRange, + _style, + _spellCheckConfiguration.misspelledTextStyle!, + spellCheckResults!, + ); + } + + // Read only mode should not paint text composing. + return widget.controller.buildTextSpan( + context: context, + style: _style, + withComposing: withComposing, + ); + } + + @override + void bringIntoView(TextPosition position, {double offset = 0}) { + // zmtzawqlp + if (supportSpecialText) { + position = + ExtendedTextLibraryUtils.convertTextInputPostionToTextPainterPostion( + renderEditable.text!, + position, + ); + } + final Rect localRect = renderEditable.getLocalRectForCaret(position); + final RevealedOffset targetOffset = _getOffsetToRevealCaret(localRect); + + // zmtzawqlp + _scrollController.jumpTo(targetOffset.offset + offset); + renderEditable.showOnScreen(rect: targetOffset.rect); + } + + ///zmt + TextEditingValue _handleSpecialTextSpan(TextEditingValue value) { + if (supportSpecialText) { + final bool textChanged = _value.text != value.text; + final bool selectionChanged = _value.selection != value.selection; + if (textChanged) { + final TextSpan newTextSpan = extendedEditableText + .specialTextSpanBuilder! + .build(value.text, textStyle: widget.style); + + final TextSpan oldTextSpan = extendedEditableText + .specialTextSpanBuilder! + .build(_value.text, textStyle: widget.style); + value = ExtendedTextLibraryUtils.handleSpecialTextSpanDelete( + value, _value, oldTextSpan, _textInputConnection); + + final String text = newTextSpan.toPlainText(); + //correct caret Offset + //make sure caret is not in text when caretIn is false + if (text != value.text || selectionChanged) { + value = ExtendedTextLibraryUtils.correctCaretOffset( + value, + newTextSpan, + _textInputConnection, + ); + } + } else if (selectionChanged) { + late final InlineSpan inlineSpan; + + // after pinying complete, the _ExtendedEditable.inlineSpan is not the same as _value.text + // #255 + // only for windows + if (defaultTargetPlatform == TargetPlatform.windows && + // correct caret offset, pinying complete + !value.composing.isValid && + _value.composing.isValid) { + inlineSpan = extendedEditableText.specialTextSpanBuilder! + .build(_value.text, textStyle: widget.style); + _value = _value.copyWith(selection: value.selection); + } else { + inlineSpan = + (_editableKey.currentWidget as _ExtendedEditable).inlineSpan; + } + + value = ExtendedTextLibraryUtils.correctCaretOffset( + value, + inlineSpan, + _textInputConnection, + oldValue: _value, + ); + } + } + + return value; + } + + @override + void updateEditingValue(TextEditingValue value) { + // This method handles text editing state updates from the platform text + // input plugin. The [EditableText] may not have the focus or an open input + // connection, as autofill can update a disconnected [EditableText]. + + // Since we still have to support keyboard select, this is the best place + // to disable text updating. + if (!_shouldCreateInputConnection) { + return; + } + + if (_checkNeedsAdjustAffinity(value)) { + value = value.copyWith( + selection: + value.selection.copyWith(affinity: _value.selection.affinity)); + } + + if (widget.readOnly) { + // In the read-only case, we only care about selection changes, and reject + // everything else. + value = _value.copyWith(selection: value.selection); + } + _lastKnownRemoteTextEditingValue = value; + // zmtzawqlp + value = _handleSpecialTextSpan(value); + if (value == _value) { + // This is possible, for example, when the numeric keyboard is input, + // the engine will notify twice for the same value. + // Track at https://github.com/flutter/flutter/issues/65811 + return; + } + + if (value.text == _value.text && value.composing == _value.composing) { + // `selection` is the only change. + SelectionChangedCause cause; + if (_textInputConnection?.scribbleInProgress ?? false) { + cause = SelectionChangedCause.scribble; + } else if (_pointOffsetOrigin != null) { + cause = SelectionChangedCause.forcePress; + } else { + cause = SelectionChangedCause.keyboard; + } + _handleSelectionChanged(value.selection, cause); + } else { + if (value.text != _value.text) { + // Hide the toolbar if the text was changed, but only hide the toolbar + // overlay; the selection handle's visibility will be handled + // by `_handleSelectionChanged`. https://github.com/flutter/flutter/issues/108673 + hideToolbar(false); + } + _currentPromptRectRange = null; + + final bool revealObscuredInput = _hasInputConnection && + widget.obscureText && + WidgetsBinding.instance.platformDispatcher.brieflyShowPassword && + value.text.length == _value.text.length + 1; + + _obscureShowCharTicksPending = + revealObscuredInput ? _kObscureShowLatestCharCursorTicks : 0; + _obscureLatestCharIndex = + revealObscuredInput ? _value.selection.baseOffset : null; + _formatAndSetValue(value, SelectionChangedCause.keyboard); + } + + // Wherever the value is changed by the user, schedule a showCaretOnScreen + // to make sure the user can see the changes they just made. Programmatic + // changes to `textEditingValue` do not trigger the behavior even if the + // text field is focused. + _scheduleShowCaretOnScreen(withAnimation: true); + if (_hasInputConnection) { + // To keep the cursor from blinking while typing, we want to restart the + // cursor timer every time a new character is typed. + _stopCursorBlink(resetCharTicks: false); + _startCursorBlink(); + } + } + + @override + void userUpdateTextEditingValue( + TextEditingValue value, SelectionChangedCause? cause) { + // zmtzawqlp + value = _handleSpecialTextSpan(value); + // Compare the current TextEditingValue with the pre-format new + // TextEditingValue value, in case the formatter would reject the change. + final bool shouldShowCaret = + widget.readOnly ? _value.selection != value.selection : _value != value; + if (shouldShowCaret) { + _scheduleShowCaretOnScreen(withAnimation: true); + } + + // Even if the value doesn't change, it may be necessary to focus and build + // the selection overlay. For example, this happens when right clicking an + // unfocused field that previously had a selection in the same spot. + if (value == textEditingValue) { + if (!widget.focusNode.hasFocus) { + _flagInternalFocus(); + widget.focusNode.requestFocus(); + _selectionOverlay ??= _createSelectionOverlay(); + } + return; + } + + _formatAndSetValue(value, cause, userInteraction: true); + } + + @override + void updateFloatingCursor(RawFloatingCursorPoint point) { + _floatingCursorResetController ??= AnimationController( + vsync: this, + )..addListener(_onFloatingCursorResetTick); + switch (point.state) { + case FloatingCursorDragState.Start: + if (_floatingCursorResetController!.isAnimating) { + _floatingCursorResetController!.stop(); + _onFloatingCursorResetTick(); + } + // Stop cursor blinking and making it visible. + _stopCursorBlink(resetCharTicks: false); + _cursorBlinkOpacityController.value = 1.0; + // We want to send in points that are centered around a (0,0) origin, so + // we cache the position. + _pointOffsetOrigin = point.offset; + + final Offset startCaretCenter; + final TextPosition currentTextPosition; + final bool shouldResetOrigin; + // Only non-null when starting a floating cursor via long press. + if (point.startLocation != null) { + shouldResetOrigin = false; + (startCaretCenter, currentTextPosition) = point.startLocation!; + } else { + shouldResetOrigin = true; + // zmtzawqlp + currentTextPosition = supportSpecialText + ? ExtendedTextLibraryUtils + .convertTextInputPostionToTextPainterPostion( + renderEditable.text!, + renderEditable.selection!.base, + ) + : TextPosition( + offset: renderEditable.selection!.baseOffset, + affinity: renderEditable.selection!.affinity); + startCaretCenter = + renderEditable.getLocalRectForCaret(currentTextPosition).center; + } + + _startCaretCenter = startCaretCenter; + _lastBoundedOffset = + renderEditable.calculateBoundedFloatingCursorOffset( + _startCaretCenter! - _floatingCursorOffset, + shouldResetOrigin: shouldResetOrigin); + _lastTextPosition = currentTextPosition; + renderEditable.setFloatingCursor( + point.state, _lastBoundedOffset!, _lastTextPosition!); + case FloatingCursorDragState.Update: + final Offset centeredPoint = point.offset! - _pointOffsetOrigin!; + final Offset rawCursorOffset = + _startCaretCenter! + centeredPoint - _floatingCursorOffset; + + _lastBoundedOffset = renderEditable + .calculateBoundedFloatingCursorOffset(rawCursorOffset); + _lastTextPosition = renderEditable.getPositionForPoint(renderEditable + .localToGlobal(_lastBoundedOffset! + _floatingCursorOffset)); + // zmtzawlp + if (supportSpecialText) { + _lastTextPosition = + ExtendedTextLibraryUtils.makeSureCaretNotInSpecialText( + renderEditable.text!, _lastTextPosition!); + } + + renderEditable.setFloatingCursor( + point.state, _lastBoundedOffset!, _lastTextPosition!); + case FloatingCursorDragState.End: + // Resume cursor blinking. + _startCursorBlink(); + // We skip animation if no update has happened. + if (_lastTextPosition != null && _lastBoundedOffset != null) { + _floatingCursorResetController!.value = 0.0; + _floatingCursorResetController!.animateTo(1.0, + // zmtzawqlp + duration: _EditableTextState._floatingCursorResetTime, + curve: Curves.decelerate); + } + } + } + + @override + void _scheduleShowCaretOnScreen({required bool withAnimation}) { + if (_showCaretOnScreenScheduled) { + return; + } + _showCaretOnScreenScheduled = true; + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + _showCaretOnScreenScheduled = false; + // Since we are in a post frame callback, check currentContext in case + // RenderEditable has been disposed (in which case it will be null). + final _RenderEditable? renderEditable = + _editableKey.currentContext?.findRenderObject() as _RenderEditable?; + if (renderEditable == null || + !(renderEditable.selection?.isValid ?? false) || + !_scrollController.hasClients) { + return; + } + + final double lineHeight = renderEditable.preferredLineHeight; + + // Enlarge the target rect by scrollPadding to ensure that caret is not + // positioned directly at the edge after scrolling. + double bottomSpacing = widget.scrollPadding.bottom; + if (_selectionOverlay?.selectionControls != null) { + final double handleHeight = _selectionOverlay!.selectionControls! + .getHandleSize(lineHeight) + .height; + final double interactiveHandleHeight = math.max( + handleHeight, + kMinInteractiveDimension, + ); + final Offset anchor = + _selectionOverlay!.selectionControls!.getHandleAnchor( + TextSelectionHandleType.collapsed, + lineHeight, + ); + final double handleCenter = handleHeight / 2 - anchor.dy; + bottomSpacing = math.max( + handleCenter + interactiveHandleHeight / 2, + bottomSpacing, + ); + } + + final EdgeInsets caretPadding = + widget.scrollPadding.copyWith(bottom: bottomSpacing); + + final Rect caretRect = renderEditable.getLocalRectForCaret( + // renderEditable.selection + // zmtzawqlp + (renderEditable as ExtendedRenderEditable).getActualSelection()!.extent, + ); + final RevealedOffset targetOffset = _getOffsetToRevealCaret(caretRect); + + final Rect rectToReveal; + final TextSelection selection = textEditingValue.selection; + if (selection.isCollapsed) { + rectToReveal = targetOffset.rect; + } else { + final List selectionBoxes = + renderEditable.getBoxesForSelection(selection); + // selectionBoxes may be empty if, for example, the selection does not + // encompass a full character, like if it only contained part of an + // extended grapheme cluster. + if (selectionBoxes.isEmpty) { + rectToReveal = targetOffset.rect; + } else { + rectToReveal = selection.baseOffset < selection.extentOffset + ? selectionBoxes.last.toRect() + : selectionBoxes.first.toRect(); + } + } + + if (withAnimation) { + _scrollController.animateTo( + targetOffset.offset, + duration: _EditableTextState._caretAnimationDuration, + curve: _EditableTextState._caretAnimationCurve, + ); + renderEditable.showOnScreen( + rect: caretPadding.inflateRect(rectToReveal), + duration: _EditableTextState._caretAnimationDuration, + curve: _EditableTextState._caretAnimationCurve, + ); + } else { + _scrollController.jumpTo(targetOffset.offset); + renderEditable.showOnScreen( + rect: caretPadding.inflateRect(rectToReveal), + ); + } + }); + } + + @override + void _updateCaretRectIfNeeded() { + // zmtzawqlp + final TextSelection? selection = // renderEditable.selection; + (renderEditable as ExtendedRenderEditable).getActualSelection(); + if (selection == null || !selection.isValid || !selection.isCollapsed) { + return; + } + final TextPosition currentTextPosition = + TextPosition(offset: selection.start); + final Rect caretRect = + renderEditable.getLocalRectForCaret(currentTextPosition); + _textInputConnection!.setCaretRect(caretRect); + } +} + +class _ExtendedEditable extends _Editable { + _ExtendedEditable({ + super.key, + required super.inlineSpan, + required super.value, + required super.startHandleLayerLink, + required super.endHandleLayerLink, + super.cursorColor, + super.backgroundCursorColor, + required super.showCursor, + required super.forceLine, + required super.readOnly, + super.textHeightBehavior, + required super.textWidthBasis, + required super.hasFocus, + required super.maxLines, + super.minLines, + required super.expands, + super.strutStyle, + super.selectionColor, + required super.textScaler, + required super.textAlign, + required super.textDirection, + super.locale, + required super.obscuringCharacter, + required super.obscureText, + required super.offset, + super.rendererIgnoresPointer = false, + required super.cursorWidth, + super.cursorHeight, + super.cursorRadius, + required super.cursorOffset, + required super.paintCursorAboveText, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.enableInteractiveSelection = true, + required super.textSelectionDelegate, + required super.devicePixelRatio, + super.promptRectRange, + super.promptRectColor, + required super.clipBehavior, + this.supportSpecialText = false, + }); + + final bool supportSpecialText; + + @override + ExtendedRenderEditable createRenderObject(BuildContext context) { + return ExtendedRenderEditable( + text: inlineSpan, + cursorColor: cursorColor, + startHandleLayerLink: startHandleLayerLink, + endHandleLayerLink: endHandleLayerLink, + backgroundCursorColor: backgroundCursorColor, + showCursor: showCursor, + forceLine: forceLine, + readOnly: readOnly, + hasFocus: hasFocus, + maxLines: maxLines, + minLines: minLines, + expands: expands, + strutStyle: strutStyle, + selectionColor: selectionColor, + textScaler: textScaler, + textAlign: textAlign, + textDirection: textDirection, + locale: locale ?? Localizations.maybeLocaleOf(context), + selection: value.selection, + offset: offset, + ignorePointer: rendererIgnoresPointer, + obscuringCharacter: obscuringCharacter, + obscureText: obscureText, + textHeightBehavior: textHeightBehavior, + textWidthBasis: textWidthBasis, + cursorWidth: cursorWidth, + cursorHeight: cursorHeight, + cursorRadius: cursorRadius, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + selectionHeightStyle: selectionHeightStyle, + selectionWidthStyle: selectionWidthStyle, + enableInteractiveSelection: enableInteractiveSelection, + textSelectionDelegate: textSelectionDelegate, + devicePixelRatio: devicePixelRatio, + promptRectRange: promptRectRange, + promptRectColor: promptRectColor, + clipBehavior: clipBehavior, + supportSpecialText: supportSpecialText, + ); + } + + // zmtzawqlp + @override + void updateRenderObject(BuildContext context, _RenderEditable renderObject) { + super.updateRenderObject(context, renderObject); + (renderObject as ExtendedRenderEditable).supportSpecialText = + supportSpecialText; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/spell_check.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/spell_check.dart new file mode 100644 index 0000000..c9d8a2e --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/spell_check.dart @@ -0,0 +1,111 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [SpellCheckConfiguration] +class ExtendedSpellCheckConfiguration extends _SpellCheckConfiguration { + /// Creates a configuration that specifies the service and suggestions handler + /// for spell check. + const ExtendedSpellCheckConfiguration({ + super.spellCheckService, + super.misspelledSelectionColor, + super.misspelledTextStyle, + // super.spellCheckSuggestionsToolbarBuilder, + this.extendedSpellCheckSuggestionsToolbarBuilder, + }); + + const ExtendedSpellCheckConfiguration.disabled() + : extendedSpellCheckSuggestionsToolbarBuilder = null, + super.disabled(); + + /// {@template flutter.widgets.EditableText.contextMenuBuilder} + /// Builds the text selection toolbar when requested by the user. + /// + /// `primaryAnchor` is the desired anchor position for the context menu, while + /// `secondaryAnchor` is the fallback location if the menu doesn't fit. + /// + /// `buttonItems` represents the buttons that would be built by default for + /// this widget. + /// + /// {@tool dartpad} + /// This example shows how to customize the menu, in this case by keeping the + /// default buttons for the platform but modifying their appearance. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.0.dart ** + /// {@end-tool} + /// + /// {@tool dartpad} + /// This example shows how to show a custom button only when an email address + /// is currently selected. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.1.dart ** + /// {@end-tool} + /// + /// See also: + /// * [AdaptiveTextSelectionToolbar], which builds the default text selection + /// toolbar for the current platform, but allows customization of the + /// buttons. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given + /// [ContextMenuButtonItem]s. + /// * [BrowserContextMenu], which allows the browser's context menu on web + /// to be disabled and Flutter-rendered context menus to appear. + /// {@endtemplate} + /// + /// If not provided, no context menu will be shown. + final ExtendedEditableTextContextMenuBuilder? + extendedSpellCheckSuggestionsToolbarBuilder; + + /// Returns a copy of the current [_SpellCheckConfiguration] instance with + /// specified overrides. + @override + _SpellCheckConfiguration copyWith({ + SpellCheckService? spellCheckService, + Color? misspelledSelectionColor, + TextStyle? misspelledTextStyle, + EditableTextContextMenuBuilder? spellCheckSuggestionsToolbarBuilder, + ExtendedEditableTextContextMenuBuilder? + extendedSpellCheckSuggestionsToolbarBuilder, + }) { + if (!_spellCheckEnabled) { + // A new configuration should be constructed to enable spell check. + return const _SpellCheckConfiguration.disabled(); + } + + return ExtendedSpellCheckConfiguration( + spellCheckService: spellCheckService ?? this.spellCheckService, + misspelledSelectionColor: + misspelledSelectionColor ?? this.misspelledSelectionColor, + misspelledTextStyle: misspelledTextStyle ?? this.misspelledTextStyle, + extendedSpellCheckSuggestionsToolbarBuilder: + extendedSpellCheckSuggestionsToolbarBuilder ?? + this.extendedSpellCheckSuggestionsToolbarBuilder, + // spellCheckSuggestionsToolbarBuilder: + // spellCheckSuggestionsToolbarBuilder ?? + // this.spellCheckSuggestionsToolbarBuilder, + ); + } + + @override + bool operator ==(Object other) { + if (identical(this, other)) { + return true; + } + + return other is ExtendedSpellCheckConfiguration && + other.spellCheckService == spellCheckService && + other.misspelledTextStyle == misspelledTextStyle && + other.spellCheckSuggestionsToolbarBuilder == + spellCheckSuggestionsToolbarBuilder && + other._spellCheckEnabled == _spellCheckEnabled && + other.extendedSpellCheckSuggestionsToolbarBuilder == + extendedSpellCheckSuggestionsToolbarBuilder; + } + + @override + int get hashCode => Object.hash( + spellCheckService, + misspelledTextStyle, + spellCheckSuggestionsToolbarBuilder, + _spellCheckEnabled, + extendedSpellCheckSuggestionsToolbarBuilder, + ); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_field.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_field.dart new file mode 100644 index 0000000..271333f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_field.dart @@ -0,0 +1,649 @@ +import 'dart:async'; +import 'dart:collection'; +import 'dart:math' as math; +import 'dart:ui' as ui; + +import 'package:extended_text_field/src/extended/cupertino/spell_check_suggestions_toolbar.dart'; +import 'package:extended_text_field/src/extended/material/spell_check_suggestions_toolbar.dart'; +import 'package:extended_text_library/extended_text_library.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; + +part 'package:extended_text_field/src/extended/rendering/editable.dart'; +part 'package:extended_text_field/src/extended/widgets/editable_text.dart'; +part 'package:extended_text_field/src/extended/widgets/spell_check.dart'; +part 'package:extended_text_field/src/extended/widgets/text_selection.dart'; +part 'package:extended_text_field/src/extended/material/selectable_text.dart'; +part 'package:extended_text_field/src/official/rendering/editable.dart'; +part 'package:extended_text_field/src/official/widgets/editable_text.dart'; +part 'package:extended_text_field/src/official/widgets/text_field.dart'; +part 'package:extended_text_field/src/official/widgets/text_selection.dart'; +part 'package:extended_text_field/src/official/widgets/spell_check.dart'; +part 'package:extended_text_field/src/official/material/selectable_text.dart'; + +class ExtendedTextField extends _TextField { + const ExtendedTextField({ + super.key, + super.groupId = EditableText, + super.controller, + super.focusNode, + super.undoController, + super.decoration = const InputDecoration(), + super.keyboardType, + super.textInputAction, + super.textCapitalization = TextCapitalization.none, + super.style, + super.strutStyle, + super.textAlign = TextAlign.start, + super.textAlignVertical, + super.textDirection, + super.readOnly = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + super.toolbarOptions, + super.showCursor, + super.autofocus = false, + super.statesController, + super.obscuringCharacter = '•', + super.obscureText = false, + super.autocorrect = true, + super.smartDashesType, + super.smartQuotesType, + super.enableSuggestions = true, + super.maxLines = 1, + super.minLines, + super.expands = false, + super.maxLength, + super.maxLengthEnforcement, + super.onChanged, + super.onEditingComplete, + super.onSubmitted, + super.onAppPrivateCommand, + super.inputFormatters, + super.enabled, + super.cursorWidth = 2.0, + super.cursorHeight, + super.cursorRadius, + super.cursorOpacityAnimates, + super.cursorColor, + super.cursorErrorColor, + super.selectionHeightStyle = ui.BoxHeightStyle.tight, + super.selectionWidthStyle = ui.BoxWidthStyle.tight, + super.keyboardAppearance, + super.scrollPadding = const EdgeInsets.all(20.0), + super.dragStartBehavior = DragStartBehavior.start, + super.enableInteractiveSelection, + super.selectionControls, + super.onTap, + super.onTapAlwaysCalled = false, + super.onTapOutside, + super.mouseCursor, + super.buildCounter, + super.scrollController, + super.scrollPhysics, + super.autofillHints = const [], + super.contentInsertionConfiguration, + super.clipBehavior = Clip.hardEdge, + super.restorationId, + super.scribbleEnabled = true, + super.enableIMEPersonalizedLearning = true, + // zmtzwqlp + // super.contextMenuBuilder = _defaultContextMenuBuilder, + this.extendedContextMenuBuilder = _defaultContextMenuBuilder, + super.canRequestFocus = true, + // zmtzawqlp + // super.spellCheckConfiguration, + this.extendedSpellCheckConfiguration, + this.specialTextSpanBuilder, + super.magnifierConfiguration, + }); + + /// build your ccustom text span + final SpecialTextSpanBuilder? specialTextSpanBuilder; + + /// {@template flutter.widgets.EditableText.contextMenuBuilder} + /// Builds the text selection toolbar when requested by the user. + /// + /// `primaryAnchor` is the desired anchor position for the context menu, while + /// `secondaryAnchor` is the fallback location if the menu doesn't fit. + /// + /// `buttonItems` represents the buttons that would be built by default for + /// this widget. + /// + /// {@tool dartpad} + /// This example shows how to customize the menu, in this case by keeping the + /// default buttons for the platform but modifying their appearance. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.0.dart ** + /// {@end-tool} + /// + /// {@tool dartpad} + /// This example shows how to show a custom button only when an email address + /// is currently selected. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.1.dart ** + /// {@end-tool} + /// + /// See also: + /// * [AdaptiveTextSelectionToolbar], which builds the default text selection + /// toolbar for the current platform, but allows customization of the + /// buttons. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given + /// [ContextMenuButtonItem]s. + /// * [BrowserContextMenu], which allows the browser's context menu on web + /// to be disabled and Flutter-rendered context menus to appear. + /// {@endtemplate} + /// + /// If not provided, no context menu will be shown. + final ExtendedEditableTextContextMenuBuilder? extendedContextMenuBuilder; + + /// {@template flutter.widgets.EditableText.spellCheckConfiguration} + /// Configuration that details how spell check should be performed. + /// + /// Specifies the [SpellCheckService] used to spell check text input and the + /// [TextStyle] used to style text with misspelled words. + /// + /// If the [SpellCheckService] is left null, spell check is disabled by + /// default unless the [DefaultSpellCheckService] is supported, in which case + /// it is used. It is currently supported only on Android and iOS. + /// + /// If this configuration is left null, then spell check is disabled by default. + /// {@endtemplate} + final ExtendedSpellCheckConfiguration? extendedSpellCheckConfiguration; + + /// zmtzawqlp + /// [AdaptiveTextSelectionToolbar.editableText] + static Widget _defaultContextMenuBuilder( + BuildContext context, ExtendedEditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.buttonItems( + buttonItems: editableTextState.contextMenuButtonItems, + anchors: editableTextState.contextMenuAnchors, + ); + // return AdaptiveTextSelectionToolbar.editableText( + // editableTextState: editableTextState, + // ); + } + + /// Returns a new [SpellCheckConfiguration] where the given configuration has + /// had any missing values replaced with their defaults for the Android + /// platform. + static ExtendedSpellCheckConfiguration inferAndroidSpellCheckConfiguration( + ExtendedSpellCheckConfiguration? configuration, + ) { + if (configuration == null || + configuration == const ExtendedSpellCheckConfiguration.disabled()) { + return const ExtendedSpellCheckConfiguration.disabled(); + } + return configuration.copyWith( + misspelledTextStyle: configuration.misspelledTextStyle ?? + TextField.materialMisspelledTextStyle, + extendedSpellCheckSuggestionsToolbarBuilder: + configuration.extendedSpellCheckSuggestionsToolbarBuilder ?? + ExtendedTextField.defaultSpellCheckSuggestionsToolbarBuilder, + // spellCheckSuggestionsToolbarBuilder: + // configuration.spellCheckSuggestionsToolbarBuilder ?? + // TextField.defaultSpellCheckSuggestionsToolbarBuilder, + ) as ExtendedSpellCheckConfiguration; + } + + /// Default builder for [TextField]'s spell check suggestions toolbar. + /// + /// On Apple platforms, builds an iOS-style toolbar. Everywhere else, builds + /// an Android-style toolbar. + /// + /// See also: + /// * [spellCheckConfiguration], where this is typically specified for + /// [TextField]. + /// * [SpellCheckConfiguration.spellCheckSuggestionsToolbarBuilder], the + /// parameter for which this is the default value for [TextField]. + /// * [CupertinoTextField.defaultSpellCheckSuggestionsToolbarBuilder], which + /// is like this but specifies the default for [CupertinoTextField]. + /// [TextField.defaultSpellCheckSuggestionsToolbarBuilder] + @visibleForTesting + static Widget defaultSpellCheckSuggestionsToolbarBuilder( + BuildContext context, + ExtendedEditableTextState editableTextState, + ) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return ExtendedCupertinoSpellCheckSuggestionsToolbar.editableText( + editableTextState: editableTextState, + ); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return ExtendedSpellCheckSuggestionsToolbar.editableText( + editableTextState: editableTextState, + ); + } + } + + /// Returns a new [SpellCheckConfiguration] where the given configuration has + /// had any missing values replaced with their defaults for the iOS platform. + static ExtendedSpellCheckConfiguration inferIOSSpellCheckConfiguration( + ExtendedSpellCheckConfiguration? configuration, + ) { + if (configuration == null || + configuration == const ExtendedSpellCheckConfiguration.disabled()) { + return const ExtendedSpellCheckConfiguration.disabled(); + } + + return configuration.copyWith( + misspelledTextStyle: configuration.misspelledTextStyle ?? + CupertinoTextField.cupertinoMisspelledTextStyle, + misspelledSelectionColor: configuration.misspelledSelectionColor ?? + // ignore: invalid_use_of_visible_for_testing_member + CupertinoTextField.kMisspelledSelectionColor, + extendedSpellCheckSuggestionsToolbarBuilder: + configuration.extendedSpellCheckSuggestionsToolbarBuilder ?? + defaultIosSpellCheckSuggestionsToolbarBuilder, + // spellCheckSuggestionsToolbarBuilder: + // configuration.spellCheckSuggestionsToolbarBuilder + // ?? CupertinoTextField.defaultSpellCheckSuggestionsToolbarBuilder, + ) as ExtendedSpellCheckConfiguration; + } + + /// Default builder for the spell check suggestions toolbar in the Cupertino + /// style. + /// + /// See also: + /// * [spellCheckConfiguration], where this is typically specified for + /// [CupertinoTextField]. + /// * [SpellCheckConfiguration.spellCheckSuggestionsToolbarBuilder], the + /// parameter for which this is the default value for [CupertinoTextField]. + /// * [TextField.defaultSpellCheckSuggestionsToolbarBuilder], which is like + /// this but specifies the default for [CupertinoTextField]. + /// [CupertinoTextField.defaultSpellCheckSuggestionsToolbarBuilder] + @visibleForTesting + static Widget defaultIosSpellCheckSuggestionsToolbarBuilder( + BuildContext context, + ExtendedEditableTextState editableTextState, + ) { + return ExtendedCupertinoSpellCheckSuggestionsToolbar.editableText( + editableTextState: editableTextState, + ); + } + + @override + State<_TextField> createState() { + return ExtendedTextFieldState(); + } +} + +class ExtendedTextFieldState extends _TextFieldState { + ExtendedTextField get extenedTextField => widget as ExtendedTextField; + + @override + Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); + assert(debugCheckHasMaterialLocalizations(context)); + assert(debugCheckHasDirectionality(context)); + assert( + !(widget.style != null && + !widget.style!.inherit && + (widget.style!.fontSize == null || + widget.style!.textBaseline == null)), + 'inherit false style must supply fontSize and textBaseline', + ); + + final ThemeData theme = Theme.of(context); + final DefaultSelectionStyle selectionStyle = + DefaultSelectionStyle.of(context); + final TextStyle? providedStyle = + MaterialStateProperty.resolveAs(widget.style, _statesController.value); + final TextStyle style = _getInputStyleForState(theme.useMaterial3 + ? _m3InputStyle(context) + : theme.textTheme.titleMedium!) + .merge(providedStyle); + final Brightness keyboardAppearance = + widget.keyboardAppearance ?? theme.brightness; + final TextEditingController controller = _effectiveController; + final FocusNode focusNode = _effectiveFocusNode; + final List formatters = [ + ...?widget.inputFormatters, + if (widget.maxLength != null) + LengthLimitingTextInputFormatter( + widget.maxLength, + maxLengthEnforcement: _effectiveMaxLengthEnforcement, + ), + ]; + + // Set configuration as disabled if not otherwise specified. If specified, + // ensure that configuration uses the correct style for misspelled words for + // the current platform, unless a custom style is specified. + // zmtzawqlp + final ExtendedSpellCheckConfiguration spellCheckConfiguration; + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + // zmtzawqlp + spellCheckConfiguration = + ExtendedTextField.inferIOSSpellCheckConfiguration( + extenedTextField.extendedSpellCheckConfiguration, + ); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + // zmtzawqlp + spellCheckConfiguration = + ExtendedTextField.inferAndroidSpellCheckConfiguration( + extenedTextField.extendedSpellCheckConfiguration, + ); + } + + TextSelectionControls? textSelectionControls = widget.selectionControls; + final bool paintCursorAboveText; + bool? cursorOpacityAnimates = widget.cursorOpacityAnimates; + Offset? cursorOffset; + final Color cursorColor; + final Color selectionColor; + Color? autocorrectionTextRectColor; + Radius? cursorRadius = widget.cursorRadius; + VoidCallback? handleDidGainAccessibilityFocus; + VoidCallback? handleDidLoseAccessibilityFocus; + + switch (theme.platform) { + case TargetPlatform.iOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = true; + textSelectionControls ??= cupertinoTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates ??= true; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + autocorrectionTextRectColor = selectionColor; + + case TargetPlatform.macOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = false; + textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + + case TargetPlatform.android: + case TargetPlatform.fuchsia: + forcePressEnabled = false; + textSelectionControls ??= materialTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + + case TargetPlatform.linux: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + + case TargetPlatform.windows: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + } + + Widget child = RepaintBoundary( + child: UnmanagedRestorationScope( + bucket: bucket, + child: ExtendedEditableText( + key: editableTextKey, + readOnly: widget.readOnly || !_isEnabled, + toolbarOptions: widget.toolbarOptions, + showCursor: widget.showCursor, + showSelectionHandles: _showSelectionHandles, + controller: controller, + focusNode: focusNode, + undoController: widget.undoController, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + textCapitalization: widget.textCapitalization, + style: style, + strutStyle: widget.strutStyle, + textAlign: widget.textAlign, + textDirection: widget.textDirection, + autofocus: widget.autofocus, + obscuringCharacter: widget.obscuringCharacter, + obscureText: widget.obscureText, + autocorrect: widget.autocorrect, + smartDashesType: widget.smartDashesType, + smartQuotesType: widget.smartQuotesType, + enableSuggestions: widget.enableSuggestions, + maxLines: widget.maxLines, + minLines: widget.minLines, + expands: widget.expands, + // Only show the selection highlight when the text field is focused. + selectionColor: focusNode.hasFocus ? selectionColor : null, + selectionControls: + widget.selectionEnabled ? textSelectionControls : null, + onChanged: widget.onChanged, + onSelectionChanged: _handleSelectionChanged, + onEditingComplete: widget.onEditingComplete, + onSubmitted: widget.onSubmitted, + onAppPrivateCommand: widget.onAppPrivateCommand, + groupId: widget.groupId, + onSelectionHandleTapped: _handleSelectionHandleTapped, + onTapOutside: widget.onTapOutside, + inputFormatters: formatters, + rendererIgnoresPointer: true, + mouseCursor: MouseCursor.defer, // TextField will handle the cursor + cursorWidth: widget.cursorWidth, + cursorHeight: widget.cursorHeight, + cursorRadius: cursorRadius, + cursorColor: cursorColor, + selectionHeightStyle: widget.selectionHeightStyle, + selectionWidthStyle: widget.selectionWidthStyle, + cursorOpacityAnimates: cursorOpacityAnimates, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + backgroundCursorColor: CupertinoColors.inactiveGray, + scrollPadding: widget.scrollPadding, + keyboardAppearance: keyboardAppearance, + enableInteractiveSelection: widget.enableInteractiveSelection, + dragStartBehavior: widget.dragStartBehavior, + scrollController: widget.scrollController, + scrollPhysics: widget.scrollPhysics, + autofillClient: this, + autocorrectionTextRectColor: autocorrectionTextRectColor, + clipBehavior: widget.clipBehavior, + restorationId: 'editable', + scribbleEnabled: widget.scribbleEnabled, + enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning, + contentInsertionConfiguration: widget.contentInsertionConfiguration, + // contextMenuBuilder: widget.contextMenuBuilder, + // spellCheckConfiguration: spellCheckConfiguration, + extendedContextMenuBuilder: + extenedTextField.extendedContextMenuBuilder, + extendedSpellCheckConfiguration: spellCheckConfiguration, + magnifierConfiguration: widget.magnifierConfiguration ?? + TextMagnifier.adaptiveMagnifierConfiguration, + // zmtzawqlp + specialTextSpanBuilder: extenedTextField.specialTextSpanBuilder, + ), + ), + ); + + if (widget.decoration != null) { + child = AnimatedBuilder( + animation: Listenable.merge([focusNode, controller]), + builder: (BuildContext context, Widget? child) { + return InputDecorator( + decoration: _getEffectiveDecoration(), + baseStyle: widget.style, + textAlign: widget.textAlign, + textAlignVertical: widget.textAlignVertical, + isHovering: _isHovering, + isFocused: focusNode.hasFocus, + isEmpty: controller.value.text.isEmpty, + expands: widget.expands, + child: child, + ); + }, + child: child, + ); + } + final MouseCursor effectiveMouseCursor = + MaterialStateProperty.resolveAs( + widget.mouseCursor ?? MaterialStateMouseCursor.textable, + _statesController.value, + ); + + final int? semanticsMaxValueLength; + if (_effectiveMaxLengthEnforcement != MaxLengthEnforcement.none && + widget.maxLength != null && + widget.maxLength! > 0) { + semanticsMaxValueLength = widget.maxLength; + } else { + semanticsMaxValueLength = null; + } + + return MouseRegion( + cursor: effectiveMouseCursor, + onEnter: (PointerEnterEvent event) => _handleHover(true), + onExit: (PointerExitEvent event) => _handleHover(false), + child: TextFieldTapRegion( + child: IgnorePointer( + ignoring: widget.ignorePointers ?? !_isEnabled, + child: AnimatedBuilder( + animation: controller, // changes the _currentLength + builder: (BuildContext context, Widget? child) { + return Semantics( + enabled: _isEnabled, + maxValueLength: semanticsMaxValueLength, + currentValueLength: _currentLength, + onTap: widget.readOnly + ? null + : () { + if (!_effectiveController.selection.isValid) { + _effectiveController.selection = + TextSelection.collapsed( + offset: _effectiveController.text.length); + } + _requestKeyboard(); + }, + onDidGainAccessibilityFocus: handleDidGainAccessibilityFocus, + onDidLoseAccessibilityFocus: handleDidLoseAccessibilityFocus, + onFocus: _isEnabled + ? () { + assert( + _effectiveFocusNode.canRequestFocus, + 'Received SemanticsAction.focus from the engine. However, the FocusNode ' + 'of this text field cannot gain focus. This likely indicates a bug. ' + 'If this text field cannot be focused (e.g. because it is not ' + 'enabled), then its corresponding semantics node must be configured ' + 'such that the assistive technology cannot request focus on it.'); + + if (_effectiveFocusNode.canRequestFocus && + !_effectiveFocusNode.hasFocus) { + _effectiveFocusNode.requestFocus(); + } else if (!widget.readOnly) { + // If the platform requested focus, that means that previously the + // platform believed that the text field did not have focus (even + // though Flutter's widget system believed otherwise). This likely + // means that the on-screen keyboard is hidden, or more generally, + // there is no current editing session in this field. To correct + // that, keyboard must be requested. + // + // A concrete scenario where this can happen is when the user + // dismisses the keyboard on the web. The editing session is + // closed by the engine, but the text field widget stays focused + // in the framework. + _requestKeyboard(); + } + } + : null, + child: child, + ); + }, + child: _selectionGestureDetectorBuilder.buildGestureDetector( + behavior: HitTestBehavior.translucent, + child: child, + ), + ), + ), + ), + ); + } + + void bringIntoView(TextPosition position, {double offset = 0}) { + (_editableText as ExtendedEditableTextState?) + ?.bringIntoView(position, offset: offset); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_selection.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_selection.dart new file mode 100644 index 0000000..f2463b4 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/extended/widgets/text_selection.dart @@ -0,0 +1,222 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [TextSelectionOverlay ] +class ExtendedTextSelectionOverlay extends _TextSelectionOverlay { + ExtendedTextSelectionOverlay({ + required super.value, + required super.context, + super.debugRequiredFor, + required super.toolbarLayerLink, + required super.startHandleLayerLink, + required super.endHandleLayerLink, + required super.renderObject, + super.selectionControls, + super.handlesVisible = false, + required super.selectionDelegate, + super.dragStartBehavior = DragStartBehavior.start, + super.onSelectionHandleTapped, + super.clipboardStatus, + super.contextMenuBuilder, + required super.magnifierConfiguration, + }); + + @override + void _handleSelectionStartHandleDragUpdate(DragUpdateDetails details) { + if (!renderObject.attached) { + return; + } + + // This is NOT the same as details.localPosition. That is relative to the + // selection handle, whereas this is relative to the RenderEditable. + final Offset localPosition = + renderObject.globalToLocal(details.globalPosition); + final double nextStartHandleDragPositionLocal = _getHandleDy( + localPosition.dy, + renderObject.globalToLocal(Offset(0.0, _startHandleDragPosition)).dy, + ); + _startHandleDragPosition = renderObject + .localToGlobal( + Offset(0.0, nextStartHandleDragPositionLocal), + ) + .dy; + final Offset handleTargetGlobal = Offset( + details.globalPosition.dx, + _startHandleDragPosition + _startHandleDragTarget, + ); + TextPosition position = + renderObject.getPositionForPoint(handleTargetGlobal); + + /// zmtzawqlp + final bool hasSpecialInlineSpanBase = + (renderObject as ExtendedRenderEditable).hasSpecialInlineSpanBase; + if (hasSpecialInlineSpanBase) { + position = + ExtendedTextLibraryUtils.convertTextPainterPostionToTextInputPostion( + renderObject.text!, position)!; + } + if (_selection.isCollapsed) { + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + hasSpecialInlineSpanBase: hasSpecialInlineSpanBase, + )); + + final TextSelection currentSelection = + TextSelection.fromPosition(position); + _handleSelectionHandleChanged(currentSelection); + return; + } + + final TextSelection newSelection; + switch (defaultTargetPlatform) { + // On Apple platforms, dragging the base handle makes it the extent. + case TargetPlatform.iOS: + case TargetPlatform.macOS: + newSelection = TextSelection( + extentOffset: position.offset, + baseOffset: _selection.end, + ); + if (newSelection.extentOffset >= _selection.end) { + return; // Don't allow order swapping. + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + newSelection = TextSelection( + baseOffset: position.offset, + extentOffset: _selection.extentOffset, + ); + if (newSelection.baseOffset >= newSelection.extentOffset) { + return; // Don't allow order swapping. + } + } + + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: newSelection.extent.offset < newSelection.base.offset + ? newSelection.extent + : newSelection.base, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + hasSpecialInlineSpanBase: hasSpecialInlineSpanBase, + )); + + _handleSelectionHandleChanged(newSelection); + } + + @override + void _handleSelectionEndHandleDragUpdate(DragUpdateDetails details) { + if (!renderObject.attached) { + return; + } + + // This is NOT the same as details.localPosition. That is relative to the + // selection handle, whereas this is relative to the RenderEditable. + final Offset localPosition = + renderObject.globalToLocal(details.globalPosition); + + final double nextEndHandleDragPositionLocal = _getHandleDy( + localPosition.dy, + renderObject.globalToLocal(Offset(0.0, _endHandleDragPosition)).dy, + ); + _endHandleDragPosition = renderObject + .localToGlobal( + Offset(0.0, nextEndHandleDragPositionLocal), + ) + .dy; + + final Offset handleTargetGlobal = Offset( + details.globalPosition.dx, + _endHandleDragPosition + _endHandleDragTarget, + ); + + TextPosition position = + renderObject.getPositionForPoint(handleTargetGlobal); + // zmtzawqlp + final bool hasSpecialInlineSpanBase = + (renderObject as ExtendedRenderEditable).hasSpecialInlineSpanBase; + if (hasSpecialInlineSpanBase) { + position = + ExtendedTextLibraryUtils.convertTextPainterPostionToTextInputPostion( + renderObject.text!, position)!; + } + if (_selection.isCollapsed) { + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + hasSpecialInlineSpanBase: hasSpecialInlineSpanBase, + )); + + final TextSelection currentSelection = + TextSelection.fromPosition(position); + _handleSelectionHandleChanged(currentSelection); + return; + } + + final TextSelection newSelection; + switch (defaultTargetPlatform) { + // On Apple platforms, dragging the base handle makes it the extent. + case TargetPlatform.iOS: + case TargetPlatform.macOS: + newSelection = TextSelection( + extentOffset: position.offset, + baseOffset: _selection.start, + ); + if (position.offset <= _selection.start) { + return; // Don't allow order swapping. + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + newSelection = TextSelection( + baseOffset: _selection.baseOffset, + extentOffset: position.offset, + ); + if (newSelection.baseOffset >= newSelection.extentOffset) { + return; // Don't allow order swapping. + } + } + + _handleSelectionHandleChanged(newSelection); + + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: newSelection.extent, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + hasSpecialInlineSpanBase: hasSpecialInlineSpanBase, + )); + } + + @override + MagnifierInfo _buildMagnifier({ + required _RenderEditable renderEditable, + required ui.Offset globalGesturePosition, + required ui.TextPosition currentTextPosition, + bool hasSpecialInlineSpanBase = false, + }) { + // zmtzawqlp + if (hasSpecialInlineSpanBase) { + currentTextPosition = + ExtendedTextLibraryUtils.convertTextInputPostionToTextPainterPostion( + renderObject.text!, currentTextPosition); + } + return super._buildMagnifier( + renderEditable: renderEditable, + globalGesturePosition: globalGesturePosition, + currentTextPosition: currentTextPosition); + } + + // @override + // void _handleSelectionHandleChanged(TextSelection newSelection) { + // // zmtzawqlp + // if ((renderObject as ExtendedRenderEditable).hasSpecialInlineSpanBase) { + // newSelection = ExtendedTextLibraryUtils + // .convertTextPainterSelectionToTextInputSelection( + // renderObject.text!, newSelection); + // } + // super._handleSelectionHandleChanged(newSelection); + // } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/binding.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/binding.dart new file mode 100644 index 0000000..89435de --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/binding.dart @@ -0,0 +1,86 @@ +import 'package:extended_text_field/src/keyboard/focus_node.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; + +/// void main() { +/// TextInputBinding(); +/// runApp(const MyApp()); +/// } +class TextInputBinding extends WidgetsFlutterBinding + with TextInputBindingMixin {} + +/// class YourBinding extends WidgetsFlutterBinding with TextInputBindingMixin,YourBindingMixin { +/// @override +/// // ignore: unnecessary_overrides +/// bool ignoreTextInputShow() { +/// // you can override it base on your case +/// // if NoKeyboardFocusNode is not enough +/// return super.ignoreTextInputShow(); +/// } +/// } +/// +/// void main() { +/// YourBinding(); +/// runApp(const MyApp()); +/// } +mixin TextInputBindingMixin on WidgetsFlutterBinding { + @override + BinaryMessenger createBinaryMessenger() { + return TextInputBinaryMessenger(super.createBinaryMessenger(), this); + } + + bool ignoreSendMessage(MethodCall methodCall) => false; + + bool ignoreTextInputShow() { + final FocusNode? focus = FocusManager.instance.primaryFocus; + if (focus != null && + focus is TextInputFocusNode && + focus.ignoreSystemKeyboardShow) { + return true; + } + return false; + } +} + +class TextInputBinaryMessenger extends BinaryMessenger { + TextInputBinaryMessenger(this.origin, this.textInputBindingMixin); + final BinaryMessenger origin; + final TextInputBindingMixin textInputBindingMixin; + @override + Future handlePlatformMessage(String channel, ByteData? data, + PlatformMessageResponseCallback? callback) async { + ServicesBinding.instance.channelBuffers.push( + channel, + data, + (ByteData? data) { + callback?.call(data); + }, + ); + } + + @override + Future? send(String channel, ByteData? message) async { + if (channel == SystemChannels.textInput.name) { + final MethodCall methodCall = + SystemChannels.textInput.codec.decodeMethodCall(message); + bool ignore = false; + switch (methodCall.method) { + case 'TextInput.show': + ignore = textInputBindingMixin.ignoreTextInputShow(); + break; + default: + ignore = textInputBindingMixin.ignoreSendMessage(methodCall); + } + + if (ignore) { + return null; + } + } + return origin.send(channel, message); + } + + @override + void setMessageHandler(String channel, MessageHandler? handler) { + origin.setMessageHandler(channel, handler); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/focus_node.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/focus_node.dart new file mode 100644 index 0000000..d4ec7da --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/keyboard/focus_node.dart @@ -0,0 +1,9 @@ +import 'package:flutter/widgets.dart'; + +/// The FocusNode to be used in [TextInputBindingMixin] +/// +class TextInputFocusNode extends FocusNode { + /// no system keyboard show + /// if it's true, it stop Flutter Framework send `TextInput.show` message to Flutter Engine + bool ignoreSystemKeyboardShow = true; +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/material/selectable_text.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/material/selectable_text.dart new file mode 100644 index 0000000..58d6a4f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/material/selectable_text.dart @@ -0,0 +1,835 @@ +// Copyright 2014 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ignore_for_file: overridden_fields + +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +// Examples can assume: +// late BuildContext context; +// late FocusNode myFocusNode; + +/// An eyeballed value that moves the cursor slightly left of where it is +/// rendered for text on Android so its positioning more accurately matches the +/// native iOS text cursor positioning. +/// +/// This value is in device pixels, not logical pixels as is typically used +/// throughout the codebase. +const int iOSHorizontalOffset = -2; + +class _TextSpanEditingController extends TextEditingController { + _TextSpanEditingController({required TextSpan textSpan}) + : _textSpan = textSpan, + super(text: textSpan.toPlainText(includeSemanticsLabels: false)); + + final TextSpan _textSpan; + + @override + TextSpan buildTextSpan( + {required BuildContext context, + TextStyle? style, + required bool withComposing}) { + // This does not care about composing. + return TextSpan( + style: style, + children: [_textSpan], + ); + } + + @override + set text(String? newText) { + // This should never be reached. + throw UnimplementedError(); + } +} + +class _SelectableTextSelectionGestureDetectorBuilder + // zmtzawqlp + extends _TextSelectionGestureDetectorBuilder { + _SelectableTextSelectionGestureDetectorBuilder({ + required _SelectableTextState state, + }) : _state = state, + super(delegate: state); + + final _SelectableTextState _state; + + /// The viewport offset pixels of any [Scrollable] containing the + /// [RenderEditable] at the last drag start. + @override + double _dragStartScrollOffset = 0.0; + + /// The viewport offset pixels of the [RenderEditable] at the last drag start. + @override + double _dragStartViewportOffset = 0.0; + + @override + double get _scrollPosition { + final ScrollableState? scrollableState = + delegate.editableTextKey.currentContext == null + ? null + : Scrollable.maybeOf(delegate.editableTextKey.currentContext!); + return scrollableState == null ? 0.0 : scrollableState.position.pixels; + } + + @override + AxisDirection? get _scrollDirection { + final ScrollableState? scrollableState = + delegate.editableTextKey.currentContext == null + ? null + : Scrollable.maybeOf(delegate.editableTextKey.currentContext!); + return scrollableState?.axisDirection; + } + + @override + void onForcePressStart(ForcePressDetails details) { + super.onForcePressStart(details); + if (delegate.selectionEnabled && shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + } + + @override + void onForcePressEnd(ForcePressDetails details) { + // Not required. + } + + @override + void onSingleLongTapStart(LongPressStartDetails details) { + if (!delegate.selectionEnabled) { + return; + } + renderEditable.selectWord(cause: SelectionChangedCause.longPress); + Feedback.forLongPress(_state.context); + _dragStartViewportOffset = renderEditable.offset.pixels; + _dragStartScrollOffset = _scrollPosition; + } + + @override + void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { + if (!delegate.selectionEnabled) { + return; + } + // Adjust the drag start offset for possible viewport offset changes. + final Offset editableOffset = renderEditable.maxLines == 1 + ? Offset(renderEditable.offset.pixels - _dragStartViewportOffset, 0.0) + : Offset(0.0, renderEditable.offset.pixels - _dragStartViewportOffset); + final Offset scrollableOffset = + switch (axisDirectionToAxis(_scrollDirection ?? AxisDirection.left)) { + Axis.horizontal => Offset(_scrollPosition - _dragStartScrollOffset, 0), + Axis.vertical => Offset(0, _scrollPosition - _dragStartScrollOffset), + }; + renderEditable.selectWordsInRange( + from: details.globalPosition - + details.offsetFromOrigin - + editableOffset - + scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.longPress, + ); + } + + @override + void onSingleTapUp(TapDragUpDetails details) { + editableText.hideToolbar(); + if (delegate.selectionEnabled) { + switch (Theme.of(_state.context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + renderEditable.selectWordEdge(cause: SelectionChangedCause.tap); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + } + } + _state.widget.onTap?.call(); + } +} + +/// A run of selectable text with a single style. +/// +/// Consider using [SelectionArea] or [SelectableRegion] instead, which enable +/// selection on a widget subtree, including but not limited to [Text] widgets. +/// +/// The [SelectableText] widget displays a string of text with a single style. +/// The string might break across multiple lines or might all be displayed on +/// the same line depending on the layout constraints. +/// +/// {@youtube 560 315 https://www.youtube.com/watch?v=ZSU3ZXOs6hc} +/// +/// The [style] argument is optional. When omitted, the text will use the style +/// from the closest enclosing [DefaultTextStyle]. If the given style's +/// [TextStyle.inherit] property is true (the default), the given style will +/// be merged with the closest enclosing [DefaultTextStyle]. This merging +/// behavior is useful, for example, to make the text bold while using the +/// default font family and size. +/// +/// {@macro flutter.material.textfield.wantKeepAlive} +/// +/// {@tool snippet} +/// +/// ```dart +/// const SelectableText( +/// 'Hello! How are you?', +/// textAlign: TextAlign.center, +/// style: TextStyle(fontWeight: FontWeight.bold), +/// ) +/// ``` +/// {@end-tool} +/// +/// Using the [SelectableText.rich] constructor, the [SelectableText] widget can +/// display a paragraph with differently styled [TextSpan]s. The sample +/// that follows displays "Hello beautiful world" with different styles +/// for each word. +/// +/// {@tool snippet} +/// +/// ```dart +/// const SelectableText.rich( +/// TextSpan( +/// text: 'Hello', // default text style +/// children: [ +/// TextSpan(text: ' beautiful ', style: TextStyle(fontStyle: FontStyle.italic)), +/// TextSpan(text: 'world', style: TextStyle(fontWeight: FontWeight.bold)), +/// ], +/// ), +/// ) +/// ``` +/// {@end-tool} +/// +/// ## Interactivity +/// +/// To make [SelectableText] react to touch events, use callback [onTap] to achieve +/// the desired behavior. +/// +/// ## Scrolling Considerations +/// +/// If this [SelectableText] is not a descendant of [Scaffold] and is being used +/// within a [Scrollable] or nested [Scrollable]s, consider placing a +/// [ScrollNotificationObserver] above the root [Scrollable] that contains this +/// [SelectableText] to ensure proper scroll coordination for [SelectableText] +/// and its components like [TextSelectionOverlay]. +/// +/// See also: +/// +/// * [Text], which is the non selectable version of this widget. +/// * [TextField], which is the editable version of this widget. +/// * [SelectionArea], which enables the selection of multiple [Text] widgets +/// and of other widgets. +class _SelectableText extends StatefulWidget { + /// Creates a selectable text widget. + /// + /// If the [style] argument is null, the text will use the style from the + /// closest enclosing [DefaultTextStyle]. + /// + + /// If the [showCursor], [autofocus], [dragStartBehavior], + /// [selectionHeightStyle], [selectionWidthStyle] and [data] arguments are + /// specified, the [maxLines] argument must be greater than zero. + const _SelectableText( + String this.data, { + super.key, + this.focusNode, + this.style, + this.strutStyle, + this.textAlign, + this.textDirection, + this.textScaler, + this.showCursor = false, + this.autofocus = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + this.toolbarOptions, + this.minLines, + this.maxLines, + this.cursorWidth = 2.0, + this.cursorHeight, + this.cursorRadius, + this.cursorColor, + this.selectionHeightStyle = ui.BoxHeightStyle.tight, + this.selectionWidthStyle = ui.BoxWidthStyle.tight, + this.dragStartBehavior = DragStartBehavior.start, + this.enableInteractiveSelection = true, + this.selectionControls, + this.onTap, + this.scrollPhysics, + this.semanticsLabel, + this.textHeightBehavior, + this.textWidthBasis, + this.onSelectionChanged, + this.contextMenuBuilder = _defaultContextMenuBuilder, + this.magnifierConfiguration, + }) : assert(maxLines == null || maxLines > 0), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + textSpan = null; + + /// Creates a selectable text widget with a [TextSpan]. + /// + /// The [TextSpan.children] attribute of the [textSpan] parameter must only + /// contain [TextSpan]s. Other types of [InlineSpan] are not allowed. + const _SelectableText.rich( + TextSpan this.textSpan, { + super.key, + this.focusNode, + this.style, + this.strutStyle, + this.textAlign, + this.textDirection, + this.textScaler, + this.showCursor = false, + this.autofocus = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + this.toolbarOptions, + this.minLines, + this.maxLines, + this.cursorWidth = 2.0, + this.cursorHeight, + this.cursorRadius, + this.cursorColor, + this.selectionHeightStyle = ui.BoxHeightStyle.tight, + this.selectionWidthStyle = ui.BoxWidthStyle.tight, + this.dragStartBehavior = DragStartBehavior.start, + this.enableInteractiveSelection = true, + this.selectionControls, + this.onTap, + this.scrollPhysics, + this.semanticsLabel, + this.textHeightBehavior, + this.textWidthBasis, + this.onSelectionChanged, + this.contextMenuBuilder = _defaultContextMenuBuilder, + this.magnifierConfiguration, + }) : assert(maxLines == null || maxLines > 0), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + data = null; + + /// The text to display. + /// + /// This will be null if a [textSpan] is provided instead. + final String? data; + + /// The text to display as a [TextSpan]. + /// + /// This will be null if [data] is provided instead. + final TextSpan? textSpan; + + /// Defines the focus for this widget. + /// + /// Text is only selectable when widget is focused. + /// + /// The [focusNode] is a long-lived object that's typically managed by a + /// [StatefulWidget] parent. See [FocusNode] for more information. + /// + /// To give the focus to this widget, provide a [focusNode] and then + /// use the current [FocusScope] to request the focus: + /// + /// ```dart + /// FocusScope.of(context).requestFocus(myFocusNode); + /// ``` + /// + /// This happens automatically when the widget is tapped. + /// + /// To be notified when the widget gains or loses the focus, add a listener + /// to the [focusNode]: + /// + /// ```dart + /// myFocusNode.addListener(() { print(myFocusNode.hasFocus); }); + /// ``` + /// + /// If null, this widget will create its own [FocusNode] with + /// [FocusNode.skipTraversal] parameter set to `true`, which causes the widget + /// to be skipped over during focus traversal. + final FocusNode? focusNode; + + /// The style to use for the text. + /// + /// If null, defaults [DefaultTextStyle] of context. + final TextStyle? style; + + /// {@macro flutter.widgets.editableText.strutStyle} + final StrutStyle? strutStyle; + + /// {@macro flutter.widgets.editableText.textAlign} + final TextAlign? textAlign; + + /// {@macro flutter.widgets.editableText.textDirection} + final TextDirection? textDirection; + + /// {@macro flutter.painting.textPainter.textScaler} + final TextScaler? textScaler; + + /// {@macro flutter.widgets.editableText.autofocus} + final bool autofocus; + + /// {@macro flutter.widgets.editableText.minLines} + final int? minLines; + + /// {@macro flutter.widgets.editableText.maxLines} + final int? maxLines; + + /// {@macro flutter.widgets.editableText.showCursor} + final bool showCursor; + + /// {@macro flutter.widgets.editableText.cursorWidth} + final double cursorWidth; + + /// {@macro flutter.widgets.editableText.cursorHeight} + final double? cursorHeight; + + /// {@macro flutter.widgets.editableText.cursorRadius} + final Radius? cursorRadius; + + /// The color of the cursor. + /// + /// The cursor indicates the current text insertion point. + /// + /// If null then [DefaultSelectionStyle.cursorColor] is used. If that is also + /// null and [ThemeData.platform] is [TargetPlatform.iOS] or + /// [TargetPlatform.macOS], then [CupertinoThemeData.primaryColor] is used. + /// Otherwise [ColorScheme.primary] of [ThemeData.colorScheme] is used. + final Color? cursorColor; + + /// Controls how tall the selection highlight boxes are computed to be. + /// + /// See [ui.BoxHeightStyle] for details on available styles. + final ui.BoxHeightStyle selectionHeightStyle; + + /// Controls how wide the selection highlight boxes are computed to be. + /// + /// See [ui.BoxWidthStyle] for details on available styles. + final ui.BoxWidthStyle selectionWidthStyle; + + /// {@macro flutter.widgets.editableText.enableInteractiveSelection} + final bool enableInteractiveSelection; + + /// {@macro flutter.widgets.editableText.selectionControls} + final TextSelectionControls? selectionControls; + + /// {@macro flutter.widgets.scrollable.dragStartBehavior} + final DragStartBehavior dragStartBehavior; + + /// Configuration of toolbar options. + /// + /// Paste and cut will be disabled regardless. + /// + /// If not set, select all and copy will be enabled by default. + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + final ToolbarOptions? toolbarOptions; + + /// {@macro flutter.widgets.editableText.selectionEnabled} + bool get selectionEnabled => enableInteractiveSelection; + + /// Called when the user taps on this selectable text. + /// + /// The selectable text builds a [GestureDetector] to handle input events like tap, + /// to trigger focus requests, to move the caret, adjust the selection, etc. + /// Handling some of those events by wrapping the selectable text with a competing + /// GestureDetector is problematic. + /// + /// To unconditionally handle taps, without interfering with the selectable text's + /// internal gesture detector, provide this callback. + /// + /// To be notified when the text field gains or loses the focus, provide a + /// [focusNode] and add a listener to that. + /// + /// To listen to arbitrary pointer events without competing with the + /// selectable text's internal gesture detector, use a [Listener]. + final GestureTapCallback? onTap; + + /// {@macro flutter.widgets.editableText.scrollPhysics} + final ScrollPhysics? scrollPhysics; + + /// {@macro flutter.widgets.Text.semanticsLabel} + final String? semanticsLabel; + + /// {@macro dart.ui.textHeightBehavior} + final TextHeightBehavior? textHeightBehavior; + + /// {@macro flutter.painting.textPainter.textWidthBasis} + final TextWidthBasis? textWidthBasis; + + /// {@macro flutter.widgets.editableText.onSelectionChanged} + final SelectionChangedCallback? onSelectionChanged; + + /// {@macro flutter.widgets.EditableText.contextMenuBuilder} + final EditableTextContextMenuBuilder? contextMenuBuilder; + + static Widget _defaultContextMenuBuilder( + BuildContext context, EditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.editableText( + editableTextState: editableTextState, + ); + } + + /// The configuration for the magnifier used when the text is selected. + /// + /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] + /// on Android, and builds nothing on all other platforms. To suppress the + /// magnifier, consider passing [TextMagnifierConfiguration.disabled]. + /// + /// {@macro flutter.widgets.magnifier.intro} + final TextMagnifierConfiguration? magnifierConfiguration; + + @override + State<_SelectableText> createState() => _SelectableTextState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties + .add(DiagnosticsProperty('data', data, defaultValue: null)); + properties.add(DiagnosticsProperty('semanticsLabel', semanticsLabel, + defaultValue: null)); + properties.add(DiagnosticsProperty('focusNode', focusNode, + defaultValue: null)); + properties.add( + DiagnosticsProperty('style', style, defaultValue: null)); + properties.add( + DiagnosticsProperty('autofocus', autofocus, defaultValue: false)); + properties.add(DiagnosticsProperty('showCursor', showCursor, + defaultValue: false)); + properties.add(IntProperty('minLines', minLines, defaultValue: null)); + properties.add(IntProperty('maxLines', maxLines, defaultValue: null)); + properties.add( + EnumProperty('textAlign', textAlign, defaultValue: null)); + properties.add(EnumProperty('textDirection', textDirection, + defaultValue: null)); + properties.add(DiagnosticsProperty('textScaler', textScaler, + defaultValue: null)); + properties + .add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0)); + properties + .add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null)); + properties.add(DiagnosticsProperty('cursorRadius', cursorRadius, + defaultValue: null)); + properties.add(DiagnosticsProperty('cursorColor', cursorColor, + defaultValue: null)); + properties.add(FlagProperty('selectionEnabled', + value: selectionEnabled, + defaultValue: true, + ifFalse: 'selection disabled')); + properties.add(DiagnosticsProperty( + 'selectionControls', selectionControls, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollPhysics', scrollPhysics, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'textHeightBehavior', textHeightBehavior, + defaultValue: null)); + } +} + +class _SelectableTextState extends State<_SelectableText> + // zmtzawqlp + implements + _TextSelectionGestureDetectorBuilderDelegate { + // zmtzawqlp + _EditableTextState? get _editableText => editableTextKey.currentState; + + late _TextSpanEditingController _controller; + + FocusNode? _focusNode; + FocusNode get _effectiveFocusNode => + widget.focusNode ?? (_focusNode ??= FocusNode(skipTraversal: true)); + + bool _showSelectionHandles = false; + + late _SelectableTextSelectionGestureDetectorBuilder + _selectionGestureDetectorBuilder; + + // API for TextSelectionGestureDetectorBuilderDelegate. + @override + late bool forcePressEnabled; + + // zmtzawqlp + @override + final GlobalKey<_EditableTextState> editableTextKey = + GlobalKey<_EditableTextState>(); + + @override + bool get selectionEnabled => widget.selectionEnabled; + // End of API for TextSelectionGestureDetectorBuilderDelegate. + + @override + void initState() { + super.initState(); + _selectionGestureDetectorBuilder = + _SelectableTextSelectionGestureDetectorBuilder( + state: this, + ); + _controller = _TextSpanEditingController( + textSpan: widget.textSpan ?? TextSpan(text: widget.data), + ); + _controller.addListener(_onControllerChanged); + } + + @override + void didUpdateWidget(_SelectableText oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.data != oldWidget.data || + widget.textSpan != oldWidget.textSpan) { + _controller.removeListener(_onControllerChanged); + _controller.dispose(); + _controller = _TextSpanEditingController( + textSpan: widget.textSpan ?? TextSpan(text: widget.data), + ); + _controller.addListener(_onControllerChanged); + } + if (_effectiveFocusNode.hasFocus && _controller.selection.isCollapsed) { + _showSelectionHandles = false; + } else { + _showSelectionHandles = true; + } + } + + @override + void dispose() { + _focusNode?.dispose(); + _controller.dispose(); + super.dispose(); + } + + void _onControllerChanged() { + final bool showSelectionHandles = + !_effectiveFocusNode.hasFocus || !_controller.selection.isCollapsed; + if (showSelectionHandles == _showSelectionHandles) { + return; + } + setState(() { + _showSelectionHandles = showSelectionHandles; + }); + } + + void _handleSelectionChanged( + TextSelection selection, SelectionChangedCause? cause) { + final bool willShowSelectionHandles = _shouldShowSelectionHandles(cause); + if (willShowSelectionHandles != _showSelectionHandles) { + setState(() { + _showSelectionHandles = willShowSelectionHandles; + }); + } + + widget.onSelectionChanged?.call(selection, cause); + + switch (Theme.of(context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + if (cause == SelectionChangedCause.longPress) { + _editableText?.bringIntoView(selection.base); + } + return; + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + // Do nothing. + } + } + + /// Toggle the toolbar when a selection handle is tapped. + void _handleSelectionHandleTapped() { + if (_controller.selection.isCollapsed) { + _editableText!.toggleToolbar(); + } + } + + bool _shouldShowSelectionHandles(SelectionChangedCause? cause) { + // When the text field is activated by something that doesn't trigger the + // selection overlay, we shouldn't show the handles either. + if (!_selectionGestureDetectorBuilder.shouldShowSelectionToolbar) { + return false; + } + + if (_controller.selection.isCollapsed) { + return false; + } + + if (cause == SelectionChangedCause.keyboard) { + return false; + } + + if (cause == SelectionChangedCause.longPress) { + return true; + } + + if (_controller.text.isNotEmpty) { + return true; + } + + return false; + } + + @override + Widget build(BuildContext context) { + // TODO(garyq): Assert to block WidgetSpans from being used here are removed, + // but we still do not yet have nice handling of things like carets, clipboard, + // and other features. We should add proper support. Currently, caret handling + // is blocked on SkParagraph switch and https://github.com/flutter/engine/pull/27010 + // should be landed in SkParagraph after the switch is complete. + assert(debugCheckHasMediaQuery(context)); + assert(debugCheckHasDirectionality(context)); + assert( + !(widget.style != null && + !widget.style!.inherit && + (widget.style!.fontSize == null || + widget.style!.textBaseline == null)), + 'inherit false style must supply fontSize and textBaseline', + ); + + final ThemeData theme = Theme.of(context); + final DefaultSelectionStyle selectionStyle = + DefaultSelectionStyle.of(context); + final FocusNode focusNode = _effectiveFocusNode; + + TextSelectionControls? textSelectionControls = widget.selectionControls; + final bool paintCursorAboveText; + final bool cursorOpacityAnimates; + Offset? cursorOffset; + final Color cursorColor; + final Color selectionColor; + Radius? cursorRadius = widget.cursorRadius; + + switch (theme.platform) { + case TargetPlatform.iOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = true; + textSelectionControls ??= cupertinoTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates = true; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + + case TargetPlatform.macOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = false; + textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates = true; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + + case TargetPlatform.android: + case TargetPlatform.fuchsia: + forcePressEnabled = false; + textSelectionControls ??= materialTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates = false; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + + case TargetPlatform.linux: + case TargetPlatform.windows: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates = false; + cursorColor = widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + } + + final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(context); + TextStyle? effectiveTextStyle = widget.style; + if (effectiveTextStyle == null || effectiveTextStyle.inherit) { + effectiveTextStyle = defaultTextStyle.style + .merge(widget.style ?? _controller._textSpan.style); + } + final Widget child = RepaintBoundary( + // zmtzawqlp + child: _EditableText( + key: editableTextKey, + style: effectiveTextStyle, + readOnly: true, + toolbarOptions: widget.toolbarOptions, + textWidthBasis: + widget.textWidthBasis ?? defaultTextStyle.textWidthBasis, + textHeightBehavior: + widget.textHeightBehavior ?? defaultTextStyle.textHeightBehavior, + showSelectionHandles: _showSelectionHandles, + showCursor: widget.showCursor, + controller: _controller, + focusNode: focusNode, + strutStyle: widget.strutStyle ?? const StrutStyle(), + textAlign: + widget.textAlign ?? defaultTextStyle.textAlign ?? TextAlign.start, + textDirection: widget.textDirection, + textScaler: widget.textScaler, + autofocus: widget.autofocus, + forceLine: false, + minLines: widget.minLines, + maxLines: widget.maxLines ?? defaultTextStyle.maxLines, + selectionColor: selectionColor, + selectionControls: + widget.selectionEnabled ? textSelectionControls : null, + onSelectionChanged: _handleSelectionChanged, + onSelectionHandleTapped: _handleSelectionHandleTapped, + rendererIgnoresPointer: true, + cursorWidth: widget.cursorWidth, + cursorHeight: widget.cursorHeight, + cursorRadius: cursorRadius, + cursorColor: cursorColor, + selectionHeightStyle: widget.selectionHeightStyle, + selectionWidthStyle: widget.selectionWidthStyle, + cursorOpacityAnimates: cursorOpacityAnimates, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + backgroundCursorColor: CupertinoColors.inactiveGray, + enableInteractiveSelection: widget.enableInteractiveSelection, + magnifierConfiguration: widget.magnifierConfiguration ?? + TextMagnifier.adaptiveMagnifierConfiguration, + dragStartBehavior: widget.dragStartBehavior, + scrollPhysics: widget.scrollPhysics, + autofillHints: null, + contextMenuBuilder: widget.contextMenuBuilder, + ), + ); + + return Semantics( + label: widget.semanticsLabel, + excludeSemantics: widget.semanticsLabel != null, + onLongPress: () { + _effectiveFocusNode.requestFocus(); + }, + child: _selectionGestureDetectorBuilder.buildGestureDetector( + behavior: HitTestBehavior.translucent, + child: child, + ), + ); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/rendering/editable.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/rendering/editable.dart new file mode 100644 index 0000000..0e5df9f --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/rendering/editable.dart @@ -0,0 +1,3136 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +const double _kCaretGap = 1.0; // pixels +const double _kCaretHeightOffset = 2.0; // pixels + +// The additional size on the x and y axis with which to expand the prototype +// cursor to render the floating cursor in pixels. +const EdgeInsets _kFloatingCursorSizeIncrease = + EdgeInsets.symmetric(horizontal: 0.5, vertical: 1.0); + +// The corner radius of the floating cursor in pixels. +const Radius _kFloatingCursorRadius = Radius.circular(1.0); +// This constant represents the shortest squared distance required between the floating cursor +// and the regular cursor when both are present in the text field. +// If the squared distance between the two cursors is less than this value, +// it's not necessary to display both cursors at the same time. +// This behavior is consistent with the one observed in iOS UITextField. +const double _kShortestDistanceSquaredWithFloatingAndRegularCursors = + 15.0 * 15.0; + +/// The consecutive sequence of [TextPosition]s that the caret should move to +/// when the user navigates the paragraph using the upward arrow key or the +/// downward arrow key. +/// +/// {@template flutter.rendering.RenderEditable.verticalArrowKeyMovement} +/// When the user presses the upward arrow key or the downward arrow key, on +/// many platforms (macOS for instance), the caret will move to the previous +/// line or the next line, while maintaining its original horizontal location. +/// When it encounters a shorter line, the caret moves to the closest horizontal +/// location within that line, and restores the original horizontal location +/// when a long enough line is encountered. +/// +/// Additionally, the caret will move to the beginning of the document if the +/// upward arrow key is pressed and the caret is already on the first line. If +/// the downward arrow key is pressed next, the caret will restore its original +/// horizontal location and move to the second line. Similarly the caret moves +/// to the end of the document if the downward arrow key is pressed when it's +/// already on the last line. +/// +/// Consider a left-aligned paragraph: +/// aa| +/// a +/// aaa +/// where the caret was initially placed at the end of the first line. Pressing +/// the downward arrow key once will move the caret to the end of the second +/// line, and twice the arrow key moves to the third line after the second "a" +/// on that line. Pressing the downward arrow key again, the caret will move to +/// the end of the third line (the end of the document). Pressing the upward +/// arrow key in this state will result in the caret moving to the end of the +/// second line. +/// +/// Vertical caret runs are typically interrupted when the layout of the text +/// changes (including when the text itself changes), or when the selection is +/// changed by other input events or programmatically (for example, when the +/// user pressed the left arrow key). +/// {@endtemplate} +/// +/// The [movePrevious] method moves the caret location (which is +/// [VerticalCaretMovementRun.current]) to the previous line, and in case +/// the caret is already on the first line, the method does nothing and returns +/// false. Similarly the [moveNext] method moves the caret to the next line, and +/// returns false if the caret is already on the last line. +/// +/// The [moveByOffset] method takes a pixel offset from the current position to move +/// the caret up or down. +/// +/// If the underlying paragraph's layout changes, [isValid] becomes false and +/// the [VerticalCaretMovementRun] must not be used. The [isValid] property must +/// be checked before calling [movePrevious], [moveNext] and [moveByOffset], +/// or accessing [current]. +class VerticalCaretMovementRun implements Iterator { + VerticalCaretMovementRun._( + this._editable, + this._lineMetrics, + this._currentTextPosition, + this._currentLine, + this._currentOffset, + ); + + Offset _currentOffset; + int _currentLine; + TextPosition _currentTextPosition; + + final List _lineMetrics; + // zmtzawqlp + final _RenderEditable _editable; + + bool _isValid = true; + + /// Whether this [VerticalCaretMovementRun] can still continue. + /// + /// A [VerticalCaretMovementRun] run is valid if the underlying text layout + /// hasn't changed. + /// + /// The [current] value and the [movePrevious], [moveNext] and [moveByOffset] + /// methods must not be accessed when [isValid] is false. + bool get isValid { + if (!_isValid) { + return false; + } + final List newLineMetrics = + _editable._textPainter.computeLineMetrics(); + // Use the implementation detail of the computeLineMetrics method to figure + // out if the current text layout has been invalidated. + if (!identical(newLineMetrics, _lineMetrics)) { + _isValid = false; + } + return _isValid; + } + + final Map> _positionCache = + >{}; + + MapEntry _getTextPositionForLine(int lineNumber) { + assert(isValid); + assert(lineNumber >= 0); + final MapEntry? cachedPosition = + _positionCache[lineNumber]; + if (cachedPosition != null) { + return cachedPosition; + } + assert(lineNumber != _currentLine); + + final Offset newOffset = + Offset(_currentOffset.dx, _lineMetrics[lineNumber].baseline); + final TextPosition closestPosition = + _editable._textPainter.getPositionForOffset(newOffset); + final MapEntry position = + MapEntry(newOffset, closestPosition); + _positionCache[lineNumber] = position; + return position; + } + + @override + TextPosition get current { + assert(isValid); + return _currentTextPosition; + } + + @override + bool moveNext() { + assert(isValid); + if (_currentLine + 1 >= _lineMetrics.length) { + return false; + } + final MapEntry position = + _getTextPositionForLine(_currentLine + 1); + _currentLine += 1; + _currentOffset = position.key; + _currentTextPosition = position.value; + return true; + } + + /// Move back to the previous element. + /// + /// Returns true and updates [current] if successful. + bool movePrevious() { + assert(isValid); + if (_currentLine <= 0) { + return false; + } + final MapEntry position = + _getTextPositionForLine(_currentLine - 1); + _currentLine -= 1; + _currentOffset = position.key; + _currentTextPosition = position.value; + return true; + } + + /// Move forward or backward by a number of elements determined + /// by pixel [offset]. + /// + /// If [offset] is negative, move backward; otherwise move forward. + /// + /// Returns true and updates [current] if successful. + bool moveByOffset(double offset) { + final Offset initialOffset = _currentOffset; + if (offset >= 0.0) { + while (_currentOffset.dy < initialOffset.dy + offset) { + if (!moveNext()) { + break; + } + } + } else { + while (_currentOffset.dy > initialOffset.dy + offset) { + if (!movePrevious()) { + break; + } + } + } + return initialOffset != _currentOffset; + } +} + +/// [RenderEditable] +/// Displays some text in a scrollable container with a potentially blinking +/// cursor and with gesture recognizers. +/// +/// This is the renderer for an editable text field. It does not directly +/// provide affordances for editing the text, but it does handle text selection +/// and manipulation of the text cursor. +/// +/// The [text] is displayed, scrolled by the given [offset], aligned according +/// to [textAlign]. The [maxLines] property controls whether the text displays +/// on one line or many. The [selection], if it is not collapsed, is painted in +/// the [selectionColor]. If it _is_ collapsed, then it represents the cursor +/// position. The cursor is shown while [showCursor] is true. It is painted in +/// the [cursorColor]. +/// +/// Keyboard handling, IME handling, scrolling, toggling the [showCursor] value +/// to actually blink the cursor, and other features not mentioned above are the +/// responsibility of higher layers and not handled by this object. +class _RenderEditable extends RenderBox + with + RelayoutWhenSystemFontsChangeMixin, + ContainerRenderObjectMixin, + RenderInlineChildrenContainerDefaults + implements TextLayoutMetrics { + /// Creates a render object that implements the visual aspects of a text field. + /// + /// The [textAlign] argument defaults to [TextAlign.start]. + /// + /// If [showCursor] is not specified, then it defaults to hiding the cursor. + /// + /// The [maxLines] property can be set to null to remove the restriction on + /// the number of lines. By default, it is 1, meaning this is a single-line + /// text field. If it is not null, it must be greater than zero. + /// + /// Use [ViewportOffset.zero] for the [offset] if there is no need for + /// scrolling. + _RenderEditable({ + InlineSpan? text, + required TextDirection textDirection, + TextAlign textAlign = TextAlign.start, + Color? cursorColor, + Color? backgroundCursorColor, + ValueNotifier? showCursor, + bool? hasFocus, + required LayerLink startHandleLayerLink, + required LayerLink endHandleLayerLink, + int? maxLines = 1, + int? minLines, + bool expands = false, + StrutStyle? strutStyle, + Color? selectionColor, + TextScaler textScaler = TextScaler.noScaling, + TextSelection? selection, + required ViewportOffset offset, + this.ignorePointer = false, + bool readOnly = false, + bool forceLine = true, + TextHeightBehavior? textHeightBehavior, + TextWidthBasis textWidthBasis = TextWidthBasis.parent, + String obscuringCharacter = '•', + bool obscureText = false, + Locale? locale, + double cursorWidth = 1.0, + double? cursorHeight, + Radius? cursorRadius, + bool paintCursorAboveText = false, + Offset cursorOffset = Offset.zero, + double devicePixelRatio = 1.0, + ui.BoxHeightStyle selectionHeightStyle = ui.BoxHeightStyle.tight, + ui.BoxWidthStyle selectionWidthStyle = ui.BoxWidthStyle.tight, + bool? enableInteractiveSelection, + this.floatingCursorAddedMargin = const EdgeInsets.fromLTRB(4, 4, 4, 5), + TextRange? promptRectRange, + Color? promptRectColor, + Clip clipBehavior = Clip.hardEdge, + required this.textSelectionDelegate, + RenderEditablePainter? painter, + RenderEditablePainter? foregroundPainter, + List? children, + }) : assert(maxLines == null || maxLines > 0), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + assert( + !expands || (maxLines == null && minLines == null), + 'minLines and maxLines must be null when expands is true.', + ), + assert(obscuringCharacter.characters.length == 1), + assert(cursorWidth >= 0.0), + assert(cursorHeight == null || cursorHeight >= 0.0), + _textPainter = TextPainter( + text: text, + textAlign: textAlign, + textDirection: textDirection, + textScaler: textScaler, + locale: locale, + maxLines: maxLines == 1 ? 1 : null, + strutStyle: strutStyle, + textHeightBehavior: textHeightBehavior, + textWidthBasis: textWidthBasis, + ), + _showCursor = showCursor ?? ValueNotifier(false), + _maxLines = maxLines, + _minLines = minLines, + _expands = expands, + _selection = selection, + _offset = offset, + _cursorWidth = cursorWidth, + _cursorHeight = cursorHeight, + _paintCursorOnTop = paintCursorAboveText, + _enableInteractiveSelection = enableInteractiveSelection, + _devicePixelRatio = devicePixelRatio, + _startHandleLayerLink = startHandleLayerLink, + _endHandleLayerLink = endHandleLayerLink, + _obscuringCharacter = obscuringCharacter, + _obscureText = obscureText, + _readOnly = readOnly, + _forceLine = forceLine, + _clipBehavior = clipBehavior, + _hasFocus = hasFocus ?? false, + _disposeShowCursor = showCursor == null { + assert(!_showCursor.value || cursorColor != null); + + _selectionPainter.highlightColor = selectionColor; + _selectionPainter.highlightedRange = selection; + _selectionPainter.selectionHeightStyle = selectionHeightStyle; + _selectionPainter.selectionWidthStyle = selectionWidthStyle; + + _autocorrectHighlightPainter.highlightColor = promptRectColor; + _autocorrectHighlightPainter.highlightedRange = promptRectRange; + + _caretPainter.caretColor = cursorColor; + _caretPainter.cursorRadius = cursorRadius; + _caretPainter.cursorOffset = cursorOffset; + _caretPainter.backgroundCursorColor = backgroundCursorColor; + + _updateForegroundPainter(foregroundPainter); + _updatePainter(painter); + addAll(children); + } + + /// Child render objects + _RenderEditableCustomPaint? _foregroundRenderObject; + _RenderEditableCustomPaint? _backgroundRenderObject; + + @override + void dispose() { + _leaderLayerHandler.layer = null; + _foregroundRenderObject?.dispose(); + _foregroundRenderObject = null; + _backgroundRenderObject?.dispose(); + _backgroundRenderObject = null; + _clipRectLayer.layer = null; + _cachedBuiltInForegroundPainters?.dispose(); + _cachedBuiltInPainters?.dispose(); + _selectionStartInViewport.dispose(); + _selectionEndInViewport.dispose(); + _autocorrectHighlightPainter.dispose(); + _selectionPainter.dispose(); + _caretPainter.dispose(); + _textPainter.dispose(); + _textIntrinsicsCache?.dispose(); + if (_disposeShowCursor) { + _showCursor.dispose(); + _disposeShowCursor = false; + } + super.dispose(); + } + + void _updateForegroundPainter(RenderEditablePainter? newPainter) { + final _CompositeRenderEditablePainter effectivePainter = newPainter == null + ? _builtInForegroundPainters + : _CompositeRenderEditablePainter(painters: [ + _builtInForegroundPainters, + newPainter, + ]); + + if (_foregroundRenderObject == null) { + final _RenderEditableCustomPaint foregroundRenderObject = + _RenderEditableCustomPaint(painter: effectivePainter); + adoptChild(foregroundRenderObject); + _foregroundRenderObject = foregroundRenderObject; + } else { + _foregroundRenderObject?.painter = effectivePainter; + } + _foregroundPainter = newPainter; + } + + /// The [RenderEditablePainter] to use for painting above this + /// [RenderEditable]'s text content. + /// + /// The new [RenderEditablePainter] will replace the previously specified + /// foreground painter, and schedule a repaint if the new painter's + /// `shouldRepaint` method returns true. + RenderEditablePainter? get foregroundPainter => _foregroundPainter; + RenderEditablePainter? _foregroundPainter; + set foregroundPainter(RenderEditablePainter? newPainter) { + if (newPainter == _foregroundPainter) { + return; + } + _updateForegroundPainter(newPainter); + } + + void _updatePainter(RenderEditablePainter? newPainter) { + final _CompositeRenderEditablePainter effectivePainter = newPainter == null + ? _builtInPainters + : _CompositeRenderEditablePainter( + painters: [_builtInPainters, newPainter]); + + if (_backgroundRenderObject == null) { + final _RenderEditableCustomPaint backgroundRenderObject = + _RenderEditableCustomPaint(painter: effectivePainter); + adoptChild(backgroundRenderObject); + _backgroundRenderObject = backgroundRenderObject; + } else { + _backgroundRenderObject?.painter = effectivePainter; + } + _painter = newPainter; + } + + /// Sets the [RenderEditablePainter] to use for painting beneath this + /// [RenderEditable]'s text content. + /// + /// The new [RenderEditablePainter] will replace the previously specified + /// painter, and schedule a repaint if the new painter's `shouldRepaint` + /// method returns true. + RenderEditablePainter? get painter => _painter; + RenderEditablePainter? _painter; + set painter(RenderEditablePainter? newPainter) { + if (newPainter == _painter) { + return; + } + _updatePainter(newPainter); + } + + // Caret Painters: + // A single painter for both the regular caret and the floating cursor. + late final _CaretPainter _caretPainter = _CaretPainter(); + + // Text Highlight painters: + final _TextHighlightPainter _selectionPainter = _TextHighlightPainter(); + final _TextHighlightPainter _autocorrectHighlightPainter = + _TextHighlightPainter(); + + _CompositeRenderEditablePainter get _builtInForegroundPainters => + _cachedBuiltInForegroundPainters ??= _createBuiltInForegroundPainters(); + _CompositeRenderEditablePainter? _cachedBuiltInForegroundPainters; + _CompositeRenderEditablePainter _createBuiltInForegroundPainters() { + return _CompositeRenderEditablePainter( + painters: [ + if (paintCursorAboveText) _caretPainter, + ], + ); + } + + _CompositeRenderEditablePainter get _builtInPainters => + _cachedBuiltInPainters ??= _createBuiltInPainters(); + _CompositeRenderEditablePainter? _cachedBuiltInPainters; + _CompositeRenderEditablePainter _createBuiltInPainters() { + return _CompositeRenderEditablePainter( + painters: [ + _autocorrectHighlightPainter, + _selectionPainter, + if (!paintCursorAboveText) _caretPainter, + ], + ); + } + + /// Whether the [handleEvent] will propagate pointer events to selection + /// handlers. + /// + /// If this property is true, the [handleEvent] assumes that this renderer + /// will be notified of input gestures via [handleTapDown], [handleTap], + /// [handleDoubleTap], and [handleLongPress]. + /// + /// If there are any gesture recognizers in the text span, the [handleEvent] + /// will still propagate pointer events to those recognizers. + /// + /// The default value of this property is false. + bool ignorePointer; + + /// {@macro dart.ui.textHeightBehavior} + TextHeightBehavior? get textHeightBehavior => _textPainter.textHeightBehavior; + set textHeightBehavior(TextHeightBehavior? value) { + if (_textPainter.textHeightBehavior == value) { + return; + } + _textPainter.textHeightBehavior = value; + markNeedsLayout(); + } + + /// {@macro flutter.painting.textPainter.textWidthBasis} + TextWidthBasis get textWidthBasis => _textPainter.textWidthBasis; + set textWidthBasis(TextWidthBasis value) { + if (_textPainter.textWidthBasis == value) { + return; + } + _textPainter.textWidthBasis = value; + markNeedsLayout(); + } + + /// The pixel ratio of the current device. + /// + /// Should be obtained by querying MediaQuery for the devicePixelRatio. + double get devicePixelRatio => _devicePixelRatio; + double _devicePixelRatio; + set devicePixelRatio(double value) { + if (devicePixelRatio == value) { + return; + } + _devicePixelRatio = value; + markNeedsLayout(); + } + + /// Character used for obscuring text if [obscureText] is true. + /// + /// Must have a length of exactly one. + String get obscuringCharacter => _obscuringCharacter; + String _obscuringCharacter; + set obscuringCharacter(String value) { + if (_obscuringCharacter == value) { + return; + } + assert(value.characters.length == 1); + _obscuringCharacter = value; + markNeedsLayout(); + } + + /// Whether to hide the text being edited (e.g., for passwords). + bool get obscureText => _obscureText; + bool _obscureText; + set obscureText(bool value) { + if (_obscureText == value) { + return; + } + _obscureText = value; + _cachedAttributedValue = null; + markNeedsSemanticsUpdate(); + } + + /// Controls how tall the selection highlight boxes are computed to be. + /// + /// See [ui.BoxHeightStyle] for details on available styles. + ui.BoxHeightStyle get selectionHeightStyle => + _selectionPainter.selectionHeightStyle; + set selectionHeightStyle(ui.BoxHeightStyle value) { + _selectionPainter.selectionHeightStyle = value; + } + + /// Controls how wide the selection highlight boxes are computed to be. + /// + /// See [ui.BoxWidthStyle] for details on available styles. + ui.BoxWidthStyle get selectionWidthStyle => + _selectionPainter.selectionWidthStyle; + set selectionWidthStyle(ui.BoxWidthStyle value) { + _selectionPainter.selectionWidthStyle = value; + } + + /// The object that controls the text selection, used by this render object + /// for implementing cut, copy, and paste keyboard shortcuts. + /// + /// It will make cut, copy and paste functionality work with the most recently + /// set [TextSelectionDelegate]. + TextSelectionDelegate textSelectionDelegate; + + /// Track whether position of the start of the selected text is within the viewport. + /// + /// For example, if the text contains "Hello World", and the user selects + /// "Hello", then scrolls so only "World" is visible, this will become false. + /// If the user scrolls back so that the "H" is visible again, this will + /// become true. + /// + /// This bool indicates whether the text is scrolled so that the handle is + /// inside the text field viewport, as opposed to whether it is actually + /// visible on the screen. + ValueListenable get selectionStartInViewport => + _selectionStartInViewport; + final ValueNotifier _selectionStartInViewport = + ValueNotifier(true); + + /// Track whether position of the end of the selected text is within the viewport. + /// + /// For example, if the text contains "Hello World", and the user selects + /// "World", then scrolls so only "Hello" is visible, this will become + /// 'false'. If the user scrolls back so that the "d" is visible again, this + /// will become 'true'. + /// + /// This bool indicates whether the text is scrolled so that the handle is + /// inside the text field viewport, as opposed to whether it is actually + /// visible on the screen. + ValueListenable get selectionEndInViewport => _selectionEndInViewport; + final ValueNotifier _selectionEndInViewport = ValueNotifier(true); + + /// Returns the TextPosition above or below the given offset. + TextPosition _getTextPositionVertical( + TextPosition position, double verticalOffset) { + final Offset caretOffset = + _textPainter.getOffsetForCaret(position, _caretPrototype); + final Offset caretOffsetTranslated = + caretOffset.translate(0.0, verticalOffset); + return _textPainter.getPositionForOffset(caretOffsetTranslated); + } + + // Start TextLayoutMetrics. + + /// {@macro flutter.services.TextLayoutMetrics.getLineAtOffset} + @override + TextSelection getLineAtOffset(TextPosition position) { + final TextRange line = _textPainter.getLineBoundary(position); + // If text is obscured, the entire string should be treated as one line. + if (obscureText) { + return TextSelection(baseOffset: 0, extentOffset: plainText.length); + } + return TextSelection(baseOffset: line.start, extentOffset: line.end); + } + + /// {@macro flutter.painting.TextPainter.getWordBoundary} + @override + TextRange getWordBoundary(TextPosition position) { + return _textPainter.getWordBoundary(position); + } + + /// {@macro flutter.services.TextLayoutMetrics.getTextPositionAbove} + @override + TextPosition getTextPositionAbove(TextPosition position) { + // The caret offset gives a location in the upper left hand corner of + // the caret so the middle of the line above is a half line above that + // point and the line below is 1.5 lines below that point. + final double preferredLineHeight = _textPainter.preferredLineHeight; + final double verticalOffset = -0.5 * preferredLineHeight; + return _getTextPositionVertical(position, verticalOffset); + } + + /// {@macro flutter.services.TextLayoutMetrics.getTextPositionBelow} + @override + TextPosition getTextPositionBelow(TextPosition position) { + // The caret offset gives a location in the upper left hand corner of + // the caret so the middle of the line above is a half line above that + // point and the line below is 1.5 lines below that point. + final double preferredLineHeight = _textPainter.preferredLineHeight; + final double verticalOffset = 1.5 * preferredLineHeight; + return _getTextPositionVertical(position, verticalOffset); + } + + // End TextLayoutMetrics. + + void _updateSelectionExtentsVisibility(Offset effectiveOffset) { + assert(selection != null); + if (!selection!.isValid) { + _selectionStartInViewport.value = false; + _selectionEndInViewport.value = false; + return; + } + final Rect visibleRegion = Offset.zero & size; + + final Offset startOffset = _textPainter.getOffsetForCaret( + TextPosition(offset: selection!.start, affinity: selection!.affinity), + _caretPrototype, + ); + // Check if the selection is visible with an approximation because a + // difference between rounded and unrounded values causes the caret to be + // reported as having a slightly (< 0.5) negative y offset. This rounding + // happens in paragraph.cc's layout and TextPainter's + // _applyFloatingPointHack. Ideally, the rounding mismatch will be fixed and + // this can be changed to be a strict check instead of an approximation. + const double visibleRegionSlop = 0.5; + _selectionStartInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(startOffset + effectiveOffset); + + final Offset endOffset = _textPainter.getOffsetForCaret( + TextPosition(offset: selection!.end, affinity: selection!.affinity), + _caretPrototype, + ); + _selectionEndInViewport.value = visibleRegion + .inflate(visibleRegionSlop) + .contains(endOffset + effectiveOffset); + } + + void _setTextEditingValue( + TextEditingValue newValue, SelectionChangedCause cause) { + textSelectionDelegate.userUpdateTextEditingValue(newValue, cause); + } + + void _setSelection(TextSelection nextSelection, SelectionChangedCause cause) { + if (nextSelection.isValid) { + // The nextSelection is calculated based on plainText, which can be out + // of sync with the textSelectionDelegate.textEditingValue by one frame. + // This is due to the render editable and editable text handle pointer + // event separately. If the editable text changes the text during the + // event handler, the render editable will use the outdated text stored in + // the plainText when handling the pointer event. + // + // If this happens, we need to make sure the new selection is still valid. + final int textLength = textSelectionDelegate.textEditingValue.text.length; + nextSelection = nextSelection.copyWith( + baseOffset: math.min(nextSelection.baseOffset, textLength), + extentOffset: math.min(nextSelection.extentOffset, textLength), + ); + } + _setTextEditingValue( + textSelectionDelegate.textEditingValue.copyWith(selection: nextSelection), + cause, + ); + } + + @override + void markNeedsPaint() { + super.markNeedsPaint(); + // Tell the painters to repaint since text layout may have changed. + _foregroundRenderObject?.markNeedsPaint(); + _backgroundRenderObject?.markNeedsPaint(); + } + + @override + void systemFontsDidChange() { + super.systemFontsDidChange(); + _textPainter.markNeedsLayout(); + } + + /// Returns a plain text version of the text in [TextPainter]. + /// + /// If [obscureText] is true, returns the obscured text. See + /// [obscureText] and [obscuringCharacter]. + /// In order to get the styled text as an [InlineSpan] tree, use [text]. + String get plainText => _textPainter.plainText; + + /// The text to paint in the form of a tree of [InlineSpan]s. + /// + /// In order to get the plain text representation, use [plainText]. + InlineSpan? get text => _textPainter.text; + final TextPainter _textPainter; + AttributedString? _cachedAttributedValue; + List? _cachedCombinedSemanticsInfos; + set text(InlineSpan? value) { + if (_textPainter.text == value) { + return; + } + _cachedLineBreakCount = null; + _textPainter.text = value; + _cachedAttributedValue = null; + _cachedCombinedSemanticsInfos = null; + markNeedsLayout(); + markNeedsSemanticsUpdate(); + } + + TextPainter? _textIntrinsicsCache; + TextPainter get _textIntrinsics { + return (_textIntrinsicsCache ??= TextPainter()) + ..text = _textPainter.text + ..textAlign = _textPainter.textAlign + ..textDirection = _textPainter.textDirection + ..textScaler = _textPainter.textScaler + ..maxLines = _textPainter.maxLines + ..ellipsis = _textPainter.ellipsis + ..locale = _textPainter.locale + ..strutStyle = _textPainter.strutStyle + ..textWidthBasis = _textPainter.textWidthBasis + ..textHeightBehavior = _textPainter.textHeightBehavior; + } + + /// How the text should be aligned horizontally. + TextAlign get textAlign => _textPainter.textAlign; + set textAlign(TextAlign value) { + if (_textPainter.textAlign == value) { + return; + } + _textPainter.textAlign = value; + markNeedsLayout(); + } + + /// The directionality of the text. + /// + /// This decides how the [TextAlign.start], [TextAlign.end], and + /// [TextAlign.justify] values of [textAlign] are interpreted. + /// + /// This is also used to disambiguate how to render bidirectional text. For + /// example, if the [text] is an English phrase followed by a Hebrew phrase, + /// in a [TextDirection.ltr] context the English phrase will be on the left + /// and the Hebrew phrase to its right, while in a [TextDirection.rtl] + /// context, the English phrase will be on the right and the Hebrew phrase on + /// its left. + // TextPainter.textDirection is nullable, but it is set to a + // non-null value in the RenderEditable constructor and we refuse to + // set it to null here, so _textPainter.textDirection cannot be null. + TextDirection get textDirection => _textPainter.textDirection!; + set textDirection(TextDirection value) { + if (_textPainter.textDirection == value) { + return; + } + _textPainter.textDirection = value; + markNeedsLayout(); + markNeedsSemanticsUpdate(); + } + + /// Used by this renderer's internal [TextPainter] to select a locale-specific + /// font. + /// + /// In some cases the same Unicode character may be rendered differently depending + /// on the locale. For example the '骨' character is rendered differently in + /// the Chinese and Japanese locales. In these cases the [locale] may be used + /// to select a locale-specific font. + /// + /// If this value is null, a system-dependent algorithm is used to select + /// the font. + Locale? get locale => _textPainter.locale; + set locale(Locale? value) { + if (_textPainter.locale == value) { + return; + } + _textPainter.locale = value; + markNeedsLayout(); + } + + /// The [StrutStyle] used by the renderer's internal [TextPainter] to + /// determine the strut to use. + StrutStyle? get strutStyle => _textPainter.strutStyle; + set strutStyle(StrutStyle? value) { + if (_textPainter.strutStyle == value) { + return; + } + _textPainter.strutStyle = value; + markNeedsLayout(); + } + + /// The color to use when painting the cursor. + Color? get cursorColor => _caretPainter.caretColor; + set cursorColor(Color? value) { + _caretPainter.caretColor = value; + } + + /// The color to use when painting the cursor aligned to the text while + /// rendering the floating cursor. + /// + /// Typically this would be set to [CupertinoColors.inactiveGray]. + /// + /// If this is null, the background cursor is not painted. + /// + /// See also: + /// + /// * [FloatingCursorDragState], which explains the floating cursor feature + /// in detail. + Color? get backgroundCursorColor => _caretPainter.backgroundCursorColor; + set backgroundCursorColor(Color? value) { + _caretPainter.backgroundCursorColor = value; + } + + bool _disposeShowCursor; + + /// Whether to paint the cursor. + ValueNotifier get showCursor => _showCursor; + ValueNotifier _showCursor; + set showCursor(ValueNotifier value) { + if (_showCursor == value) { + return; + } + if (attached) { + _showCursor.removeListener(_showHideCursor); + } + if (_disposeShowCursor) { + _showCursor.dispose(); + _disposeShowCursor = false; + } + _showCursor = value; + if (attached) { + _showHideCursor(); + _showCursor.addListener(_showHideCursor); + } + } + + void _showHideCursor() { + _caretPainter.shouldPaint = showCursor.value; + } + + /// Whether the editable is currently focused. + bool get hasFocus => _hasFocus; + bool _hasFocus = false; + set hasFocus(bool value) { + if (_hasFocus == value) { + return; + } + _hasFocus = value; + markNeedsSemanticsUpdate(); + } + + /// Whether this rendering object will take a full line regardless the text width. + bool get forceLine => _forceLine; + bool _forceLine = false; + set forceLine(bool value) { + if (_forceLine == value) { + return; + } + _forceLine = value; + markNeedsLayout(); + } + + /// Whether this rendering object is read only. + bool get readOnly => _readOnly; + bool _readOnly = false; + set readOnly(bool value) { + if (_readOnly == value) { + return; + } + _readOnly = value; + markNeedsSemanticsUpdate(); + } + + /// The maximum number of lines for the text to span, wrapping if necessary. + /// + /// If this is 1 (the default), the text will not wrap, but will extend + /// indefinitely instead. + /// + /// If this is null, there is no limit to the number of lines. + /// + /// When this is not null, the intrinsic height of the render object is the + /// height of one line of text multiplied by this value. In other words, this + /// also controls the height of the actual editing widget. + int? get maxLines => _maxLines; + int? _maxLines; + + /// The value may be null. If it is not null, then it must be greater than zero. + set maxLines(int? value) { + assert(value == null || value > 0); + if (maxLines == value) { + return; + } + _maxLines = value; + + // Special case maxLines == 1 to keep only the first line so we can get the + // height of the first line in case there are hard line breaks in the text. + // See the `_preferredHeight` method. + _textPainter.maxLines = value == 1 ? 1 : null; + markNeedsLayout(); + } + + /// {@macro flutter.widgets.editableText.minLines} + int? get minLines => _minLines; + int? _minLines; + + /// The value may be null. If it is not null, then it must be greater than zero. + set minLines(int? value) { + assert(value == null || value > 0); + if (minLines == value) { + return; + } + _minLines = value; + markNeedsLayout(); + } + + /// {@macro flutter.widgets.editableText.expands} + bool get expands => _expands; + bool _expands; + set expands(bool value) { + if (expands == value) { + return; + } + _expands = value; + markNeedsLayout(); + } + + /// The color to use when painting the selection. + Color? get selectionColor => _selectionPainter.highlightColor; + set selectionColor(Color? value) { + _selectionPainter.highlightColor = value; + } + + /// The number of font pixels for each logical pixel. + /// + /// For example, if the text scale factor is 1.5, text will be 50% larger than + /// the specified font size. + + /// {@macro flutter.painting.textPainter.textScaler} + TextScaler get textScaler => _textPainter.textScaler; + set textScaler(TextScaler value) { + if (_textPainter.textScaler == value) { + return; + } + _textPainter.textScaler = value; + markNeedsLayout(); + } + + /// The region of text that is selected, if any. + /// + /// The caret position is represented by a collapsed selection. + /// + /// If [selection] is null, there is no selection and attempts to + /// manipulate the selection will throw. + TextSelection? get selection => _selection; + TextSelection? _selection; + set selection(TextSelection? value) { + if (_selection == value) { + return; + } + _selection = value; + _selectionPainter.highlightedRange = value; + markNeedsPaint(); + markNeedsSemanticsUpdate(); + } + + /// The offset at which the text should be painted. + /// + /// If the text content is larger than the editable line itself, the editable + /// line clips the text. This property controls which part of the text is + /// visible by shifting the text by the given offset before clipping. + ViewportOffset get offset => _offset; + ViewportOffset _offset; + set offset(ViewportOffset value) { + if (_offset == value) { + return; + } + if (attached) { + _offset.removeListener(markNeedsPaint); + } + _offset = value; + if (attached) { + _offset.addListener(markNeedsPaint); + } + markNeedsLayout(); + } + + /// How thick the cursor will be. + double get cursorWidth => _cursorWidth; + double _cursorWidth = 1.0; + set cursorWidth(double value) { + if (_cursorWidth == value) { + return; + } + _cursorWidth = value; + markNeedsLayout(); + } + + /// How tall the cursor will be. + /// + /// This can be null, in which case the getter will actually return [preferredLineHeight]. + /// + /// Setting this to itself fixes the value to the current [preferredLineHeight]. Setting + /// this to null returns the behavior of deferring to [preferredLineHeight]. + // TODO(ianh): This is a confusing API. We should have a separate getter for the effective cursor height. + double get cursorHeight => _cursorHeight ?? preferredLineHeight; + double? _cursorHeight; + set cursorHeight(double? value) { + if (_cursorHeight == value) { + return; + } + _cursorHeight = value; + markNeedsLayout(); + } + + /// {@template flutter.rendering.RenderEditable.paintCursorAboveText} + /// If the cursor should be painted on top of the text or underneath it. + /// + /// By default, the cursor should be painted on top for iOS platforms and + /// underneath for Android platforms. + /// {@endtemplate} + bool get paintCursorAboveText => _paintCursorOnTop; + bool _paintCursorOnTop; + set paintCursorAboveText(bool value) { + if (_paintCursorOnTop == value) { + return; + } + _paintCursorOnTop = value; + // Clear cached built-in painters and reconfigure painters. + _cachedBuiltInForegroundPainters = null; + _cachedBuiltInPainters = null; + // Call update methods to rebuild and set the effective painters. + _updateForegroundPainter(_foregroundPainter); + _updatePainter(_painter); + } + + /// {@template flutter.rendering.RenderEditable.cursorOffset} + /// The offset that is used, in pixels, when painting the cursor on screen. + /// + /// By default, the cursor position should be set to an offset of + /// (-[cursorWidth] * 0.5, 0.0) on iOS platforms and (0, 0) on Android + /// platforms. The origin from where the offset is applied to is the arbitrary + /// location where the cursor ends up being rendered from by default. + /// {@endtemplate} + Offset get cursorOffset => _caretPainter.cursorOffset; + set cursorOffset(Offset value) { + _caretPainter.cursorOffset = value; + } + + /// How rounded the corners of the cursor should be. + /// + /// A null value is the same as [Radius.zero]. + Radius? get cursorRadius => _caretPainter.cursorRadius; + set cursorRadius(Radius? value) { + _caretPainter.cursorRadius = value; + } + + /// The [LayerLink] of start selection handle. + /// + /// [RenderEditable] is responsible for calculating the [Offset] of this + /// [LayerLink], which will be used as [CompositedTransformTarget] of start handle. + LayerLink get startHandleLayerLink => _startHandleLayerLink; + LayerLink _startHandleLayerLink; + set startHandleLayerLink(LayerLink value) { + if (_startHandleLayerLink == value) { + return; + } + _startHandleLayerLink = value; + markNeedsPaint(); + } + + /// The [LayerLink] of end selection handle. + /// + /// [RenderEditable] is responsible for calculating the [Offset] of this + /// [LayerLink], which will be used as [CompositedTransformTarget] of end handle. + LayerLink get endHandleLayerLink => _endHandleLayerLink; + LayerLink _endHandleLayerLink; + set endHandleLayerLink(LayerLink value) { + if (_endHandleLayerLink == value) { + return; + } + _endHandleLayerLink = value; + markNeedsPaint(); + } + + /// The padding applied to text field. Used to determine the bounds when + /// moving the floating cursor. + /// + /// Defaults to a padding with left, top and right set to 4, bottom to 5. + /// + /// See also: + /// + /// * [FloatingCursorDragState], which explains the floating cursor feature + /// in detail. + EdgeInsets floatingCursorAddedMargin; + + /// Returns true if the floating cursor is visible, false otherwise. + bool get floatingCursorOn => _floatingCursorOn; + bool _floatingCursorOn = false; + late TextPosition _floatingCursorTextPosition; + + /// Whether to allow the user to change the selection. + /// + /// Since [RenderEditable] does not handle selection manipulation + /// itself, this actually only affects whether the accessibility + /// hints provided to the system (via + /// [describeSemanticsConfiguration]) will enable selection + /// manipulation. It's the responsibility of this object's owner + /// to provide selection manipulation affordances. + /// + /// This field is used by [selectionEnabled] (which then controls + /// the accessibility hints mentioned above). When null, + /// [obscureText] is used to determine the value of + /// [selectionEnabled] instead. + bool? get enableInteractiveSelection => _enableInteractiveSelection; + bool? _enableInteractiveSelection; + set enableInteractiveSelection(bool? value) { + if (_enableInteractiveSelection == value) { + return; + } + _enableInteractiveSelection = value; + markNeedsLayout(); + markNeedsSemanticsUpdate(); + } + + /// Whether interactive selection are enabled based on the values of + /// [enableInteractiveSelection] and [obscureText]. + /// + /// Since [RenderEditable] does not handle selection manipulation + /// itself, this actually only affects whether the accessibility + /// hints provided to the system (via + /// [describeSemanticsConfiguration]) will enable selection + /// manipulation. It's the responsibility of this object's owner + /// to provide selection manipulation affordances. + /// + /// By default, [enableInteractiveSelection] is null, [obscureText] is false, + /// and this getter returns true. + /// + /// If [enableInteractiveSelection] is null and [obscureText] is true, then this + /// getter returns false. This is the common case for password fields. + /// + /// If [enableInteractiveSelection] is non-null then its value is + /// returned. An application might [enableInteractiveSelection] to + /// true to enable interactive selection for a password field, or to + /// false to unconditionally disable interactive selection. + bool get selectionEnabled { + return enableInteractiveSelection ?? !obscureText; + } + + /// The color used to paint the prompt rectangle. + /// + /// The prompt rectangle will only be requested on non-web iOS applications. + // TODO(ianh): We should change the getter to return null when _promptRectRange is null + // (otherwise, if you set it to null and then get it, you get back non-null). + // Alternatively, we could stop supporting setting this to null. + Color? get promptRectColor => _autocorrectHighlightPainter.highlightColor; + set promptRectColor(Color? newValue) { + _autocorrectHighlightPainter.highlightColor = newValue; + } + + /// Dismisses the currently displayed prompt rectangle and displays a new prompt rectangle + /// over [newRange] in the given color [promptRectColor]. + /// + /// The prompt rectangle will only be requested on non-web iOS applications. + /// + /// When set to null, the currently displayed prompt rectangle (if any) will be dismissed. + // ignore: use_setters_to_change_properties, (API predates enforcing the lint) + void setPromptRectRange(TextRange? newRange) { + _autocorrectHighlightPainter.highlightedRange = newRange; + } + + /// The maximum amount the text is allowed to scroll. + /// + /// This value is only valid after layout and can change as additional + /// text is entered or removed in order to accommodate expanding when + /// [expands] is set to true. + double get maxScrollExtent => _maxScrollExtent; + double _maxScrollExtent = 0; + + double get _caretMargin => _kCaretGap + cursorWidth; + + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.hardEdge]. + Clip get clipBehavior => _clipBehavior; + Clip _clipBehavior = Clip.hardEdge; + set clipBehavior(Clip value) { + if (value != _clipBehavior) { + _clipBehavior = value; + markNeedsPaint(); + markNeedsSemanticsUpdate(); + } + } + + /// Collected during [describeSemanticsConfiguration], used by + /// [assembleSemanticsNode] and [_combineSemanticsInfo]. + List? _semanticsInfo; + + // Caches [SemanticsNode]s created during [assembleSemanticsNode] so they + // can be re-used when [assembleSemanticsNode] is called again. This ensures + // stable ids for the [SemanticsNode]s of [TextSpan]s across + // [assembleSemanticsNode] invocations. + LinkedHashMap? _cachedChildNodes; + + /// Returns a list of rects that bound the given selection, and the text + /// direction. The text direction is used by the engine to calculate + /// the closest position to a given point. + /// + /// See [TextPainter.getBoxesForSelection] for more details. + List getBoxesForSelection(TextSelection selection) { + _computeTextMetricsIfNeeded(); + return _textPainter + .getBoxesForSelection(selection) + .map((TextBox textBox) => TextBox.fromLTRBD( + textBox.left + _paintOffset.dx, + textBox.top + _paintOffset.dy, + textBox.right + _paintOffset.dx, + textBox.bottom + _paintOffset.dy, + textBox.direction)) + .toList(); + } + + @override + void describeSemanticsConfiguration(SemanticsConfiguration config) { + super.describeSemanticsConfiguration(config); + _semanticsInfo = _textPainter.text!.getSemanticsInformation(); + // TODO(chunhtai): the macOS does not provide a public API to support text + // selections across multiple semantics nodes. Remove this platform check + // once we can support it. + // https://github.com/flutter/flutter/issues/77957 + if (_semanticsInfo!.any( + (InlineSpanSemanticsInformation info) => info.recognizer != null) && + defaultTargetPlatform != TargetPlatform.macOS) { + // TODO(zmtzawqlp): we support custom text span, so assert is not need here. + // assert(readOnly && !obscureText); + // For Selectable rich text with recognizer, we need to create a semantics + // node for each text fragment. + config + ..isSemanticBoundary = true + ..explicitChildNodes = true; + return; + } + if (_cachedAttributedValue == null) { + if (obscureText) { + _cachedAttributedValue = + AttributedString(obscuringCharacter * plainText.length); + } else { + final StringBuffer buffer = StringBuffer(); + int offset = 0; + final List attributes = []; + for (final InlineSpanSemanticsInformation info in _semanticsInfo!) { + final String label = info.semanticsLabel ?? info.text; + for (final StringAttribute infoAttribute in info.stringAttributes) { + final TextRange originalRange = infoAttribute.range; + attributes.add( + infoAttribute.copy( + range: TextRange( + start: offset + originalRange.start, + end: offset + originalRange.end), + ), + ); + } + buffer.write(label); + offset += label.length; + } + _cachedAttributedValue = + AttributedString(buffer.toString(), attributes: attributes); + } + } + config + ..attributedValue = _cachedAttributedValue! + ..isObscured = obscureText + ..isMultiline = _isMultiline + ..textDirection = textDirection + ..isFocused = hasFocus + ..isTextField = true + ..isReadOnly = readOnly; + + if (hasFocus && selectionEnabled) { + config.onSetSelection = _handleSetSelection; + } + + if (hasFocus && !readOnly) { + config.onSetText = _handleSetText; + } + + if (selectionEnabled && (selection?.isValid ?? false)) { + config.textSelection = selection; + if (_textPainter.getOffsetBefore(selection!.extentOffset) != null) { + config + ..onMoveCursorBackwardByWord = _handleMoveCursorBackwardByWord + ..onMoveCursorBackwardByCharacter = + _handleMoveCursorBackwardByCharacter; + } + if (_textPainter.getOffsetAfter(selection!.extentOffset) != null) { + config + ..onMoveCursorForwardByWord = _handleMoveCursorForwardByWord + ..onMoveCursorForwardByCharacter = + _handleMoveCursorForwardByCharacter; + } + } + } + + void _handleSetText(String text) { + textSelectionDelegate.userUpdateTextEditingValue( + TextEditingValue( + text: text, + selection: TextSelection.collapsed(offset: text.length), + ), + SelectionChangedCause.keyboard, + ); + } + + @override + void assembleSemanticsNode(SemanticsNode node, SemanticsConfiguration config, + Iterable children) { + assert(_semanticsInfo != null && _semanticsInfo!.isNotEmpty); + final List newChildren = []; + TextDirection currentDirection = textDirection; + Rect currentRect; + double ordinal = 0.0; + int start = 0; + int placeholderIndex = 0; + int childIndex = 0; + RenderBox? child = firstChild; + final LinkedHashMap newChildCache = + LinkedHashMap(); + _cachedCombinedSemanticsInfos ??= combineSemanticsInfo(_semanticsInfo!); + for (final InlineSpanSemanticsInformation info + in _cachedCombinedSemanticsInfos!) { + final TextSelection selection = TextSelection( + baseOffset: start, + extentOffset: start + info.text.length, + ); + start += info.text.length; + + if (info.isPlaceholder) { + // A placeholder span may have 0 to multiple semantics nodes, we need + // to annotate all of the semantics nodes belong to this span. + while (children.length > childIndex && + children + .elementAt(childIndex) + .isTagged(PlaceholderSpanIndexSemanticsTag(placeholderIndex))) { + final SemanticsNode childNode = children.elementAt(childIndex); + final TextParentData parentData = + child!.parentData! as TextParentData; + assert(parentData.offset != null); + newChildren.add(childNode); + childIndex += 1; + } + child = childAfter(child!); + placeholderIndex += 1; + } else { + final TextDirection initialDirection = currentDirection; + final List rects = + _textPainter.getBoxesForSelection(selection); + if (rects.isEmpty) { + continue; + } + Rect rect = rects.first.toRect(); + currentDirection = rects.first.direction; + for (final ui.TextBox textBox in rects.skip(1)) { + rect = rect.expandToInclude(textBox.toRect()); + currentDirection = textBox.direction; + } + // Any of the text boxes may have had infinite dimensions. + // We shouldn't pass infinite dimensions up to the bridges. + rect = Rect.fromLTWH( + math.max(0.0, rect.left), + math.max(0.0, rect.top), + math.min(rect.width, constraints.maxWidth), + math.min(rect.height, constraints.maxHeight), + ); + // Round the current rectangle to make this API testable and add some + // padding so that the accessibility rects do not overlap with the text. + currentRect = Rect.fromLTRB( + rect.left.floorToDouble() - 4.0, + rect.top.floorToDouble() - 4.0, + rect.right.ceilToDouble() + 4.0, + rect.bottom.ceilToDouble() + 4.0, + ); + final SemanticsConfiguration configuration = SemanticsConfiguration() + ..sortKey = OrdinalSortKey(ordinal++) + ..textDirection = initialDirection + ..attributedLabel = AttributedString(info.semanticsLabel ?? info.text, + attributes: info.stringAttributes); + switch (info.recognizer) { + case TapGestureRecognizer(onTap: final VoidCallback? onTap): + case DoubleTapGestureRecognizer( + onDoubleTap: final VoidCallback? onTap + ): + if (onTap != null) { + configuration.onTap = onTap; + configuration.isLink = true; + } + case LongPressGestureRecognizer( + onLongPress: final GestureLongPressCallback? onLongPress + ): + if (onLongPress != null) { + configuration.onLongPress = onLongPress; + } + case null: + break; + default: + assert(false, '${info.recognizer.runtimeType} is not supported.'); + } + if (node.parentPaintClipRect != null) { + final Rect paintRect = + node.parentPaintClipRect!.intersect(currentRect); + configuration.isHidden = paintRect.isEmpty && !currentRect.isEmpty; + } + late final SemanticsNode newChild; + if (_cachedChildNodes?.isNotEmpty ?? false) { + newChild = _cachedChildNodes!.remove(_cachedChildNodes!.keys.first)!; + } else { + final UniqueKey key = UniqueKey(); + newChild = SemanticsNode( + key: key, + showOnScreen: _createShowOnScreenFor(key), + ); + } + newChild + ..updateWith(config: configuration) + ..rect = currentRect; + newChildCache[newChild.key!] = newChild; + newChildren.add(newChild); + } + } + _cachedChildNodes = newChildCache; + node.updateWith(config: config, childrenInInversePaintOrder: newChildren); + } + + VoidCallback? _createShowOnScreenFor(Key key) { + return () { + final SemanticsNode node = _cachedChildNodes![key]!; + showOnScreen(descendant: this, rect: node.rect); + }; + } + + // TODO(ianh): in theory, [selection] could become null between when + // we last called describeSemanticsConfiguration and when the + // callbacks are invoked, in which case the callbacks will crash... + + void _handleSetSelection(TextSelection selection) { + _setSelection(selection, SelectionChangedCause.keyboard); + } + + void _handleMoveCursorForwardByCharacter(bool extendSelection) { + assert(selection != null); + final int? extentOffset = + _textPainter.getOffsetAfter(selection!.extentOffset); + if (extentOffset == null) { + return; + } + final int baseOffset = + !extendSelection ? extentOffset : selection!.baseOffset; + _setSelection( + TextSelection(baseOffset: baseOffset, extentOffset: extentOffset), + SelectionChangedCause.keyboard, + ); + } + + void _handleMoveCursorBackwardByCharacter(bool extendSelection) { + assert(selection != null); + final int? extentOffset = + _textPainter.getOffsetBefore(selection!.extentOffset); + if (extentOffset == null) { + return; + } + final int baseOffset = + !extendSelection ? extentOffset : selection!.baseOffset; + _setSelection( + TextSelection(baseOffset: baseOffset, extentOffset: extentOffset), + SelectionChangedCause.keyboard, + ); + } + + void _handleMoveCursorForwardByWord(bool extendSelection) { + assert(selection != null); + final TextRange currentWord = + _textPainter.getWordBoundary(selection!.extent); + final TextRange? nextWord = _getNextWord(currentWord.end); + if (nextWord == null) { + return; + } + final int baseOffset = + extendSelection ? selection!.baseOffset : nextWord.start; + _setSelection( + TextSelection( + baseOffset: baseOffset, + extentOffset: nextWord.start, + ), + SelectionChangedCause.keyboard, + ); + } + + void _handleMoveCursorBackwardByWord(bool extendSelection) { + assert(selection != null); + final TextRange currentWord = + _textPainter.getWordBoundary(selection!.extent); + final TextRange? previousWord = _getPreviousWord(currentWord.start - 1); + if (previousWord == null) { + return; + } + final int baseOffset = + extendSelection ? selection!.baseOffset : previousWord.start; + _setSelection( + TextSelection( + baseOffset: baseOffset, + extentOffset: previousWord.start, + ), + SelectionChangedCause.keyboard, + ); + } + + TextRange? _getNextWord(int offset) { + while (true) { + final TextRange range = + _textPainter.getWordBoundary(TextPosition(offset: offset)); + if (!range.isValid || range.isCollapsed) { + return null; + } + if (!_onlyWhitespace(range)) { + return range; + } + offset = range.end; + } + } + + TextRange? _getPreviousWord(int offset) { + while (offset >= 0) { + final TextRange range = + _textPainter.getWordBoundary(TextPosition(offset: offset)); + if (!range.isValid || range.isCollapsed) { + return null; + } + if (!_onlyWhitespace(range)) { + return range; + } + offset = range.start - 1; + } + return null; + } + + // Check if the given text range only contains white space or separator + // characters. + // + // Includes newline characters from ASCII and separators from the + // [unicode separator category](https://www.compart.com/en/unicode/category/Zs) + // TODO(zanderso): replace when we expose this ICU information. + bool _onlyWhitespace(TextRange range) { + for (int i = range.start; i < range.end; i++) { + final int codeUnit = text!.codeUnitAt(i)!; + if (!TextLayoutMetrics.isWhitespace(codeUnit)) { + return false; + } + } + return true; + } + + @override + void attach(PipelineOwner owner) { + super.attach(owner); + _foregroundRenderObject?.attach(owner); + _backgroundRenderObject?.attach(owner); + + _tap = TapGestureRecognizer(debugOwner: this) + ..onTapDown = _handleTapDown + ..onTap = _handleTap; + _longPress = LongPressGestureRecognizer(debugOwner: this) + ..onLongPress = _handleLongPress; + _offset.addListener(markNeedsPaint); + _showHideCursor(); + _showCursor.addListener(_showHideCursor); + } + + @override + void detach() { + _tap.dispose(); + _longPress.dispose(); + _offset.removeListener(markNeedsPaint); + _showCursor.removeListener(_showHideCursor); + super.detach(); + _foregroundRenderObject?.detach(); + _backgroundRenderObject?.detach(); + } + + @override + void redepthChildren() { + final RenderObject? foregroundChild = _foregroundRenderObject; + final RenderObject? backgroundChild = _backgroundRenderObject; + if (foregroundChild != null) { + redepthChild(foregroundChild); + } + if (backgroundChild != null) { + redepthChild(backgroundChild); + } + super.redepthChildren(); + } + + @override + void visitChildren(RenderObjectVisitor visitor) { + final RenderObject? foregroundChild = _foregroundRenderObject; + final RenderObject? backgroundChild = _backgroundRenderObject; + if (foregroundChild != null) { + visitor(foregroundChild); + } + if (backgroundChild != null) { + visitor(backgroundChild); + } + super.visitChildren(visitor); + } + + bool get _isMultiline => maxLines != 1; + + Axis get _viewportAxis => _isMultiline ? Axis.vertical : Axis.horizontal; + + Offset get _paintOffset { + return switch (_viewportAxis) { + Axis.horizontal => Offset(-offset.pixels, 0.0), + Axis.vertical => Offset(0.0, -offset.pixels), + }; + } + + double get _viewportExtent { + assert(hasSize); + return switch (_viewportAxis) { + Axis.horizontal => size.width, + Axis.vertical => size.height, + }; + } + + double _getMaxScrollExtent(Size contentSize) { + assert(hasSize); + return switch (_viewportAxis) { + Axis.horizontal => math.max(0.0, contentSize.width - size.width), + Axis.vertical => math.max(0.0, contentSize.height - size.height), + }; + } + + // We need to check the paint offset here because during animation, the start of + // the text may position outside the visible region even when the text fits. + bool get _hasVisualOverflow => + _maxScrollExtent > 0 || _paintOffset != Offset.zero; + + /// Returns the local coordinates of the endpoints of the given selection. + /// + /// If the selection is collapsed (and therefore occupies a single point), the + /// returned list is of length one. Otherwise, the selection is not collapsed + /// and the returned list is of length two. In this case, however, the two + /// points might actually be co-located (e.g., because of a bidirectional + /// selection that contains some text but whose ends meet in the middle). + /// + /// See also: + /// + /// * [getLocalRectForCaret], which is the equivalent but for + /// a [TextPosition] rather than a [TextSelection]. + List getEndpointsForSelection(TextSelection selection) { + _computeTextMetricsIfNeeded(); + + final Offset paintOffset = _paintOffset; + + final List boxes = selection.isCollapsed + ? [] + : _textPainter.getBoxesForSelection(selection, + boxHeightStyle: selectionHeightStyle, + boxWidthStyle: selectionWidthStyle); + if (boxes.isEmpty) { + // TODO(mpcomplete): This doesn't work well at an RTL/LTR boundary. + final Offset caretOffset = + _textPainter.getOffsetForCaret(selection.extent, _caretPrototype); + final Offset start = + Offset(0.0, preferredLineHeight) + caretOffset + paintOffset; + return [TextSelectionPoint(start, null)]; + } else { + final Offset start = Offset( + clampDouble(boxes.first.start, 0, _textPainter.size.width), + boxes.first.bottom) + + paintOffset; + final Offset end = Offset( + clampDouble(boxes.last.end, 0, _textPainter.size.width), + boxes.last.bottom) + + paintOffset; + return [ + TextSelectionPoint(start, boxes.first.direction), + TextSelectionPoint(end, boxes.last.direction), + ]; + } + } + + /// Returns the smallest [Rect], in the local coordinate system, that covers + /// the text within the [TextRange] specified. + /// + /// This method is used to calculate the approximate position of the IME bar + /// on iOS. + /// + /// Returns null if [TextRange.isValid] is false for the given `range`, or the + /// given `range` is collapsed. + Rect? getRectForComposingRange(TextRange range) { + if (!range.isValid || range.isCollapsed) { + return null; + } + _computeTextMetricsIfNeeded(); + + final List boxes = _textPainter.getBoxesForSelection( + TextSelection(baseOffset: range.start, extentOffset: range.end), + boxHeightStyle: selectionHeightStyle, + boxWidthStyle: selectionWidthStyle, + ); + + return boxes + .fold( + null, + (Rect? accum, TextBox incoming) => + accum?.expandToInclude(incoming.toRect()) ?? incoming.toRect(), + ) + ?.shift(_paintOffset); + } + + /// Returns the position in the text for the given global coordinate. + /// + /// See also: + /// + /// * [getLocalRectForCaret], which is the reverse operation, taking + /// a [TextPosition] and returning a [Rect]. + /// * [TextPainter.getPositionForOffset], which is the equivalent method + /// for a [TextPainter] object. + TextPosition getPositionForPoint(Offset globalPosition) { + _computeTextMetricsIfNeeded(); + return _textPainter + .getPositionForOffset(globalToLocal(globalPosition) - _paintOffset); + } + + /// Returns the [Rect] in local coordinates for the caret at the given text + /// position. + /// + /// See also: + /// + /// * [getPositionForPoint], which is the reverse operation, taking + /// an [Offset] in global coordinates and returning a [TextPosition]. + /// * [getEndpointsForSelection], which is the equivalent but for + /// a selection rather than a particular text position. + /// * [TextPainter.getOffsetForCaret], the equivalent method for a + /// [TextPainter] object. + Rect getLocalRectForCaret(TextPosition caretPosition) { + _computeTextMetricsIfNeeded(); + final Rect caretPrototype = _caretPrototype; + final Offset caretOffset = + _textPainter.getOffsetForCaret(caretPosition, caretPrototype); + Rect caretRect = caretPrototype.shift(caretOffset + cursorOffset); + final double scrollableWidth = + math.max(_textPainter.width + _caretMargin, size.width); + + final double caretX = clampDouble( + caretRect.left, 0, math.max(scrollableWidth - _caretMargin, 0)); + caretRect = Offset(caretX, caretRect.top) & caretRect.size; + + final double fullHeight = + _textPainter.getFullHeightForCaret(caretPosition, caretPrototype); + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + // Center the caret vertically along the text. + final double heightDiff = fullHeight - caretRect.height; + caretRect = Rect.fromLTWH( + caretRect.left, + caretRect.top + heightDiff / 2, + caretRect.width, + caretRect.height, + ); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + // Override the height to take the full height of the glyph at the TextPosition + // when not on iOS. iOS has special handling that creates a taller caret. + // TODO(garyq): see https://github.com/flutter/flutter/issues/120836. + final double caretHeight = cursorHeight; + // Center the caret vertically along the text. + final double heightDiff = fullHeight - caretHeight; + caretRect = Rect.fromLTWH( + caretRect.left, + caretRect.top - _kCaretHeightOffset + heightDiff / 2, + caretRect.width, + caretHeight, + ); + } + + caretRect = caretRect.shift(_paintOffset); + return caretRect.shift(_snapToPhysicalPixel(caretRect.topLeft)); + } + + @override + double computeMinIntrinsicWidth(double height) { + final List placeholderDimensions = + layoutInlineChildren( + double.infinity, + (RenderBox child, BoxConstraints constraints) => + Size(child.getMinIntrinsicWidth(double.infinity), 0.0), + ChildLayoutHelper.getDryBaseline, + ); + final (double minWidth, double maxWidth) = _adjustConstraints(); + return (_textIntrinsics + ..setPlaceholderDimensions(placeholderDimensions) + ..layout(minWidth: minWidth, maxWidth: maxWidth)) + .minIntrinsicWidth; + } + + @override + double computeMaxIntrinsicWidth(double height) { + final List placeholderDimensions = + layoutInlineChildren( + double.infinity, + // Height and baseline is irrelevant as all text will be laid + // out in a single line. Therefore, using 0.0 as a dummy for the height. + (RenderBox child, BoxConstraints constraints) => + Size(child.getMaxIntrinsicWidth(double.infinity), 0.0), + ChildLayoutHelper.getDryBaseline, + ); + final (double minWidth, double maxWidth) = _adjustConstraints(); + return (_textIntrinsics + ..setPlaceholderDimensions(placeholderDimensions) + ..layout(minWidth: minWidth, maxWidth: maxWidth)) + .maxIntrinsicWidth + + _caretMargin; + } + + /// An estimate of the height of a line in the text. See [TextPainter.preferredLineHeight]. + /// This does not require the layout to be updated. + double get preferredLineHeight => _textPainter.preferredLineHeight; + + int? _cachedLineBreakCount; + int _countHardLineBreaks(String text) { + final int? cachedValue = _cachedLineBreakCount; + if (cachedValue != null) { + return cachedValue; + } + int count = 0; + for (int index = 0; index < text.length; index += 1) { + switch (text.codeUnitAt(index)) { + case 0x000A: // LF + case 0x0085: // NEL + case 0x000B: // VT + case 0x000C: // FF, treating it as a regular line separator + case 0x2028: // LS + case 0x2029: // PS + count += 1; + } + } + return _cachedLineBreakCount = count; + } + + double _preferredHeight(double width) { + final int? maxLines = this.maxLines; + final int? minLines = this.minLines ?? maxLines; + final double minHeight = preferredLineHeight * (minLines ?? 0); + assert(maxLines != 1 || _textIntrinsics.maxLines == 1); + + if (maxLines == null) { + final double estimatedHeight; + if (width == double.infinity) { + estimatedHeight = + preferredLineHeight * (_countHardLineBreaks(plainText) + 1); + } else { + final (double minWidth, double maxWidth) = + _adjustConstraints(maxWidth: width); + estimatedHeight = (_textIntrinsics + ..layout(minWidth: minWidth, maxWidth: maxWidth)) + .height; + } + return math.max(estimatedHeight, minHeight); + } + + // Special case maxLines == 1 since it forces the scrollable direction + // to be horizontal. Report the real height to prevent the text from being + // clipped. + if (maxLines == 1) { + // The _layoutText call lays out the paragraph using infinite width when + // maxLines == 1. Also _textPainter.maxLines will be set to 1 so should + // there be any line breaks only the first line is shown. + final (double minWidth, double maxWidth) = + _adjustConstraints(maxWidth: width); + return (_textIntrinsics..layout(minWidth: minWidth, maxWidth: maxWidth)) + .height; + } + if (minLines == maxLines) { + return minHeight; + } + final double maxHeight = preferredLineHeight * maxLines; + final (double minWidth, double maxWidth) = + _adjustConstraints(maxWidth: width); + return clampDouble( + (_textIntrinsics..layout(minWidth: minWidth, maxWidth: maxWidth)).height, + minHeight, + maxHeight, + ); + } + + @override + double computeMinIntrinsicHeight(double width) => + getMaxIntrinsicHeight(width); + + @override + double computeMaxIntrinsicHeight(double width) { + _textIntrinsics.setPlaceholderDimensions( + layoutInlineChildren(width, ChildLayoutHelper.dryLayoutChild, + ChildLayoutHelper.getDryBaseline), + ); + return _preferredHeight(width); + } + + @override + double computeDistanceToActualBaseline(TextBaseline baseline) { + _computeTextMetricsIfNeeded(); + return _textPainter.computeDistanceToActualBaseline(baseline); + } + + @override + bool hitTestSelf(Offset position) => true; + + @override + @protected + bool hitTestChildren(BoxHitTestResult result, {required Offset position}) { + final Offset effectivePosition = position - _paintOffset; + final GlyphInfo? glyph = + _textPainter.getClosestGlyphForOffset(effectivePosition); + // The hit-test can't fall through the horizontal gaps between visually + // adjacent characters on the same line, even with a large letter-spacing or + // text justification, as graphemeClusterLayoutBounds.width is the advance + // width to the next character, so there's no gap between their + // graphemeClusterLayoutBounds rects. + final InlineSpan? spanHit = glyph != null && + glyph.graphemeClusterLayoutBounds.contains(effectivePosition) + ? _textPainter.text!.getSpanForPosition( + TextPosition(offset: glyph.graphemeClusterCodeUnitRange.start)) + : null; + switch (spanHit) { + case final HitTestTarget span: + result.add(HitTestEntry(span)); + return true; + case _: + return hitTestInlineChildren(result, effectivePosition); + } + } + + late TapGestureRecognizer _tap; + late LongPressGestureRecognizer _longPress; + + @override + void handleEvent(PointerEvent event, BoxHitTestEntry entry) { + assert(debugHandleEvent(event, entry)); + if (event is PointerDownEvent) { + assert(!debugNeedsLayout); + + if (!ignorePointer) { + // Propagates the pointer event to selection handlers. + _tap.addPointer(event); + _longPress.addPointer(event); + } + } + } + + Offset? _lastTapDownPosition; + Offset? _lastSecondaryTapDownPosition; + + /// {@template flutter.rendering.RenderEditable.lastSecondaryTapDownPosition} + /// The position of the most recent secondary tap down event on this text + /// input. + /// {@endtemplate} + Offset? get lastSecondaryTapDownPosition => _lastSecondaryTapDownPosition; + + /// Tracks the position of a secondary tap event. + /// + /// Should be called before attempting to change the selection based on the + /// position of a secondary tap. + void handleSecondaryTapDown(TapDownDetails details) { + _lastTapDownPosition = details.globalPosition; + _lastSecondaryTapDownPosition = details.globalPosition; + } + + /// If [ignorePointer] is false (the default) then this method is called by + /// the internal gesture recognizer's [TapGestureRecognizer.onTapDown] + /// callback. + /// + /// When [ignorePointer] is true, an ancestor widget must respond to tap + /// down events by calling this method. + void handleTapDown(TapDownDetails details) { + _lastTapDownPosition = details.globalPosition; + } + + void _handleTapDown(TapDownDetails details) { + assert(!ignorePointer); + handleTapDown(details); + } + + /// If [ignorePointer] is false (the default) then this method is called by + /// the internal gesture recognizer's [TapGestureRecognizer.onTap] + /// callback. + /// + /// When [ignorePointer] is true, an ancestor widget must respond to tap + /// events by calling this method. + void handleTap() { + selectPosition(cause: SelectionChangedCause.tap); + } + + void _handleTap() { + assert(!ignorePointer); + handleTap(); + } + + /// If [ignorePointer] is false (the default) then this method is called by + /// the internal gesture recognizer's [DoubleTapGestureRecognizer.onDoubleTap] + /// callback. + /// + /// When [ignorePointer] is true, an ancestor widget must respond to double + /// tap events by calling this method. + void handleDoubleTap() { + selectWord(cause: SelectionChangedCause.doubleTap); + } + + /// If [ignorePointer] is false (the default) then this method is called by + /// the internal gesture recognizer's [LongPressGestureRecognizer.onLongPress] + /// callback. + /// + /// When [ignorePointer] is true, an ancestor widget must respond to long + /// press events by calling this method. + void handleLongPress() { + selectWord(cause: SelectionChangedCause.longPress); + } + + void _handleLongPress() { + assert(!ignorePointer); + handleLongPress(); + } + + /// Move selection to the location of the last tap down. + /// + /// {@template flutter.rendering.RenderEditable.selectPosition} + /// This method is mainly used to translate user inputs in global positions + /// into a [TextSelection]. When used in conjunction with a [EditableText], + /// the selection change is fed back into [TextEditingController.selection]. + /// + /// If you have a [TextEditingController], it's generally easier to + /// programmatically manipulate its `value` or `selection` directly. + /// {@endtemplate} + void selectPosition({required SelectionChangedCause cause}) { + selectPositionAt(from: _lastTapDownPosition!, cause: cause); + } + + /// Select text between the global positions [from] and [to]. + /// + /// [from] corresponds to the [TextSelection.baseOffset], and [to] corresponds + /// to the [TextSelection.extentOffset]. + void selectPositionAt( + {required Offset from, + Offset? to, + required SelectionChangedCause cause}) { + _computeTextMetricsIfNeeded(); + final TextPosition fromPosition = + _textPainter.getPositionForOffset(globalToLocal(from) - _paintOffset); + final TextPosition? toPosition = to == null + ? null + : _textPainter.getPositionForOffset(globalToLocal(to) - _paintOffset); + + final int baseOffset = fromPosition.offset; + final int extentOffset = toPosition?.offset ?? fromPosition.offset; + + final TextSelection newSelection = TextSelection( + baseOffset: baseOffset, + extentOffset: extentOffset, + affinity: fromPosition.affinity, + ); + + _setSelection(newSelection, cause); + } + + /// {@macro flutter.painting.TextPainter.wordBoundaries} + WordBoundary get wordBoundaries => _textPainter.wordBoundaries; + + /// Select a word around the location of the last tap down. + /// + /// {@macro flutter.rendering.RenderEditable.selectPosition} + void selectWord({required SelectionChangedCause cause}) { + selectWordsInRange(from: _lastTapDownPosition!, cause: cause); + } + + /// Selects the set words of a paragraph that intersect a given range of global positions. + /// + /// The set of words selected are not strictly bounded by the range of global positions. + /// + /// The first and last endpoints of the selection will always be at the + /// beginning and end of a word respectively. + /// + /// {@macro flutter.rendering.RenderEditable.selectPosition} + void selectWordsInRange( + {required Offset from, + Offset? to, + required SelectionChangedCause cause}) { + _computeTextMetricsIfNeeded(); + final TextPosition fromPosition = + _textPainter.getPositionForOffset(globalToLocal(from) - _paintOffset); + final TextSelection fromWord = getWordAtOffset(fromPosition); + final TextPosition toPosition = to == null + ? fromPosition + : _textPainter.getPositionForOffset(globalToLocal(to) - _paintOffset); + final TextSelection toWord = + toPosition == fromPosition ? fromWord : getWordAtOffset(toPosition); + final bool isFromWordBeforeToWord = fromWord.start < toWord.end; + + _setSelection( + TextSelection( + baseOffset: isFromWordBeforeToWord + ? fromWord.base.offset + : fromWord.extent.offset, + extentOffset: + isFromWordBeforeToWord ? toWord.extent.offset : toWord.base.offset, + affinity: fromWord.affinity, + ), + cause, + ); + } + + /// Move the selection to the beginning or end of a word. + /// + /// {@macro flutter.rendering.RenderEditable.selectPosition} + void selectWordEdge({required SelectionChangedCause cause}) { + _computeTextMetricsIfNeeded(); + assert(_lastTapDownPosition != null); + final TextPosition position = _textPainter.getPositionForOffset( + globalToLocal(_lastTapDownPosition!) - _paintOffset); + final TextRange word = _textPainter.getWordBoundary(position); + late TextSelection newSelection; + if (position.offset <= word.start) { + newSelection = TextSelection.collapsed(offset: word.start); + } else { + newSelection = TextSelection.collapsed( + offset: word.end, affinity: TextAffinity.upstream); + } + _setSelection(newSelection, cause); + } + + /// Returns a [TextSelection] that encompasses the word at the given + /// [TextPosition]. + @visibleForTesting + TextSelection getWordAtOffset(TextPosition position) { + // When long-pressing past the end of the text, we want a collapsed cursor. + if (position.offset >= plainText.length) { + return TextSelection.fromPosition(TextPosition( + offset: plainText.length, affinity: TextAffinity.upstream)); + } + // If text is obscured, the entire sentence should be treated as one word. + if (obscureText) { + return TextSelection(baseOffset: 0, extentOffset: plainText.length); + } + final TextRange word = _textPainter.getWordBoundary(position); + final int effectiveOffset; + switch (position.affinity) { + case TextAffinity.upstream: + // upstream affinity is effectively -1 in text position. + effectiveOffset = position.offset - 1; + case TextAffinity.downstream: + effectiveOffset = position.offset; + } + assert(effectiveOffset >= 0); + + // On iOS, select the previous word if there is a previous word, or select + // to the end of the next word if there is a next word. Select nothing if + // there is neither a previous word nor a next word. + // + // If the platform is Android and the text is read only, try to select the + // previous word if there is one; otherwise, select the single whitespace at + // the position. + if (effectiveOffset > 0 && + TextLayoutMetrics.isWhitespace(plainText.codeUnitAt(effectiveOffset))) { + final TextRange? previousWord = _getPreviousWord(word.start); + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + if (previousWord == null) { + final TextRange? nextWord = _getNextWord(word.start); + if (nextWord == null) { + return TextSelection.collapsed(offset: position.offset); + } + return TextSelection( + baseOffset: position.offset, + extentOffset: nextWord.end, + ); + } + return TextSelection( + baseOffset: previousWord.start, + extentOffset: position.offset, + ); + case TargetPlatform.android: + if (readOnly) { + if (previousWord == null) { + return TextSelection( + baseOffset: position.offset, + extentOffset: position.offset + 1, + ); + } + return TextSelection( + baseOffset: previousWord.start, + extentOffset: position.offset, + ); + } + case TargetPlatform.fuchsia: + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + break; + } + } + + return TextSelection(baseOffset: word.start, extentOffset: word.end); + } + + // Placeholder dimensions representing the sizes of child inline widgets. + // + // These need to be cached because the text painter's placeholder dimensions + // will be overwritten during intrinsic width/height calculations and must be + // restored to the original values before final layout and painting. + List? _placeholderDimensions; + + (double minWidth, double maxWidth) _adjustConstraints( + {double minWidth = 0.0, double maxWidth = double.infinity}) { + final double availableMaxWidth = math.max(0.0, maxWidth - _caretMargin); + final double availableMinWidth = math.min(minWidth, availableMaxWidth); + return ( + forceLine ? availableMaxWidth : availableMinWidth, + _isMultiline ? availableMaxWidth : double.infinity, + ); + } + + // Computes the text metrics if `_textPainter`'s layout information was marked + // as dirty. + // + // This method must be called in `RenderEditable`'s public methods that expose + // `_textPainter`'s metrics. For instance, `systemFontsDidChange` sets + // _textPainter._paragraph to null, so accessing _textPainter's metrics + // immediately after `systemFontsDidChange` without first calling this method + // may crash. + // + // This method is also called in various paint methods (`RenderEditable.paint` + // as well as its foreground/background painters' `paint`). It's needed + // because invisible render objects kept in the tree by `KeepAlive` may not + // get a chance to do layout but can still paint. + // See https://github.com/flutter/flutter/issues/84896. + // + // This method only re-computes layout if the underlying `_textPainter`'s + // layout cache is invalidated (by calling `TextPainter.markNeedsLayout`), or + // the constraints used to layout the `_textPainter` is different. See + // `TextPainter.layout`. + void _computeTextMetricsIfNeeded() { + final (double minWidth, double maxWidth) = _adjustConstraints( + minWidth: constraints.minWidth, maxWidth: constraints.maxWidth); + _textPainter.layout(minWidth: minWidth, maxWidth: maxWidth); + } + + late Rect _caretPrototype; + + // TODO(LongCatIsLooong): https://github.com/flutter/flutter/issues/120836 + // + /// On iOS, the cursor is taller than the cursor on Android. The height + /// of the cursor for iOS is approximate and obtained through an eyeball + /// comparison. + void _computeCaretPrototype() { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + _caretPrototype = + Rect.fromLTWH(0.0, 0.0, cursorWidth, cursorHeight + 2); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + _caretPrototype = Rect.fromLTWH(0.0, _kCaretHeightOffset, cursorWidth, + cursorHeight - 2.0 * _kCaretHeightOffset); + } + } + + // Computes the offset to apply to the given [sourceOffset] so it perfectly + // snaps to physical pixels. + Offset _snapToPhysicalPixel(Offset sourceOffset) { + final Offset globalOffset = localToGlobal(sourceOffset); + final double pixelMultiple = 1.0 / _devicePixelRatio; + return Offset( + globalOffset.dx.isFinite + ? (globalOffset.dx / pixelMultiple).round() * pixelMultiple - + globalOffset.dx + : 0, + globalOffset.dy.isFinite + ? (globalOffset.dy / pixelMultiple).round() * pixelMultiple - + globalOffset.dy + : 0, + ); + } + + @override + @protected + Size computeDryLayout(covariant BoxConstraints constraints) { + final (double minWidth, double maxWidth) = _adjustConstraints( + minWidth: constraints.minWidth, maxWidth: constraints.maxWidth); + _textIntrinsics + ..setPlaceholderDimensions(layoutInlineChildren(constraints.maxWidth, + ChildLayoutHelper.dryLayoutChild, ChildLayoutHelper.getDryBaseline)) + ..layout(minWidth: minWidth, maxWidth: maxWidth); + final double width = forceLine + ? constraints.maxWidth + : constraints.constrainWidth(_textIntrinsics.size.width + _caretMargin); + return Size(width, + constraints.constrainHeight(_preferredHeight(constraints.maxWidth))); + } + + @override + double computeDryBaseline( + covariant BoxConstraints constraints, TextBaseline baseline) { + final (double minWidth, double maxWidth) = _adjustConstraints( + minWidth: constraints.minWidth, maxWidth: constraints.maxWidth); + _textIntrinsics + ..setPlaceholderDimensions(layoutInlineChildren(constraints.maxWidth, + ChildLayoutHelper.dryLayoutChild, ChildLayoutHelper.getDryBaseline)) + ..layout(minWidth: minWidth, maxWidth: maxWidth); + return _textIntrinsics.computeDistanceToActualBaseline(baseline); + } + + @override + void performLayout() { + final BoxConstraints constraints = this.constraints; + _placeholderDimensions = layoutInlineChildren(constraints.maxWidth, + ChildLayoutHelper.layoutChild, ChildLayoutHelper.getBaseline); + final (double minWidth, double maxWidth) = _adjustConstraints( + minWidth: constraints.minWidth, maxWidth: constraints.maxWidth); + _textPainter + ..setPlaceholderDimensions(_placeholderDimensions) + ..layout(minWidth: minWidth, maxWidth: maxWidth); + positionInlineChildren(_textPainter.inlinePlaceholderBoxes!); + _computeCaretPrototype(); + + final double width = forceLine + ? constraints.maxWidth + : constraints.constrainWidth(_textPainter.width + _caretMargin); + assert(maxLines != 1 || _textPainter.maxLines == 1); + final double preferredHeight = switch (maxLines) { + null => + math.max(_textPainter.height, preferredLineHeight * (minLines ?? 0)), + 1 => _textPainter.height, + final int maxLines => clampDouble( + _textPainter.height, + preferredLineHeight * (minLines ?? maxLines), + preferredLineHeight * maxLines, + ), + }; + + size = Size(width, constraints.constrainHeight(preferredHeight)); + final Size contentSize = + Size(_textPainter.width + _caretMargin, _textPainter.height); + + final BoxConstraints painterConstraints = BoxConstraints.tight(contentSize); + + _foregroundRenderObject?.layout(painterConstraints); + _backgroundRenderObject?.layout(painterConstraints); + + _maxScrollExtent = _getMaxScrollExtent(contentSize); + offset.applyViewportDimension(_viewportExtent); + offset.applyContentDimensions(0.0, _maxScrollExtent); + } + + // The relative origin in relation to the distance the user has theoretically + // dragged the floating cursor offscreen. This value is used to account for the + // difference in the rendering position and the raw offset value. + Offset _relativeOrigin = Offset.zero; + Offset? _previousOffset; + bool _shouldResetOrigin = true; + bool _resetOriginOnLeft = false; + bool _resetOriginOnRight = false; + bool _resetOriginOnTop = false; + bool _resetOriginOnBottom = false; + double? _resetFloatingCursorAnimationValue; + + static Offset _calculateAdjustedCursorOffset( + Offset offset, Rect boundingRects) { + final double adjustedX = + clampDouble(offset.dx, boundingRects.left, boundingRects.right); + final double adjustedY = + clampDouble(offset.dy, boundingRects.top, boundingRects.bottom); + return Offset(adjustedX, adjustedY); + } + + /// Returns the position within the text field closest to the raw cursor offset. + /// + /// See also: + /// + /// * [FloatingCursorDragState], which explains the floating cursor feature + /// in detail. + Offset calculateBoundedFloatingCursorOffset(Offset rawCursorOffset, + {bool? shouldResetOrigin}) { + Offset deltaPosition = Offset.zero; + final double topBound = -floatingCursorAddedMargin.top; + final double bottomBound = math.min(size.height, _textPainter.height) - + preferredLineHeight + + floatingCursorAddedMargin.bottom; + final double leftBound = -floatingCursorAddedMargin.left; + final double rightBound = math.min(size.width, _textPainter.width) + + floatingCursorAddedMargin.right; + final Rect boundingRects = + Rect.fromLTRB(leftBound, topBound, rightBound, bottomBound); + + if (shouldResetOrigin != null) { + _shouldResetOrigin = shouldResetOrigin; + } + + if (!_shouldResetOrigin) { + return _calculateAdjustedCursorOffset(rawCursorOffset, boundingRects); + } + + if (_previousOffset != null) { + deltaPosition = rawCursorOffset - _previousOffset!; + } + + // If the raw cursor offset has gone off an edge, we want to reset the relative + // origin of the dragging when the user drags back into the field. + if (_resetOriginOnLeft && deltaPosition.dx > 0) { + _relativeOrigin = + Offset(rawCursorOffset.dx - boundingRects.left, _relativeOrigin.dy); + _resetOriginOnLeft = false; + } else if (_resetOriginOnRight && deltaPosition.dx < 0) { + _relativeOrigin = + Offset(rawCursorOffset.dx - boundingRects.right, _relativeOrigin.dy); + _resetOriginOnRight = false; + } + if (_resetOriginOnTop && deltaPosition.dy > 0) { + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - boundingRects.top); + _resetOriginOnTop = false; + } else if (_resetOriginOnBottom && deltaPosition.dy < 0) { + _relativeOrigin = + Offset(_relativeOrigin.dx, rawCursorOffset.dy - boundingRects.bottom); + _resetOriginOnBottom = false; + } + + final double currentX = rawCursorOffset.dx - _relativeOrigin.dx; + final double currentY = rawCursorOffset.dy - _relativeOrigin.dy; + final Offset adjustedOffset = _calculateAdjustedCursorOffset( + Offset(currentX, currentY), boundingRects); + + if (currentX < boundingRects.left && deltaPosition.dx < 0) { + _resetOriginOnLeft = true; + } else if (currentX > boundingRects.right && deltaPosition.dx > 0) { + _resetOriginOnRight = true; + } + if (currentY < boundingRects.top && deltaPosition.dy < 0) { + _resetOriginOnTop = true; + } else if (currentY > boundingRects.bottom && deltaPosition.dy > 0) { + _resetOriginOnBottom = true; + } + + _previousOffset = rawCursorOffset; + + return adjustedOffset; + } + + /// Sets the screen position of the floating cursor and the text position + /// closest to the cursor. + /// + /// See also: + /// + /// * [FloatingCursorDragState], which explains the floating cursor feature + /// in detail. + void setFloatingCursor(FloatingCursorDragState state, Offset boundedOffset, + TextPosition lastTextPosition, + {double? resetLerpValue}) { + if (state == FloatingCursorDragState.End) { + _relativeOrigin = Offset.zero; + _previousOffset = null; + _shouldResetOrigin = true; + _resetOriginOnBottom = false; + _resetOriginOnTop = false; + _resetOriginOnRight = false; + _resetOriginOnBottom = false; + } + _floatingCursorOn = state != FloatingCursorDragState.End; + _resetFloatingCursorAnimationValue = resetLerpValue; + if (_floatingCursorOn) { + _floatingCursorTextPosition = lastTextPosition; + final double? animationValue = _resetFloatingCursorAnimationValue; + final EdgeInsets sizeAdjustment = animationValue != null + ? EdgeInsets.lerp( + _kFloatingCursorSizeIncrease, EdgeInsets.zero, animationValue)! + : _kFloatingCursorSizeIncrease; + _caretPainter.floatingCursorRect = + sizeAdjustment.inflateRect(_caretPrototype).shift(boundedOffset); + } else { + _caretPainter.floatingCursorRect = null; + } + _caretPainter.showRegularCaret = _resetFloatingCursorAnimationValue == null; + } + + MapEntry _lineNumberFor( + TextPosition startPosition, List metrics) { + // TODO(LongCatIsLooong): include line boundaries information in + // ui.LineMetrics, then we can get rid of this. + final Offset offset = + _textPainter.getOffsetForCaret(startPosition, Rect.zero); + for (final ui.LineMetrics lineMetrics in metrics) { + if (lineMetrics.baseline > offset.dy) { + return MapEntry( + lineMetrics.lineNumber, Offset(offset.dx, lineMetrics.baseline)); + } + } + assert(startPosition.offset == 0, + 'unable to find the line for $startPosition'); + return MapEntry( + math.max(0, metrics.length - 1), + Offset( + offset.dx, + metrics.isNotEmpty + ? metrics.last.baseline + metrics.last.descent + : 0.0), + ); + } + + /// Starts a [VerticalCaretMovementRun] at the given location in the text, for + /// handling consecutive vertical caret movements. + /// + /// This can be used to handle consecutive upward/downward arrow key movements + /// in an input field. + /// + /// {@macro flutter.rendering.RenderEditable.verticalArrowKeyMovement} + /// + /// The [VerticalCaretMovementRun.isValid] property indicates whether the text + /// layout has changed and the vertical caret run is invalidated. + /// + /// The caller should typically discard a [VerticalCaretMovementRun] when + /// its [VerticalCaretMovementRun.isValid] becomes false, or on other + /// occasions where the vertical caret run should be interrupted. + VerticalCaretMovementRun startVerticalCaretMovement( + TextPosition startPosition) { + final List metrics = _textPainter.computeLineMetrics(); + final MapEntry currentLine = + _lineNumberFor(startPosition, metrics); + return VerticalCaretMovementRun._( + this, + metrics, + startPosition, + currentLine.key, + currentLine.value, + ); + } + + void _paintContents(PaintingContext context, Offset offset) { + final Offset effectiveOffset = offset + _paintOffset; + + if (selection != null && !_floatingCursorOn) { + _updateSelectionExtentsVisibility(effectiveOffset); + } + + final RenderBox? foregroundChild = _foregroundRenderObject; + final RenderBox? backgroundChild = _backgroundRenderObject; + + // The painters paint in the viewport's coordinate space, since the + // textPainter's coordinate space is not known to high level widgets. + if (backgroundChild != null) { + context.paintChild(backgroundChild, offset); + } + + _textPainter.paint(context.canvas, effectiveOffset); + paintInlineChildren(context, effectiveOffset); + + if (foregroundChild != null) { + context.paintChild(foregroundChild, offset); + } + } + + final LayerHandle _leaderLayerHandler = + LayerHandle(); + + void _paintHandleLayers(PaintingContext context, + List endpoints, Offset offset) { + Offset startPoint = endpoints[0].point; + startPoint = Offset( + clampDouble(startPoint.dx, 0.0, size.width), + clampDouble(startPoint.dy, 0.0, size.height), + ); + _leaderLayerHandler.layer = + LeaderLayer(link: startHandleLayerLink, offset: startPoint + offset); + context.pushLayer( + _leaderLayerHandler.layer!, + super.paint, + Offset.zero, + ); + if (endpoints.length == 2) { + Offset endPoint = endpoints[1].point; + endPoint = Offset( + clampDouble(endPoint.dx, 0.0, size.width), + clampDouble(endPoint.dy, 0.0, size.height), + ); + context.pushLayer( + LeaderLayer(link: endHandleLayerLink, offset: endPoint + offset), + super.paint, + Offset.zero, + ); + } + } + + @override + void applyPaintTransform(RenderBox child, Matrix4 transform) { + if (child == _foregroundRenderObject || child == _backgroundRenderObject) { + return; + } + defaultApplyPaintTransform(child, transform); + } + + @override + void paint(PaintingContext context, Offset offset) { + _computeTextMetricsIfNeeded(); + if (_hasVisualOverflow && clipBehavior != Clip.none) { + _clipRectLayer.layer = context.pushClipRect( + needsCompositing, + offset, + Offset.zero & size, + _paintContents, + clipBehavior: clipBehavior, + oldLayer: _clipRectLayer.layer, + ); + } else { + _clipRectLayer.layer = null; + _paintContents(context, offset); + } + final TextSelection? selection = this.selection; + if (selection != null && selection.isValid) { + _paintHandleLayers(context, getEndpointsForSelection(selection), offset); + } + } + + final LayerHandle _clipRectLayer = + LayerHandle(); + + @override + Rect? describeApproximatePaintClip(RenderObject child) { + switch (clipBehavior) { + case Clip.none: + return null; + case Clip.hardEdge: + case Clip.antiAlias: + case Clip.antiAliasWithSaveLayer: + return _hasVisualOverflow ? Offset.zero & size : null; + } + } + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(ColorProperty('cursorColor', cursorColor)); + properties.add( + DiagnosticsProperty>('showCursor', showCursor)); + properties.add(IntProperty('maxLines', maxLines)); + properties.add(IntProperty('minLines', minLines)); + properties.add( + DiagnosticsProperty('expands', expands, defaultValue: false)); + properties.add(ColorProperty('selectionColor', selectionColor)); + properties.add(DiagnosticsProperty('textScaler', textScaler, + defaultValue: TextScaler.noScaling)); + properties + .add(DiagnosticsProperty('locale', locale, defaultValue: null)); + properties.add(DiagnosticsProperty('selection', selection)); + properties.add(DiagnosticsProperty('offset', offset)); + } + + @override + List debugDescribeChildren() { + return [ + if (text != null) + text!.toDiagnosticsNode( + name: 'text', + style: DiagnosticsTreeStyle.transition, + ), + ]; + } +} + +class _RenderEditableCustomPaint extends RenderBox { + _RenderEditableCustomPaint({ + RenderEditablePainter? painter, + }) : _painter = painter, + super(); + + // zmtzawqlp + @override + _RenderEditable? get parent => super.parent as _RenderEditable?; + + @override + bool get isRepaintBoundary => true; + + @override + bool get sizedByParent => true; + + RenderEditablePainter? get painter => _painter; + RenderEditablePainter? _painter; + set painter(RenderEditablePainter? newValue) { + if (newValue == painter) { + return; + } + + final RenderEditablePainter? oldPainter = painter; + _painter = newValue; + + if (newValue?.shouldRepaint(oldPainter) ?? true) { + markNeedsPaint(); + } + + if (attached) { + oldPainter?.removeListener(markNeedsPaint); + newValue?.addListener(markNeedsPaint); + } + } + + @override + void paint(PaintingContext context, Offset offset) { + // zmtzawlp + final _RenderEditable? parent = this.parent; + assert(parent != null); + final RenderEditablePainter? painter = this.painter; + if (painter != null && parent != null) { + parent._computeTextMetricsIfNeeded(); + painter.paint(context.canvas, size, parent); + } + } + + @override + void attach(PipelineOwner owner) { + super.attach(owner); + _painter?.addListener(markNeedsPaint); + } + + @override + void detach() { + _painter?.removeListener(markNeedsPaint); + super.detach(); + } + + @override + @protected + Size computeDryLayout(covariant BoxConstraints constraints) => + constraints.biggest; +} + +/// An interface that paints within a [RenderEditable]'s bounds, above or +/// beneath its text content. +/// +/// This painter is typically used for painting auxiliary content that depends +/// on text layout metrics (for instance, for painting carets and text highlight +/// blocks). It can paint independently from its [RenderEditable], allowing it +/// to repaint without triggering a repaint on the entire [RenderEditable] stack +/// when only auxiliary content changes (e.g. a blinking cursor) are present. It +/// will be scheduled to repaint when: +/// +/// * It's assigned to a new [RenderEditable] (replacing a prior +/// [RenderEditablePainter]) and the [shouldRepaint] method returns true. +/// * Any of the [RenderEditable]s it is attached to repaints. +/// * The [notifyListeners] method is called, which typically happens when the +/// painter's attributes change. +/// +/// See also: +/// +/// * [RenderEditable.foregroundPainter], which takes a [RenderEditablePainter] +/// and sets it as the foreground painter of the [RenderEditable]. +/// * [RenderEditable.painter], which takes a [RenderEditablePainter] +/// and sets it as the background painter of the [RenderEditable]. +/// * [CustomPainter], a similar class which paints within a [RenderCustomPaint]. +abstract class RenderEditablePainter extends ChangeNotifier { + /// Determines whether repaint is needed when a new [RenderEditablePainter] + /// is provided to a [RenderEditable]. + /// + /// If the new instance represents different information than the old + /// instance, then the method should return true, otherwise it should return + /// false. When [oldDelegate] is null, this method should always return true + /// unless the new painter initially does not paint anything. + /// + /// If the method returns false, then the [paint] call might be optimized + /// away. However, the [paint] method will get called whenever the + /// [RenderEditable]s it attaches to repaint, even if [shouldRepaint] returns + /// false. + bool shouldRepaint(RenderEditablePainter? oldDelegate); + + /// Paints within the bounds of a [RenderEditable]. + /// + /// The given [Canvas] has the same coordinate space as the [RenderEditable], + /// which may be different from the coordinate space the [RenderEditable]'s + /// [TextPainter] uses, when the text moves inside the [RenderEditable]. + /// + /// Paint operations performed outside of the region defined by the [canvas]'s + /// origin and the [size] parameter may get clipped, when [RenderEditable]'s + /// [RenderEditable.clipBehavior] is not [Clip.none]. + // zmtzawqlp + void paint(Canvas canvas, Size size, _RenderEditable renderEditable); +} + +class _TextHighlightPainter extends RenderEditablePainter { + _TextHighlightPainter({ + TextRange? highlightedRange, + Color? highlightColor, + }) : _highlightedRange = highlightedRange, + _highlightColor = highlightColor; + + final Paint highlightPaint = Paint(); + + Color? get highlightColor => _highlightColor; + Color? _highlightColor; + set highlightColor(Color? newValue) { + if (newValue == _highlightColor) { + return; + } + _highlightColor = newValue; + notifyListeners(); + } + + TextRange? get highlightedRange => _highlightedRange; + TextRange? _highlightedRange; + set highlightedRange(TextRange? newValue) { + if (newValue == _highlightedRange) { + return; + } + _highlightedRange = newValue; + notifyListeners(); + } + + /// Controls how tall the selection highlight boxes are computed to be. + /// + /// See [ui.BoxHeightStyle] for details on available styles. + ui.BoxHeightStyle get selectionHeightStyle => _selectionHeightStyle; + ui.BoxHeightStyle _selectionHeightStyle = ui.BoxHeightStyle.tight; + set selectionHeightStyle(ui.BoxHeightStyle value) { + if (_selectionHeightStyle == value) { + return; + } + _selectionHeightStyle = value; + notifyListeners(); + } + + /// Controls how wide the selection highlight boxes are computed to be. + /// + /// See [ui.BoxWidthStyle] for details on available styles. + ui.BoxWidthStyle get selectionWidthStyle => _selectionWidthStyle; + ui.BoxWidthStyle _selectionWidthStyle = ui.BoxWidthStyle.tight; + set selectionWidthStyle(ui.BoxWidthStyle value) { + if (_selectionWidthStyle == value) { + return; + } + _selectionWidthStyle = value; + notifyListeners(); + } + + // zmtzawqlp + @override + void paint(Canvas canvas, Size size, _RenderEditable renderEditable) { + final TextRange? range = highlightedRange; + final Color? color = highlightColor; + if (range == null || color == null || range.isCollapsed) { + return; + } + + highlightPaint.color = color; + // zmtzawqlp + final TextPainter textPainter = renderEditable._textPainter; + final List boxes = textPainter.getBoxesForSelection( + TextSelection(baseOffset: range.start, extentOffset: range.end), + boxHeightStyle: selectionHeightStyle, + boxWidthStyle: selectionWidthStyle, + ); + + for (final TextBox box in boxes) { + canvas.drawRect( + box.toRect().shift(renderEditable._paintOffset).intersect( + Rect.fromLTWH(0, 0, textPainter.width, textPainter.height)), + highlightPaint, + ); + } + } + + @override + bool shouldRepaint(RenderEditablePainter? oldDelegate) { + if (identical(oldDelegate, this)) { + return false; + } + if (oldDelegate == null) { + return highlightColor != null && highlightedRange != null; + } + return oldDelegate is! _TextHighlightPainter || + oldDelegate.highlightColor != highlightColor || + oldDelegate.highlightedRange != highlightedRange || + oldDelegate.selectionHeightStyle != selectionHeightStyle || + oldDelegate.selectionWidthStyle != selectionWidthStyle; + } +} + +class _CaretPainter extends RenderEditablePainter { + _CaretPainter(); + + bool get shouldPaint => _shouldPaint; + bool _shouldPaint = true; + set shouldPaint(bool value) { + if (shouldPaint == value) { + return; + } + _shouldPaint = value; + notifyListeners(); + } + + // This is directly manipulated by the RenderEditable during + // setFloatingCursor. + // + // When changing this value, the caller is responsible for ensuring that + // listeners are notified. + bool showRegularCaret = false; + + final Paint caretPaint = Paint(); + late final Paint floatingCursorPaint = Paint(); + + Color? get caretColor => _caretColor; + Color? _caretColor; + set caretColor(Color? value) { + if (caretColor?.value == value?.value) { + return; + } + + _caretColor = value; + notifyListeners(); + } + + Radius? get cursorRadius => _cursorRadius; + Radius? _cursorRadius; + set cursorRadius(Radius? value) { + if (_cursorRadius == value) { + return; + } + _cursorRadius = value; + notifyListeners(); + } + + Offset get cursorOffset => _cursorOffset; + Offset _cursorOffset = Offset.zero; + set cursorOffset(Offset value) { + if (_cursorOffset == value) { + return; + } + _cursorOffset = value; + notifyListeners(); + } + + Color? get backgroundCursorColor => _backgroundCursorColor; + Color? _backgroundCursorColor; + set backgroundCursorColor(Color? value) { + if (backgroundCursorColor?.value == value?.value) { + return; + } + + _backgroundCursorColor = value; + if (showRegularCaret) { + notifyListeners(); + } + } + + Rect? get floatingCursorRect => _floatingCursorRect; + Rect? _floatingCursorRect; + set floatingCursorRect(Rect? value) { + if (_floatingCursorRect == value) { + return; + } + _floatingCursorRect = value; + notifyListeners(); + } + + // zmtzawqlp + void paintRegularCursor(Canvas canvas, _RenderEditable renderEditable, + Color caretColor, TextPosition textPosition) { + final Rect integralRect = renderEditable.getLocalRectForCaret(textPosition); + if (shouldPaint) { + if (floatingCursorRect != null) { + final double distanceSquared = + (floatingCursorRect!.center - integralRect.center).distanceSquared; + if (distanceSquared < + _kShortestDistanceSquaredWithFloatingAndRegularCursors) { + return; + } + } + final Radius? radius = cursorRadius; + caretPaint.color = caretColor; + if (radius == null) { + canvas.drawRect(integralRect, caretPaint); + } else { + final RRect caretRRect = RRect.fromRectAndRadius(integralRect, radius); + canvas.drawRRect(caretRRect, caretPaint); + } + } + } + +// zmtzawqlp + @override + void paint(Canvas canvas, Size size, _RenderEditable renderEditable) { + // Compute the caret location even when `shouldPaint` is false. + + // final TextSelection? selection = renderEditable.selection; + // zmtzawqlp + final TextSelection? selection = + (renderEditable as ExtendedRenderEditable).getActualSelection(); + + if (selection == null || !selection.isCollapsed || !selection.isValid) { + return; + } + + final Rect? floatingCursorRect = this.floatingCursorRect; + + final Color? caretColor = floatingCursorRect == null + ? this.caretColor + : showRegularCaret + ? backgroundCursorColor + : null; + final TextPosition caretTextPosition = floatingCursorRect == null + ? selection.extent + : renderEditable._floatingCursorTextPosition; + + if (caretColor != null) { + paintRegularCursor(canvas, renderEditable, caretColor, caretTextPosition); + } + + final Color? floatingCursorColor = this.caretColor?.withOpacity(0.75); + // Floating Cursor. + if (floatingCursorRect == null || + floatingCursorColor == null || + !shouldPaint) { + return; + } + + canvas.drawRRect( + RRect.fromRectAndRadius(floatingCursorRect, _kFloatingCursorRadius), + floatingCursorPaint..color = floatingCursorColor, + ); + } + + @override + bool shouldRepaint(RenderEditablePainter? oldDelegate) { + if (identical(this, oldDelegate)) { + return false; + } + + if (oldDelegate == null) { + return shouldPaint; + } + return oldDelegate is! _CaretPainter || + oldDelegate.shouldPaint != shouldPaint || + oldDelegate.showRegularCaret != showRegularCaret || + oldDelegate.caretColor != caretColor || + oldDelegate.cursorRadius != cursorRadius || + oldDelegate.cursorOffset != cursorOffset || + oldDelegate.backgroundCursorColor != backgroundCursorColor || + oldDelegate.floatingCursorRect != floatingCursorRect; + } +} + +class _CompositeRenderEditablePainter extends RenderEditablePainter { + _CompositeRenderEditablePainter({required this.painters}); + + final List painters; + + @override + void addListener(VoidCallback listener) { + for (final RenderEditablePainter painter in painters) { + painter.addListener(listener); + } + } + + @override + void removeListener(VoidCallback listener) { + for (final RenderEditablePainter painter in painters) { + painter.removeListener(listener); + } + } + + // zmtzawqlp + @override + void paint(Canvas canvas, Size size, _RenderEditable renderEditable) { + for (final RenderEditablePainter painter in painters) { + painter.paint(canvas, size, renderEditable); + } + } + + @override + bool shouldRepaint(RenderEditablePainter? oldDelegate) { + if (identical(oldDelegate, this)) { + return false; + } + if (oldDelegate is! _CompositeRenderEditablePainter || + oldDelegate.painters.length != painters.length) { + return true; + } + + final Iterator oldPainters = + oldDelegate.painters.iterator; + final Iterator newPainters = painters.iterator; + while (oldPainters.moveNext() && newPainters.moveNext()) { + if (newPainters.current.shouldRepaint(oldPainters.current)) { + return true; + } + } + + return false; + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/editable_text.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/editable_text.dart new file mode 100644 index 0000000..1bd4cfa --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/editable_text.dart @@ -0,0 +1,6031 @@ +// ignore_for_file: unused_field + +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +// Signature for a function that determines the target location of the given +// [TextPosition] after applying the given [TextBoundary]. +typedef _ApplyTextBoundary = TextPosition Function( + TextPosition, bool, TextBoundary); + +// The time it takes for the cursor to fade from fully opaque to fully +// transparent and vice versa. A full cursor blink, from transparent to opaque +// to transparent, is twice this duration. +const Duration _kCursorBlinkHalfPeriod = Duration(milliseconds: 500); + +// Number of cursor ticks during which the most recently entered character +// is shown in an obscured text field. +const int _kObscureShowLatestCharCursorTicks = 3; + +/// The default mime types to be used when allowedMimeTypes is not provided. +/// +/// The default value supports inserting images of any supported format. +const List kDefaultContentInsertionMimeTypes = [ + 'image/png', + 'image/bmp', + 'image/jpg', + 'image/tiff', + 'image/gif', + 'image/jpeg', + 'image/webp' +]; + +class _CompositionCallback extends SingleChildRenderObjectWidget { + const _CompositionCallback( + {required this.compositeCallback, required this.enabled, super.child}); + final CompositionCallback compositeCallback; + final bool enabled; + + @override + RenderObject createRenderObject(BuildContext context) { + return _RenderCompositionCallback(compositeCallback, enabled); + } + + @override + void updateRenderObject( + BuildContext context, _RenderCompositionCallback renderObject) { + super.updateRenderObject(context, renderObject); + // _EditableTextState always uses the same callback. + assert(renderObject.compositeCallback == compositeCallback); + renderObject.enabled = enabled; + } +} + +class _RenderCompositionCallback extends RenderProxyBox { + _RenderCompositionCallback(this.compositeCallback, this._enabled); + + final CompositionCallback compositeCallback; + VoidCallback? _cancelCallback; + + bool get enabled => _enabled; + bool _enabled = false; + set enabled(bool newValue) { + _enabled = newValue; + if (!newValue) { + _cancelCallback?.call(); + _cancelCallback = null; + } else if (_cancelCallback == null) { + markNeedsPaint(); + } + } + + @override + void paint(PaintingContext context, ui.Offset offset) { + if (enabled) { + _cancelCallback ??= context.addCompositionCallback(compositeCallback); + } + super.paint(context, offset); + } +} + +// A time-value pair that represents a key frame in an animation. +class _KeyFrame { + const _KeyFrame(this.time, this.value); + // Values extracted from iOS 15.4 UIKit. + static const List<_KeyFrame> iOSBlinkingCaretKeyFrames = <_KeyFrame>[ + _KeyFrame(0, 1), // 0 + _KeyFrame(0.5, 1), // 1 + _KeyFrame(0.5375, 0.75), // 2 + _KeyFrame(0.575, 0.5), // 3 + _KeyFrame(0.6125, 0.25), // 4 + _KeyFrame(0.65, 0), // 5 + _KeyFrame(0.85, 0), // 6 + _KeyFrame(0.8875, 0.25), // 7 + _KeyFrame(0.925, 0.5), // 8 + _KeyFrame(0.9625, 0.75), // 9 + _KeyFrame(1, 1), // 10 + ]; + + // The timing, in seconds, of the specified animation `value`. + final double time; + final double value; +} + +class _DiscreteKeyFrameSimulation extends Simulation { + _DiscreteKeyFrameSimulation.iOSBlinkingCaret() + : this._(_KeyFrame.iOSBlinkingCaretKeyFrames, 1); + _DiscreteKeyFrameSimulation._(this._keyFrames, this.maxDuration) + : assert(_keyFrames.isNotEmpty), + assert(_keyFrames.last.time <= maxDuration), + assert(() { + for (int i = 0; i < _keyFrames.length - 1; i += 1) { + if (_keyFrames[i].time > _keyFrames[i + 1].time) { + return false; + } + } + return true; + }(), 'The key frame sequence must be sorted by time.'); + + final double maxDuration; + + final List<_KeyFrame> _keyFrames; + + @override + double dx(double time) => 0; + + @override + bool isDone(double time) => time >= maxDuration; + + // The index of the KeyFrame corresponds to the most recent input `time`. + int _lastKeyFrameIndex = 0; + + @override + double x(double time) { + final int length = _keyFrames.length; + + // Perform a linear search in the sorted key frame list, starting from the + // last key frame found, since the input `time` usually monotonically + // increases by a small amount. + int searchIndex; + final int endIndex; + if (_keyFrames[_lastKeyFrameIndex].time > time) { + // The simulation may have restarted. Search within the index range + // [0, _lastKeyFrameIndex). + searchIndex = 0; + endIndex = _lastKeyFrameIndex; + } else { + searchIndex = _lastKeyFrameIndex; + endIndex = length; + } + + // Find the target key frame. Don't have to check (endIndex - 1): if + // (endIndex - 2) doesn't work we'll have to pick (endIndex - 1) anyways. + while (searchIndex < endIndex - 1) { + assert(_keyFrames[searchIndex].time <= time); + final _KeyFrame next = _keyFrames[searchIndex + 1]; + if (time < next.time) { + break; + } + searchIndex += 1; + } + + _lastKeyFrameIndex = searchIndex; + return _keyFrames[_lastKeyFrameIndex].value; + } +} + +/// [EditableText] +/// A basic text input field. +/// +/// This widget interacts with the [TextInput] service to let the user edit the +/// text it contains. It also provides scrolling, selection, and cursor +/// movement. +/// +/// The [EditableText] widget is a low-level widget that is intended as a +/// building block for custom widget sets. For a complete user experience, +/// consider using a [TextField] or [CupertinoTextField]. +/// +/// ## Handling User Input +/// +/// Currently the user may change the text this widget contains via keyboard or +/// the text selection menu. When the user inserted or deleted text, you will be +/// notified of the change and get a chance to modify the new text value: +/// +/// * The [inputFormatters] will be first applied to the user input. +/// +/// * The [controller]'s [TextEditingController.value] will be updated with the +/// formatted result, and the [controller]'s listeners will be notified. +/// +/// * The [onChanged] callback, if specified, will be called last. +/// +/// ## Input Actions +/// +/// A [TextInputAction] can be provided to customize the appearance of the +/// action button on the soft keyboard for Android and iOS. The default action +/// is [TextInputAction.done]. +/// +/// Many [TextInputAction]s are common between Android and iOS. However, if a +/// [textInputAction] is provided that is not supported by the current +/// platform in debug mode, an error will be thrown when the corresponding +/// EditableText receives focus. For example, providing iOS's "emergencyCall" +/// action when running on an Android device will result in an error when in +/// debug mode. In release mode, incompatible [TextInputAction]s are replaced +/// either with "unspecified" on Android, or "default" on iOS. Appropriate +/// [textInputAction]s can be chosen by checking the current platform and then +/// selecting the appropriate action. +/// +/// {@template flutter.widgets.EditableText.lifeCycle} +/// ## Lifecycle +/// +/// Upon completion of editing, like pressing the "done" button on the keyboard, +/// two actions take place: +/// +/// 1st: Editing is finalized. The default behavior of this step includes +/// an invocation of [onChanged]. That default behavior can be overridden. +/// See [onEditingComplete] for details. +/// +/// 2nd: [onSubmitted] is invoked with the user's input value. +/// +/// [onSubmitted] can be used to manually move focus to another input widget +/// when a user finishes with the currently focused input widget. +/// +/// When the widget has focus, it will prevent itself from disposing via +/// [AutomaticKeepAliveClientMixin.wantKeepAlive] in order to avoid losing the +/// selection. Removing the focus will allow it to be disposed. +/// {@endtemplate} +/// +/// Rather than using this widget directly, consider using [TextField], which +/// is a full-featured, material-design text input field with placeholder text, +/// labels, and [Form] integration. +/// +/// ## Text Editing [Intent]s and Their Default [Action]s +/// +/// This widget provides default [Action]s for handling common text editing +/// [Intent]s such as deleting, copying and pasting in the text field. These +/// [Action]s can be directly invoked using [Actions.invoke] or the +/// [Actions.maybeInvoke] method. The default text editing keyboard [Shortcuts], +/// typically declared in [DefaultTextEditingShortcuts], also use these +/// [Intent]s and [Action]s to perform the text editing operations they are +/// bound to. +/// +/// The default handling of a specific [Intent] can be overridden by placing an +/// [Actions] widget above this widget. See the [Action] class and the +/// [Action.overridable] constructor for more information on how a pre-defined +/// overridable [Action] can be overridden. +/// +/// ### Intents for Deleting Text and Their Default Behavior +/// +/// | **Intent Class** | **Default Behavior when there's selected text** | **Default Behavior when there is a [caret](https://en.wikipedia.org/wiki/Caret_navigation) (The selection is [TextSelection.collapsed])** | +/// | :------------------------------- | :--------------------------------------------------- | :----------------------------------------------------------------------- | +/// | [DeleteCharacterIntent] | Deletes the selected text | Deletes the user-perceived character before or after the caret location. | +/// | [DeleteToNextWordBoundaryIntent] | Deletes the selected text and the word before/after the selection's [TextSelection.extent] position | Deletes from the caret location to the previous or the next word boundary | +/// | [DeleteToLineBreakIntent] | Deletes the selected text, and deletes to the start/end of the line from the selection's [TextSelection.extent] position | Deletes from the caret location to the logical start or end of the current line | +/// +/// ### Intents for Moving the [Caret](https://en.wikipedia.org/wiki/Caret_navigation) +/// +/// | **Intent Class** | **Default Behavior when there's selected text** | **Default Behavior when there is a caret ([TextSelection.collapsed])** | +/// | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------- | :---------------------------------------------------------------------- | +/// | [ExtendSelectionByCharacterIntent](`collapseSelection: true`) | Collapses the selection to the logical start/end of the selection | Moves the caret past the user-perceived character before or after the current caret location. | +/// | [ExtendSelectionToNextWordBoundaryIntent](`collapseSelection: true`) | Collapses the selection to the word boundary before/after the selection's [TextSelection.extent] position | Moves the caret to the previous/next word boundary. | +/// | [ExtendSelectionToNextWordBoundaryOrCaretLocationIntent](`collapseSelection: true`) | Collapses the selection to the word boundary before/after the selection's [TextSelection.extent] position, or [TextSelection.base], whichever is closest in the given direction | Moves the caret to the previous/next word boundary. | +/// | [ExtendSelectionToLineBreakIntent](`collapseSelection: true`) | Collapses the selection to the start/end of the line at the selection's [TextSelection.extent] position | Moves the caret to the start/end of the current line .| +/// | [ExtendSelectionVerticallyToAdjacentLineIntent](`collapseSelection: true`) | Collapses the selection to the position closest to the selection's [TextSelection.extent], on the previous/next adjacent line | Moves the caret to the closest position on the previous/next adjacent line. | +/// | [ExtendSelectionVerticallyToAdjacentPageIntent](`collapseSelection: true`) | Collapses the selection to the position closest to the selection's [TextSelection.extent], on the previous/next adjacent page | Moves the caret to the closest position on the previous/next adjacent page. | +/// | [ExtendSelectionToDocumentBoundaryIntent](`collapseSelection: true`) | Collapses the selection to the start/end of the document | Moves the caret to the start/end of the document. | +/// +/// #### Intents for Extending the Selection +/// +/// | **Intent Class** | **Default Behavior when there's selected text** | **Default Behavior when there is a caret ([TextSelection.collapsed])** | +/// | :----------------------------------------------------------------------------------- | :--------------------------------------------------------------- | :---------------------------------------------------------------------- | +/// | [ExtendSelectionByCharacterIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] past the user-perceived character before/after it | +/// | [ExtendSelectionToNextWordBoundaryIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the previous/next word boundary | +/// | [ExtendSelectionToNextWordBoundaryOrCaretLocationIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the previous/next word boundary, or [TextSelection.base] whichever is closest in the given direction | Moves the selection's [TextSelection.extent] to the previous/next word boundary. | +/// | [ExtendSelectionToLineBreakIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the start/end of the line | +/// | [ExtendSelectionVerticallyToAdjacentLineIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the closest position on the previous/next adjacent line | +/// | [ExtendSelectionVerticallyToAdjacentPageIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the closest position on the previous/next adjacent page | +/// | [ExtendSelectionToDocumentBoundaryIntent](`collapseSelection: false`) | Moves the selection's [TextSelection.extent] to the start/end of the document | +/// | [SelectAllTextIntent] | Selects the entire document | +/// +/// ### Other Intents +/// +/// | **Intent Class** | **Default Behavior** | +/// | :-------------------------------------- | :--------------------------------------------------- | +/// | [DoNothingAndStopPropagationTextIntent] | Does nothing in the input field, and prevents the key event from further propagating in the widget tree. | +/// | [ReplaceTextIntent] | Replaces the current [TextEditingValue] in the input field's [TextEditingController], and triggers all related user callbacks and [TextInputFormatter]s. | +/// | [UpdateSelectionIntent] | Updates the current selection in the input field's [TextEditingController], and triggers the [onSelectionChanged] callback. | +/// | [CopySelectionTextIntent] | Copies or cuts the selected text into the clipboard | +/// | [PasteTextIntent] | Inserts the current text in the clipboard after the caret location, or replaces the selected text if the selection is not collapsed. | +/// +/// ## Text Editing [Shortcuts] +/// +/// It's also possible to directly remap keyboard shortcuts to new [Intent]s by +/// inserting a [Shortcuts] widget above this in the widget tree. When using +/// [WidgetsApp], the large set of default text editing keyboard shortcuts are +/// declared near the top of the widget tree in [DefaultTextEditingShortcuts], +/// and any [Shortcuts] widget between it and this [EditableText] will override +/// those defaults. +/// +/// {@template flutter.widgets.editableText.shortcutsAndTextInput} +/// ### Interactions Between [Shortcuts] and Text Input +/// +/// Shortcuts prevent text input fields from receiving their keystrokes as text +/// input. For example, placing a [Shortcuts] widget in the widget tree above +/// a text input field and creating a shortcut for [LogicalKeyboardKey.keyA] +/// will prevent the field from receiving that key as text input. In other +/// words, typing key "A" into the field will trigger the shortcut and will not +/// insert a letter "a" into the field. +/// +/// This happens because of the way that key strokes are handled in Flutter. +/// When a keystroke is received in Flutter's engine, it first gives the +/// framework the opportunity to handle it as a raw key event through +/// [SystemChannels.keyEvent]. This is what [Shortcuts] listens to indirectly +/// through its [FocusNode]. If it is not handled, then it will proceed to try +/// handling it as text input through [SystemChannels.textInput], which is what +/// [EditableTextState] listens to through [TextInputClient]. +/// +/// This behavior, where a shortcut prevents text input into some field, can be +/// overridden by using another [Shortcuts] widget lower in the widget tree and +/// mapping the desired key stroke(s) to [DoNothingAndStopPropagationIntent]. +/// The key event will be reported as unhandled by the framework and will then +/// be sent as text input as usual. +/// {@endtemplate} +/// +/// ## Gesture Events Handling +/// +/// When [rendererIgnoresPointer] is false (the default), this widget provides +/// rudimentary, platform-agnostic gesture handling for user actions such as +/// tapping, long-pressing, and scrolling. +/// +/// To provide more complete gesture handling, including double-click to select +/// a word, drag selection, and platform-specific handling of gestures such as +/// long presses, consider setting [rendererIgnoresPointer] to true and using +/// [TextSelectionGestureDetectorBuilder]. +/// +/// {@template flutter.widgets.editableText.showCaretOnScreen} +/// ## Keep the caret visible when focused +/// +/// When focused, this widget will make attempts to keep the text area and its +/// caret (even when [showCursor] is `false`) visible, on these occasions: +/// +/// * When the user focuses this text field and it is not [readOnly]. +/// * When the user changes the selection of the text field, or changes the +/// text when the text field is not [readOnly]. +/// * When the virtual keyboard pops up. +/// {@endtemplate} +/// +/// ## Scrolling Considerations +/// +/// If this [EditableText] is not a descendant of [Scaffold] and is being used +/// within a [Scrollable] or nested [Scrollable]s, consider placing a +/// [ScrollNotificationObserver] above the root [Scrollable] that contains this +/// [EditableText] to ensure proper scroll coordination for [EditableText] and +/// its components like [TextSelectionOverlay]. +/// +/// {@template flutter.widgets.editableText.accessibility} +/// ## Troubleshooting Common Accessibility Issues +/// +/// ### Customizing User Input Accessibility Announcements +/// +/// To customize user input accessibility announcements triggered by text +/// changes, use [SemanticsService.announce] to make the desired +/// accessibility announcement. +/// +/// On iOS, the on-screen keyboard may announce the most recent input +/// incorrectly when a [TextInputFormatter] inserts a thousands separator to +/// a currency value text field. The following example demonstrates how to +/// suppress the default accessibility announcements by always announcing +/// the content of the text field as a US currency value (the `\$` inserts +/// a dollar sign, the `$newText` interpolates the `newText` variable): +/// +/// ```dart +/// onChanged: (String newText) { +/// if (newText.isNotEmpty) { +/// SemanticsService.announce('\$$newText', Directionality.of(context)); +/// } +/// } +/// ``` +/// +/// {@endtemplate} +/// +/// See also: +/// +/// * [TextField], which is a full-featured, material-design text input field +/// with placeholder text, labels, and [Form] integration. +class _EditableText extends StatefulWidget { + /// Creates a basic text input control. + /// + /// The [maxLines] property can be set to null to remove the restriction on + /// the number of lines. By default, it is one, meaning this is a single-line + /// text field. [maxLines] must be null or greater than zero. + /// + /// If [keyboardType] is not set or is null, its value will be inferred from + /// [autofillHints], if [autofillHints] is not empty. Otherwise it defaults to + /// [TextInputType.text] if [maxLines] is exactly one, and + /// [TextInputType.multiline] if [maxLines] is null or greater than one. + /// + /// The text cursor is not shown if [showCursor] is false or if [showCursor] + /// is null (the default) and [readOnly] is true. + _EditableText({ + super.key, + required this.controller, + required this.focusNode, + this.readOnly = false, + this.obscuringCharacter = '•', + this.obscureText = false, + this.autocorrect = true, + SmartDashesType? smartDashesType, + SmartQuotesType? smartQuotesType, + this.enableSuggestions = true, + required this.style, + StrutStyle? strutStyle, + required this.cursorColor, + required this.backgroundCursorColor, + this.textAlign = TextAlign.start, + this.textDirection, + this.locale, + this.textScaler, + this.maxLines = 1, + this.minLines, + this.expands = false, + this.forceLine = true, + this.textHeightBehavior, + this.textWidthBasis = TextWidthBasis.parent, + this.autofocus = false, + bool? showCursor, + this.showSelectionHandles = false, + this.selectionColor, + this.selectionControls, + TextInputType? keyboardType, + this.textInputAction, + this.textCapitalization = TextCapitalization.none, + this.onChanged, + this.onEditingComplete, + this.onSubmitted, + this.onAppPrivateCommand, + this.onSelectionChanged, + this.onSelectionHandleTapped, + this.groupId = EditableText, + this.onTapOutside, + List? inputFormatters, + this.mouseCursor, + this.rendererIgnoresPointer = false, + this.cursorWidth = 2.0, + this.cursorHeight, + this.cursorRadius, + this.cursorOpacityAnimates = false, + this.cursorOffset, + this.paintCursorAboveText = false, + this.selectionHeightStyle = ui.BoxHeightStyle.tight, + this.selectionWidthStyle = ui.BoxWidthStyle.tight, + this.scrollPadding = const EdgeInsets.all(20.0), + this.keyboardAppearance = Brightness.light, + this.dragStartBehavior = DragStartBehavior.start, + bool? enableInteractiveSelection, + this.scrollController, + this.scrollPhysics, + this.autocorrectionTextRectColor, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + ToolbarOptions? toolbarOptions, + this.autofillHints = const [], + this.autofillClient, + this.clipBehavior = Clip.hardEdge, + this.restorationId, + this.scrollBehavior, + this.scribbleEnabled = true, + this.enableIMEPersonalizedLearning = true, + this.contentInsertionConfiguration, + this.contextMenuBuilder, + this.spellCheckConfiguration, + this.magnifierConfiguration = TextMagnifierConfiguration.disabled, + this.undoController, + }) : assert(obscuringCharacter.length == 1), + smartDashesType = smartDashesType ?? + (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled), + smartQuotesType = smartQuotesType ?? + (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + assert( + !expands || (maxLines == null && minLines == null), + 'minLines and maxLines must be null when expands is true.', + ), + assert(!obscureText || maxLines == 1, + 'Obscured fields cannot be multiline.'), + enableInteractiveSelection = + enableInteractiveSelection ?? (!readOnly || !obscureText), + toolbarOptions = selectionControls is TextSelectionHandleControls && + toolbarOptions == null + ? ToolbarOptions.empty + : toolbarOptions ?? + (obscureText + ? (readOnly + // No point in even offering "Select All" in a read-only obscured + // field. + ? ToolbarOptions.empty + // Writable, but obscured. + : const ToolbarOptions( + selectAll: true, + paste: true, + )) + : (readOnly + // Read-only, not obscured. + ? const ToolbarOptions( + selectAll: true, + copy: true, + ) + // Writable, not obscured. + : const ToolbarOptions( + copy: true, + cut: true, + selectAll: true, + paste: true, + ))), + assert( + spellCheckConfiguration == null || + spellCheckConfiguration == + // zmtzawqlp + const _SpellCheckConfiguration.disabled() || + spellCheckConfiguration.misspelledTextStyle != null, + 'spellCheckConfiguration must specify a misspelledTextStyle if spell check behavior is desired', + ), + _strutStyle = strutStyle, + keyboardType = keyboardType ?? + _inferKeyboardType( + autofillHints: autofillHints, maxLines: maxLines), + inputFormatters = maxLines == 1 + ? [ + FilteringTextInputFormatter.singleLineFormatter, + ...inputFormatters ?? + const Iterable.empty(), + ] + : inputFormatters, + showCursor = showCursor ?? !readOnly; + + /// Controls the text being edited. + final TextEditingController controller; + + /// Controls whether this widget has keyboard focus. + final FocusNode focusNode; + + /// {@template flutter.widgets.editableText.obscuringCharacter} + /// Character used for obscuring text if [obscureText] is true. + /// + /// Must be only a single character. + /// + /// Defaults to the character U+2022 BULLET (•). + /// {@endtemplate} + final String obscuringCharacter; + + /// {@template flutter.widgets.editableText.obscureText} + /// Whether to hide the text being edited (e.g., for passwords). + /// + /// When this is set to true, all the characters in the text field are + /// replaced by [obscuringCharacter], and the text in the field cannot be + /// copied with copy or cut. If [readOnly] is also true, then the text cannot + /// be selected. + /// + /// Defaults to false. + /// {@endtemplate} + final bool obscureText; + + /// {@macro dart.ui.textHeightBehavior} + final TextHeightBehavior? textHeightBehavior; + + /// {@macro flutter.painting.textPainter.textWidthBasis} + final TextWidthBasis textWidthBasis; + + /// {@template flutter.widgets.editableText.readOnly} + /// Whether the text can be changed. + /// + /// When this is set to true, the text cannot be modified + /// by any shortcut or keyboard operation. The text is still selectable. + /// + /// Defaults to false. + /// {@endtemplate} + final bool readOnly; + + /// Whether the text will take the full width regardless of the text width. + /// + /// When this is set to false, the width will be based on text width, which + /// will also be affected by [textWidthBasis]. + /// + /// Defaults to true. + /// + /// See also: + /// + /// * [textWidthBasis], which controls the calculation of text width. + final bool forceLine; + + /// Configuration of toolbar options. + /// + /// By default, all options are enabled. If [readOnly] is true, paste and cut + /// will be disabled regardless. If [obscureText] is true, cut and copy will + /// be disabled regardless. If [readOnly] and [obscureText] are both true, + /// select all will also be disabled. + final ToolbarOptions toolbarOptions; + + /// Whether to show selection handles. + /// + /// When a selection is active, there will be two handles at each side of + /// boundary, or one handle if the selection is collapsed. The handles can be + /// dragged to adjust the selection. + /// + /// See also: + /// + /// * [showCursor], which controls the visibility of the cursor. + final bool showSelectionHandles; + + /// {@template flutter.widgets.editableText.showCursor} + /// Whether to show cursor. + /// + /// The cursor refers to the blinking caret when the [EditableText] is focused. + /// {@endtemplate} + /// + /// See also: + /// + /// * [showSelectionHandles], which controls the visibility of the selection handles. + final bool showCursor; + + /// {@template flutter.widgets.editableText.autocorrect} + /// Whether to enable autocorrection. + /// + /// Defaults to true. + /// {@endtemplate} + final bool autocorrect; + + /// {@macro flutter.services.TextInputConfiguration.smartDashesType} + final SmartDashesType smartDashesType; + + /// {@macro flutter.services.TextInputConfiguration.smartQuotesType} + final SmartQuotesType smartQuotesType; + + /// {@macro flutter.services.TextInputConfiguration.enableSuggestions} + final bool enableSuggestions; + + /// The text style to use for the editable text. + final TextStyle style; + + /// Controls the undo state of the current editable text. + /// + /// If null, this widget will create its own [UndoHistoryController]. + final UndoHistoryController? undoController; + + /// {@template flutter.widgets.editableText.strutStyle} + /// The strut style used for the vertical layout. + /// + /// [StrutStyle] is used to establish a predictable vertical layout. + /// Since fonts may vary depending on user input and due to font + /// fallback, [StrutStyle.forceStrutHeight] is enabled by default + /// to lock all lines to the height of the base [TextStyle], provided by + /// [style]. This ensures the typed text fits within the allotted space. + /// + /// If null, the strut used will inherit values from the [style] and will + /// have [StrutStyle.forceStrutHeight] set to true. When no [style] is + /// passed, the theme's [TextStyle] will be used to generate [strutStyle] + /// instead. + /// + /// To disable strut-based vertical alignment and allow dynamic vertical + /// layout based on the glyphs typed, use [StrutStyle.disabled]. + /// + /// Flutter's strut is based on [typesetting strut](https://en.wikipedia.org/wiki/Strut_(typesetting)) + /// and CSS's [line-height](https://www.w3.org/TR/CSS2/visudet.html#line-height). + /// {@endtemplate} + /// + /// Within editable text and text fields, [StrutStyle] will not use its standalone + /// default values, and will instead inherit omitted/null properties from the + /// [TextStyle] instead. See [StrutStyle.inheritFromTextStyle]. + StrutStyle get strutStyle { + if (_strutStyle == null) { + return StrutStyle.fromTextStyle(style, forceStrutHeight: true); + } + return _strutStyle.inheritFromTextStyle(style); + } + + final StrutStyle? _strutStyle; + + /// {@template flutter.widgets.editableText.textAlign} + /// How the text should be aligned horizontally. + /// + /// Defaults to [TextAlign.start]. + /// {@endtemplate} + final TextAlign textAlign; + + /// {@template flutter.widgets.editableText.textDirection} + /// The directionality of the text. + /// + /// This decides how [textAlign] values like [TextAlign.start] and + /// [TextAlign.end] are interpreted. + /// + /// This is also used to disambiguate how to render bidirectional text. For + /// example, if the text is an English phrase followed by a Hebrew phrase, + /// in a [TextDirection.ltr] context the English phrase will be on the left + /// and the Hebrew phrase to its right, while in a [TextDirection.rtl] + /// context, the English phrase will be on the right and the Hebrew phrase on + /// its left. + /// + /// Defaults to the ambient [Directionality], if any. + /// {@endtemplate} + final TextDirection? textDirection; + + /// {@template flutter.widgets.editableText.textCapitalization} + /// Configures how the platform keyboard will select an uppercase or + /// lowercase keyboard. + /// + /// Only supports text keyboards, other keyboard types will ignore this + /// configuration. Capitalization is locale-aware. + /// + /// Defaults to [TextCapitalization.none]. + /// + /// See also: + /// + /// * [TextCapitalization], for a description of each capitalization behavior. + /// + /// {@endtemplate} + final TextCapitalization textCapitalization; + + /// Used to select a font when the same Unicode character can + /// be rendered differently, depending on the locale. + /// + /// It's rarely necessary to set this property. By default its value + /// is inherited from the enclosing app with `Localizations.localeOf(context)`. + /// + /// See [RenderEditable.locale] for more information. + final Locale? locale; + + /// {@template flutter.widgets.editableText.textScaleFactor} + /// The number of font pixels for each logical pixel. + /// + /// For example, if the text scale factor is 1.5, text will be 50% larger than + /// the specified font size. + /// + /// Defaults to the [MediaQueryData.textScaleFactor] obtained from the ambient + /// [MediaQuery], or 1.0 if there is no [MediaQuery] in scope. + /// {@endtemplate} + + /// {@macro flutter.painting.textPainter.textScaler} + final TextScaler? textScaler; + + /// The color to use when painting the cursor. + final Color cursorColor; + + /// The color to use when painting the autocorrection Rect. + /// + /// For [CupertinoTextField]s, the value is set to the ambient + /// [CupertinoThemeData.primaryColor] with 20% opacity. For [TextField]s, the + /// value is null on non-iOS platforms and the same color used in [CupertinoTextField] + /// on iOS. + /// + /// Currently the autocorrection Rect only appears on iOS. + /// + /// Defaults to null, which disables autocorrection Rect painting. + final Color? autocorrectionTextRectColor; + + /// The color to use when painting the background cursor aligned with the text + /// while rendering the floating cursor. + /// + /// Typically this would be set to [CupertinoColors.inactiveGray]. + /// + /// See also: + /// + /// * [FloatingCursorDragState], which explains the floating cursor feature + /// in detail. + final Color backgroundCursorColor; + + /// {@template flutter.widgets.editableText.maxLines} + /// The maximum number of lines to show at one time, wrapping if necessary. + /// + /// This affects the height of the field itself and does not limit the number + /// of lines that can be entered into the field. + /// + /// If this is 1 (the default), the text will not wrap, but will scroll + /// horizontally instead. + /// + /// If this is null, there is no limit to the number of lines, and the text + /// container will start with enough vertical space for one line and + /// automatically grow to accommodate additional lines as they are entered, up + /// to the height of its constraints. + /// + /// If this is not null, the value must be greater than zero, and it will lock + /// the input to the given number of lines and take up enough horizontal space + /// to accommodate that number of lines. Setting [minLines] as well allows the + /// input to grow and shrink between the indicated range. + /// + /// The full set of behaviors possible with [minLines] and [maxLines] are as + /// follows. These examples apply equally to [TextField], [TextFormField], + /// [CupertinoTextField], and [EditableText]. + /// + /// Input that occupies a single line and scrolls horizontally as needed. + /// ```dart + /// const TextField() + /// ``` + /// + /// Input whose height grows from one line up to as many lines as needed for + /// the text that was entered. If a height limit is imposed by its parent, it + /// will scroll vertically when its height reaches that limit. + /// ```dart + /// const TextField(maxLines: null) + /// ``` + /// + /// The input's height is large enough for the given number of lines. If + /// additional lines are entered the input scrolls vertically. + /// ```dart + /// const TextField(maxLines: 2) + /// ``` + /// + /// Input whose height grows with content between a min and max. An infinite + /// max is possible with `maxLines: null`. + /// ```dart + /// const TextField(minLines: 2, maxLines: 4) + /// ``` + /// + /// See also: + /// + /// * [minLines], which sets the minimum number of lines visible. + /// {@endtemplate} + /// * [expands], which determines whether the field should fill the height of + /// its parent. + final int? maxLines; + + /// {@template flutter.widgets.editableText.minLines} + /// The minimum number of lines to occupy when the content spans fewer lines. + /// + /// This affects the height of the field itself and does not limit the number + /// of lines that can be entered into the field. + /// + /// If this is null (default), text container starts with enough vertical space + /// for one line and grows to accommodate additional lines as they are entered. + /// + /// This can be used in combination with [maxLines] for a varying set of behaviors. + /// + /// If the value is set, it must be greater than zero. If the value is greater + /// than 1, [maxLines] should also be set to either null or greater than + /// this value. + /// + /// When [maxLines] is set as well, the height will grow between the indicated + /// range of lines. When [maxLines] is null, it will grow as high as needed, + /// starting from [minLines]. + /// + /// A few examples of behaviors possible with [minLines] and [maxLines] are as follows. + /// These apply equally to [TextField], [TextFormField], [CupertinoTextField], + /// and [EditableText]. + /// + /// Input that always occupies at least 2 lines and has an infinite max. + /// Expands vertically as needed. + /// ```dart + /// TextField(minLines: 2) + /// ``` + /// + /// Input whose height starts from 2 lines and grows up to 4 lines at which + /// point the height limit is reached. If additional lines are entered it will + /// scroll vertically. + /// ```dart + /// const TextField(minLines:2, maxLines: 4) + /// ``` + /// + /// Defaults to null. + /// + /// See also: + /// + /// * [maxLines], which sets the maximum number of lines visible, and has + /// several examples of how minLines and maxLines interact to produce + /// various behaviors. + /// {@endtemplate} + /// * [expands], which determines whether the field should fill the height of + /// its parent. + final int? minLines; + + /// {@template flutter.widgets.editableText.expands} + /// Whether this widget's height will be sized to fill its parent. + /// + /// If set to true and wrapped in a parent widget like [Expanded] or + /// [SizedBox], the input will expand to fill the parent. + /// + /// [maxLines] and [minLines] must both be null when this is set to true, + /// otherwise an error is thrown. + /// + /// Defaults to false. + /// + /// See the examples in [maxLines] for the complete picture of how [maxLines], + /// [minLines], and [expands] interact to produce various behaviors. + /// + /// Input that matches the height of its parent: + /// ```dart + /// const Expanded( + /// child: TextField(maxLines: null, expands: true), + /// ) + /// ``` + /// {@endtemplate} + final bool expands; + + /// {@template flutter.widgets.editableText.autofocus} + /// Whether this text field should focus itself if nothing else is already + /// focused. + /// + /// If true, the keyboard will open as soon as this text field obtains focus. + /// Otherwise, the keyboard is only shown after the user taps the text field. + /// + /// Defaults to false. + /// {@endtemplate} + // See https://github.com/flutter/flutter/issues/7035 for the rationale for this + // keyboard behavior. + final bool autofocus; + + /// The color to use when painting the selection. + /// + /// If this property is null, this widget gets the selection color from the + /// [DefaultSelectionStyle]. + /// + /// For [CupertinoTextField]s, the value is set to the ambient + /// [CupertinoThemeData.primaryColor] with 20% opacity. For [TextField]s, the + /// value is set to the ambient [TextSelectionThemeData.selectionColor]. + final Color? selectionColor; + + /// {@template flutter.widgets.editableText.selectionControls} + /// Optional delegate for building the text selection handles. + /// + /// Historically, this field also controlled the toolbar. This is now handled + /// by [contextMenuBuilder] instead. However, for backwards compatibility, when + /// [selectionControls] is set to an object that does not mix in + /// [TextSelectionHandleControls], [contextMenuBuilder] is ignored and the + /// [TextSelectionControls.buildToolbar] method is used instead. + /// {@endtemplate} + /// + /// See also: + /// + /// * [CupertinoTextField], which wraps an [EditableText] and which shows the + /// selection toolbar upon user events that are appropriate on the iOS + /// platform. + /// * [TextField], a Material Design themed wrapper of [EditableText], which + /// shows the selection toolbar upon appropriate user events based on the + /// user's platform set in [ThemeData.platform]. + final TextSelectionControls? selectionControls; + + /// {@template flutter.widgets.editableText.keyboardType} + /// The type of keyboard to use for editing the text. + /// + /// Defaults to [TextInputType.text] if [maxLines] is one and + /// [TextInputType.multiline] otherwise. + /// {@endtemplate} + final TextInputType keyboardType; + + /// The type of action button to use with the soft keyboard. + final TextInputAction? textInputAction; + + /// {@template flutter.widgets.editableText.onChanged} + /// Called when the user initiates a change to the TextField's + /// value: when they have inserted or deleted text. + /// + /// This callback doesn't run when the TextField's text is changed + /// programmatically, via the TextField's [controller]. Typically it + /// isn't necessary to be notified of such changes, since they're + /// initiated by the app itself. + /// + /// To be notified of all changes to the TextField's text, cursor, + /// and selection, one can add a listener to its [controller] with + /// [TextEditingController.addListener]. + /// + /// [onChanged] is called before [onSubmitted] when user indicates completion + /// of editing, such as when pressing the "done" button on the keyboard. That + /// default behavior can be overridden. See [onEditingComplete] for details. + /// + /// {@tool dartpad} + /// This example shows how onChanged could be used to check the TextField's + /// current value each time the user inserts or deletes a character. + /// + /// ** See code in examples/api/lib/widgets/editable_text/editable_text.on_changed.0.dart ** + /// {@end-tool} + /// {@endtemplate} + /// + /// ## Handling emojis and other complex characters + /// {@template flutter.widgets.EditableText.onChanged} + /// It's important to always use + /// [characters](https://pub.dev/packages/characters) when dealing with user + /// input text that may contain complex characters. This will ensure that + /// extended grapheme clusters and surrogate pairs are treated as single + /// characters, as they appear to the user. + /// + /// For example, when finding the length of some user input, use + /// `string.characters.length`. Do NOT use `string.length` or even + /// `string.runes.length`. For the complex character "👨‍👩‍👦", this + /// appears to the user as a single character, and `string.characters.length` + /// intuitively returns 1. On the other hand, `string.length` returns 8, and + /// `string.runes.length` returns 5! + /// {@endtemplate} + /// + /// See also: + /// + /// * [inputFormatters], which are called before [onChanged] + /// runs and can validate and change ("format") the input value. + /// * [onEditingComplete], [onSubmitted], [onSelectionChanged]: + /// which are more specialized input change notifications. + /// * [TextEditingController], which implements the [Listenable] interface + /// and notifies its listeners on [TextEditingValue] changes. + final ValueChanged? onChanged; + + /// {@template flutter.widgets.editableText.onEditingComplete} + /// Called when the user submits editable content (e.g., user presses the "done" + /// button on the keyboard). + /// + /// The default implementation of [onEditingComplete] executes 2 different + /// behaviors based on the situation: + /// + /// - When a completion action is pressed, such as "done", "go", "send", or + /// "search", the user's content is submitted to the [controller] and then + /// focus is given up. + /// + /// - When a non-completion action is pressed, such as "next" or "previous", + /// the user's content is submitted to the [controller], but focus is not + /// given up because developers may want to immediately move focus to + /// another input widget within [onSubmitted]. + /// + /// Providing [onEditingComplete] prevents the aforementioned default behavior. + /// {@endtemplate} + final VoidCallback? onEditingComplete; + + /// {@template flutter.widgets.editableText.onSubmitted} + /// Called when the user indicates that they are done editing the text in the + /// field. + /// + /// By default, [onSubmitted] is called after [onChanged] when the user + /// has finalized editing; or, if the default behavior has been overridden, + /// after [onEditingComplete]. See [onEditingComplete] for details. + /// + /// ## Testing + /// The following is the recommended way to trigger [onSubmitted] in a test: + /// + /// ```dart + /// await tester.testTextInput.receiveAction(TextInputAction.done); + /// ``` + /// + /// Sending a `LogicalKeyboardKey.enter` via `tester.sendKeyEvent` will not + /// trigger [onSubmitted]. This is because on a real device, the engine + /// translates the enter key to a done action, but `tester.sendKeyEvent` sends + /// the key to the framework only. + /// {@endtemplate} + final ValueChanged? onSubmitted; + + /// {@template flutter.widgets.editableText.onAppPrivateCommand} + /// This is used to receive a private command from the input method. + /// + /// Called when the result of [TextInputClient.performPrivateCommand] is + /// received. + /// + /// This can be used to provide domain-specific features that are only known + /// between certain input methods and their clients. + /// + /// See also: + /// * [performPrivateCommand](https://developer.android.com/reference/android/view/inputmethod/InputConnection#performPrivateCommand\(java.lang.String,%20android.os.Bundle\)), + /// which is the Android documentation for performPrivateCommand, used to + /// send a command from the input method. + /// * [sendAppPrivateCommand](https://developer.android.com/reference/android/view/inputmethod/InputMethodManager#sendAppPrivateCommand), + /// which is the Android documentation for sendAppPrivateCommand, used to + /// send a command to the input method. + /// {@endtemplate} + final AppPrivateCommandCallback? onAppPrivateCommand; + + /// {@template flutter.widgets.editableText.onSelectionChanged} + /// Called when the user changes the selection of text (including the cursor + /// location). + /// {@endtemplate} + final SelectionChangedCallback? onSelectionChanged; + + /// {@macro flutter.widgets.SelectionOverlay.onSelectionHandleTapped} + final VoidCallback? onSelectionHandleTapped; + + /// {@template flutter.widgets.editableText.groupId} + /// The group identifier for the [TextFieldTapRegion] of this text field. + /// + /// Text fields with the same group identifier share the same tap region. + /// Defaults to the type of [EditableText]. + /// + /// See also: + /// + /// * [TextFieldTapRegion], to give a [groupId] to a widget that is to be + /// included in a [EditableText]'s tap region that has [groupId] set. + /// {@endtemplate} + final Object groupId; + + /// {@template flutter.widgets.editableText.onTapOutside} + /// Called for each tap that occurs outside of the[TextFieldTapRegion] group + /// when the text field is focused. + /// + /// If this is null, [FocusNode.unfocus] will be called on the [focusNode] for + /// this text field when a [PointerDownEvent] is received on another part of + /// the UI. However, it will not unfocus as a result of mobile application + /// touch events (which does not include mouse clicks), to conform with the + /// platform conventions. To change this behavior, a callback may be set here + /// that operates differently from the default. + /// + /// When adding additional controls to a text field (for example, a spinner, a + /// button that copies the selected text, or modifies formatting), it is + /// helpful if tapping on that control doesn't unfocus the text field. In + /// order for an external widget to be considered as part of the text field + /// for the purposes of tapping "outside" of the field, wrap the control in a + /// [TextFieldTapRegion]. + /// + /// The [PointerDownEvent] passed to the function is the event that caused the + /// notification. It is possible that the event may occur outside of the + /// immediate bounding box defined by the text field, although it will be + /// within the bounding box of a [TextFieldTapRegion] member. + /// {@endtemplate} + /// + /// {@tool dartpad} + /// This example shows how to use a `TextFieldTapRegion` to wrap a set of + /// "spinner" buttons that increment and decrement a value in the [TextField] + /// without causing the text field to lose keyboard focus. + /// + /// This example includes a generic `SpinnerField` class that you can copy + /// into your own project and customize. + /// + /// ** See code in examples/api/lib/widgets/tap_region/text_field_tap_region.0.dart ** + /// {@end-tool} + /// + /// See also: + /// + /// * [TapRegion] for how the region group is determined. + final TapRegionCallback? onTapOutside; + + /// {@template flutter.widgets.editableText.inputFormatters} + /// Optional input validation and formatting overrides. + /// + /// Formatters are run in the provided order when the user changes the text + /// this widget contains. When this parameter changes, the new formatters will + /// not be applied until the next time the user inserts or deletes text. + /// Similar to the [onChanged] callback, formatters don't run when the text is + /// changed programmatically via [controller]. + /// + /// See also: + /// + /// * [TextEditingController], which implements the [Listenable] interface + /// and notifies its listeners on [TextEditingValue] changes. + /// {@endtemplate} + final List? inputFormatters; + + /// The cursor for a mouse pointer when it enters or is hovering over the + /// widget. + /// + /// If this property is null, [SystemMouseCursors.text] will be used. + /// + /// The [mouseCursor] is the only property of [EditableText] that controls the + /// appearance of the mouse pointer. All other properties related to "cursor" + /// stands for the text cursor, which is usually a blinking vertical line at + /// the editing position. + final MouseCursor? mouseCursor; + + /// Whether the caller will provide gesture handling (true), or if the + /// [EditableText] is expected to handle basic gestures (false). + /// + /// When this is false, the [EditableText] (or more specifically, the + /// [RenderEditable]) enables some rudimentary gestures (tap to position the + /// cursor, long-press to select all, and some scrolling behavior). + /// + /// These behaviors are sufficient for debugging purposes but are inadequate + /// for user-facing applications. To enable platform-specific behaviors, use a + /// [TextSelectionGestureDetectorBuilder] to wrap the [EditableText], and set + /// [rendererIgnoresPointer] to true. + /// + /// When [rendererIgnoresPointer] is true true, the [RenderEditable] created + /// by this widget will not handle pointer events. + /// + /// This property is false by default. + /// + /// See also: + /// + /// * [RenderEditable.ignorePointer], which implements this feature. + /// * [TextSelectionGestureDetectorBuilder], which implements platform-specific + /// gestures and behaviors. + final bool rendererIgnoresPointer; + + /// {@template flutter.widgets.editableText.cursorWidth} + /// How thick the cursor will be. + /// + /// Defaults to 2.0. + /// + /// The cursor will draw under the text. The cursor width will extend + /// to the right of the boundary between characters for left-to-right text + /// and to the left for right-to-left text. This corresponds to extending + /// downstream relative to the selected position. Negative values may be used + /// to reverse this behavior. + /// {@endtemplate} + final double cursorWidth; + + /// {@template flutter.widgets.editableText.cursorHeight} + /// How tall the cursor will be. + /// + /// If this property is null, [RenderEditable.preferredLineHeight] will be used. + /// {@endtemplate} + final double? cursorHeight; + + /// {@template flutter.widgets.editableText.cursorRadius} + /// How rounded the corners of the cursor should be. + /// + /// By default, the cursor has no radius. + /// {@endtemplate} + final Radius? cursorRadius; + + /// {@template flutter.widgets.editableText.cursorOpacityAnimates} + /// Whether the cursor will animate from fully transparent to fully opaque + /// during each cursor blink. + /// + /// By default, the cursor opacity will animate on iOS platforms and will not + /// animate on Android platforms. + /// {@endtemplate} + final bool cursorOpacityAnimates; + + ///{@macro flutter.rendering.RenderEditable.cursorOffset} + final Offset? cursorOffset; + + ///{@macro flutter.rendering.RenderEditable.paintCursorAboveText} + final bool paintCursorAboveText; + + /// Controls how tall the selection highlight boxes are computed to be. + /// + /// See [ui.BoxHeightStyle] for details on available styles. + final ui.BoxHeightStyle selectionHeightStyle; + + /// Controls how wide the selection highlight boxes are computed to be. + /// + /// See [ui.BoxWidthStyle] for details on available styles. + final ui.BoxWidthStyle selectionWidthStyle; + + /// The appearance of the keyboard. + /// + /// This setting is only honored on iOS devices. + /// + /// Defaults to [Brightness.light]. + final Brightness keyboardAppearance; + + /// {@template flutter.widgets.editableText.scrollPadding} + /// Configures padding to edges surrounding a [Scrollable] when the Textfield scrolls into view. + /// + /// When this widget receives focus and is not completely visible (for example scrolled partially + /// off the screen or overlapped by the keyboard) + /// then it will attempt to make itself visible by scrolling a surrounding [Scrollable], if one is present. + /// This value controls how far from the edges of a [Scrollable] the TextField will be positioned after the scroll. + /// + /// Defaults to EdgeInsets.all(20.0). + /// {@endtemplate} + final EdgeInsets scrollPadding; + + /// {@template flutter.widgets.editableText.enableInteractiveSelection} + /// Whether to enable user interface affordances for changing the + /// text selection. + /// + /// For example, setting this to true will enable features such as + /// long-pressing the TextField to select text and show the + /// cut/copy/paste menu, and tapping to move the text caret. + /// + /// When this is false, the text selection cannot be adjusted by + /// the user, text cannot be copied, and the user cannot paste into + /// the text field from the clipboard. + /// + /// Defaults to true. + /// {@endtemplate} + final bool enableInteractiveSelection; + + /// Setting this property to true makes the cursor stop blinking or fading + /// on and off once the cursor appears on focus. This property is useful for + /// testing purposes. + /// + /// It does not affect the necessity to focus the EditableText for the cursor + /// to appear in the first place. + /// + /// Defaults to false, resulting in a typical blinking cursor. + static bool debugDeterministicCursor = false; + + /// {@macro flutter.widgets.scrollable.dragStartBehavior} + final DragStartBehavior dragStartBehavior; + + /// {@template flutter.widgets.editableText.scrollController} + /// The [ScrollController] to use when vertically scrolling the input. + /// + /// If null, it will instantiate a new ScrollController. + /// + /// See [Scrollable.controller]. + /// {@endtemplate} + final ScrollController? scrollController; + + /// {@template flutter.widgets.editableText.scrollPhysics} + /// The [ScrollPhysics] to use when vertically scrolling the input. + /// + /// If not specified, it will behave according to the current platform. + /// + /// See [Scrollable.physics]. + /// {@endtemplate} + /// + /// If an explicit [ScrollBehavior] is provided to [scrollBehavior], the + /// [ScrollPhysics] provided by that behavior will take precedence after + /// [scrollPhysics]. + final ScrollPhysics? scrollPhysics; + + /// {@template flutter.widgets.editableText.scribbleEnabled} + /// Whether iOS 14 Scribble features are enabled for this widget. + /// + /// Only available on iPads. + /// + /// Defaults to true. + /// {@endtemplate} + final bool scribbleEnabled; + + /// {@template flutter.widgets.editableText.selectionEnabled} + /// Same as [enableInteractiveSelection]. + /// + /// This getter exists primarily for consistency with + /// [RenderEditable.selectionEnabled]. + /// {@endtemplate} + bool get selectionEnabled => enableInteractiveSelection; + + /// {@template flutter.widgets.editableText.autofillHints} + /// A list of strings that helps the autofill service identify the type of this + /// text input. + /// + /// When set to null, this text input will not send its autofill information + /// to the platform, preventing it from participating in autofills triggered + /// by a different [AutofillClient], even if they're in the same + /// [AutofillScope]. Additionally, on Android and web, setting this to null + /// will disable autofill for this text field. + /// + /// The minimum platform SDK version that supports Autofill is API level 26 + /// for Android, and iOS 10.0 for iOS. + /// + /// Defaults to an empty list. + /// + /// ### Setting up iOS autofill: + /// + /// To provide the best user experience and ensure your app fully supports + /// password autofill on iOS, follow these steps: + /// + /// * Set up your iOS app's + /// [associated domains](https://developer.apple.com/documentation/safariservices/supporting_associated_domains_in_your_app). + /// * Some autofill hints only work with specific [keyboardType]s. For example, + /// [AutofillHints.name] requires [TextInputType.name] and [AutofillHints.email] + /// works only with [TextInputType.emailAddress]. Make sure the input field has a + /// compatible [keyboardType]. Empirically, [TextInputType.name] works well + /// with many autofill hints that are predefined on iOS. + /// + /// ### Troubleshooting Autofill + /// + /// Autofill service providers rely heavily on [autofillHints]. Make sure the + /// entries in [autofillHints] are supported by the autofill service currently + /// in use (the name of the service can typically be found in your mobile + /// device's system settings). + /// + /// #### Autofill UI refuses to show up when I tap on the text field + /// + /// Check the device's system settings and make sure autofill is turned on, + /// and there are available credentials stored in the autofill service. + /// + /// * iOS password autofill: Go to Settings -> Password, turn on "Autofill + /// Passwords", and add new passwords for testing by pressing the top right + /// "+" button. Use an arbitrary "website" if you don't have associated + /// domains set up for your app. As long as there's at least one password + /// stored, you should be able to see a key-shaped icon in the quick type + /// bar on the software keyboard, when a password related field is focused. + /// + /// * iOS contact information autofill: iOS seems to pull contact info from + /// the Apple ID currently associated with the device. Go to Settings -> + /// Apple ID (usually the first entry, or "Sign in to your iPhone" if you + /// haven't set up one on the device), and fill out the relevant fields. If + /// you wish to test more contact info types, try adding them in Contacts -> + /// My Card. + /// + /// * Android autofill: Go to Settings -> System -> Languages & input -> + /// Autofill service. Enable the autofill service of your choice, and make + /// sure there are available credentials associated with your app. + /// + /// #### I called `TextInput.finishAutofillContext` but the autofill save + /// prompt isn't showing + /// + /// * iOS: iOS may not show a prompt or any other visual indication when it + /// saves user password. Go to Settings -> Password and check if your new + /// password is saved. Neither saving password nor auto-generating strong + /// password works without properly setting up associated domains in your + /// app. To set up associated domains, follow the instructions in + /// . + /// + /// {@endtemplate} + /// {@macro flutter.services.AutofillConfiguration.autofillHints} + final Iterable? autofillHints; + + /// The [AutofillClient] that controls this input field's autofill behavior. + /// + /// When null, this widget's [EditableTextState] will be used as the + /// [AutofillClient]. This property may override [autofillHints]. + final AutofillClient? autofillClient; + + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.hardEdge]. + final Clip clipBehavior; + + /// Restoration ID to save and restore the scroll offset of the + /// [EditableText]. + /// + /// If a restoration id is provided, the [EditableText] will persist its + /// current scroll offset and restore it during state restoration. + /// + /// The scroll offset is persisted in a [RestorationBucket] claimed from + /// the surrounding [RestorationScope] using the provided restoration ID. + /// + /// Persisting and restoring the content of the [EditableText] is the + /// responsibility of the owner of the [controller], who may use a + /// [RestorableTextEditingController] for that purpose. + /// + /// See also: + /// + /// * [RestorationManager], which explains how state restoration works in + /// Flutter. + final String? restorationId; + + /// {@template flutter.widgets.shadow.scrollBehavior} + /// A [ScrollBehavior] that will be applied to this widget individually. + /// + /// Defaults to null, wherein the inherited [ScrollBehavior] is copied and + /// modified to alter the viewport decoration, like [Scrollbar]s. + /// {@endtemplate} + /// + /// [ScrollBehavior]s also provide [ScrollPhysics]. If an explicit + /// [ScrollPhysics] is provided in [scrollPhysics], it will take precedence, + /// followed by [scrollBehavior], and then the inherited ancestor + /// [ScrollBehavior]. + /// + /// The [ScrollBehavior] of the inherited [ScrollConfiguration] will be + /// modified by default to only apply a [Scrollbar] if [maxLines] is greater + /// than 1. + final ScrollBehavior? scrollBehavior; + + /// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning} + final bool enableIMEPersonalizedLearning; + + /// {@template flutter.widgets.editableText.contentInsertionConfiguration} + /// Configuration of handler for media content inserted via the system input + /// method. + /// + /// Defaults to null in which case media content insertion will be disabled, + /// and the system will display a message informing the user that the text field + /// does not support inserting media content. + /// + /// Set [ContentInsertionConfiguration.onContentInserted] to provide a handler. + /// Additionally, set [ContentInsertionConfiguration.allowedMimeTypes] + /// to limit the allowable mime types for inserted content. + /// + /// {@tool dartpad} + /// + /// This example shows how to access the data for inserted content in your + /// `TextField`. + /// + /// ** See code in examples/api/lib/widgets/editable_text/editable_text.on_content_inserted.0.dart ** + /// {@end-tool} + /// + /// If [contentInsertionConfiguration] is not provided, by default + /// an empty list of mime types will be sent to the Flutter Engine. + /// A handler function must be provided in order to customize the allowable + /// mime types for inserted content. + /// + /// If rich content is inserted without a handler, the system will display + /// a message informing the user that the current text input does not support + /// inserting rich content. + /// {@endtemplate} + final ContentInsertionConfiguration? contentInsertionConfiguration; + + /// {@template flutter.widgets.EditableText.contextMenuBuilder} + /// Builds the text selection toolbar when requested by the user. + /// + /// The context menu is built when [EditableTextState.showToolbar] is called, + /// typically by one of the callbacks installed by the widget created by + /// [TextSelectionGestureDetectorBuilder.buildGestureDetector]. The widget + /// returned by [contextMenuBuilder] is passed to a [ContextMenuController]. + /// + /// If no callback is provided, no context menu will be shown. + /// + /// The [EditableTextContextMenuBuilder] signature used by the + /// [contextMenuBuilder] callback has two parameters, the [BuildContext] of + /// the [EditableText] and the [EditableTextState] of the [EditableText]. + /// + /// The [EditableTextState] has two properties that are especially useful when + /// building the widgets for the context menu: + /// + /// * [EditableTextState.contextMenuAnchors] specifies the desired anchor + /// position for the context menu. + /// + /// * [EditableTextState.contextMenuButtonItems] represents the buttons that + /// should typically be built for this widget (e.g. cut, copy, paste). + /// + /// The [TextSelectionToolbarLayoutDelegate] class may be particularly useful + /// in honoring the preferred anchor positions. + /// + /// For backwards compatibility, when [selectionControls] is set to an object + /// that does not mix in [TextSelectionHandleControls], [contextMenuBuilder] + /// is ignored and the [TextSelectionControls.buildToolbar] method is used + /// instead. + /// + /// {@tool dartpad} + /// This example shows how to customize the menu, in this case by keeping the + /// default buttons for the platform but modifying their appearance. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.0.dart ** + /// {@end-tool} + /// + /// {@tool dartpad} + /// This example shows how to show a custom button only when an email address + /// is currently selected. + /// + /// ** See code in examples/api/lib/material/context_menu/editable_text_toolbar_builder.1.dart ** + /// {@end-tool} + /// + /// See also: + /// * [AdaptiveTextSelectionToolbar], which builds the default text selection + /// toolbar for the current platform, but allows customization of the + /// buttons. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given + /// [ContextMenuButtonItem]s. + /// * [BrowserContextMenu], which allows the browser's context menu on web + /// to be disabled and Flutter-rendered context menus to appear. + /// {@endtemplate} + final EditableTextContextMenuBuilder? contextMenuBuilder; + + /// {@template flutter.widgets.EditableText.spellCheckConfiguration} + /// Configuration that details how spell check should be performed. + /// + /// Specifies the [SpellCheckService] used to spell check text input and the + /// [TextStyle] used to style text with misspelled words. + /// + /// If the [SpellCheckService] is left null, spell check is disabled by + /// default unless the [DefaultSpellCheckService] is supported, in which case + /// it is used. It is currently supported only on Android and iOS. + /// + /// If this configuration is left null, then spell check is disabled by default. + /// {@endtemplate} + // zmtzawqlp + final _SpellCheckConfiguration? spellCheckConfiguration; + + /// The configuration for the magnifier to use with selections in this text + /// field. + /// + /// {@macro flutter.widgets.magnifier.intro} + final TextMagnifierConfiguration magnifierConfiguration; + + bool get _userSelectionEnabled => + enableInteractiveSelection && (!readOnly || !obscureText); + + /// Returns the [ContextMenuButtonItem]s representing the buttons in this + /// platform's default selection menu for an editable field. + /// + /// For example, [EditableText] uses this to generate the default buttons for + /// its context menu. + /// + /// See also: + /// + /// * [EditableTextState.contextMenuButtonItems], which gives the + /// [ContextMenuButtonItem]s for a specific EditableText. + /// * [SelectableRegion.getSelectableButtonItems], which performs a similar + /// role but for content that is selectable but not editable. + /// * [AdaptiveTextSelectionToolbar], which builds the toolbar itself, and can + /// take a list of [ContextMenuButtonItem]s with + /// [AdaptiveTextSelectionToolbar.buttonItems]. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the button + /// Widgets for the current platform given [ContextMenuButtonItem]s. + static List getEditableButtonItems({ + required final ClipboardStatus? clipboardStatus, + required final VoidCallback? onCopy, + required final VoidCallback? onCut, + required final VoidCallback? onPaste, + required final VoidCallback? onSelectAll, + required final VoidCallback? onLookUp, + required final VoidCallback? onSearchWeb, + required final VoidCallback? onShare, + required final VoidCallback? onLiveTextInput, + }) { + final List resultButtonItem = + []; + + // Configure button items with clipboard. + if (onPaste == null || clipboardStatus != ClipboardStatus.unknown) { + // If the paste button is enabled, don't render anything until the state + // of the clipboard is known, since it's used to determine if paste is + // shown. + + // On Android, the share button is before the select all button. + final bool showShareBeforeSelectAll = + defaultTargetPlatform == TargetPlatform.android; + + resultButtonItem.addAll([ + if (onCut != null) + ContextMenuButtonItem( + onPressed: onCut, + type: ContextMenuButtonType.cut, + ), + if (onCopy != null) + ContextMenuButtonItem( + onPressed: onCopy, + type: ContextMenuButtonType.copy, + ), + if (onPaste != null) + ContextMenuButtonItem( + onPressed: onPaste, + type: ContextMenuButtonType.paste, + ), + if (onShare != null && showShareBeforeSelectAll) + ContextMenuButtonItem( + onPressed: onShare, + type: ContextMenuButtonType.share, + ), + if (onSelectAll != null) + ContextMenuButtonItem( + onPressed: onSelectAll, + type: ContextMenuButtonType.selectAll, + ), + if (onLookUp != null) + ContextMenuButtonItem( + onPressed: onLookUp, + type: ContextMenuButtonType.lookUp, + ), + if (onSearchWeb != null) + ContextMenuButtonItem( + onPressed: onSearchWeb, + type: ContextMenuButtonType.searchWeb, + ), + if (onShare != null && !showShareBeforeSelectAll) + ContextMenuButtonItem( + onPressed: onShare, + type: ContextMenuButtonType.share, + ), + ]); + } + + // Config button items with Live Text. + if (onLiveTextInput != null) { + resultButtonItem.add(ContextMenuButtonItem( + onPressed: onLiveTextInput, + type: ContextMenuButtonType.liveTextInput, + )); + } + + return resultButtonItem; + } + + // Infer the keyboard type of an `EditableText` if it's not specified. + static TextInputType _inferKeyboardType({ + required Iterable? autofillHints, + required int? maxLines, + }) { + if (autofillHints == null || autofillHints.isEmpty) { + return maxLines == 1 ? TextInputType.text : TextInputType.multiline; + } + + final String effectiveHint = autofillHints.first; + + // On iOS oftentimes specifying a text content type is not enough to qualify + // the input field for autofill. The keyboard type also needs to be compatible + // with the content type. To get autofill to work by default on EditableText, + // the keyboard type inference on iOS is done differently from other platforms. + // + // The entries with "autofill not working" comments are the iOS text content + // types that should work with the specified keyboard type but won't trigger + // (even within a native app). Tested on iOS 13.5. + if (!kIsWeb) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + const Map iOSKeyboardType = + { + AutofillHints.addressCity: TextInputType.name, + AutofillHints.addressCityAndState: + TextInputType.name, // Autofill not working. + AutofillHints.addressState: TextInputType.name, + AutofillHints.countryName: TextInputType.name, + AutofillHints.creditCardNumber: + TextInputType.number, // Couldn't test. + AutofillHints.email: TextInputType.emailAddress, + AutofillHints.familyName: TextInputType.name, + AutofillHints.fullStreetAddress: TextInputType.name, + AutofillHints.givenName: TextInputType.name, + AutofillHints.jobTitle: TextInputType.name, // Autofill not working. + AutofillHints.location: TextInputType.name, // Autofill not working. + AutofillHints.middleName: + TextInputType.name, // Autofill not working. + AutofillHints.name: TextInputType.name, + AutofillHints.namePrefix: + TextInputType.name, // Autofill not working. + AutofillHints.nameSuffix: + TextInputType.name, // Autofill not working. + AutofillHints.newPassword: TextInputType.text, + AutofillHints.newUsername: TextInputType.text, + AutofillHints.nickname: TextInputType.name, // Autofill not working. + AutofillHints.oneTimeCode: TextInputType.number, + AutofillHints.organizationName: + TextInputType.text, // Autofill not working. + AutofillHints.password: TextInputType.text, + AutofillHints.postalCode: TextInputType.name, + AutofillHints.streetAddressLine1: TextInputType.name, + AutofillHints.streetAddressLine2: + TextInputType.name, // Autofill not working. + AutofillHints.sublocality: + TextInputType.name, // Autofill not working. + AutofillHints.telephoneNumber: TextInputType.name, + AutofillHints.url: TextInputType.url, // Autofill not working. + AutofillHints.username: TextInputType.text, + }; + + final TextInputType? keyboardType = iOSKeyboardType[effectiveHint]; + if (keyboardType != null) { + return keyboardType; + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + break; + } + } + + if (maxLines != 1) { + return TextInputType.multiline; + } + + const Map inferKeyboardType = + { + AutofillHints.addressCity: TextInputType.streetAddress, + AutofillHints.addressCityAndState: TextInputType.streetAddress, + AutofillHints.addressState: TextInputType.streetAddress, + AutofillHints.birthday: TextInputType.datetime, + AutofillHints.birthdayDay: TextInputType.datetime, + AutofillHints.birthdayMonth: TextInputType.datetime, + AutofillHints.birthdayYear: TextInputType.datetime, + AutofillHints.countryCode: TextInputType.number, + AutofillHints.countryName: TextInputType.text, + AutofillHints.creditCardExpirationDate: TextInputType.datetime, + AutofillHints.creditCardExpirationDay: TextInputType.datetime, + AutofillHints.creditCardExpirationMonth: TextInputType.datetime, + AutofillHints.creditCardExpirationYear: TextInputType.datetime, + AutofillHints.creditCardFamilyName: TextInputType.name, + AutofillHints.creditCardGivenName: TextInputType.name, + AutofillHints.creditCardMiddleName: TextInputType.name, + AutofillHints.creditCardName: TextInputType.name, + AutofillHints.creditCardNumber: TextInputType.number, + AutofillHints.creditCardSecurityCode: TextInputType.number, + AutofillHints.creditCardType: TextInputType.text, + AutofillHints.email: TextInputType.emailAddress, + AutofillHints.familyName: TextInputType.name, + AutofillHints.fullStreetAddress: TextInputType.streetAddress, + AutofillHints.gender: TextInputType.text, + AutofillHints.givenName: TextInputType.name, + AutofillHints.impp: TextInputType.url, + AutofillHints.jobTitle: TextInputType.text, + AutofillHints.language: TextInputType.text, + AutofillHints.location: TextInputType.streetAddress, + AutofillHints.middleInitial: TextInputType.name, + AutofillHints.middleName: TextInputType.name, + AutofillHints.name: TextInputType.name, + AutofillHints.namePrefix: TextInputType.name, + AutofillHints.nameSuffix: TextInputType.name, + AutofillHints.newPassword: TextInputType.text, + AutofillHints.newUsername: TextInputType.text, + AutofillHints.nickname: TextInputType.text, + AutofillHints.oneTimeCode: TextInputType.text, + AutofillHints.organizationName: TextInputType.text, + AutofillHints.password: TextInputType.text, + AutofillHints.photo: TextInputType.text, + AutofillHints.postalAddress: TextInputType.streetAddress, + AutofillHints.postalAddressExtended: TextInputType.streetAddress, + AutofillHints.postalAddressExtendedPostalCode: TextInputType.number, + AutofillHints.postalCode: TextInputType.number, + AutofillHints.streetAddressLevel1: TextInputType.streetAddress, + AutofillHints.streetAddressLevel2: TextInputType.streetAddress, + AutofillHints.streetAddressLevel3: TextInputType.streetAddress, + AutofillHints.streetAddressLevel4: TextInputType.streetAddress, + AutofillHints.streetAddressLine1: TextInputType.streetAddress, + AutofillHints.streetAddressLine2: TextInputType.streetAddress, + AutofillHints.streetAddressLine3: TextInputType.streetAddress, + AutofillHints.sublocality: TextInputType.streetAddress, + AutofillHints.telephoneNumber: TextInputType.phone, + AutofillHints.telephoneNumberAreaCode: TextInputType.phone, + AutofillHints.telephoneNumberCountryCode: TextInputType.phone, + AutofillHints.telephoneNumberDevice: TextInputType.phone, + AutofillHints.telephoneNumberExtension: TextInputType.phone, + AutofillHints.telephoneNumberLocal: TextInputType.phone, + AutofillHints.telephoneNumberLocalPrefix: TextInputType.phone, + AutofillHints.telephoneNumberLocalSuffix: TextInputType.phone, + AutofillHints.telephoneNumberNational: TextInputType.phone, + AutofillHints.transactionAmount: + TextInputType.numberWithOptions(decimal: true), + AutofillHints.transactionCurrency: TextInputType.text, + AutofillHints.url: TextInputType.url, + AutofillHints.username: TextInputType.text, + }; + + return inferKeyboardType[effectiveHint] ?? TextInputType.text; + } + + @override + // zmtzawqlp + _EditableTextState createState() => _EditableTextState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add( + DiagnosticsProperty('controller', controller)); + properties.add(DiagnosticsProperty('focusNode', focusNode)); + properties.add(DiagnosticsProperty('obscureText', obscureText, + defaultValue: false)); + properties.add( + DiagnosticsProperty('readOnly', readOnly, defaultValue: false)); + properties.add(DiagnosticsProperty('autocorrect', autocorrect, + defaultValue: true)); + properties.add(EnumProperty( + 'smartDashesType', smartDashesType, + defaultValue: + obscureText ? SmartDashesType.disabled : SmartDashesType.enabled)); + properties.add(EnumProperty( + 'smartQuotesType', smartQuotesType, + defaultValue: + obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled)); + properties.add(DiagnosticsProperty( + 'enableSuggestions', enableSuggestions, + defaultValue: true)); + style.debugFillProperties(properties); + properties.add( + EnumProperty('textAlign', textAlign, defaultValue: null)); + properties.add(EnumProperty('textDirection', textDirection, + defaultValue: null)); + properties + .add(DiagnosticsProperty('locale', locale, defaultValue: null)); + properties.add(DiagnosticsProperty('textScaler', textScaler, + defaultValue: null)); + properties.add(IntProperty('maxLines', maxLines, defaultValue: 1)); + properties.add(IntProperty('minLines', minLines, defaultValue: null)); + properties.add( + DiagnosticsProperty('expands', expands, defaultValue: false)); + properties.add( + DiagnosticsProperty('autofocus', autofocus, defaultValue: false)); + properties.add(DiagnosticsProperty( + 'keyboardType', keyboardType, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollController', scrollController, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollPhysics', scrollPhysics, + defaultValue: null)); + properties.add(DiagnosticsProperty>( + 'autofillHints', autofillHints, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'textHeightBehavior', textHeightBehavior, + defaultValue: null)); + properties.add(DiagnosticsProperty('scribbleEnabled', scribbleEnabled, + defaultValue: true)); + properties.add(DiagnosticsProperty( + 'enableIMEPersonalizedLearning', enableIMEPersonalizedLearning, + defaultValue: true)); + properties.add(DiagnosticsProperty( + 'enableInteractiveSelection', enableInteractiveSelection, + defaultValue: true)); + properties.add(DiagnosticsProperty( + 'undoController', undoController, + defaultValue: null)); + properties.add(DiagnosticsProperty<_SpellCheckConfiguration>( + 'spellCheckConfiguration', spellCheckConfiguration, + defaultValue: null)); + properties.add(DiagnosticsProperty>('contentCommitMimeTypes', + contentInsertionConfiguration?.allowedMimeTypes ?? const [], + defaultValue: contentInsertionConfiguration == null + ? const [] + : kDefaultContentInsertionMimeTypes)); + } +} + +/// State for a [EditableText]. +/// zmtzawqlp +class _EditableTextState extends State<_EditableText> + with + AutomaticKeepAliveClientMixin<_EditableText>, + WidgetsBindingObserver, + TickerProviderStateMixin<_EditableText>, + TextSelectionDelegate, + TextInputClient + implements AutofillClient { + Timer? _cursorTimer; + AnimationController get _cursorBlinkOpacityController { + return _backingCursorBlinkOpacityController ??= AnimationController( + vsync: this, + )..addListener(_onCursorColorTick); + } + + AnimationController? _backingCursorBlinkOpacityController; + late final Simulation _iosBlinkCursorSimulation = + _DiscreteKeyFrameSimulation.iOSBlinkingCaret(); + + final ValueNotifier _cursorVisibilityNotifier = + ValueNotifier(true); + final GlobalKey _editableKey = GlobalKey(); + + /// Detects whether the clipboard can paste. + final ClipboardStatusNotifier clipboardStatus = kIsWeb + // Web browsers will show a permission dialog when Clipboard.hasStrings is + // called. In an EditableText, this will happen before the paste button is + // clicked, often before the context menu is even shown. To avoid this + // poor user experience, always show the paste button on web. + ? _WebClipboardStatusNotifier() + : ClipboardStatusNotifier(); + + /// Detects whether the Live Text input is enabled. + /// + /// See also: + /// * [LiveText], where the availability of Live Text input can be obtained. + final LiveTextInputStatusNotifier? _liveTextInputStatus = + kIsWeb ? null : LiveTextInputStatusNotifier(); + + TextInputConnection? _textInputConnection; + bool get _hasInputConnection => _textInputConnection?.attached ?? false; + + /// zmtzawqlp + _TextSelectionOverlay? _selectionOverlay; + ScrollNotificationObserverState? _scrollNotificationObserver; + ({ + TextEditingValue value, + Rect selectionBounds + })? _dataWhenToolbarShowScheduled; + bool _listeningToScrollNotificationObserver = false; + + bool get _webContextMenuEnabled => kIsWeb && BrowserContextMenu.enabled; + + final GlobalKey _scrollableKey = GlobalKey(); + ScrollController? _internalScrollController; + ScrollController get _scrollController => + widget.scrollController ?? + (_internalScrollController ??= ScrollController()); + + final LayerLink _toolbarLayerLink = LayerLink(); + final LayerLink _startHandleLayerLink = LayerLink(); + final LayerLink _endHandleLayerLink = LayerLink(); + + bool _didAutoFocus = false; + + AutofillGroupState? _currentAutofillScope; + @override + AutofillScope? get currentAutofillScope => _currentAutofillScope; + + AutofillClient get _effectiveAutofillClient => widget.autofillClient ?? this; + + /// zmtzawqlp + late _SpellCheckConfiguration _spellCheckConfiguration; + late TextStyle _style; + + /// Configuration that determines how spell check will be performed. + /// + /// If possible, this configuration will contain a default for the + /// [SpellCheckService] if it is not otherwise specified. + /// + /// See also: + /// * [DefaultSpellCheckService], the spell check service used by default. + @visibleForTesting + + /// zmtzawqlp + _SpellCheckConfiguration get spellCheckConfiguration => + _spellCheckConfiguration; + + /// Whether or not spell check is enabled. + /// + /// Spell check is enabled when a [SpellCheckConfiguration] has been specified + /// for the widget. + bool get spellCheckEnabled => _spellCheckConfiguration.spellCheckEnabled; + + /// The most up-to-date spell check results for text input. + /// + /// These results will be updated via calls to spell check through a + /// [SpellCheckService] and used by this widget to build the [TextSpan] tree + /// for text input and menus for replacement suggestions of misspelled words. + SpellCheckResults? spellCheckResults; + + bool get _spellCheckResultsReceived => + spellCheckEnabled && + spellCheckResults != null && + spellCheckResults!.suggestionSpans.isNotEmpty; + + /// The text processing service used to retrieve the native text processing actions. + final ProcessTextService _processTextService = DefaultProcessTextService(); + + /// The list of native text processing actions provided by the engine. + final List _processTextActions = []; + + /// Whether to create an input connection with the platform for text editing + /// or not. + /// + /// Read-only input fields do not need a connection with the platform since + /// there's no need for text editing capabilities (e.g. virtual keyboard). + /// + /// On the web, we always need a connection because we want some browser + /// functionalities to continue to work on read-only input fields like: + /// + /// - Relevant context menu. + /// - cmd/ctrl+c shortcut to copy. + /// - cmd/ctrl+a to select all. + /// - Changing the selection using a physical keyboard. + bool get _shouldCreateInputConnection => kIsWeb || !widget.readOnly; + + // The time it takes for the floating cursor to snap to the text aligned + // cursor position after the user has finished placing it. + static const Duration _floatingCursorResetTime = Duration(milliseconds: 125); + + AnimationController? _floatingCursorResetController; + + Orientation? _lastOrientation; + + @override + bool get wantKeepAlive => widget.focusNode.hasFocus; + + Color get _cursorColor { + final double effectiveOpacity = math.min( + widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value); + return widget.cursorColor.withOpacity(effectiveOpacity); + } + + @override + bool get cutEnabled { + if (widget.selectionControls is! TextSelectionHandleControls) { + return widget.toolbarOptions.cut && + !widget.readOnly && + !widget.obscureText; + } + return !widget.readOnly && + !widget.obscureText && + !textEditingValue.selection.isCollapsed; + } + + @override + bool get copyEnabled { + if (widget.selectionControls is! TextSelectionHandleControls) { + return widget.toolbarOptions.copy && !widget.obscureText; + } + return !widget.obscureText && !textEditingValue.selection.isCollapsed; + } + + @override + bool get pasteEnabled { + if (widget.selectionControls is! TextSelectionHandleControls) { + return widget.toolbarOptions.paste && !widget.readOnly; + } + return !widget.readOnly && + (clipboardStatus.value == ClipboardStatus.pasteable); + } + + @override + bool get selectAllEnabled { + if (widget.selectionControls is! TextSelectionHandleControls) { + return widget.toolbarOptions.selectAll && + (!widget.readOnly || !widget.obscureText) && + widget.enableInteractiveSelection; + } + + if (!widget.enableInteractiveSelection || + (widget.readOnly && widget.obscureText)) { + return false; + } + + switch (defaultTargetPlatform) { + case TargetPlatform.macOS: + return false; + case TargetPlatform.iOS: + return textEditingValue.text.isNotEmpty && + textEditingValue.selection.isCollapsed; + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return textEditingValue.text.isNotEmpty && + !(textEditingValue.selection.start == 0 && + textEditingValue.selection.end == textEditingValue.text.length); + } + } + + @override + bool get lookUpEnabled { + if (defaultTargetPlatform != TargetPlatform.iOS) { + return false; + } + return !widget.obscureText && + !textEditingValue.selection.isCollapsed && + textEditingValue.selection.textInside(textEditingValue.text).trim() != + ''; + } + + @override + bool get searchWebEnabled { + if (defaultTargetPlatform != TargetPlatform.iOS) { + return false; + } + + return !widget.obscureText && + !textEditingValue.selection.isCollapsed && + textEditingValue.selection.textInside(textEditingValue.text).trim() != + ''; + } + + @override + bool get shareEnabled { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.iOS: + return !widget.obscureText && + !textEditingValue.selection.isCollapsed && + textEditingValue.selection + .textInside(textEditingValue.text) + .trim() != + ''; + case TargetPlatform.macOS: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return false; + } + } + + @override + bool get liveTextInputEnabled { + return _liveTextInputStatus?.value == LiveTextInputStatus.enabled && + !widget.obscureText && + !widget.readOnly && + textEditingValue.selection.isCollapsed; + } + + void _onChangedClipboardStatus() { + setState(() { + // Inform the widget that the value of clipboardStatus has changed. + }); + } + + void _onChangedLiveTextInputStatus() { + setState(() { + // Inform the widget that the value of liveTextInputStatus has changed. + }); + } + + TextEditingValue get _textEditingValueforTextLayoutMetrics { + final Widget? editableWidget = _editableKey.currentContext?.widget; + if (editableWidget is! _Editable) { + throw StateError('_Editable must be mounted.'); + } + return editableWidget.value; + } + + /// Copy current selection to [Clipboard]. + @override + void copySelection(SelectionChangedCause cause) { + final TextSelection selection = textEditingValue.selection; + if (selection.isCollapsed || widget.obscureText) { + return; + } + final String text = textEditingValue.text; + Clipboard.setData(ClipboardData(text: selection.textInside(text))); + if (cause == SelectionChangedCause.toolbar) { + bringIntoView(textEditingValue.selection.extent); + hideToolbar(false); + + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + break; + case TargetPlatform.android: + case TargetPlatform.fuchsia: + // Collapse the selection and hide the toolbar and handles. + userUpdateTextEditingValue( + TextEditingValue( + text: textEditingValue.text, + selection: TextSelection.collapsed( + offset: textEditingValue.selection.end), + ), + SelectionChangedCause.toolbar, + ); + } + } + clipboardStatus.update(); + } + + /// Cut current selection to [Clipboard]. + @override + void cutSelection(SelectionChangedCause cause) { + if (widget.readOnly || widget.obscureText) { + return; + } + final TextSelection selection = textEditingValue.selection; + final String text = textEditingValue.text; + if (selection.isCollapsed) { + return; + } + Clipboard.setData(ClipboardData(text: selection.textInside(text))); + _replaceText(ReplaceTextIntent(textEditingValue, '', selection, cause)); + if (cause == SelectionChangedCause.toolbar) { + // Schedule a call to bringIntoView() after renderEditable updates. + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + bringIntoView(textEditingValue.selection.extent); + } + }, debugLabel: 'EditableText.bringSelectionIntoView'); + hideToolbar(); + } + clipboardStatus.update(); + } + + bool get _allowPaste { + return !widget.readOnly && textEditingValue.selection.isValid; + } + + /// Paste text from [Clipboard]. + @override + Future pasteText(SelectionChangedCause cause) async { + if (!_allowPaste) { + return; + } + // Snapshot the input before using `await`. + // See https://github.com/flutter/flutter/issues/11427 + final ClipboardData? data = await Clipboard.getData(Clipboard.kTextPlain); + if (data == null) { + return; + } + _pasteText(cause, data.text!); + } + + void _pasteText(SelectionChangedCause cause, String text) { + if (!_allowPaste) { + return; + } + + // After the paste, the cursor should be collapsed and located after the + // pasted content. + final TextSelection selection = textEditingValue.selection; + final int lastSelectionIndex = + math.max(selection.baseOffset, selection.extentOffset); + final TextEditingValue collapsedTextEditingValue = + textEditingValue.copyWith( + selection: TextSelection.collapsed(offset: lastSelectionIndex), + ); + + userUpdateTextEditingValue( + collapsedTextEditingValue.replaced(selection, text), + cause, + ); + if (cause == SelectionChangedCause.toolbar) { + // Schedule a call to bringIntoView() after renderEditable updates. + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted) { + bringIntoView(textEditingValue.selection.extent); + } + }, debugLabel: 'EditableText.bringSelectionIntoView'); + hideToolbar(); + } + } + + /// Select the entire text value. + @override + void selectAll(SelectionChangedCause cause) { + if (widget.readOnly && widget.obscureText) { + // If we can't modify it, and we can't copy it, there's no point in + // selecting it. + return; + } + userUpdateTextEditingValue( + textEditingValue.copyWith( + selection: TextSelection( + baseOffset: 0, extentOffset: textEditingValue.text.length), + ), + cause, + ); + + if (cause == SelectionChangedCause.toolbar) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + break; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + hideToolbar(); + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + bringIntoView(textEditingValue.selection.extent); + case TargetPlatform.macOS: + case TargetPlatform.iOS: + break; + } + } + } + + /// Look up the current selection, + /// as in the "Look Up" edit menu button on iOS. + /// + /// Currently this is only implemented for iOS. + /// + /// Throws an error if the selection is empty or collapsed. + Future lookUpSelection(SelectionChangedCause cause) async { + assert(!widget.obscureText); + + final String text = + textEditingValue.selection.textInside(textEditingValue.text); + if (widget.obscureText || text.isEmpty) { + return; + } + await SystemChannels.platform.invokeMethod( + 'LookUp.invoke', + text, + ); + } + + /// Launch a web search on the current selection, + /// as in the "Search Web" edit menu button on iOS. + /// + /// Currently this is only implemented for iOS. + /// + /// When 'obscureText' is true or the selection is empty, + /// this function will not do anything + Future searchWebForSelection(SelectionChangedCause cause) async { + assert(!widget.obscureText); + if (widget.obscureText) { + return; + } + + final String text = + textEditingValue.selection.textInside(textEditingValue.text); + if (text.isNotEmpty) { + await SystemChannels.platform.invokeMethod( + 'SearchWeb.invoke', + text, + ); + } + } + + /// Launch the share interface for the current selection, + /// as in the "Share..." edit menu button on iOS. + /// + /// Currently this is only implemented for iOS and Android. + /// + /// When 'obscureText' is true or the selection is empty, + /// this function will not do anything + Future shareSelection(SelectionChangedCause cause) async { + assert(!widget.obscureText); + if (widget.obscureText) { + return; + } + + final String text = + textEditingValue.selection.textInside(textEditingValue.text); + if (text.isNotEmpty) { + await SystemChannels.platform.invokeMethod( + 'Share.invoke', + text, + ); + } + } + + void _startLiveTextInput(SelectionChangedCause cause) { + if (!liveTextInputEnabled) { + return; + } + if (_hasInputConnection) { + LiveText.startLiveTextInput(); + } + if (cause == SelectionChangedCause.toolbar) { + hideToolbar(); + } + } + + /// Finds specified [SuggestionSpan] that matches the provided index using + /// binary search. + /// + /// See also: + /// + /// * [SpellCheckSuggestionsToolbar], the Material style spell check + /// suggestions toolbar that uses this method to render the correct + /// suggestions in the toolbar for a misspelled word. + SuggestionSpan? findSuggestionSpanAtCursorIndex(int cursorIndex) { + if (!_spellCheckResultsReceived || + spellCheckResults!.suggestionSpans.last.range.end < cursorIndex) { + // No spell check results have been received or the cursor index is out + // of range that suggestionSpans covers. + return null; + } + + final List suggestionSpans = + spellCheckResults!.suggestionSpans; + int leftIndex = 0; + int rightIndex = suggestionSpans.length - 1; + int midIndex = 0; + + while (leftIndex <= rightIndex) { + midIndex = ((leftIndex + rightIndex) / 2).floor(); + final int currentSpanStart = suggestionSpans[midIndex].range.start; + final int currentSpanEnd = suggestionSpans[midIndex].range.end; + + if (cursorIndex <= currentSpanEnd && cursorIndex >= currentSpanStart) { + return suggestionSpans[midIndex]; + } else if (cursorIndex <= currentSpanStart) { + rightIndex = midIndex - 1; + } else { + leftIndex = midIndex + 1; + } + } + return null; + } + + /// Infers the [_SpellCheckConfiguration] used to perform spell check. + /// + /// If spell check is enabled, this will try to infer a value for + /// the [SpellCheckService] if left unspecified. + /// zmtzawqlp + static _SpellCheckConfiguration _inferSpellCheckConfiguration( + _SpellCheckConfiguration? configuration) { + final SpellCheckService? spellCheckService = + configuration?.spellCheckService; + final bool spellCheckAutomaticallyDisabled = configuration == null || + configuration == const _SpellCheckConfiguration.disabled(); + final bool spellCheckServiceIsConfigured = spellCheckService != null || + spellCheckService == null && + WidgetsBinding + .instance.platformDispatcher.nativeSpellCheckServiceDefined; + if (spellCheckAutomaticallyDisabled || !spellCheckServiceIsConfigured) { + // Only enable spell check if a non-disabled configuration is provided + // and if that configuration does not specify a spell check service, + // a native spell checker must be supported. + assert(() { + if (!spellCheckAutomaticallyDisabled && + !spellCheckServiceIsConfigured) { + FlutterError.reportError( + FlutterErrorDetails( + exception: FlutterError( + 'Spell check was enabled with spellCheckConfiguration, but the ' + 'current platform does not have a supported spell check ' + 'service, and none was provided. Consider disabling spell ' + 'check for this platform or passing a SpellCheckConfiguration ' + 'with a specified spell check service.', + ), + library: 'widget library', + stack: StackTrace.current, + ), + ); + } + return true; + }()); + return const _SpellCheckConfiguration.disabled(); + } + + return configuration.copyWith( + spellCheckService: spellCheckService ?? DefaultSpellCheckService()); + } + + /// Returns the [ContextMenuButtonItem]s for the given [ToolbarOptions]. + @Deprecated( + 'Use `contextMenuBuilder` instead of `toolbarOptions`. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + List? buttonItemsForToolbarOptions( + [TargetPlatform? targetPlatform]) { + final ToolbarOptions toolbarOptions = widget.toolbarOptions; + if (toolbarOptions == ToolbarOptions.empty) { + return null; + } + return [ + if (toolbarOptions.cut && cutEnabled) + ContextMenuButtonItem( + onPressed: () { + cutSelection(SelectionChangedCause.toolbar); + }, + type: ContextMenuButtonType.cut, + ), + if (toolbarOptions.copy && copyEnabled) + ContextMenuButtonItem( + onPressed: () { + copySelection(SelectionChangedCause.toolbar); + }, + type: ContextMenuButtonType.copy, + ), + if (toolbarOptions.paste && pasteEnabled) + ContextMenuButtonItem( + onPressed: () { + pasteText(SelectionChangedCause.toolbar); + }, + type: ContextMenuButtonType.paste, + ), + if (toolbarOptions.selectAll && selectAllEnabled) + ContextMenuButtonItem( + onPressed: () { + selectAll(SelectionChangedCause.toolbar); + }, + type: ContextMenuButtonType.selectAll, + ), + ]; + } + + /// Gets the line heights at the start and end of the selection for the given + /// [_EditableTextState]. + /// + /// See also: + /// + /// * [TextSelectionToolbarAnchors.getSelectionRect], which depends on this + /// information. + ({double startGlyphHeight, double endGlyphHeight}) getGlyphHeights() { + final TextSelection selection = textEditingValue.selection; + + // Only calculate handle rects if the text in the previous frame + // is the same as the text in the current frame. This is done because + // widget.renderObject contains the renderEditable from the previous frame. + // If the text changed between the current and previous frames then + // widget.renderObject.getRectForComposingRange might fail. In cases where + // the current frame is different from the previous we fall back to + // renderObject.preferredLineHeight. + final InlineSpan span = renderEditable.text!; + final String prevText = span.toPlainText(); + final String currText = textEditingValue.text; + if (prevText != currText || !selection.isValid || selection.isCollapsed) { + return ( + startGlyphHeight: renderEditable.preferredLineHeight, + endGlyphHeight: renderEditable.preferredLineHeight, + ); + } + + final String selectedGraphemes = selection.textInside(currText); + final int firstSelectedGraphemeExtent = + selectedGraphemes.characters.first.length; + final Rect? startCharacterRect = + renderEditable.getRectForComposingRange(TextRange( + start: selection.start, + end: selection.start + firstSelectedGraphemeExtent, + )); + final int lastSelectedGraphemeExtent = + selectedGraphemes.characters.last.length; + final Rect? endCharacterRect = + renderEditable.getRectForComposingRange(TextRange( + start: selection.end - lastSelectedGraphemeExtent, + end: selection.end, + )); + return ( + startGlyphHeight: + startCharacterRect?.height ?? renderEditable.preferredLineHeight, + endGlyphHeight: + endCharacterRect?.height ?? renderEditable.preferredLineHeight, + ); + } + + /// {@template flutter.widgets.EditableText.getAnchors} + /// Returns the anchor points for the default context menu. + /// {@endtemplate} + /// + /// See also: + /// + /// * [contextMenuButtonItems], which provides the [ContextMenuButtonItem]s + /// for the default context menu buttons. + TextSelectionToolbarAnchors get contextMenuAnchors { + if (renderEditable.lastSecondaryTapDownPosition != null) { + return TextSelectionToolbarAnchors( + primaryAnchor: renderEditable.lastSecondaryTapDownPosition!, + ); + } + + final ( + startGlyphHeight: double startGlyphHeight, + endGlyphHeight: double endGlyphHeight + ) = getGlyphHeights(); + final TextSelection selection = textEditingValue.selection; + final List points = + renderEditable.getEndpointsForSelection(selection); + return TextSelectionToolbarAnchors.fromSelection( + renderBox: renderEditable, + startGlyphHeight: startGlyphHeight, + endGlyphHeight: endGlyphHeight, + selectionEndpoints: points, + ); + } + + /// Returns the [ContextMenuButtonItem]s representing the buttons in this + /// platform's default selection menu for [_EditableText]. + /// + /// See also: + /// + /// * [EditableText.getEditableButtonItems], which performs a similar role, + /// but for any editable field, not just specifically EditableText. + /// * [SelectableRegionState.contextMenuButtonItems], which performs a similar + /// role but for content that is selectable but not editable. + /// * [contextMenuAnchors], which provides the anchor points for the default + /// context menu. + /// * [AdaptiveTextSelectionToolbar], which builds the toolbar itself, and can + /// take a list of [ContextMenuButtonItem]s with + /// [AdaptiveTextSelectionToolbar.buttonItems]. + /// * [AdaptiveTextSelectionToolbar.getAdaptiveButtons], which builds the + /// button Widgets for the current platform given [ContextMenuButtonItem]s. + List get contextMenuButtonItems { + return buttonItemsForToolbarOptions() ?? + EditableText.getEditableButtonItems( + clipboardStatus: clipboardStatus.value, + onCopy: copyEnabled + ? () => copySelection(SelectionChangedCause.toolbar) + : null, + onCut: cutEnabled + ? () => cutSelection(SelectionChangedCause.toolbar) + : null, + onPaste: pasteEnabled + ? () => pasteText(SelectionChangedCause.toolbar) + : null, + onSelectAll: selectAllEnabled + ? () => selectAll(SelectionChangedCause.toolbar) + : null, + onLookUp: lookUpEnabled + ? () => lookUpSelection(SelectionChangedCause.toolbar) + : null, + onSearchWeb: searchWebEnabled + ? () => searchWebForSelection(SelectionChangedCause.toolbar) + : null, + onShare: shareEnabled + ? () => shareSelection(SelectionChangedCause.toolbar) + : null, + onLiveTextInput: liveTextInputEnabled + ? () => _startLiveTextInput(SelectionChangedCause.toolbar) + : null, + ) + ..addAll(_textProcessingActionButtonItems); + } + + List get _textProcessingActionButtonItems { + final List buttonItems = []; + final TextSelection selection = textEditingValue.selection; + if (widget.obscureText || !selection.isValid || selection.isCollapsed) { + return buttonItems; + } + + for (final ProcessTextAction action in _processTextActions) { + buttonItems.add(ContextMenuButtonItem( + label: action.label, + onPressed: () async { + final String selectedText = + selection.textInside(textEditingValue.text); + if (selectedText.isNotEmpty) { + final String? processedText = await _processTextService + .processTextAction(action.id, selectedText, widget.readOnly); + // If an activity does not return a modified version, just hide the toolbar. + // Otherwise use the result to replace the selected text. + if (processedText != null && _allowPaste) { + _pasteText(SelectionChangedCause.toolbar, processedText); + } else { + hideToolbar(); + } + } + }, + )); + } + return buttonItems; + } + + // State lifecycle: + + @override + void initState() { + super.initState(); + _liveTextInputStatus?.addListener(_onChangedLiveTextInputStatus); + clipboardStatus.addListener(_onChangedClipboardStatus); + widget.controller.addListener(_didChangeTextEditingValue); + widget.focusNode.addListener(_handleFocusChanged); + _cursorVisibilityNotifier.value = widget.showCursor; + // zmtzawqlp + // _spellCheckConfiguration = + // _inferSpellCheckConfiguration(widget.spellCheckConfiguration); + _initProcessTextActions(); + } + + /// Query the engine to initialize the list of text processing actions to show + /// in the text selection toolbar. + Future _initProcessTextActions() async { + _processTextActions.clear(); + _processTextActions.addAll(await _processTextService.queryTextActions()); + } + + // Whether `TickerMode.of(context)` is true and animations (like blinking the + // cursor) are supposed to run. + bool _tickersEnabled = true; + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + + _style = MediaQuery.boldTextOf(context) + ? widget.style.merge(const TextStyle(fontWeight: FontWeight.bold)) + : widget.style; + + final AutofillGroupState? newAutofillGroup = AutofillGroup.maybeOf(context); + if (currentAutofillScope != newAutofillGroup) { + _currentAutofillScope?.unregister(autofillId); + _currentAutofillScope = newAutofillGroup; + _currentAutofillScope?.register(_effectiveAutofillClient); + } + + if (!_didAutoFocus && widget.autofocus) { + _didAutoFocus = true; + SchedulerBinding.instance.addPostFrameCallback((_) { + if (mounted && renderEditable.hasSize) { + _flagInternalFocus(); + FocusScope.of(context).autofocus(widget.focusNode); + } + }, debugLabel: 'EditableText.autofocus'); + } + + // Restart or stop the blinking cursor when TickerMode changes. + final bool newTickerEnabled = TickerMode.of(context); + if (_tickersEnabled != newTickerEnabled) { + _tickersEnabled = newTickerEnabled; + if (_showBlinkingCursor) { + _startCursorBlink(); + } else if (!_tickersEnabled && _cursorTimer != null) { + _stopCursorBlink(); + } + } + + // Check for changes in viewId. + if (_hasInputConnection) { + final int newViewId = View.of(context).viewId; + if (newViewId != _viewId) { + _textInputConnection! + .updateConfig(_effectiveAutofillClient.textInputConfiguration); + } + } + + if (defaultTargetPlatform != TargetPlatform.iOS && + defaultTargetPlatform != TargetPlatform.android) { + return; + } + + // Hide the text selection toolbar on mobile when orientation changes. + final Orientation orientation = MediaQuery.orientationOf(context); + if (_lastOrientation == null) { + _lastOrientation = orientation; + return; + } + if (orientation != _lastOrientation) { + _lastOrientation = orientation; + if (defaultTargetPlatform == TargetPlatform.iOS) { + hideToolbar(false); + } + if (defaultTargetPlatform == TargetPlatform.android) { + hideToolbar(); + } + } + + if (_listeningToScrollNotificationObserver) { + // Only update subscription when we have previously subscribed to the + // scroll notification observer. We only subscribe to the scroll + // notification observer when the context menu is shown on platforms that + // support _platformSupportsFadeOnScroll. + _scrollNotificationObserver + ?.removeListener(_handleContextMenuOnParentScroll); + _scrollNotificationObserver = ScrollNotificationObserver.maybeOf(context); + _scrollNotificationObserver + ?.addListener(_handleContextMenuOnParentScroll); + } + } + + @override + + /// zmtzawqlp + void didUpdateWidget(_EditableText oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.controller != oldWidget.controller) { + oldWidget.controller.removeListener(_didChangeTextEditingValue); + widget.controller.addListener(_didChangeTextEditingValue); + _updateRemoteEditingValueIfNeeded(); + } + + if (_selectionOverlay != null && + (widget.contextMenuBuilder != oldWidget.contextMenuBuilder || + widget.selectionControls != oldWidget.selectionControls || + widget.onSelectionHandleTapped != + oldWidget.onSelectionHandleTapped || + widget.dragStartBehavior != oldWidget.dragStartBehavior || + widget.magnifierConfiguration != + oldWidget.magnifierConfiguration)) { + final bool shouldShowToolbar = _selectionOverlay!.toolbarIsVisible; + final bool shouldShowHandles = _selectionOverlay!.handlesVisible; + _selectionOverlay!.dispose(); + _selectionOverlay = _createSelectionOverlay(); + if (shouldShowToolbar || shouldShowHandles) { + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + if (shouldShowToolbar) { + _selectionOverlay!.showToolbar(); + } + if (shouldShowHandles) { + _selectionOverlay!.showHandles(); + } + }); + } + } else if (widget.controller.selection != oldWidget.controller.selection) { + _selectionOverlay?.update(_value); + } + _selectionOverlay?.handlesVisible = widget.showSelectionHandles; + + if (widget.autofillClient != oldWidget.autofillClient) { + _currentAutofillScope + ?.unregister(oldWidget.autofillClient?.autofillId ?? autofillId); + _currentAutofillScope?.register(_effectiveAutofillClient); + } + + if (widget.focusNode != oldWidget.focusNode) { + oldWidget.focusNode.removeListener(_handleFocusChanged); + widget.focusNode.addListener(_handleFocusChanged); + updateKeepAlive(); + } + + if (!_shouldCreateInputConnection) { + _closeInputConnectionIfNeeded(); + } else if (oldWidget.readOnly && _hasFocus) { + // _openInputConnection must be called after layout information is available. + // See https://github.com/flutter/flutter/issues/126312 + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + _openInputConnection(); + }, debugLabel: 'EditableText.openInputConnection'); + } + + if (kIsWeb && _hasInputConnection) { + if (oldWidget.readOnly != widget.readOnly) { + _textInputConnection! + .updateConfig(_effectiveAutofillClient.textInputConfiguration); + } + } + + if (_hasInputConnection) { + if (oldWidget.obscureText != widget.obscureText) { + _textInputConnection! + .updateConfig(_effectiveAutofillClient.textInputConfiguration); + } + } + + if (widget.style != oldWidget.style) { + // The _textInputConnection will pick up the new style when it attaches in + // _openInputConnection. + _style = MediaQuery.boldTextOf(context) + ? widget.style.merge(const TextStyle(fontWeight: FontWeight.bold)) + : widget.style; + if (_hasInputConnection) { + _textInputConnection!.setStyle( + fontFamily: _style.fontFamily, + fontSize: _style.fontSize, + fontWeight: _style.fontWeight, + textDirection: _textDirection, + textAlign: widget.textAlign, + ); + } + } + + if (widget.showCursor != oldWidget.showCursor) { + _startOrStopCursorTimerIfNeeded(); + } + final bool canPaste = + widget.selectionControls is TextSelectionHandleControls + ? pasteEnabled + : widget.selectionControls?.canPaste(this) ?? false; + if (widget.selectionEnabled && pasteEnabled && canPaste) { + clipboardStatus.update(); + } + } + + void _disposeScrollNotificationObserver() { + _listeningToScrollNotificationObserver = false; + if (_scrollNotificationObserver != null) { + _scrollNotificationObserver! + .removeListener(_handleContextMenuOnParentScroll); + _scrollNotificationObserver = null; + } + } + + @override + void dispose() { + _internalScrollController?.dispose(); + _currentAutofillScope?.unregister(autofillId); + widget.controller.removeListener(_didChangeTextEditingValue); + _floatingCursorResetController?.dispose(); + _floatingCursorResetController = null; + _closeInputConnectionIfNeeded(); + assert(!_hasInputConnection); + _cursorTimer?.cancel(); + _cursorTimer = null; + _backingCursorBlinkOpacityController?.dispose(); + _backingCursorBlinkOpacityController = null; + _selectionOverlay?.dispose(); + _selectionOverlay = null; + widget.focusNode.removeListener(_handleFocusChanged); + WidgetsBinding.instance.removeObserver(this); + _liveTextInputStatus?.removeListener(_onChangedLiveTextInputStatus); + _liveTextInputStatus?.dispose(); + clipboardStatus.removeListener(_onChangedClipboardStatus); + clipboardStatus.dispose(); + _cursorVisibilityNotifier.dispose(); + FocusManager.instance.removeListener(_unflagInternalFocus); + _disposeScrollNotificationObserver(); + super.dispose(); + assert(_batchEditDepth <= 0, 'unfinished batch edits: $_batchEditDepth'); + } + + // TextInputClient implementation: + + /// The last known [TextEditingValue] of the platform text input plugin. + /// + /// This value is updated when the platform text input plugin sends a new + /// update via [updateEditingValue], or when [EditableText] calls + /// [TextInputConnection.setEditingState] to overwrite the platform text input + /// plugin's [TextEditingValue]. + /// + /// Used in [_updateRemoteEditingValueIfNeeded] to determine whether the + /// remote value is outdated and needs updating. + TextEditingValue? _lastKnownRemoteTextEditingValue; + + @override + TextEditingValue get currentTextEditingValue => _value; + + @override + void updateEditingValue(TextEditingValue value) { + // This method handles text editing state updates from the platform text + // input plugin. The [EditableText] may not have the focus or an open input + // connection, as autofill can update a disconnected [EditableText]. + + // Since we still have to support keyboard select, this is the best place + // to disable text updating. + if (!_shouldCreateInputConnection) { + return; + } + + if (_checkNeedsAdjustAffinity(value)) { + value = value.copyWith( + selection: + value.selection.copyWith(affinity: _value.selection.affinity)); + } + + if (widget.readOnly) { + // In the read-only case, we only care about selection changes, and reject + // everything else. + value = _value.copyWith(selection: value.selection); + } + _lastKnownRemoteTextEditingValue = value; + + if (value == _value) { + // This is possible, for example, when the numeric keyboard is input, + // the engine will notify twice for the same value. + // Track at https://github.com/flutter/flutter/issues/65811 + return; + } + + if (value.text == _value.text && value.composing == _value.composing) { + // `selection` is the only change. + SelectionChangedCause cause; + if (_textInputConnection?.scribbleInProgress ?? false) { + cause = SelectionChangedCause.scribble; + } else if (_pointOffsetOrigin != null) { + // For floating cursor selection when force pressing the space bar. + cause = SelectionChangedCause.forcePress; + } else { + cause = SelectionChangedCause.keyboard; + } + _handleSelectionChanged(value.selection, cause); + } else { + if (value.text != _value.text) { + // Hide the toolbar if the text was changed, but only hide the toolbar + // overlay; the selection handle's visibility will be handled + // by `_handleSelectionChanged`. https://github.com/flutter/flutter/issues/108673 + hideToolbar(false); + } + _currentPromptRectRange = null; + + final bool revealObscuredInput = _hasInputConnection && + widget.obscureText && + WidgetsBinding.instance.platformDispatcher.brieflyShowPassword && + value.text.length == _value.text.length + 1; + + _obscureShowCharTicksPending = + revealObscuredInput ? _kObscureShowLatestCharCursorTicks : 0; + _obscureLatestCharIndex = + revealObscuredInput ? _value.selection.baseOffset : null; + _formatAndSetValue(value, SelectionChangedCause.keyboard); + } + + if (_showBlinkingCursor && _cursorTimer != null) { + // To keep the cursor from blinking while typing, restart the timer here. + _stopCursorBlink(resetCharTicks: false); + _startCursorBlink(); + } + + // Wherever the value is changed by the user, schedule a showCaretOnScreen + // to make sure the user can see the changes they just made. Programmatic + // changes to `textEditingValue` do not trigger the behavior even if the + // text field is focused. + _scheduleShowCaretOnScreen(withAnimation: true); + } + + bool _checkNeedsAdjustAffinity(TextEditingValue value) { + // Trust the engine affinity if the text changes or selection changes. + return value.text == _value.text && + value.selection.isCollapsed == _value.selection.isCollapsed && + value.selection.start == _value.selection.start && + value.selection.affinity != _value.selection.affinity; + } + + @override + void performAction(TextInputAction action) { + switch (action) { + case TextInputAction.newline: + // If this is a multiline EditableText, do nothing for a "newline" + // action; The newline is already inserted. Otherwise, finalize + // editing. + if (!_isMultiline) { + _finalizeEditing(action, shouldUnfocus: true); + } + case TextInputAction.done: + case TextInputAction.go: + case TextInputAction.next: + case TextInputAction.previous: + case TextInputAction.search: + case TextInputAction.send: + _finalizeEditing(action, shouldUnfocus: true); + case TextInputAction.continueAction: + case TextInputAction.emergencyCall: + case TextInputAction.join: + case TextInputAction.none: + case TextInputAction.route: + case TextInputAction.unspecified: + // Finalize editing, but don't give up focus because this keyboard + // action does not imply the user is done inputting information. + _finalizeEditing(action, shouldUnfocus: false); + } + } + + @override + void performPrivateCommand(String action, Map data) { + widget.onAppPrivateCommand?.call(action, data); + } + + @override + void insertContent(KeyboardInsertedContent content) { + assert(widget.contentInsertionConfiguration?.allowedMimeTypes + .contains(content.mimeType) ?? + false); + widget.contentInsertionConfiguration?.onContentInserted.call(content); + } + + // The original position of the caret on FloatingCursorDragState.start. + Offset? _startCaretCenter; + + // The most recent text position as determined by the location of the floating + // cursor. + TextPosition? _lastTextPosition; + + // The offset of the floating cursor as determined from the start call. + Offset? _pointOffsetOrigin; + + // The most recent position of the floating cursor. + Offset? _lastBoundedOffset; + + // Because the center of the cursor is preferredLineHeight / 2 below the touch + // origin, but the touch origin is used to determine which line the cursor is + // on, we need this offset to correctly render and move the cursor. + Offset get _floatingCursorOffset => + Offset(0, renderEditable.preferredLineHeight / 2); + + @override + void updateFloatingCursor(RawFloatingCursorPoint point) { + _floatingCursorResetController ??= AnimationController( + vsync: this, + )..addListener(_onFloatingCursorResetTick); + switch (point.state) { + case FloatingCursorDragState.Start: + if (_floatingCursorResetController!.isAnimating) { + _floatingCursorResetController!.stop(); + _onFloatingCursorResetTick(); + } + // Stop cursor blinking and making it visible. + _stopCursorBlink(resetCharTicks: false); + _cursorBlinkOpacityController.value = 1.0; + // We want to send in points that are centered around a (0,0) origin, so + // we cache the position. + _pointOffsetOrigin = point.offset; + + final Offset startCaretCenter; + final TextPosition currentTextPosition; + final bool shouldResetOrigin; + // Only non-null when starting a floating cursor via long press. + if (point.startLocation != null) { + shouldResetOrigin = false; + (startCaretCenter, currentTextPosition) = point.startLocation!; + } else { + shouldResetOrigin = true; + currentTextPosition = TextPosition( + offset: renderEditable.selection!.baseOffset, + affinity: renderEditable.selection!.affinity); + startCaretCenter = + renderEditable.getLocalRectForCaret(currentTextPosition).center; + } + + _startCaretCenter = startCaretCenter; + _lastBoundedOffset = + renderEditable.calculateBoundedFloatingCursorOffset( + _startCaretCenter! - _floatingCursorOffset, + shouldResetOrigin: shouldResetOrigin); + _lastTextPosition = currentTextPosition; + renderEditable.setFloatingCursor( + point.state, _lastBoundedOffset!, _lastTextPosition!); + case FloatingCursorDragState.Update: + final Offset centeredPoint = point.offset! - _pointOffsetOrigin!; + final Offset rawCursorOffset = + _startCaretCenter! + centeredPoint - _floatingCursorOffset; + + _lastBoundedOffset = renderEditable + .calculateBoundedFloatingCursorOffset(rawCursorOffset); + _lastTextPosition = renderEditable.getPositionForPoint(renderEditable + .localToGlobal(_lastBoundedOffset! + _floatingCursorOffset)); + renderEditable.setFloatingCursor( + point.state, _lastBoundedOffset!, _lastTextPosition!); + case FloatingCursorDragState.End: + // Resume cursor blinking. + _startCursorBlink(); + // We skip animation if no update has happened. + if (_lastTextPosition != null && _lastBoundedOffset != null) { + _floatingCursorResetController!.value = 0.0; + _floatingCursorResetController!.animateTo(1.0, + duration: _floatingCursorResetTime, curve: Curves.decelerate); + } + } + } + + void _onFloatingCursorResetTick() { + final Offset finalPosition = + renderEditable.getLocalRectForCaret(_lastTextPosition!).centerLeft - + _floatingCursorOffset; + if (_floatingCursorResetController!.isCompleted) { + renderEditable.setFloatingCursor( + FloatingCursorDragState.End, finalPosition, _lastTextPosition!); + // During a floating cursor's move gesture (1 finger), a cursor is + // animated only visually, without actually updating the selection. + // Only after move gesture is complete, this function will be called + // to actually update the selection to the new cursor location with + // zero selection length. + + // However, During a floating cursor's selection gesture (2 fingers), the + // selection is constantly updated by the engine throughout the gesture. + // Thus when the gesture is complete, we should not update the selection + // to the cursor location with zero selection length, because that would + // overwrite the selection made by floating cursor selection. + + // Here we use `isCollapsed` to distinguish between floating cursor's + // move gesture (1 finger) vs selection gesture (2 fingers), as + // the engine does not provide information other than notifying a + // new selection during with selection gesture (2 fingers). + if (renderEditable.selection!.isCollapsed) { + // The cause is technically the force cursor, but the cause is listed as tap as the desired functionality is the same. + _handleSelectionChanged(TextSelection.fromPosition(_lastTextPosition!), + SelectionChangedCause.forcePress); + } + _startCaretCenter = null; + _lastTextPosition = null; + _pointOffsetOrigin = null; + _lastBoundedOffset = null; + } else { + final double lerpValue = _floatingCursorResetController!.value; + final double lerpX = + ui.lerpDouble(_lastBoundedOffset!.dx, finalPosition.dx, lerpValue)!; + final double lerpY = + ui.lerpDouble(_lastBoundedOffset!.dy, finalPosition.dy, lerpValue)!; + + renderEditable.setFloatingCursor(FloatingCursorDragState.Update, + Offset(lerpX, lerpY), _lastTextPosition!, + resetLerpValue: lerpValue); + } + } + + @pragma('vm:notify-debugger-on-exception') + void _finalizeEditing(TextInputAction action, {required bool shouldUnfocus}) { + // Take any actions necessary now that the user has completed editing. + if (widget.onEditingComplete != null) { + try { + widget.onEditingComplete!(); + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: + ErrorDescription('while calling onEditingComplete for $action'), + )); + } + } else { + // Default behavior if the developer did not provide an + // onEditingComplete callback: Finalize editing and remove focus, or move + // it to the next/previous field, depending on the action. + widget.controller.clearComposing(); + if (shouldUnfocus) { + switch (action) { + case TextInputAction.none: + case TextInputAction.unspecified: + case TextInputAction.done: + case TextInputAction.go: + case TextInputAction.search: + case TextInputAction.send: + case TextInputAction.continueAction: + case TextInputAction.join: + case TextInputAction.route: + case TextInputAction.emergencyCall: + case TextInputAction.newline: + widget.focusNode.unfocus(); + case TextInputAction.next: + widget.focusNode.nextFocus(); + case TextInputAction.previous: + widget.focusNode.previousFocus(); + } + } + } + + final ValueChanged? onSubmitted = widget.onSubmitted; + if (onSubmitted == null) { + return; + } + + // Invoke optional callback with the user's submitted content. + try { + onSubmitted(_value.text); + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: ErrorDescription('while calling onSubmitted for $action'), + )); + } + + // If `shouldUnfocus` is true, the text field should no longer be focused + // after the microtask queue is drained. But in case the developer cancelled + // the focus change in the `onSubmitted` callback by focusing this input + // field again, reset the soft keyboard. + // See https://github.com/flutter/flutter/issues/84240. + // + // `_restartConnectionIfNeeded` creates a new TextInputConnection to replace + // the current one. This on iOS switches to a new input view and on Android + // restarts the input method, and in both cases the soft keyboard will be + // reset. + if (shouldUnfocus) { + _scheduleRestartConnection(); + } + } + + int _batchEditDepth = 0; + + /// Begins a new batch edit, within which new updates made to the text editing + /// value will not be sent to the platform text input plugin. + /// + /// Batch edits nest. When the outermost batch edit finishes, [endBatchEdit] + /// will attempt to send [currentTextEditingValue] to the text input plugin if + /// it detected a change. + void beginBatchEdit() { + _batchEditDepth += 1; + } + + /// Ends the current batch edit started by the last call to [beginBatchEdit], + /// and send [currentTextEditingValue] to the text input plugin if needed. + /// + /// Throws an error in debug mode if this [EditableText] is not in a batch + /// edit. + void endBatchEdit() { + _batchEditDepth -= 1; + assert( + _batchEditDepth >= 0, + 'Unbalanced call to endBatchEdit: beginBatchEdit must be called first.', + ); + _updateRemoteEditingValueIfNeeded(); + } + + void _updateRemoteEditingValueIfNeeded() { + if (_batchEditDepth > 0 || !_hasInputConnection) { + return; + } + final TextEditingValue localValue = _value; + if (localValue == _lastKnownRemoteTextEditingValue) { + return; + } + _textInputConnection!.setEditingState(localValue); + _lastKnownRemoteTextEditingValue = localValue; + } + + TextEditingValue get _value => widget.controller.value; + set _value(TextEditingValue value) { + widget.controller.value = value; + } + + bool get _hasFocus => widget.focusNode.hasFocus; + bool get _isMultiline => widget.maxLines != 1; + + // Finds the closest scroll offset to the current scroll offset that fully + // reveals the given caret rect. If the given rect's main axis extent is too + // large to be fully revealed in `renderEditable`, it will be centered along + // the main axis. + // + // If this is a multiline EditableText (which means the Editable can only + // scroll vertically), the given rect's height will first be extended to match + // `renderEditable.preferredLineHeight`, before the target scroll offset is + // calculated. + RevealedOffset _getOffsetToRevealCaret(Rect rect) { + if (!_scrollController.position.allowImplicitScrolling) { + return RevealedOffset(offset: _scrollController.offset, rect: rect); + } + + final Size editableSize = renderEditable.size; + final double additionalOffset; + final Offset unitOffset; + + if (!_isMultiline) { + additionalOffset = rect.width >= editableSize.width + // Center `rect` if it's oversized. + ? editableSize.width / 2 - rect.center.dx + // Valid additional offsets range from (rect.right - size.width) + // to (rect.left). Pick the closest one if out of range. + : clampDouble(0.0, rect.right - editableSize.width, rect.left); + unitOffset = const Offset(1, 0); + } else { + // The caret is vertically centered within the line. Expand the caret's + // height so that it spans the line because we're going to ensure that the + // entire expanded caret is scrolled into view. + final Rect expandedRect = Rect.fromCenter( + center: rect.center, + width: rect.width, + height: math.max(rect.height, renderEditable.preferredLineHeight), + ); + + additionalOffset = expandedRect.height >= editableSize.height + ? editableSize.height / 2 - expandedRect.center.dy + : clampDouble( + 0.0, expandedRect.bottom - editableSize.height, expandedRect.top); + unitOffset = const Offset(0, 1); + } + + // No overscrolling when encountering tall fonts/scripts that extend past + // the ascent. + final double targetOffset = clampDouble( + additionalOffset + _scrollController.offset, + _scrollController.position.minScrollExtent, + _scrollController.position.maxScrollExtent, + ); + + final double offsetDelta = _scrollController.offset - targetOffset; + return RevealedOffset( + rect: rect.shift(unitOffset * offsetDelta), offset: targetOffset); + } + + /// Whether to send the autofill information to the autofill service. True by + /// default. + bool get _needsAutofill => _effectiveAutofillClient + .textInputConfiguration.autofillConfiguration.enabled; + + // Must be called after layout. + // See https://github.com/flutter/flutter/issues/126312 + void _openInputConnection() { + if (!_shouldCreateInputConnection) { + return; + } + if (!_hasInputConnection) { + final TextEditingValue localValue = _value; + + // When _needsAutofill == true && currentAutofillScope == null, autofill + // is allowed but saving the user input from the text field is + // discouraged. + // + // In case the autofillScope changes from a non-null value to null, or + // _needsAutofill changes to false from true, the platform needs to be + // notified to exclude this field from the autofill context. So we need to + // provide the autofillId. + _textInputConnection = _needsAutofill && currentAutofillScope != null + ? currentAutofillScope! + .attach(this, _effectiveAutofillClient.textInputConfiguration) + : TextInput.attach( + this, _effectiveAutofillClient.textInputConfiguration); + _updateSizeAndTransform(); + _schedulePeriodicPostFrameCallbacks(); + _textInputConnection! + ..setStyle( + fontFamily: _style.fontFamily, + fontSize: _style.fontSize, + fontWeight: _style.fontWeight, + textDirection: _textDirection, + textAlign: widget.textAlign, + ) + ..setEditingState(localValue) + ..show(); + if (_needsAutofill) { + // Request autofill AFTER the size and the transform have been sent to + // the platform text input plugin. + _textInputConnection!.requestAutofill(); + } + _lastKnownRemoteTextEditingValue = localValue; + } else { + _textInputConnection!.show(); + } + } + + void _closeInputConnectionIfNeeded() { + if (_hasInputConnection) { + _textInputConnection!.close(); + _textInputConnection = null; + _lastKnownRemoteTextEditingValue = null; + _scribbleCacheKey = null; + removeTextPlaceholder(); + } + } + + void _openOrCloseInputConnectionIfNeeded() { + if (_hasFocus && widget.focusNode.consumeKeyboardToken()) { + _openInputConnection(); + } else if (!_hasFocus) { + _closeInputConnectionIfNeeded(); + widget.controller.clearComposing(); + } + } + + bool _restartConnectionScheduled = false; + void _scheduleRestartConnection() { + if (_restartConnectionScheduled) { + return; + } + _restartConnectionScheduled = true; + scheduleMicrotask(_restartConnectionIfNeeded); + } + + // Discards the current [TextInputConnection] and establishes a new one. + // + // This method is rarely needed. This is currently used to reset the input + // type when the "submit" text input action is triggered and the developer + // puts the focus back to this input field.. + void _restartConnectionIfNeeded() { + _restartConnectionScheduled = false; + if (!_hasInputConnection || !_shouldCreateInputConnection) { + return; + } + _textInputConnection!.close(); + _textInputConnection = null; + _lastKnownRemoteTextEditingValue = null; + + final AutofillScope? currentAutofillScope = + _needsAutofill ? this.currentAutofillScope : null; + final TextInputConnection newConnection = currentAutofillScope?.attach( + this, textInputConfiguration) ?? + TextInput.attach(this, _effectiveAutofillClient.textInputConfiguration); + _textInputConnection = newConnection; + + newConnection + ..show() + ..setStyle( + fontFamily: _style.fontFamily, + fontSize: _style.fontSize, + fontWeight: _style.fontWeight, + textDirection: _textDirection, + textAlign: widget.textAlign, + ) + ..setEditingState(_value); + _lastKnownRemoteTextEditingValue = _value; + } + + @override + void didChangeInputControl( + TextInputControl? oldControl, TextInputControl? newControl) { + if (_hasFocus && _hasInputConnection) { + oldControl?.hide(); + newControl?.show(); + } + } + + @override + void connectionClosed() { + if (_hasInputConnection) { + _textInputConnection!.connectionClosedReceived(); + _textInputConnection = null; + _lastKnownRemoteTextEditingValue = null; + widget.focusNode.unfocus(); + } + } + + // Indicates that a call to _handleFocusChanged originated within + // EditableText, allowing it to distinguish between internal and external + // focus changes. + bool _nextFocusChangeIsInternal = false; + + // Sets _nextFocusChangeIsInternal to true only until any subsequent focus + // change happens. + void _flagInternalFocus() { + _nextFocusChangeIsInternal = true; + FocusManager.instance.addListener(_unflagInternalFocus); + } + + void _unflagInternalFocus() { + _nextFocusChangeIsInternal = false; + FocusManager.instance.removeListener(_unflagInternalFocus); + } + + /// Express interest in interacting with the keyboard. + /// + /// If this control is already attached to the keyboard, this function will + /// request that the keyboard become visible. Otherwise, this function will + /// ask the focus system that it become focused. If successful in acquiring + /// focus, the control will then attach to the keyboard and request that the + /// keyboard become visible. + void requestKeyboard() { + if (_hasFocus) { + _openInputConnection(); + } else { + _flagInternalFocus(); + widget.focusNode + .requestFocus(); // This eventually calls _openInputConnection also, see _handleFocusChanged. + } + } + + void _updateOrDisposeSelectionOverlayIfNeeded() { + if (_selectionOverlay != null) { + if (_hasFocus) { + _selectionOverlay!.update(_value); + } else { + _selectionOverlay!.dispose(); + _selectionOverlay = null; + } + } + } + + final bool _platformSupportsFadeOnScroll = switch (defaultTargetPlatform) { + TargetPlatform.android || TargetPlatform.iOS => true, + TargetPlatform.fuchsia || + TargetPlatform.linux || + TargetPlatform.macOS || + TargetPlatform.windows => + false, + }; + + bool _isInternalScrollableNotification(BuildContext? notificationContext) { + final ScrollableState? scrollableState = + notificationContext?.findAncestorStateOfType(); + return _scrollableKey.currentContext == scrollableState?.context; + } + + bool _scrollableNotificationIsFromSameSubtree( + BuildContext? notificationContext) { + if (notificationContext == null) { + return false; + } + BuildContext? currentContext = context; + // The notification context of a ScrollNotification points to the RawGestureDetector + // of the Scrollable. We get the ScrollableState associated with this notification + // by looking up the tree. + final ScrollableState? notificationScrollableState = + notificationContext.findAncestorStateOfType(); + if (notificationScrollableState == null) { + return false; + } + while (currentContext != null) { + final ScrollableState? scrollableState = + currentContext.findAncestorStateOfType(); + if (scrollableState == notificationScrollableState) { + return true; + } + currentContext = scrollableState?.context; + } + return false; + } + + void _handleContextMenuOnParentScroll(ScrollNotification notification) { + // Do some preliminary checks to avoid expensive subtree traversal. + if (notification is! ScrollStartNotification && + notification is! ScrollEndNotification) { + return; + } + switch (notification) { + case ScrollStartNotification() when _dataWhenToolbarShowScheduled != null: + case ScrollEndNotification() when _dataWhenToolbarShowScheduled == null: + break; + case ScrollEndNotification() + when _dataWhenToolbarShowScheduled!.value != _value: + _dataWhenToolbarShowScheduled = null; + _disposeScrollNotificationObserver(); + case ScrollNotification(:final BuildContext? context) + when !_isInternalScrollableNotification(context) && + _scrollableNotificationIsFromSameSubtree(context): + _handleContextMenuOnScroll(notification); + } + } + + Rect _calculateDeviceRect() { + final Size screenSize = MediaQuery.sizeOf(context); + final ui.FlutterView view = View.of(context); + final double obscuredVertical = + (view.padding.top + view.padding.bottom + view.viewInsets.bottom) / + view.devicePixelRatio; + final double obscuredHorizontal = + (view.padding.left + view.padding.right) / view.devicePixelRatio; + final Size visibleScreenSize = Size(screenSize.width - obscuredHorizontal, + screenSize.height - obscuredVertical); + return Rect.fromLTWH( + view.padding.left / view.devicePixelRatio, + view.padding.top / view.devicePixelRatio, + visibleScreenSize.width, + visibleScreenSize.height); + } + + bool _showToolbarOnScreenScheduled = false; + void _handleContextMenuOnScroll(ScrollNotification notification) { + if (_webContextMenuEnabled) { + return; + } + if (!_platformSupportsFadeOnScroll) { + _selectionOverlay?.updateForScroll(); + return; + } + // When the scroll begins and the toolbar is visible, hide it + // until scrolling ends. + // + // The selection and renderEditable need to be visible within the current + // viewport for the toolbar to show when scrolling ends. If they are not + // then the toolbar is shown when they are scrolled back into view, unless + // invalidated by a change in TextEditingValue. + if (notification is ScrollStartNotification) { + if (_dataWhenToolbarShowScheduled != null) { + return; + } + final bool toolbarIsVisible = _selectionOverlay != null && + _selectionOverlay!.toolbarIsVisible && + !_selectionOverlay!.spellCheckToolbarIsVisible; + if (!toolbarIsVisible) { + return; + } + final List selectionBoxes = + renderEditable.getBoxesForSelection(_value.selection); + final Rect selectionBounds = _value.selection.isCollapsed || + selectionBoxes.isEmpty + ? renderEditable.getLocalRectForCaret(_value.selection.extent) + : selectionBoxes + .map((TextBox box) => box.toRect()) + .reduce((Rect result, Rect rect) => result.expandToInclude(rect)); + _dataWhenToolbarShowScheduled = + (value: _value, selectionBounds: selectionBounds); + _selectionOverlay?.hideToolbar(); + } else if (notification is ScrollEndNotification) { + if (_dataWhenToolbarShowScheduled == null) { + return; + } + if (_dataWhenToolbarShowScheduled!.value != _value) { + // Value has changed so we should invalidate any toolbar scheduling. + _dataWhenToolbarShowScheduled = null; + _disposeScrollNotificationObserver(); + return; + } + + if (_showToolbarOnScreenScheduled) { + return; + } + _showToolbarOnScreenScheduled = true; + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + _showToolbarOnScreenScheduled = false; + if (!mounted) { + return; + } + final Rect deviceRect = _calculateDeviceRect(); + final bool selectionVisibleInEditable = + renderEditable.selectionStartInViewport.value || + renderEditable.selectionEndInViewport.value; + final Rect selectionBounds = MatrixUtils.transformRect( + renderEditable.getTransformTo(null), + _dataWhenToolbarShowScheduled!.selectionBounds); + final bool selectionOverlapsWithDeviceRect = + !selectionBounds.hasNaN && deviceRect.overlaps(selectionBounds); + + if (selectionVisibleInEditable && + selectionOverlapsWithDeviceRect && + _selectionInViewport( + _dataWhenToolbarShowScheduled!.selectionBounds)) { + showToolbar(); + _dataWhenToolbarShowScheduled = null; + } + }, debugLabel: 'EditableText.scheduleToolbar'); + } + } + + bool _selectionInViewport(Rect selectionBounds) { + RenderAbstractViewport? closestViewport = + RenderAbstractViewport.maybeOf(renderEditable); + while (closestViewport != null) { + final Rect selectionBoundsLocalToViewport = MatrixUtils.transformRect( + renderEditable.getTransformTo(closestViewport), selectionBounds); + if (selectionBoundsLocalToViewport.hasNaN || + closestViewport.paintBounds.hasNaN || + !closestViewport.paintBounds + .overlaps(selectionBoundsLocalToViewport)) { + return false; + } + closestViewport = RenderAbstractViewport.maybeOf(closestViewport.parent); + } + return true; + } + + // zmtzawqlp + _TextSelectionOverlay _createSelectionOverlay() { + // final EditableTextContextMenuBuilder? contextMenuBuilder = + // widget.contextMenuBuilder; + final _TextSelectionOverlay selectionOverlay = _TextSelectionOverlay( + clipboardStatus: clipboardStatus, + context: context, + value: _value, + debugRequiredFor: widget, + toolbarLayerLink: _toolbarLayerLink, + startHandleLayerLink: _startHandleLayerLink, + endHandleLayerLink: _endHandleLayerLink, + renderObject: renderEditable, + selectionControls: widget.selectionControls, + selectionDelegate: this, + dragStartBehavior: widget.dragStartBehavior, + onSelectionHandleTapped: widget.onSelectionHandleTapped, + // zmtzawqlp + // contextMenuBuilder: contextMenuBuilder == null || _webContextMenuEnabled + // ? null + // : (BuildContext context) { + // return contextMenuBuilder( + // context, + // this, + // ); + // }, + magnifierConfiguration: widget.magnifierConfiguration, + ); + + return selectionOverlay; + } + + @pragma('vm:notify-debugger-on-exception') + void _handleSelectionChanged( + TextSelection selection, SelectionChangedCause? cause) { + // We return early if the selection is not valid. This can happen when the + // text of [EditableText] is updated at the same time as the selection is + // changed by a gesture event. + final String text = widget.controller.value.text; + if (text.length < selection.end || text.length < selection.start) { + return; + } + + widget.controller.selection = selection; + + // This will show the keyboard for all selection changes on the + // EditableText except for those triggered by a keyboard input. + // Typically EditableText shouldn't take user keyboard input if + // it's not focused already. If the EditableText is being + // autofilled it shouldn't request focus. + switch (cause) { + case null: + case SelectionChangedCause.doubleTap: + case SelectionChangedCause.drag: + case SelectionChangedCause.forcePress: + case SelectionChangedCause.longPress: + case SelectionChangedCause.scribble: + case SelectionChangedCause.tap: + case SelectionChangedCause.toolbar: + requestKeyboard(); + case SelectionChangedCause.keyboard: + if (_hasFocus) { + requestKeyboard(); + } + } + if (widget.selectionControls == null && widget.contextMenuBuilder == null) { + _selectionOverlay?.dispose(); + _selectionOverlay = null; + } else { + if (_selectionOverlay == null) { + _selectionOverlay = _createSelectionOverlay(); + } else { + _selectionOverlay!.update(_value); + } + _selectionOverlay!.handlesVisible = widget.showSelectionHandles; + _selectionOverlay!.showHandles(); + } + // TODO(chunhtai): we should make sure selection actually changed before + // we call the onSelectionChanged. + // https://github.com/flutter/flutter/issues/76349. + try { + widget.onSelectionChanged?.call(selection, cause); + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: + ErrorDescription('while calling onSelectionChanged for $cause'), + )); + } + + // To keep the cursor from blinking while it moves, restart the timer here. + if (_showBlinkingCursor && _cursorTimer != null) { + _stopCursorBlink(resetCharTicks: false); + _startCursorBlink(); + } + } + + // Animation configuration for scrolling the caret back on screen. + static const Duration _caretAnimationDuration = Duration(milliseconds: 100); + static const Curve _caretAnimationCurve = Curves.fastOutSlowIn; + + bool _showCaretOnScreenScheduled = false; + + void _scheduleShowCaretOnScreen({required bool withAnimation}) { + if (_showCaretOnScreenScheduled) { + return; + } + _showCaretOnScreenScheduled = true; + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + _showCaretOnScreenScheduled = false; + // Since we are in a post frame callback, check currentContext in case + // RenderEditable has been disposed (in which case it will be null). + // zmtzawqlp + final _RenderEditable? renderEditable = + _editableKey.currentContext?.findRenderObject() as _RenderEditable?; + if (renderEditable == null || + !(renderEditable.selection?.isValid ?? false) || + !_scrollController.hasClients) { + return; + } + + final double lineHeight = renderEditable.preferredLineHeight; + + // Enlarge the target rect by scrollPadding to ensure that caret is not + // positioned directly at the edge after scrolling. + double bottomSpacing = widget.scrollPadding.bottom; + if (_selectionOverlay?.selectionControls != null) { + final double handleHeight = _selectionOverlay!.selectionControls! + .getHandleSize(lineHeight) + .height; + final double interactiveHandleHeight = math.max( + handleHeight, + kMinInteractiveDimension, + ); + final Offset anchor = + _selectionOverlay!.selectionControls!.getHandleAnchor( + TextSelectionHandleType.collapsed, + lineHeight, + ); + final double handleCenter = handleHeight / 2 - anchor.dy; + bottomSpacing = math.max( + handleCenter + interactiveHandleHeight / 2, + bottomSpacing, + ); + } + + final EdgeInsets caretPadding = + widget.scrollPadding.copyWith(bottom: bottomSpacing); + + final Rect caretRect = + renderEditable.getLocalRectForCaret(renderEditable.selection!.extent); + final RevealedOffset targetOffset = _getOffsetToRevealCaret(caretRect); + + final Rect rectToReveal; + final TextSelection selection = textEditingValue.selection; + if (selection.isCollapsed) { + rectToReveal = targetOffset.rect; + } else { + final List selectionBoxes = + renderEditable.getBoxesForSelection(selection); + // selectionBoxes may be empty if, for example, the selection does not + // encompass a full character, like if it only contained part of an + // extended grapheme cluster. + if (selectionBoxes.isEmpty) { + rectToReveal = targetOffset.rect; + } else { + rectToReveal = selection.baseOffset < selection.extentOffset + ? selectionBoxes.last.toRect() + : selectionBoxes.first.toRect(); + } + } + + if (withAnimation) { + _scrollController.animateTo( + targetOffset.offset, + duration: _caretAnimationDuration, + curve: _caretAnimationCurve, + ); + renderEditable.showOnScreen( + rect: caretPadding.inflateRect(rectToReveal), + duration: _caretAnimationDuration, + curve: _caretAnimationCurve, + ); + } else { + _scrollController.jumpTo(targetOffset.offset); + renderEditable.showOnScreen( + rect: caretPadding.inflateRect(rectToReveal), + ); + } + }, debugLabel: 'EditableText.showCaret'); + } + + late double _lastBottomViewInset; + + @override + void didChangeMetrics() { + if (!mounted) { + return; + } + final ui.FlutterView view = View.of(context); + if (_lastBottomViewInset != view.viewInsets.bottom) { + SchedulerBinding.instance.addPostFrameCallback((Duration _) { + _selectionOverlay?.updateForScroll(); + }, debugLabel: 'EditableText.updateForScroll'); + if (_lastBottomViewInset < view.viewInsets.bottom) { + // Because the metrics change signal from engine will come here every frame + // (on both iOS and Android). So we don't need to show caret with animation. + _scheduleShowCaretOnScreen(withAnimation: false); + } + } + _lastBottomViewInset = view.viewInsets.bottom; + } + + Future _performSpellCheck(final String text) async { + try { + final Locale? localeForSpellChecking = + widget.locale ?? Localizations.maybeLocaleOf(context); + + assert( + localeForSpellChecking != null, + 'Locale must be specified in widget or Localization widget must be in scope', + ); + + final List? suggestions = await _spellCheckConfiguration + .spellCheckService! + .fetchSpellCheckSuggestions(localeForSpellChecking!, text); + + if (suggestions == null) { + // The request to fetch spell check suggestions was canceled due to ongoing request. + return; + } + + spellCheckResults = SpellCheckResults(text, suggestions); + renderEditable.text = buildTextSpan(); + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: ErrorDescription('while performing spell check'), + )); + } + } + + @pragma('vm:notify-debugger-on-exception') + void _formatAndSetValue(TextEditingValue value, SelectionChangedCause? cause, + {bool userInteraction = false}) { + final TextEditingValue oldValue = _value; + final bool textChanged = oldValue.text != value.text; + final bool textCommitted = + !oldValue.composing.isCollapsed && value.composing.isCollapsed; + final bool selectionChanged = oldValue.selection != value.selection; + + if (textChanged || textCommitted) { + // Only apply input formatters if the text has changed (including uncommitted + // text in the composing region), or when the user committed the composing + // text. + // Gboard is very persistent in restoring the composing region. Applying + // input formatters on composing-region-only changes (except clearing the + // current composing region) is very infinite-loop-prone: the formatters + // will keep trying to modify the composing region while Gboard will keep + // trying to restore the original composing region. + try { + value = widget.inputFormatters?.fold( + value, + (TextEditingValue newValue, TextInputFormatter formatter) => + formatter.formatEditUpdate(_value, newValue), + ) ?? + value; + + if (spellCheckEnabled && + value.text.isNotEmpty && + _value.text != value.text) { + _performSpellCheck(value.text); + } + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: ErrorDescription('while applying input formatters'), + )); + } + } + + final TextSelection oldTextSelection = textEditingValue.selection; + + // Put all optional user callback invocations in a batch edit to prevent + // sending multiple `TextInput.updateEditingValue` messages. + beginBatchEdit(); + _value = value; + // Changes made by the keyboard can sometimes be "out of band" for listening + // components, so always send those events, even if we didn't think it + // changed. Also, the user long pressing should always send a selection change + // as well. + if (selectionChanged || + (userInteraction && + (cause == SelectionChangedCause.longPress || + cause == SelectionChangedCause.keyboard))) { + _handleSelectionChanged(_value.selection, cause); + _bringIntoViewBySelectionState(oldTextSelection, value.selection, cause); + } + final String currentText = _value.text; + if (oldValue.text != currentText) { + try { + widget.onChanged?.call(currentText); + } catch (exception, stack) { + FlutterError.reportError(FlutterErrorDetails( + exception: exception, + stack: stack, + library: 'widgets', + context: ErrorDescription('while calling onChanged'), + )); + } + } + endBatchEdit(); + } + + void _bringIntoViewBySelectionState(TextSelection oldSelection, + TextSelection newSelection, SelectionChangedCause? cause) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + if (cause == SelectionChangedCause.longPress || + cause == SelectionChangedCause.drag) { + bringIntoView(newSelection.extent); + } + case TargetPlatform.linux: + case TargetPlatform.windows: + case TargetPlatform.fuchsia: + case TargetPlatform.android: + if (cause == SelectionChangedCause.drag) { + if (oldSelection.baseOffset != newSelection.baseOffset) { + bringIntoView(newSelection.base); + } else if (oldSelection.extentOffset != newSelection.extentOffset) { + bringIntoView(newSelection.extent); + } + } + } + } + + void _onCursorColorTick() { + final double effectiveOpacity = math.min( + widget.cursorColor.alpha / 255.0, _cursorBlinkOpacityController.value); + renderEditable.cursorColor = + widget.cursorColor.withOpacity(effectiveOpacity); + _cursorVisibilityNotifier.value = widget.showCursor && + (EditableText.debugDeterministicCursor || + _cursorBlinkOpacityController.value > 0); + } + + bool get _showBlinkingCursor => + _hasFocus && + _value.selection.isCollapsed && + widget.showCursor && + _tickersEnabled && + !renderEditable.floatingCursorOn; + + /// Whether the blinking cursor is actually visible at this precise moment + /// (it's hidden half the time, since it blinks). + @visibleForTesting + bool get cursorCurrentlyVisible => _cursorBlinkOpacityController.value > 0; + + /// The cursor blink interval (the amount of time the cursor is in the "on" + /// state or the "off" state). A complete cursor blink period is twice this + /// value (half on, half off). + @visibleForTesting + Duration get cursorBlinkInterval => _kCursorBlinkHalfPeriod; + + /// The current status of the text selection handles. + + // @visibleForTesting + // zmtzawqlp + // TextSelectionOverlay? get selectionOverlay => _selectionOverlay; + + int _obscureShowCharTicksPending = 0; + int? _obscureLatestCharIndex; + + void _startCursorBlink() { + assert(!(_cursorTimer?.isActive ?? false) || + !(_backingCursorBlinkOpacityController?.isAnimating ?? false)); + if (!widget.showCursor) { + return; + } + if (!_tickersEnabled) { + return; + } + _cursorTimer?.cancel(); + _cursorBlinkOpacityController.value = 1.0; + if (EditableText.debugDeterministicCursor) { + return; + } + if (widget.cursorOpacityAnimates) { + _cursorBlinkOpacityController + .animateWith(_iosBlinkCursorSimulation) + .whenComplete(_onCursorTick); + } else { + _cursorTimer = Timer.periodic(_kCursorBlinkHalfPeriod, (Timer timer) { + _onCursorTick(); + }); + } + } + + void _onCursorTick() { + if (_obscureShowCharTicksPending > 0) { + _obscureShowCharTicksPending = + WidgetsBinding.instance.platformDispatcher.brieflyShowPassword + ? _obscureShowCharTicksPending - 1 + : 0; + if (_obscureShowCharTicksPending == 0) { + setState(() {}); + } + } + + if (widget.cursorOpacityAnimates) { + _cursorTimer?.cancel(); + // Schedule this as an async task to avoid blocking tester.pumpAndSettle + // indefinitely. + _cursorTimer = Timer( + Duration.zero, + () => _cursorBlinkOpacityController + .animateWith(_iosBlinkCursorSimulation) + .whenComplete(_onCursorTick)); + } else { + if (!(_cursorTimer?.isActive ?? false) && _tickersEnabled) { + _cursorTimer = Timer.periodic(_kCursorBlinkHalfPeriod, (Timer timer) { + _onCursorTick(); + }); + } + _cursorBlinkOpacityController.value = + _cursorBlinkOpacityController.value == 0 ? 1 : 0; + } + } + + void _stopCursorBlink({bool resetCharTicks = true}) { + // If the cursor is animating, stop the animation, and we always + // want the cursor to be visible when the floating cursor is enabled. + _cursorBlinkOpacityController.value = + renderEditable.floatingCursorOn ? 1.0 : 0.0; + _cursorTimer?.cancel(); + _cursorTimer = null; + if (resetCharTicks) { + _obscureShowCharTicksPending = 0; + } + } + + void _startOrStopCursorTimerIfNeeded() { + if (!_showBlinkingCursor) { + _stopCursorBlink(); + } else if (_cursorTimer == null) { + _startCursorBlink(); + } + } + + void _didChangeTextEditingValue() { + if (_hasFocus && !_value.selection.isValid) { + // If this field is focused and the selection is invalid, place the cursor at + // the end. Does not rely on _handleFocusChanged because it makes selection + // handles visible on Android. + // Unregister as a listener to the text controller while making the change. + widget.controller.removeListener(_didChangeTextEditingValue); + widget.controller.selection = _adjustedSelectionWhenFocused()!; + widget.controller.addListener(_didChangeTextEditingValue); + } + _updateRemoteEditingValueIfNeeded(); + _startOrStopCursorTimerIfNeeded(); + _updateOrDisposeSelectionOverlayIfNeeded(); + // TODO(abarth): Teach RenderEditable about ValueNotifier + // to avoid this setState(). + setState(() {/* We use widget.controller.value in build(). */}); + _verticalSelectionUpdateAction.stopCurrentVerticalRunIfSelectionChanges(); + } + + void _handleFocusChanged() { + _openOrCloseInputConnectionIfNeeded(); + _startOrStopCursorTimerIfNeeded(); + _updateOrDisposeSelectionOverlayIfNeeded(); + if (_hasFocus) { + // Listen for changing viewInsets, which indicates keyboard showing up. + WidgetsBinding.instance.addObserver(this); + _lastBottomViewInset = View.of(context).viewInsets.bottom; + if (!widget.readOnly) { + _scheduleShowCaretOnScreen(withAnimation: true); + } + final TextSelection? updatedSelection = _adjustedSelectionWhenFocused(); + if (updatedSelection != null) { + _handleSelectionChanged(updatedSelection, null); + } + } else { + WidgetsBinding.instance.removeObserver(this); + setState(() { + _currentPromptRectRange = null; + }); + } + updateKeepAlive(); + } + + TextSelection? _adjustedSelectionWhenFocused() { + TextSelection? selection; + final bool shouldSelectAll = widget.selectionEnabled && + kIsWeb && + !_isMultiline && + !_nextFocusChangeIsInternal; + if (shouldSelectAll) { + // On native web, single line tags select all when receiving + // focus. + selection = TextSelection( + baseOffset: 0, + extentOffset: _value.text.length, + ); + } else if (!_value.selection.isValid) { + // Place cursor at the end if the selection is invalid when we receive focus. + selection = TextSelection.collapsed(offset: _value.text.length); + } + return selection; + } + + void _compositeCallback(Layer layer) { + // The callback can be invoked when the layer is detached. + // The input connection can be closed by the platform in which case this + // widget doesn't rebuild. + if (!renderEditable.attached || !_hasInputConnection) { + return; + } + assert(mounted); + assert((context as Element).debugIsActive); + _updateSizeAndTransform(); + } + + // Must be called after layout. + // See https://github.com/flutter/flutter/issues/126312 + void _updateSizeAndTransform() { + final Size size = renderEditable.size; + final Matrix4 transform = renderEditable.getTransformTo(null); + _textInputConnection!.setEditableSizeAndTransform(size, transform); + } + + void _schedulePeriodicPostFrameCallbacks([Duration? duration]) { + if (!_hasInputConnection) { + return; + } + _updateSelectionRects(); + _updateComposingRectIfNeeded(); + _updateCaretRectIfNeeded(); + SchedulerBinding.instance.addPostFrameCallback( + _schedulePeriodicPostFrameCallbacks, + debugLabel: 'EditableText.postFrameCallbacks'); + } + + _ScribbleCacheKey? _scribbleCacheKey; + + void _updateSelectionRects({bool force = false}) { + if (!widget.scribbleEnabled || + defaultTargetPlatform != TargetPlatform.iOS) { + return; + } + + final ScrollDirection scrollDirection = + _scrollController.position.userScrollDirection; + if (scrollDirection != ScrollDirection.idle) { + return; + } + + final InlineSpan inlineSpan = renderEditable.text!; + double? textScaleFactor; + final TextScaler effectiveTextScaler = switch (( + widget.textScaler, textScaleFactor // widget.textScaleFactor + )) { + (final TextScaler textScaler, _) => textScaler, + (null, final double textScaleFactor) => + TextScaler.linear(textScaleFactor), + (null, null) => MediaQuery.textScalerOf(context), + }; + + final _ScribbleCacheKey newCacheKey = _ScribbleCacheKey( + inlineSpan: inlineSpan, + textAlign: widget.textAlign, + textDirection: _textDirection, + textScaler: effectiveTextScaler, + textHeightBehavior: widget.textHeightBehavior ?? + DefaultTextHeightBehavior.maybeOf(context), + locale: widget.locale, + structStyle: widget.strutStyle, + placeholder: _placeholderLocation, + size: renderEditable.size, + ); + + final RenderComparison comparison = force + ? RenderComparison.layout + : _scribbleCacheKey?.compare(newCacheKey) ?? RenderComparison.layout; + if (comparison.index < RenderComparison.layout.index) { + return; + } + _scribbleCacheKey = newCacheKey; + + final List rects = []; + int graphemeStart = 0; + // Can't use _value.text here: the controller value could change between + // frames. + final String plainText = + inlineSpan.toPlainText(includeSemanticsLabels: false); + final CharacterRange characterRange = CharacterRange(plainText); + while (characterRange.moveNext()) { + final int graphemeEnd = graphemeStart + characterRange.current.length; + final List boxes = renderEditable.getBoxesForSelection( + TextSelection(baseOffset: graphemeStart, extentOffset: graphemeEnd), + ); + + final TextBox? box = boxes.isEmpty ? null : boxes.first; + if (box != null) { + final Rect paintBounds = renderEditable.paintBounds; + // Stop early when characters are already below the bottom edge of the + // RenderEditable, regardless of its clipBehavior. + if (paintBounds.bottom <= box.top) { + break; + } + // Include any TextBox which intersects with the RenderEditable. + if (paintBounds.left <= box.right && + box.left <= paintBounds.right && + paintBounds.top <= box.bottom) { + // At least some part of the letter is visible within the text field. + rects.add(SelectionRect( + position: graphemeStart, + bounds: box.toRect(), + direction: box.direction)); + } + } + graphemeStart = graphemeEnd; + } + _textInputConnection!.setSelectionRects(rects); + } + + // Sends the current composing rect to the embedder's text input plugin. + // + // In cases where the composing rect hasn't been updated in the embedder due + // to the lag of asynchronous messages over the channel, the position of the + // current caret rect is used instead. + // + // See: [_updateCaretRectIfNeeded] + void _updateComposingRectIfNeeded() { + final TextRange composingRange = _value.composing; + assert(mounted); + Rect? composingRect = + renderEditable.getRectForComposingRange(composingRange); + // Send the caret location instead if there's no marked text yet. + if (composingRect == null) { + final int offset = composingRange.isValid ? composingRange.start : 0; + composingRect = + renderEditable.getLocalRectForCaret(TextPosition(offset: offset)); + } + _textInputConnection!.setComposingRect(composingRect); + } + + // Sends the current caret rect to the embedder's text input plugin. + // + // The position of the caret rect is updated periodically such that if the + // user initiates composing input, the current cursor rect can be used for + // the first character until the composing rect can be sent. + // + // On selection changes, the start of the selection is used. This ensures + // that regardless of the direction the selection was created, the cursor is + // set to the position where next text input occurs. This position is used to + // position the IME's candidate selection menu. + // + // See: [_updateComposingRectIfNeeded] + void _updateCaretRectIfNeeded() { + final TextSelection? selection = renderEditable.selection; + if (selection == null || !selection.isValid) { + return; + } + final TextPosition currentTextPosition = + TextPosition(offset: selection.start); + final Rect caretRect = + renderEditable.getLocalRectForCaret(currentTextPosition); + _textInputConnection!.setCaretRect(caretRect); + } + + TextDirection get _textDirection => + widget.textDirection ?? Directionality.of(context); + + /// The renderer for this widget's descendant. + /// + /// This property is typically used to notify the renderer of input gestures + /// when [RenderEditable.ignorePointer] is true. + /// zmtzawqlp + late final _RenderEditable renderEditable = + _editableKey.currentContext!.findRenderObject()! as _RenderEditable; + + @override + TextEditingValue get textEditingValue => _value; + + double get _devicePixelRatio => MediaQuery.devicePixelRatioOf(context); + + @override + void userUpdateTextEditingValue( + TextEditingValue value, SelectionChangedCause? cause) { + // Compare the current TextEditingValue with the pre-format new + // TextEditingValue value, in case the formatter would reject the change. + final bool shouldShowCaret = + widget.readOnly ? _value.selection != value.selection : _value != value; + if (shouldShowCaret) { + _scheduleShowCaretOnScreen(withAnimation: true); + } + + // Even if the value doesn't change, it may be necessary to focus and build + // the selection overlay. For example, this happens when right clicking an + // unfocused field that previously had a selection in the same spot. + if (value == textEditingValue) { + if (!widget.focusNode.hasFocus) { + _flagInternalFocus(); + widget.focusNode.requestFocus(); + _selectionOverlay ??= _createSelectionOverlay(); + } + return; + } + + _formatAndSetValue(value, cause, userInteraction: true); + } + + @override + void bringIntoView(TextPosition position) { + final Rect localRect = renderEditable.getLocalRectForCaret(position); + final RevealedOffset targetOffset = _getOffsetToRevealCaret(localRect); + + _scrollController.jumpTo(targetOffset.offset); + renderEditable.showOnScreen(rect: targetOffset.rect); + } + + /// Shows the selection toolbar at the location of the current cursor. + /// + /// Returns `false` if a toolbar couldn't be shown, such as when the toolbar + /// is already shown, or when no text selection currently exists. + @override + bool showToolbar() { + // Web is using native dom elements to enable clipboard functionality of the + // context menu: copy, paste, select, cut. It might also provide additional + // functionality depending on the browser (such as translate). Due to this, + // we should not show a Flutter toolbar for the editable text elements + // unless the browser's context menu is explicitly disabled. + if (_webContextMenuEnabled) { + return false; + } + + if (_selectionOverlay == null) { + return false; + } + _liveTextInputStatus?.update(); + clipboardStatus.update(); + _selectionOverlay!.showToolbar(); + // Listen to parent scroll events when the toolbar is visible so it can be + // hidden during a scroll on supported platforms. + if (_platformSupportsFadeOnScroll) { + _listeningToScrollNotificationObserver = true; + _scrollNotificationObserver + ?.removeListener(_handleContextMenuOnParentScroll); + _scrollNotificationObserver = ScrollNotificationObserver.maybeOf(context); + _scrollNotificationObserver + ?.addListener(_handleContextMenuOnParentScroll); + } + return true; + } + + @override + void hideToolbar([bool hideHandles = true]) { + // Stop listening to parent scroll events when toolbar is hidden. + _disposeScrollNotificationObserver(); + if (hideHandles) { + // Hide the handles and the toolbar. + _selectionOverlay?.hide(); + } else if (_selectionOverlay?.toolbarIsVisible ?? false) { + // Hide only the toolbar but not the handles. + _selectionOverlay?.hideToolbar(); + } + } + + /// Toggles the visibility of the toolbar. + void toggleToolbar([bool hideHandles = true]) { + final _TextSelectionOverlay selectionOverlay = + _selectionOverlay ??= _createSelectionOverlay(); + if (selectionOverlay.toolbarIsVisible) { + hideToolbar(hideHandles); + } else { + showToolbar(); + } + } + + /// Shows toolbar with spell check suggestions of misspelled words that are + /// available for click-and-replace. + bool showSpellCheckSuggestionsToolbar() { + // Spell check suggestions toolbars are intended to be shown on non-web + // platforms. Additionally, the Cupertino style toolbar can't be drawn on + // the web with the HTML renderer due to + // https://github.com/flutter/flutter/issues/123560. + if (!spellCheckEnabled || + _webContextMenuEnabled || + widget.readOnly || + _selectionOverlay == null || + !_spellCheckResultsReceived || + findSuggestionSpanAtCursorIndex( + textEditingValue.selection.extentOffset) == + null) { + // Only attempt to show the spell check suggestions toolbar if there + // is a toolbar specified and spell check suggestions available to show. + return false; + } + + assert( + _spellCheckConfiguration.spellCheckSuggestionsToolbarBuilder != null, + 'spellCheckSuggestionsToolbarBuilder must be defined in ' + 'SpellCheckConfiguration to show a toolbar with spell check ' + 'suggestions', + ); + // zmtzawqlp + // _selectionOverlay! + // .showSpellCheckSuggestionsToolbar( + // (BuildContext context) { + // return _spellCheckConfiguration + // .spellCheckSuggestionsToolbarBuilder!( + // context, + // this, + // ); + // }, + // ); + return true; + } + + /// Shows the magnifier at the position given by `positionToShow`, + /// if there is no magnifier visible. + /// + /// Updates the magnifier to the position given by `positionToShow`, + /// if there is a magnifier visible. + /// + /// Does nothing if a magnifier couldn't be shown, such as when the selection + /// overlay does not currently exist. + void showMagnifier(Offset positionToShow) { + if (_selectionOverlay == null) { + return; + } + + if (_selectionOverlay!.magnifierIsVisible) { + _selectionOverlay!.updateMagnifier(positionToShow); + } else { + _selectionOverlay!.showMagnifier(positionToShow); + } + } + + /// Hides the magnifier if it is visible. + void hideMagnifier() { + if (_selectionOverlay == null) { + return; + } + + if (_selectionOverlay!.magnifierIsVisible) { + _selectionOverlay!.hideMagnifier(); + } + } + + // Tracks the location a [_ScribblePlaceholder] should be rendered in the + // text. + // + // A value of -1 indicates there should be no placeholder, otherwise the + // value should be between 0 and the length of the text, inclusive. + int _placeholderLocation = -1; + + @override + void insertTextPlaceholder(Size size) { + if (!widget.scribbleEnabled) { + return; + } + + if (!widget.controller.selection.isValid) { + return; + } + + setState(() { + _placeholderLocation = + _value.text.length - widget.controller.selection.end; + }); + } + + @override + void removeTextPlaceholder() { + if (!widget.scribbleEnabled || _placeholderLocation == -1) { + return; + } + + setState(() { + _placeholderLocation = -1; + }); + } + + @override + void performSelector(String selectorName) { + final Intent? intent = intentForMacOSSelector(selectorName); + + if (intent != null) { + final BuildContext? primaryContext = primaryFocus?.context; + if (primaryContext != null) { + Actions.invoke(primaryContext, intent); + } + } + } + + @override + String get autofillId => 'EditableText-$hashCode'; + + int? _viewId; + + @override + TextInputConfiguration get textInputConfiguration { + final List? autofillHints = + widget.autofillHints?.toList(growable: false); + final AutofillConfiguration autofillConfiguration = autofillHints != null + ? AutofillConfiguration( + uniqueIdentifier: autofillId, + autofillHints: autofillHints, + currentEditingValue: currentTextEditingValue, + ) + : AutofillConfiguration.disabled; + + _viewId = View.of(context).viewId; + return TextInputConfiguration( + viewId: _viewId, + inputType: widget.keyboardType, + readOnly: widget.readOnly, + obscureText: widget.obscureText, + autocorrect: widget.autocorrect, + smartDashesType: widget.smartDashesType, + smartQuotesType: widget.smartQuotesType, + enableSuggestions: widget.enableSuggestions, + enableInteractiveSelection: widget._userSelectionEnabled, + inputAction: widget.textInputAction ?? + (widget.keyboardType == TextInputType.multiline + ? TextInputAction.newline + : TextInputAction.done), + textCapitalization: widget.textCapitalization, + keyboardAppearance: widget.keyboardAppearance, + autofillConfiguration: autofillConfiguration, + enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning, + allowedMimeTypes: widget.contentInsertionConfiguration == null + ? const [] + : widget.contentInsertionConfiguration!.allowedMimeTypes, + ); + } + + @override + void autofill(TextEditingValue value) => updateEditingValue(value); + + // null if no promptRect should be shown. + TextRange? _currentPromptRectRange; + + @override + void showAutocorrectionPromptRect(int start, int end) { + setState(() { + _currentPromptRectRange = TextRange(start: start, end: end); + }); + } + + VoidCallback? _semanticsOnCopy(TextSelectionControls? controls) { + return widget.selectionEnabled && + _hasFocus && + (widget.selectionControls is TextSelectionHandleControls + ? copyEnabled + : copyEnabled && + (widget.selectionControls?.canCopy(this) ?? false)) + ? () { + controls?.handleCopy(this); + copySelection(SelectionChangedCause.toolbar); + } + : null; + } + + VoidCallback? _semanticsOnCut(TextSelectionControls? controls) { + return widget.selectionEnabled && + _hasFocus && + (widget.selectionControls is TextSelectionHandleControls + ? cutEnabled + : cutEnabled && + (widget.selectionControls?.canCut(this) ?? false)) + ? () { + controls?.handleCut(this); + cutSelection(SelectionChangedCause.toolbar); + } + : null; + } + + VoidCallback? _semanticsOnPaste(TextSelectionControls? controls) { + return widget.selectionEnabled && + _hasFocus && + (widget.selectionControls is TextSelectionHandleControls + ? pasteEnabled + : pasteEnabled && + (widget.selectionControls?.canPaste(this) ?? false)) && + (clipboardStatus.value == ClipboardStatus.pasteable) + ? () { + controls?.handlePaste(this); + pasteText(SelectionChangedCause.toolbar); + } + : null; + } + + // Returns the closest boundary location to `extent` but not including `extent` + // itself (unless already at the start/end of the text), in the direction + // specified by `forward`. + TextPosition _moveBeyondTextBoundary( + TextPosition extent, bool forward, TextBoundary textBoundary) { + assert(extent.offset >= 0); + final int newOffset = forward + ? textBoundary.getTrailingTextBoundaryAt(extent.offset) ?? + _value.text.length + // if x is a boundary defined by `textBoundary`, most textBoundaries (except + // LineBreaker) guarantees `x == textBoundary.getLeadingTextBoundaryAt(x)`. + // Use x - 1 here to make sure we don't get stuck at the fixed point x. + : textBoundary.getLeadingTextBoundaryAt(extent.offset - 1) ?? 0; + return TextPosition(offset: newOffset); + } + + // Returns the closest boundary location to `extent`, including `extent` + // itself, in the direction specified by `forward`. + // + // This method returns a fixed point of itself: applying `_toTextBoundary` + // again on the returned TextPosition gives the same TextPosition. It's used + // exclusively for handling line boundaries, since performing "move to line + // start" more than once usually doesn't move you to the previous line. + TextPosition _moveToTextBoundary( + TextPosition extent, bool forward, TextBoundary textBoundary) { + assert(extent.offset >= 0); + final int caretOffset; + switch (extent.affinity) { + case TextAffinity.upstream: + if (extent.offset < 1 && !forward) { + assert(extent.offset == 0); + return const TextPosition(offset: 0); + } + // When the text affinity is upstream, the caret is associated with the + // grapheme before the code unit at `extent.offset`. + // TODO(LongCatIsLooong): don't assume extent.offset is at a grapheme + // boundary, and do this instead: + // final int graphemeStart = CharacterRange.at(string, extent.offset).stringBeforeLength - 1; + caretOffset = math.max(0, extent.offset - 1); + case TextAffinity.downstream: + caretOffset = extent.offset; + } + // The line boundary range does not include some control characters + // (most notably, Line Feed), in which case there's + // `x ∉ getTextBoundaryAt(x)`. In case `caretOffset` points to one such + // control character, we define that these control characters themselves are + // still part of the previous line, but also exclude them from the + // line boundary range since they're non-printing. IOW, no additional + // processing needed since the LineBoundary class does exactly that. + return forward + ? TextPosition( + offset: textBoundary.getTrailingTextBoundaryAt(caretOffset) ?? + _value.text.length, + affinity: TextAffinity.upstream) + : TextPosition( + offset: textBoundary.getLeadingTextBoundaryAt(caretOffset) ?? 0); + } + + // --------------------------- Text Editing Actions --------------------------- + + TextBoundary _characterBoundary() => widget.obscureText + ? _CodePointBoundary(_value.text) + : CharacterBoundary(_value.text); + TextBoundary _nextWordBoundary() => widget.obscureText + ? _documentBoundary() + : renderEditable.wordBoundaries.moveByWordBoundary; + TextBoundary _linebreak() => + widget.obscureText ? _documentBoundary() : LineBoundary(renderEditable); + TextBoundary _paragraphBoundary() => ParagraphBoundary(_value.text); + TextBoundary _documentBoundary() => DocumentBoundary(_value.text); + + Action _makeOverridable(Action defaultAction) { + return Action.overridable( + context: context, defaultAction: defaultAction); + } + + /// Transpose the characters immediately before and after the current + /// collapsed selection. + /// + /// When the cursor is at the end of the text, transposes the last two + /// characters, if they exist. + /// + /// When the cursor is at the start of the text, does nothing. + void _transposeCharacters(TransposeCharactersIntent intent) { + if (_value.text.characters.length <= 1 || + !_value.selection.isCollapsed || + _value.selection.baseOffset == 0) { + return; + } + + final String text = _value.text; + final TextSelection selection = _value.selection; + final bool atEnd = selection.baseOffset == text.length; + final CharacterRange transposing = + CharacterRange.at(text, selection.baseOffset); + if (atEnd) { + transposing.moveBack(2); + } else { + transposing + ..moveBack() + ..expandNext(); + } + assert(transposing.currentCharacters.length == 2); + + userUpdateTextEditingValue( + TextEditingValue( + text: transposing.stringBefore + + transposing.currentCharacters.last + + transposing.currentCharacters.first + + transposing.stringAfter, + selection: TextSelection.collapsed( + offset: transposing.stringBeforeLength + transposing.current.length, + ), + ), + SelectionChangedCause.keyboard, + ); + } + + late final Action _transposeCharactersAction = + CallbackAction(onInvoke: _transposeCharacters); + + void _replaceText(ReplaceTextIntent intent) { + final TextEditingValue oldValue = _value; + final TextEditingValue newValue = intent.currentTextEditingValue.replaced( + intent.replacementRange, + intent.replacementText, + ); + userUpdateTextEditingValue(newValue, intent.cause); + + // If there's no change in text and selection (e.g. when selecting and + // pasting identical text), the widget won't be rebuilt on value update. + // Handle this by calling _didChangeTextEditingValue() so caret and scroll + // updates can happen. + if (newValue == oldValue) { + _didChangeTextEditingValue(); + } + } + + late final Action _replaceTextAction = + CallbackAction(onInvoke: _replaceText); + + // Scrolls either to the beginning or end of the document depending on the + // intent's `forward` parameter. + void _scrollToDocumentBoundary(ScrollToDocumentBoundaryIntent intent) { + if (intent.forward) { + bringIntoView(TextPosition(offset: _value.text.length)); + } else { + bringIntoView(const TextPosition(offset: 0)); + } + } + + /// Handles [ScrollIntent] by scrolling the [Scrollable] inside of + /// [EditableText]. + void _scroll(ScrollIntent intent) { + if (intent.type != ScrollIncrementType.page) { + return; + } + + final ScrollPosition position = _scrollController.position; + if (widget.maxLines == 1) { + _scrollController.jumpTo(position.maxScrollExtent); + return; + } + + // If the field isn't scrollable, do nothing. For example, when the lines of + // text is less than maxLines, the field has nothing to scroll. + if (position.maxScrollExtent == 0.0 && position.minScrollExtent == 0.0) { + return; + } + + final ScrollableState? state = + _scrollableKey.currentState as ScrollableState?; + final double increment = + ScrollAction.getDirectionalIncrement(state!, intent); + final double destination = clampDouble( + position.pixels + increment, + position.minScrollExtent, + position.maxScrollExtent, + ); + if (destination == position.pixels) { + return; + } + _scrollController.jumpTo(destination); + } + + void _updateSelection(UpdateSelectionIntent intent) { + assert( + intent.newSelection.start <= intent.currentTextEditingValue.text.length, + 'invalid selection: ${intent.newSelection}: it must not exceed the current text length ${intent.currentTextEditingValue.text.length}', + ); + assert( + intent.newSelection.end <= intent.currentTextEditingValue.text.length, + 'invalid selection: ${intent.newSelection}: it must not exceed the current text length ${intent.currentTextEditingValue.text.length}', + ); + + bringIntoView(intent.newSelection.extent); + userUpdateTextEditingValue( + intent.currentTextEditingValue.copyWith(selection: intent.newSelection), + intent.cause, + ); + } + + late final Action _updateSelectionAction = + CallbackAction(onInvoke: _updateSelection); + + late final _UpdateTextSelectionVerticallyAction< + DirectionalCaretMovementIntent> _verticalSelectionUpdateAction = + _UpdateTextSelectionVerticallyAction( + this); + + Object? _hideToolbarIfVisible(DismissIntent intent) { + if (_selectionOverlay?.toolbarIsVisible ?? false) { + hideToolbar(false); + return null; + } + return Actions.invoke(context, intent); + } + + /// The default behavior used if [onTapOutside] is null. + /// + /// The `event` argument is the [PointerDownEvent] that caused the notification. + void _defaultOnTapOutside(PointerDownEvent event) { + /// The focus dropping behavior is only present on desktop platforms + /// and mobile browsers. + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + // On mobile platforms, we don't unfocus on touch events unless they're + // in the web browser, but we do unfocus for all other kinds of events. + switch (event.kind) { + case ui.PointerDeviceKind.touch: + if (kIsWeb) { + widget.focusNode.unfocus(); + } + case ui.PointerDeviceKind.mouse: + case ui.PointerDeviceKind.stylus: + case ui.PointerDeviceKind.invertedStylus: + case ui.PointerDeviceKind.unknown: + widget.focusNode.unfocus(); + case ui.PointerDeviceKind.trackpad: + throw UnimplementedError( + 'Unexpected pointer down event for trackpad'); + } + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + widget.focusNode.unfocus(); + } + } + + late final Map> _actions = >{ + DoNothingAndStopPropagationTextIntent: DoNothingAction(consumesKey: false), + ReplaceTextIntent: _replaceTextAction, + UpdateSelectionIntent: _updateSelectionAction, + DirectionalFocusIntent: DirectionalFocusAction.forTextField(), + DismissIntent: + CallbackAction(onInvoke: _hideToolbarIfVisible), + + // Delete + DeleteCharacterIntent: _makeOverridable( + _DeleteTextAction( + this, _characterBoundary, _moveBeyondTextBoundary)), + DeleteToNextWordBoundaryIntent: _makeOverridable( + _DeleteTextAction( + this, _nextWordBoundary, _moveBeyondTextBoundary)), + DeleteToLineBreakIntent: _makeOverridable( + _DeleteTextAction( + this, _linebreak, _moveToTextBoundary)), + + // Extend/Move Selection + ExtendSelectionByCharacterIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _characterBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: false)), + ExtendSelectionToNextWordBoundaryIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _nextWordBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: true)), + ExtendSelectionToNextParagraphBoundaryIntent: _makeOverridable( + _UpdateTextSelectionAction< + ExtendSelectionToNextParagraphBoundaryIntent>( + this, _paragraphBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: true)), + ExtendSelectionToLineBreakIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _linebreak, _moveToTextBoundary, + ignoreNonCollapsedSelection: true)), + ExtendSelectionVerticallyToAdjacentLineIntent: + _makeOverridable(_verticalSelectionUpdateAction), + ExtendSelectionVerticallyToAdjacentPageIntent: + _makeOverridable(_verticalSelectionUpdateAction), + ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent: + _makeOverridable(_UpdateTextSelectionAction< + ExtendSelectionToNextParagraphBoundaryOrCaretLocationIntent>( + this, _paragraphBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: true)), + ExtendSelectionToDocumentBoundaryIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _documentBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: true)), + ExtendSelectionToNextWordBoundaryOrCaretLocationIntent: _makeOverridable( + _UpdateTextSelectionAction< + ExtendSelectionToNextWordBoundaryOrCaretLocationIntent>( + this, _nextWordBoundary, _moveBeyondTextBoundary, + ignoreNonCollapsedSelection: true)), + ScrollToDocumentBoundaryIntent: _makeOverridable( + CallbackAction( + onInvoke: _scrollToDocumentBoundary)), + ScrollIntent: CallbackAction(onInvoke: _scroll), + + // Expand Selection + ExpandSelectionToLineBreakIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _linebreak, _moveToTextBoundary, + ignoreNonCollapsedSelection: true, isExpand: true)), + ExpandSelectionToDocumentBoundaryIntent: _makeOverridable( + _UpdateTextSelectionAction( + this, _documentBoundary, _moveToTextBoundary, + ignoreNonCollapsedSelection: true, + isExpand: true, + extentAtIndex: true)), + + // Copy Paste + SelectAllTextIntent: _makeOverridable(_SelectAllAction(this)), + CopySelectionTextIntent: _makeOverridable(_CopySelectionAction(this)), + PasteTextIntent: _makeOverridable(CallbackAction( + onInvoke: (PasteTextIntent intent) => pasteText(intent.cause))), + + TransposeCharactersIntent: _makeOverridable(_transposeCharactersAction), + }; + + // zmtzawqlp + // @override + // Widget build(BuildContext context) { + // assert(debugCheckHasMediaQuery(context)); + // super.build(context); // See AutomaticKeepAliveClientMixin. + + // final TextSelectionControls? controls = widget.selectionControls; + // final TextScaler effectiveTextScaler = + // switch ((widget.textScaler, widget.textScaleFactor)) { + // (final TextScaler textScaler, _) => textScaler, + // (null, final double textScaleFactor) => + // TextScaler.linear(textScaleFactor), + // (null, null) => MediaQuery.textScalerOf(context), + // }; + + // return _CompositionCallback( + // compositeCallback: _compositeCallback, + // enabled: _hasInputConnection, + // child: TextFieldTapRegion( + // groupId: widget.groupId, + // onTapOutside: + // _hasFocus ? widget.onTapOutside ?? _defaultOnTapOutside : null, + // debugLabel: kReleaseMode ? null : 'EditableText', + // child: MouseRegion( + // cursor: widget.mouseCursor ?? SystemMouseCursors.text, + // child: Actions( + // actions: _actions, + // child: UndoHistory( + // value: widget.controller, + // onTriggered: (TextEditingValue value) { + // userUpdateTextEditingValue( + // value, SelectionChangedCause.keyboard); + // }, + // shouldChangeUndoStack: + // (TextEditingValue? oldValue, TextEditingValue newValue) { + // if (!newValue.selection.isValid) { + // return false; + // } + + // if (oldValue == null) { + // return true; + // } + + // switch (defaultTargetPlatform) { + // case TargetPlatform.iOS: + // case TargetPlatform.macOS: + // case TargetPlatform.fuchsia: + // case TargetPlatform.linux: + // case TargetPlatform.windows: + // // Composing text is not counted in history coalescing. + // if (!widget.controller.value.composing.isCollapsed) { + // return false; + // } + // case TargetPlatform.android: + // // Gboard on Android puts non-CJK words in composing regions. Coalesce + // // composing text in order to allow the saving of partial words in that + // // case. + // break; + // } + + // return oldValue.text != newValue.text || + // oldValue.composing != newValue.composing; + // }, + // undoStackModifier: (TextEditingValue value) { + // // On Android we should discard the composing region when pushing + // // a new entry to the undo stack. This prevents the TextInputPlugin + // // from restarting the input on every undo/redo when the composing + // // region is changed by the framework. + // return defaultTargetPlatform == TargetPlatform.android + // ? value.copyWith(composing: TextRange.empty) + // : value; + // }, + // focusNode: widget.focusNode, + // controller: widget.undoController, + // child: Focus( + // focusNode: widget.focusNode, + // includeSemantics: false, + // debugLabel: kReleaseMode ? null : 'EditableText', + // child: NotificationListener( + // onNotification: (ScrollNotification notification) { + // _handleContextMenuOnScroll(notification); + // _scribbleCacheKey = null; + // return false; + // }, + // child: Scrollable( + // key: _scrollableKey, + // excludeFromSemantics: true, + // axisDirection: + // _isMultiline ? AxisDirection.down : AxisDirection.right, + // controller: _scrollController, + // physics: widget.scrollPhysics, + // dragStartBehavior: widget.dragStartBehavior, + // restorationId: widget.restorationId, + // // If a ScrollBehavior is not provided, only apply scrollbars when + // // multiline. The overscroll indicator should not be applied in + // // either case, glowing or stretching. + // scrollBehavior: widget.scrollBehavior ?? + // ScrollConfiguration.of(context).copyWith( + // scrollbars: _isMultiline, + // overscroll: false, + // ), + // viewportBuilder: + // (BuildContext context, ViewportOffset offset) { + // return CompositedTransformTarget( + // link: _toolbarLayerLink, + // child: Semantics( + // onCopy: _semanticsOnCopy(controls), + // onCut: _semanticsOnCut(controls), + // onPaste: _semanticsOnPaste(controls), + // child: _ScribbleFocusable( + // focusNode: widget.focusNode, + // editableKey: _editableKey, + // enabled: widget.scribbleEnabled, + // updateSelectionRects: () { + // _openInputConnection(); + // _updateSelectionRects(force: true); + // }, + // child: SizeChangedLayoutNotifier( + // child: _Editable( + // key: _editableKey, + // startHandleLayerLink: _startHandleLayerLink, + // endHandleLayerLink: _endHandleLayerLink, + // inlineSpan: buildTextSpan(), + // value: _value, + // cursorColor: _cursorColor, + // backgroundCursorColor: + // widget.backgroundCursorColor, + // showCursor: _cursorVisibilityNotifier, + // forceLine: widget.forceLine, + // readOnly: widget.readOnly, + // hasFocus: _hasFocus, + // maxLines: widget.maxLines, + // minLines: widget.minLines, + // expands: widget.expands, + // strutStyle: widget.strutStyle, + // selectionColor: _selectionOverlay + // ?.spellCheckToolbarIsVisible ?? + // false + // ? _spellCheckConfiguration + // .misspelledSelectionColor ?? + // widget.selectionColor + // : widget.selectionColor, + // textScaler: effectiveTextScaler, + // textAlign: widget.textAlign, + // textDirection: _textDirection, + // locale: widget.locale, + // textHeightBehavior: widget.textHeightBehavior ?? + // DefaultTextHeightBehavior.maybeOf(context), + // textWidthBasis: widget.textWidthBasis, + // obscuringCharacter: widget.obscuringCharacter, + // obscureText: widget.obscureText, + // offset: offset, + // rendererIgnoresPointer: + // widget.rendererIgnoresPointer, + // cursorWidth: widget.cursorWidth, + // cursorHeight: widget.cursorHeight, + // cursorRadius: widget.cursorRadius, + // cursorOffset: + // widget.cursorOffset ?? Offset.zero, + // selectionHeightStyle: + // widget.selectionHeightStyle, + // selectionWidthStyle: widget.selectionWidthStyle, + // paintCursorAboveText: + // widget.paintCursorAboveText, + // enableInteractiveSelection: + // widget._userSelectionEnabled, + // textSelectionDelegate: this, + // devicePixelRatio: _devicePixelRatio, + // promptRectRange: _currentPromptRectRange, + // promptRectColor: + // widget.autocorrectionTextRectColor, + // clipBehavior: widget.clipBehavior, + // ), + // ), + // ), + // ), + // ); + // }, + // ), + // ), + // ), + // ), + // ), + // ), + // ), + // ); + // } + + /// Builds [TextSpan] from current editing value. + /// + /// By default makes text in composing range appear as underlined. + /// Descendants can override this method to customize appearance of text. + TextSpan buildTextSpan() { + if (widget.obscureText) { + String text = _value.text; + text = widget.obscuringCharacter * text.length; + // Reveal the latest character in an obscured field only on mobile. + // Newer versions of iOS (iOS 15+) no longer reveal the most recently + // entered character. + const Set mobilePlatforms = { + TargetPlatform.android, + TargetPlatform.fuchsia, + }; + final bool brieflyShowPassword = + WidgetsBinding.instance.platformDispatcher.brieflyShowPassword && + mobilePlatforms.contains(defaultTargetPlatform); + if (brieflyShowPassword) { + final int? o = + _obscureShowCharTicksPending > 0 ? _obscureLatestCharIndex : null; + if (o != null && o >= 0 && o < text.length) { + text = text.replaceRange(o, o + 1, _value.text.substring(o, o + 1)); + } + } + return TextSpan(style: _style, text: text); + } + if (_placeholderLocation >= 0 && + _placeholderLocation <= _value.text.length) { + final List<_ScribblePlaceholder> placeholders = <_ScribblePlaceholder>[]; + final int placeholderLocation = _value.text.length - _placeholderLocation; + if (_isMultiline) { + // The zero size placeholder here allows the line to break and keep the caret on the first line. + placeholders.add(const _ScribblePlaceholder( + child: SizedBox.shrink(), size: Size.zero)); + placeholders.add(_ScribblePlaceholder( + child: const SizedBox.shrink(), + size: Size(renderEditable.size.width, 0.0))); + } else { + placeholders.add(const _ScribblePlaceholder( + child: SizedBox.shrink(), size: Size(100.0, 0.0))); + } + return TextSpan( + style: _style, + children: [ + TextSpan(text: _value.text.substring(0, placeholderLocation)), + ...placeholders, + TextSpan(text: _value.text.substring(placeholderLocation)), + ], + ); + } + final bool withComposing = !widget.readOnly && _hasFocus; + if (_spellCheckResultsReceived) { + // If the composing range is out of range for the current text, ignore it to + // preserve the tree integrity, otherwise in release mode a RangeError will + // be thrown and this EditableText will be built with a broken subtree. + assert(!_value.composing.isValid || + !withComposing || + _value.isComposingRangeValid); + + final bool composingRegionOutOfRange = + !_value.isComposingRangeValid || !withComposing; + + return buildTextSpanWithSpellCheckSuggestions( + _value, + composingRegionOutOfRange, + _style, + _spellCheckConfiguration.misspelledTextStyle!, + spellCheckResults!, + ); + } + + // Read only mode should not paint text composing. + return widget.controller.buildTextSpan( + context: context, + style: _style, + withComposing: withComposing, + ); + } +} + +class _Editable extends MultiChildRenderObjectWidget { + _Editable({ + super.key, + required this.inlineSpan, + required this.value, + required this.startHandleLayerLink, + required this.endHandleLayerLink, + this.cursorColor, + this.backgroundCursorColor, + required this.showCursor, + required this.forceLine, + required this.readOnly, + this.textHeightBehavior, + required this.textWidthBasis, + required this.hasFocus, + required this.maxLines, + this.minLines, + required this.expands, + this.strutStyle, + this.selectionColor, + required this.textScaler, + required this.textAlign, + required this.textDirection, + this.locale, + required this.obscuringCharacter, + required this.obscureText, + required this.offset, + this.rendererIgnoresPointer = false, + required this.cursorWidth, + this.cursorHeight, + this.cursorRadius, + required this.cursorOffset, + required this.paintCursorAboveText, + this.selectionHeightStyle = ui.BoxHeightStyle.tight, + this.selectionWidthStyle = ui.BoxWidthStyle.tight, + this.enableInteractiveSelection = true, + required this.textSelectionDelegate, + required this.devicePixelRatio, + this.promptRectRange, + this.promptRectColor, + required this.clipBehavior, + }) : super( + children: WidgetSpan.extractFromInlineSpan(inlineSpan, textScaler)); + + final InlineSpan inlineSpan; + final TextEditingValue value; + final Color? cursorColor; + final LayerLink startHandleLayerLink; + final LayerLink endHandleLayerLink; + final Color? backgroundCursorColor; + final ValueNotifier showCursor; + final bool forceLine; + final bool readOnly; + final bool hasFocus; + final int? maxLines; + final int? minLines; + final bool expands; + final StrutStyle? strutStyle; + final Color? selectionColor; + final TextScaler textScaler; + final TextAlign textAlign; + final TextDirection textDirection; + final Locale? locale; + final String obscuringCharacter; + final bool obscureText; + final TextHeightBehavior? textHeightBehavior; + final TextWidthBasis textWidthBasis; + final ViewportOffset offset; + final bool rendererIgnoresPointer; + final double cursorWidth; + final double? cursorHeight; + final Radius? cursorRadius; + final Offset cursorOffset; + final bool paintCursorAboveText; + final ui.BoxHeightStyle selectionHeightStyle; + final ui.BoxWidthStyle selectionWidthStyle; + final bool enableInteractiveSelection; + final TextSelectionDelegate textSelectionDelegate; + final double devicePixelRatio; + final TextRange? promptRectRange; + final Color? promptRectColor; + final Clip clipBehavior; + + // zmtzawqlp + @override + _RenderEditable createRenderObject(BuildContext context) { + return _RenderEditable( + text: inlineSpan, + cursorColor: cursorColor, + startHandleLayerLink: startHandleLayerLink, + endHandleLayerLink: endHandleLayerLink, + backgroundCursorColor: backgroundCursorColor, + showCursor: showCursor, + forceLine: forceLine, + readOnly: readOnly, + hasFocus: hasFocus, + maxLines: maxLines, + minLines: minLines, + expands: expands, + strutStyle: strutStyle, + selectionColor: selectionColor, + textScaler: textScaler, + textAlign: textAlign, + textDirection: textDirection, + locale: locale ?? Localizations.maybeLocaleOf(context), + selection: value.selection, + offset: offset, + ignorePointer: rendererIgnoresPointer, + obscuringCharacter: obscuringCharacter, + obscureText: obscureText, + textHeightBehavior: textHeightBehavior, + textWidthBasis: textWidthBasis, + cursorWidth: cursorWidth, + cursorHeight: cursorHeight, + cursorRadius: cursorRadius, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + selectionHeightStyle: selectionHeightStyle, + selectionWidthStyle: selectionWidthStyle, + enableInteractiveSelection: enableInteractiveSelection, + textSelectionDelegate: textSelectionDelegate, + devicePixelRatio: devicePixelRatio, + promptRectRange: promptRectRange, + promptRectColor: promptRectColor, + clipBehavior: clipBehavior, + ); + } + + // zmtzawqlp + @override + void updateRenderObject(BuildContext context, _RenderEditable renderObject) { + renderObject + ..text = inlineSpan + ..cursorColor = cursorColor + ..startHandleLayerLink = startHandleLayerLink + ..endHandleLayerLink = endHandleLayerLink + ..backgroundCursorColor = backgroundCursorColor + ..showCursor = showCursor + ..forceLine = forceLine + ..readOnly = readOnly + ..hasFocus = hasFocus + ..maxLines = maxLines + ..minLines = minLines + ..expands = expands + ..strutStyle = strutStyle + ..selectionColor = selectionColor + ..textScaler = textScaler + ..textAlign = textAlign + ..textDirection = textDirection + ..locale = locale ?? Localizations.maybeLocaleOf(context) + ..selection = value.selection + ..offset = offset + ..ignorePointer = rendererIgnoresPointer + ..textHeightBehavior = textHeightBehavior + ..textWidthBasis = textWidthBasis + ..obscuringCharacter = obscuringCharacter + ..obscureText = obscureText + ..cursorWidth = cursorWidth + ..cursorHeight = cursorHeight + ..cursorRadius = cursorRadius + ..cursorOffset = cursorOffset + ..selectionHeightStyle = selectionHeightStyle + ..selectionWidthStyle = selectionWidthStyle + ..enableInteractiveSelection = enableInteractiveSelection + ..textSelectionDelegate = textSelectionDelegate + ..devicePixelRatio = devicePixelRatio + ..paintCursorAboveText = paintCursorAboveText + ..promptRectColor = promptRectColor + ..clipBehavior = clipBehavior + ..setPromptRectRange(promptRectRange); + } +} + +@immutable +class _ScribbleCacheKey { + const _ScribbleCacheKey({ + required this.inlineSpan, + required this.textAlign, + required this.textDirection, + required this.textScaler, + required this.textHeightBehavior, + required this.locale, + required this.structStyle, + required this.placeholder, + required this.size, + }); + + final TextAlign textAlign; + final TextDirection textDirection; + final TextScaler textScaler; + final TextHeightBehavior? textHeightBehavior; + final Locale? locale; + final StrutStyle structStyle; + final int placeholder; + final Size size; + final InlineSpan inlineSpan; + + RenderComparison compare(_ScribbleCacheKey other) { + if (identical(other, this)) { + return RenderComparison.identical; + } + final bool needsLayout = textAlign != other.textAlign || + textDirection != other.textDirection || + textScaler != other.textScaler || + (textHeightBehavior ?? const TextHeightBehavior()) != + (other.textHeightBehavior ?? const TextHeightBehavior()) || + locale != other.locale || + structStyle != other.structStyle || + placeholder != other.placeholder || + size != other.size; + return needsLayout + ? RenderComparison.layout + : inlineSpan.compareTo(other.inlineSpan); + } +} + +class _ScribbleFocusable extends StatefulWidget { + const _ScribbleFocusable({ + required this.child, + required this.focusNode, + required this.editableKey, + required this.updateSelectionRects, + required this.enabled, + }); + + final Widget child; + final FocusNode focusNode; + final GlobalKey editableKey; + final VoidCallback updateSelectionRects; + final bool enabled; + + @override + _ScribbleFocusableState createState() => _ScribbleFocusableState(); +} + +class _ScribbleFocusableState extends State<_ScribbleFocusable> + implements ScribbleClient { + _ScribbleFocusableState() + : _elementIdentifier = (_nextElementIdentifier++).toString(); + + @override + void initState() { + super.initState(); + if (widget.enabled) { + TextInput.registerScribbleElement(elementIdentifier, this); + } + } + + @override + void didUpdateWidget(_ScribbleFocusable oldWidget) { + super.didUpdateWidget(oldWidget); + if (!oldWidget.enabled && widget.enabled) { + TextInput.registerScribbleElement(elementIdentifier, this); + } + + if (oldWidget.enabled && !widget.enabled) { + TextInput.unregisterScribbleElement(elementIdentifier); + } + } + + @override + void dispose() { + TextInput.unregisterScribbleElement(elementIdentifier); + super.dispose(); + } + + // zmtzawqlp + _RenderEditable? get renderEditable => + widget.editableKey.currentContext?.findRenderObject() as _RenderEditable?; + + static int _nextElementIdentifier = 1; + final String _elementIdentifier; + + @override + String get elementIdentifier => _elementIdentifier; + + @override + void onScribbleFocus(Offset offset) { + widget.focusNode.requestFocus(); + renderEditable?.selectPositionAt( + from: offset, cause: SelectionChangedCause.scribble); + widget.updateSelectionRects(); + } + + @override + bool isInScribbleRect(Rect rect) { + final Rect calculatedBounds = bounds; + if (renderEditable?.readOnly ?? false) { + return false; + } + if (calculatedBounds == Rect.zero) { + return false; + } + if (!calculatedBounds.overlaps(rect)) { + return false; + } + final Rect intersection = calculatedBounds.intersect(rect); + final HitTestResult result = HitTestResult(); + WidgetsBinding.instance + .hitTestInView(result, intersection.center, View.of(context).viewId); + return result.path + .any((HitTestEntry entry) => entry.target == renderEditable); + } + + @override + Rect get bounds { + final RenderBox? box = context.findRenderObject() as RenderBox?; + if (box == null || !mounted || !box.attached) { + return Rect.zero; + } + final Matrix4 transform = box.getTransformTo(null); + return MatrixUtils.transformRect( + transform, Rect.fromLTWH(0, 0, box.size.width, box.size.height)); + } + + @override + Widget build(BuildContext context) { + return widget.child; + } +} + +class _ScribblePlaceholder extends WidgetSpan { + const _ScribblePlaceholder({ + required super.child, + required this.size, + }); + + /// The size of the span, used in place of adding a placeholder size to the [TextPainter]. + final Size size; + + @override + void build( + ui.ParagraphBuilder builder, { + TextScaler textScaler = TextScaler.noScaling, + List? dimensions, + }) { + assert(debugAssertIsValid()); + final bool hasStyle = style != null; + if (hasStyle) { + builder.pushStyle(style!.getTextStyle(textScaler: textScaler)); + } + builder.addPlaceholder(size.width, size.height, alignment); + if (hasStyle) { + builder.pop(); + } + } +} + +/// A text boundary that uses code points as logical boundaries. +/// +/// A code point represents a single character. This may be smaller than what is +/// represented by a user-perceived character, or grapheme. For example, a +/// single grapheme (in this case a Unicode extended grapheme cluster) like +/// "👨‍👩‍👦" consists of five code points: the man emoji, a zero +/// width joiner, the woman emoji, another zero width joiner, and the boy emoji. +/// The [String] has a length of eight because each emoji consists of two code +/// units. +/// +/// Code units are the units by which Dart's String class is measured, which is +/// encoded in UTF-16. +/// +/// See also: +/// +/// * [String.runes], which deals with code points like this class. +/// * [String.characters], which deals with graphemes. +/// * [CharacterBoundary], which is a [TextBoundary] like this class, but whose +/// boundaries are graphemes instead of code points. +class _CodePointBoundary extends TextBoundary { + const _CodePointBoundary(this._text); + + final String _text; + + // Returns true if the given position falls in the center of a surrogate pair. + bool _breaksSurrogatePair(int position) { + assert(position > 0 && position < _text.length && _text.length > 1); + return TextPainter.isHighSurrogate(_text.codeUnitAt(position - 1)) && + TextPainter.isLowSurrogate(_text.codeUnitAt(position)); + } + + @override + int? getLeadingTextBoundaryAt(int position) { + if (_text.isEmpty || position < 0) { + return null; + } + if (position == 0) { + return 0; + } + if (position >= _text.length) { + return _text.length; + } + if (_text.length <= 1) { + return position; + } + + return _breaksSurrogatePair(position) ? position - 1 : position; + } + + @override + int? getTrailingTextBoundaryAt(int position) { + if (_text.isEmpty || position >= _text.length) { + return null; + } + if (position < 0) { + return 0; + } + if (position == _text.length - 1) { + return _text.length; + } + if (_text.length <= 1) { + return position; + } + + return _breaksSurrogatePair(position + 1) ? position + 2 : position + 1; + } +} + +// ------------------------------- Text Actions ------------------------------- +class _DeleteTextAction + extends ContextAction { + _DeleteTextAction(this.state, this.getTextBoundary, this._applyTextBoundary); + + /// zmtzawqlp + final _EditableTextState state; + final TextBoundary Function() getTextBoundary; + final _ApplyTextBoundary _applyTextBoundary; + + @override + Object? invoke(T intent, [BuildContext? context]) { + final TextSelection selection = state._value.selection; + if (!selection.isValid) { + return null; + } + assert(selection.isValid); + // Expands the selection to ensure the range covers full graphemes. + final TextBoundary atomicBoundary = state._characterBoundary(); + if (!selection.isCollapsed) { + // Expands the selection to ensure the range covers full graphemes. + final TextRange range = TextRange( + start: atomicBoundary.getLeadingTextBoundaryAt(selection.start) ?? + state._value.text.length, + end: atomicBoundary.getTrailingTextBoundaryAt(selection.end - 1) ?? 0, + ); + return Actions.invoke( + context!, + ReplaceTextIntent( + state._value, '', range, SelectionChangedCause.keyboard), + ); + } + + final int target = + _applyTextBoundary(selection.base, intent.forward, getTextBoundary()) + .offset; + + final TextRange rangeToDelete = TextSelection( + baseOffset: intent.forward + ? atomicBoundary.getLeadingTextBoundaryAt(selection.baseOffset) ?? + state._value.text.length + : atomicBoundary + .getTrailingTextBoundaryAt(selection.baseOffset - 1) ?? + 0, + extentOffset: target, + ); + return Actions.invoke( + context!, + ReplaceTextIntent( + state._value, '', rangeToDelete, SelectionChangedCause.keyboard), + ); + } + + @override + bool get isActionEnabled => + !state.widget.readOnly && state._value.selection.isValid; +} + +class _UpdateTextSelectionAction + extends ContextAction { + _UpdateTextSelectionAction( + this.state, + this.getTextBoundary, + this.applyTextBoundary, { + required this.ignoreNonCollapsedSelection, + this.isExpand = false, + this.extentAtIndex = false, + }); + + /// zmtzawqlp + final _EditableTextState state; + final bool ignoreNonCollapsedSelection; + final bool isExpand; + final bool extentAtIndex; + final TextBoundary Function() getTextBoundary; + final _ApplyTextBoundary applyTextBoundary; + + static const int NEWLINE_CODE_UNIT = 10; + + // Returns true iff the given position is at a wordwrap boundary in the + // upstream position. + bool _isAtWordwrapUpstream(TextPosition position) { + final TextPosition end = TextPosition( + offset: state.renderEditable.getLineAtOffset(position).end, + affinity: TextAffinity.upstream, + ); + return end == position && + end.offset != state.textEditingValue.text.length && + state.textEditingValue.text.codeUnitAt(position.offset) != + NEWLINE_CODE_UNIT; + } + + // Returns true if the given position at a wordwrap boundary in the + // downstream position. + bool _isAtWordwrapDownstream(TextPosition position) { + final TextPosition start = TextPosition( + offset: state.renderEditable.getLineAtOffset(position).start, + ); + return start == position && + start.offset != 0 && + state.textEditingValue.text.codeUnitAt(position.offset - 1) != + NEWLINE_CODE_UNIT; + } + + @override + Object? invoke(T intent, [BuildContext? context]) { + final TextSelection selection = state._value.selection; + assert(selection.isValid); + + final bool collapseSelection = + intent.collapseSelection || !state.widget.selectionEnabled; + if (!selection.isCollapsed && + !ignoreNonCollapsedSelection && + collapseSelection) { + return Actions.invoke( + context!, + UpdateSelectionIntent( + state._value, + TextSelection.collapsed( + offset: intent.forward ? selection.end : selection.start), + SelectionChangedCause.keyboard, + )); + } + + TextPosition extent = selection.extent; + // If continuesAtWrap is true extent and is at the relevant wordwrap, then + // move it just to the other side of the wordwrap. + if (intent.continuesAtWrap) { + if (intent.forward && _isAtWordwrapUpstream(extent)) { + extent = TextPosition( + offset: extent.offset, + ); + } else if (!intent.forward && _isAtWordwrapDownstream(extent)) { + extent = TextPosition( + offset: extent.offset, + affinity: TextAffinity.upstream, + ); + } + } + + final bool shouldTargetBase = isExpand && + (intent.forward + ? selection.baseOffset > selection.extentOffset + : selection.baseOffset < selection.extentOffset); + final TextPosition newExtent = applyTextBoundary( + shouldTargetBase ? selection.base : extent, + intent.forward, + getTextBoundary()); + final TextSelection newSelection = collapseSelection || + (!isExpand && newExtent.offset == selection.baseOffset) + ? TextSelection.fromPosition(newExtent) + : isExpand + ? selection.expandTo( + newExtent, extentAtIndex || selection.isCollapsed) + : selection.extendTo(newExtent); + + final bool shouldCollapseToBase = intent.collapseAtReversal && + (selection.baseOffset - selection.extentOffset) * + (selection.baseOffset - newSelection.extentOffset) < + 0; + final TextSelection newRange = shouldCollapseToBase + ? TextSelection.fromPosition(selection.base) + : newSelection; + return Actions.invoke( + context!, + UpdateSelectionIntent( + state._value, newRange, SelectionChangedCause.keyboard)); + } + + @override + bool get isActionEnabled => state._value.selection.isValid; +} + +class _UpdateTextSelectionVerticallyAction< + T extends DirectionalCaretMovementIntent> extends ContextAction { + _UpdateTextSelectionVerticallyAction(this.state); + + /// zmtzawqlp + final _EditableTextState state; + + VerticalCaretMovementRun? _verticalMovementRun; + TextSelection? _runSelection; + + void stopCurrentVerticalRunIfSelectionChanges() { + final TextSelection? runSelection = _runSelection; + if (runSelection == null) { + assert(_verticalMovementRun == null); + return; + } + _runSelection = state._value.selection; + final TextSelection currentSelection = state.widget.controller.selection; + final bool continueCurrentRun = currentSelection.isValid && + currentSelection.isCollapsed && + currentSelection.baseOffset == runSelection.baseOffset && + currentSelection.extentOffset == runSelection.extentOffset; + if (!continueCurrentRun) { + _verticalMovementRun = null; + _runSelection = null; + } + } + + @override + void invoke(T intent, [BuildContext? context]) { + assert(state._value.selection.isValid); + + final bool collapseSelection = + intent.collapseSelection || !state.widget.selectionEnabled; + final TextEditingValue value = state._textEditingValueforTextLayoutMetrics; + if (!value.selection.isValid) { + return; + } + + if (_verticalMovementRun?.isValid == false) { + _verticalMovementRun = null; + _runSelection = null; + } + + final VerticalCaretMovementRun currentRun = _verticalMovementRun ?? + state.renderEditable + .startVerticalCaretMovement(state.renderEditable.selection!.extent); + + final bool shouldMove = intent + is ExtendSelectionVerticallyToAdjacentPageIntent + ? currentRun.moveByOffset( + (intent.forward ? 1.0 : -1.0) * state.renderEditable.size.height) + : intent.forward + ? currentRun.moveNext() + : currentRun.movePrevious(); + final TextPosition newExtent = shouldMove + ? currentRun.current + : intent.forward + ? TextPosition(offset: value.text.length) + : const TextPosition(offset: 0); + final TextSelection newSelection = collapseSelection + ? TextSelection.fromPosition(newExtent) + : value.selection.extendTo(newExtent); + + Actions.invoke( + context!, + UpdateSelectionIntent( + value, newSelection, SelectionChangedCause.keyboard), + ); + if (state._value.selection == newSelection) { + _verticalMovementRun = currentRun; + _runSelection = newSelection; + } + } + + @override + bool get isActionEnabled => state._value.selection.isValid; +} + +class _SelectAllAction extends ContextAction { + _SelectAllAction(this.state); + + /// zmtzawqlp + final _EditableTextState state; + + @override + Object? invoke(SelectAllTextIntent intent, [BuildContext? context]) { + return Actions.invoke( + context!, + UpdateSelectionIntent( + state._value, + TextSelection(baseOffset: 0, extentOffset: state._value.text.length), + intent.cause, + ), + ); + } + + @override + bool get isActionEnabled => state.widget.selectionEnabled; +} + +class _CopySelectionAction extends ContextAction { + _CopySelectionAction(this.state); + + /// zmtzawqlp + final _EditableTextState state; + + @override + void invoke(CopySelectionTextIntent intent, [BuildContext? context]) { + if (intent.collapseSelection) { + state.cutSelection(intent.cause); + } else { + state.copySelection(intent.cause); + } + } + + @override + bool get isActionEnabled => + state._value.selection.isValid && !state._value.selection.isCollapsed; +} + +/// A [ClipboardStatusNotifier] whose [value] is hardcoded to +/// [ClipboardStatus.pasteable]. +/// +/// Useful to avoid showing a permission dialog on web, which happens when +/// [Clipboard.hasStrings] is called. +class _WebClipboardStatusNotifier extends ClipboardStatusNotifier { + @override + ClipboardStatus value = ClipboardStatus.pasteable; + + @override + Future update() { + return Future.value(); + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/spell_check.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/spell_check.dart new file mode 100644 index 0000000..627e392 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/spell_check.dart @@ -0,0 +1,419 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [SpellCheckConfiguration] +/// Controls how spell check is performed for text input. +/// +/// This configuration determines the [SpellCheckService] used to fetch the +/// [List] spell check results and the [TextStyle] used to +/// mark misspelled words within text input. +@immutable +class _SpellCheckConfiguration { + /// Creates a configuration that specifies the service and suggestions handler + /// for spell check. + const _SpellCheckConfiguration({ + this.spellCheckService, + this.misspelledSelectionColor, + this.misspelledTextStyle, + this.spellCheckSuggestionsToolbarBuilder, + }) : _spellCheckEnabled = true; + + /// Creates a configuration that disables spell check. + const _SpellCheckConfiguration.disabled() + : _spellCheckEnabled = false, + spellCheckService = null, + spellCheckSuggestionsToolbarBuilder = null, + misspelledTextStyle = null, + misspelledSelectionColor = null; + + /// The service used to fetch spell check results for text input. + final SpellCheckService? spellCheckService; + + /// The color the paint the selection highlight when spell check is showing + /// suggestions for a misspelled word. + /// + /// For example, on iOS, the selection appears red while the spell check menu + /// is showing. + final Color? misspelledSelectionColor; + + /// Style used to indicate misspelled words. + /// + /// This is nullable to allow style-specific wrappers of [EditableText] + /// to infer this, but this must be specified if this configuration is + /// provided directly to [EditableText] or its construction will fail with an + /// assertion error. + final TextStyle? misspelledTextStyle; + + /// Builds the toolbar used to display spell check suggestions for misspelled + /// words. + final EditableTextContextMenuBuilder? spellCheckSuggestionsToolbarBuilder; + + final bool _spellCheckEnabled; + + /// Whether or not the configuration should enable or disable spell check. + bool get spellCheckEnabled => _spellCheckEnabled; + + /// Returns a copy of the current [_SpellCheckConfiguration] instance with + /// specified overrides. + _SpellCheckConfiguration copyWith( + {SpellCheckService? spellCheckService, + Color? misspelledSelectionColor, + TextStyle? misspelledTextStyle, + EditableTextContextMenuBuilder? spellCheckSuggestionsToolbarBuilder}) { + if (!_spellCheckEnabled) { + // A new configuration should be constructed to enable spell check. + return const _SpellCheckConfiguration.disabled(); + } + + return _SpellCheckConfiguration( + spellCheckService: spellCheckService ?? this.spellCheckService, + misspelledSelectionColor: + misspelledSelectionColor ?? this.misspelledSelectionColor, + misspelledTextStyle: misspelledTextStyle ?? this.misspelledTextStyle, + spellCheckSuggestionsToolbarBuilder: + spellCheckSuggestionsToolbarBuilder ?? + this.spellCheckSuggestionsToolbarBuilder, + ); + } + + @override + String toString() { + return '${objectRuntimeType(this, 'SpellCheckConfiguration')}(' + '${_spellCheckEnabled ? 'enabled' : 'disabled'}, ' + 'service: $spellCheckService, ' + 'text style: $misspelledTextStyle, ' + 'toolbar builder: $spellCheckSuggestionsToolbarBuilder' + ')'; + } + + @override + bool operator ==(Object other) { + if (other.runtimeType != runtimeType) { + return false; + } + + return other is _SpellCheckConfiguration && + other.spellCheckService == spellCheckService && + other.misspelledTextStyle == misspelledTextStyle && + other.spellCheckSuggestionsToolbarBuilder == + spellCheckSuggestionsToolbarBuilder && + other._spellCheckEnabled == _spellCheckEnabled; + } + + @override + int get hashCode => Object.hash(spellCheckService, misspelledTextStyle, + spellCheckSuggestionsToolbarBuilder, _spellCheckEnabled); +} + +// Methods for displaying spell check results: + +/// Adjusts spell check results to correspond to [newText] if the only results +/// that the handler has access to are the [results] corresponding to +/// [resultsText]. +/// +/// Used in the case where the request for the spell check results of the +/// [newText] is lagging in order to avoid display of incorrect results. +List _correctSpellCheckResults( + String newText, String resultsText, List results) { + final List correctedSpellCheckResults = []; + int spanPointer = 0; + int offset = 0; + + // Assumes that the order of spans has not been jumbled for optimization + // purposes, and will only search since the previously found span. + int searchStart = 0; + + while (spanPointer < results.length) { + final SuggestionSpan currentSpan = results[spanPointer]; + final String currentSpanText = + resultsText.substring(currentSpan.range.start, currentSpan.range.end); + final int spanLength = currentSpan.range.end - currentSpan.range.start; + + // Try finding SuggestionSpan from resultsText in new text. + final String escapedText = RegExp.escape(currentSpanText); + final RegExp currentSpanTextRegexp = RegExp('\\b$escapedText\\b'); + final int foundIndex = + newText.substring(searchStart).indexOf(currentSpanTextRegexp); + + // Check whether word was found exactly where expected or elsewhere in the newText. + final bool currentSpanFoundExactly = + currentSpan.range.start == foundIndex + searchStart; + final bool currentSpanFoundExactlyWithOffset = + currentSpan.range.start + offset == foundIndex + searchStart; + final bool currentSpanFoundElsewhere = foundIndex >= 0; + + if (currentSpanFoundExactly || currentSpanFoundExactlyWithOffset) { + // currentSpan was found at the same index in newText and resultsText + // or at the same index with the previously calculated adjustment by + // the offset value, so apply it to new text by adding it to the list of + // corrected results. + final SuggestionSpan adjustedSpan = SuggestionSpan( + TextRange( + start: currentSpan.range.start + offset, + end: currentSpan.range.end + offset, + ), + currentSpan.suggestions, + ); + + // Start search for the next misspelled word at the end of currentSpan. + searchStart = currentSpan.range.end + 1 + offset; + correctedSpellCheckResults.add(adjustedSpan); + } else if (currentSpanFoundElsewhere) { + // Word was pushed forward but not modified. + final int adjustedSpanStart = searchStart + foundIndex; + final int adjustedSpanEnd = adjustedSpanStart + spanLength; + final SuggestionSpan adjustedSpan = SuggestionSpan( + TextRange(start: adjustedSpanStart, end: adjustedSpanEnd), + currentSpan.suggestions, + ); + + // Start search for the next misspelled word at the end of the + // adjusted currentSpan. + searchStart = adjustedSpanEnd + 1; + // Adjust offset to reflect the difference between where currentSpan + // was positioned in resultsText versus in newText. + offset = adjustedSpanStart - currentSpan.range.start; + correctedSpellCheckResults.add(adjustedSpan); + } + spanPointer++; + } + return correctedSpellCheckResults; +} + +/// Builds the [TextSpan] tree given the current state of the text input and +/// spell check results. +/// +/// The [value] is the current [TextEditingValue] requested to be rendered +/// by a text input widget. The [composingWithinCurrentTextRange] value +/// represents whether or not there is a valid composing region in the +/// [value]. The [style] is the [TextStyle] to render the [value]'s text with, +/// and the [misspelledTextStyle] is the [TextStyle] to render misspelled +/// words within the [value]'s text with. The [spellCheckResults] are the +/// results of spell checking the [value]'s text. +TextSpan buildTextSpanWithSpellCheckSuggestions( + TextEditingValue value, + bool composingWithinCurrentTextRange, + TextStyle? style, + TextStyle misspelledTextStyle, + SpellCheckResults spellCheckResults) { + List spellCheckResultsSpans = + spellCheckResults.suggestionSpans; + final String spellCheckResultsText = spellCheckResults.spellCheckedText; + + if (spellCheckResultsText != value.text) { + spellCheckResultsSpans = _correctSpellCheckResults( + value.text, spellCheckResultsText, spellCheckResultsSpans); + } + + // We will draw the TextSpan tree based on the composing region, if it is + // available. + // TODO(camsim99): The two separate strategies for building TextSpan trees + // based on the availability of a composing region should be merged: + // https://github.com/flutter/flutter/issues/124142. + final bool shouldConsiderComposingRegion = + defaultTargetPlatform == TargetPlatform.android; + if (shouldConsiderComposingRegion) { + return TextSpan( + style: style, + children: _buildSubtreesWithComposingRegion( + spellCheckResultsSpans, + value, + style, + misspelledTextStyle, + composingWithinCurrentTextRange, + ), + ); + } + + return TextSpan( + style: style, + children: _buildSubtreesWithoutComposingRegion( + spellCheckResultsSpans, + value, + style, + misspelledTextStyle, + value.selection.baseOffset, + ), + ); +} + +/// Builds the [TextSpan] tree for spell check without considering the composing +/// region. Instead, uses the cursor to identify the word that's actively being +/// edited and shouldn't be spell checked. This is useful for platforms and IMEs +/// that don't use the composing region for the active word. +List _buildSubtreesWithoutComposingRegion( + List? spellCheckSuggestions, + TextEditingValue value, + TextStyle? style, + TextStyle misspelledStyle, + int cursorIndex, +) { + final List textSpanTreeChildren = []; + + int textPointer = 0; + int currentSpanPointer = 0; + int endIndex; + final String text = value.text; + final TextStyle misspelledJointStyle = + style?.merge(misspelledStyle) ?? misspelledStyle; + bool cursorInCurrentSpan = false; + + // Add text interwoven with any misspelled words to the tree. + if (spellCheckSuggestions != null) { + while (textPointer < text.length && + currentSpanPointer < spellCheckSuggestions.length) { + final SuggestionSpan currentSpan = + spellCheckSuggestions[currentSpanPointer]; + + if (currentSpan.range.start > textPointer) { + endIndex = currentSpan.range.start < text.length + ? currentSpan.range.start + : text.length; + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(textPointer, endIndex), + )); + textPointer = endIndex; + } else { + endIndex = currentSpan.range.end < text.length + ? currentSpan.range.end + : text.length; + cursorInCurrentSpan = currentSpan.range.start <= cursorIndex && + currentSpan.range.end >= cursorIndex; + textSpanTreeChildren.add(TextSpan( + style: cursorInCurrentSpan ? style : misspelledJointStyle, + text: text.substring(currentSpan.range.start, endIndex), + )); + + textPointer = endIndex; + currentSpanPointer++; + } + } + } + + // Add any remaining text to the tree if applicable. + if (textPointer < text.length) { + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(textPointer, text.length), + )); + } + + return textSpanTreeChildren; +} + +/// Builds [TextSpan] subtree for text with misspelled words with logic based on +/// a valid composing region. +List _buildSubtreesWithComposingRegion( + List? spellCheckSuggestions, + TextEditingValue value, + TextStyle? style, + TextStyle misspelledStyle, + bool composingWithinCurrentTextRange) { + final List textSpanTreeChildren = []; + + int textPointer = 0; + int currentSpanPointer = 0; + int endIndex; + SuggestionSpan currentSpan; + final String text = value.text; + final TextRange composingRegion = value.composing; + final TextStyle composingTextStyle = + style?.merge(const TextStyle(decoration: TextDecoration.underline)) ?? + const TextStyle(decoration: TextDecoration.underline); + final TextStyle misspelledJointStyle = + style?.merge(misspelledStyle) ?? misspelledStyle; + bool textPointerWithinComposingRegion = false; + bool currentSpanIsComposingRegion = false; + + // Add text interwoven with any misspelled words to the tree. + if (spellCheckSuggestions != null) { + while (textPointer < text.length && + currentSpanPointer < spellCheckSuggestions.length) { + currentSpan = spellCheckSuggestions[currentSpanPointer]; + + if (currentSpan.range.start > textPointer) { + endIndex = currentSpan.range.start < text.length + ? currentSpan.range.start + : text.length; + textPointerWithinComposingRegion = + composingRegion.start >= textPointer && + composingRegion.end <= endIndex && + !composingWithinCurrentTextRange; + + if (textPointerWithinComposingRegion) { + _addComposingRegionTextSpans(textSpanTreeChildren, text, textPointer, + composingRegion, style, composingTextStyle); + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(composingRegion.end, endIndex), + )); + } else { + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(textPointer, endIndex), + )); + } + + textPointer = endIndex; + } else { + endIndex = currentSpan.range.end < text.length + ? currentSpan.range.end + : text.length; + currentSpanIsComposingRegion = textPointer >= composingRegion.start && + endIndex <= composingRegion.end && + !composingWithinCurrentTextRange; + textSpanTreeChildren.add(TextSpan( + style: currentSpanIsComposingRegion + ? composingTextStyle + : misspelledJointStyle, + text: text.substring(currentSpan.range.start, endIndex), + )); + + textPointer = endIndex; + currentSpanPointer++; + } + } + } + + // Add any remaining text to the tree if applicable. + if (textPointer < text.length) { + if (textPointer < composingRegion.start && + !composingWithinCurrentTextRange) { + _addComposingRegionTextSpans(textSpanTreeChildren, text, textPointer, + composingRegion, style, composingTextStyle); + + if (composingRegion.end != text.length) { + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(composingRegion.end, text.length), + )); + } + } else { + textSpanTreeChildren.add(TextSpan( + style: style, + text: text.substring(textPointer, text.length), + )); + } + } + + return textSpanTreeChildren; +} + +/// Helper method to create [TextSpan] tree children for specified range of +/// text up to and including the composing region. +void _addComposingRegionTextSpans( + List treeChildren, + String text, + int start, + TextRange composingRegion, + TextStyle? style, + TextStyle composingTextStyle) { + treeChildren.add(TextSpan( + style: style, + text: text.substring(start, composingRegion.start), + )); + treeChildren.add(TextSpan( + style: composingTextStyle, + text: text.substring(composingRegion.start, composingRegion.end), + )); +} diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_field.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_field.dart new file mode 100644 index 0000000..76b93a6 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_field.dart @@ -0,0 +1,1804 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [TextField] +class _TextFieldSelectionGestureDetectorBuilder + extends _TextSelectionGestureDetectorBuilder { + _TextFieldSelectionGestureDetectorBuilder({ + required _TextFieldState state, + }) : _state = state, + super(delegate: state); + + final _TextFieldState _state; + + @override + void onForcePressStart(ForcePressDetails details) { + super.onForcePressStart(details); + if (delegate.selectionEnabled && shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + } + + @override + void onForcePressEnd(ForcePressDetails details) { + // Not required. + } + + @override + bool get onUserTapAlwaysCalled => _state.widget.onTapAlwaysCalled; + + @override + void onUserTap() { + _state.widget.onTap?.call(); + } + + @override + void onSingleLongTapStart(LongPressStartDetails details) { + super.onSingleLongTapStart(details); + if (delegate.selectionEnabled) { + switch (Theme.of(_state.context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + break; + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + Feedback.forLongPress(_state.context); + } + } + } +} + +/// A Material Design text field. +/// +/// A text field lets the user enter text, either with hardware keyboard or with +/// an onscreen keyboard. +/// +/// The text field calls the [onChanged] callback whenever the user changes the +/// text in the field. If the user indicates that they are done typing in the +/// field (e.g., by pressing a button on the soft keyboard), the text field +/// calls the [onSubmitted] callback. +/// +/// To control the text that is displayed in the text field, use the +/// [controller]. For example, to set the initial value of the text field, use +/// a [controller] that already contains some text. The [controller] can also +/// control the selection and composing region (and to observe changes to the +/// text, selection, and composing region). +/// +/// By default, a text field has a [decoration] that draws a divider below the +/// text field. You can use the [decoration] property to control the decoration, +/// for example by adding a label or an icon. If you set the [decoration] +/// property to null, the decoration will be removed entirely, including the +/// extra padding introduced by the decoration to save space for the labels. +/// +/// If [decoration] is non-null (which is the default), the text field requires +/// one of its ancestors to be a [Material] widget. +/// +/// To integrate the [TextField] into a [Form] with other [FormField] widgets, +/// consider using [TextFormField]. +/// +/// {@template flutter.material.textfield.wantKeepAlive} +/// When the widget has focus, it will prevent itself from disposing via its +/// underlying [EditableText]'s [AutomaticKeepAliveClientMixin.wantKeepAlive] in +/// order to avoid losing the selection. Removing the focus will allow it to be +/// disposed. +/// {@endtemplate} +/// +/// Remember to call [TextEditingController.dispose] on the [TextEditingController] +/// when it is no longer needed. This will ensure we discard any resources used +/// by the object. +/// +/// If this field is part of a scrolling container that lazily constructs its +/// children, like a [ListView] or a [CustomScrollView], then a [controller] +/// should be specified. The controller's lifetime should be managed by a +/// stateful widget ancestor of the scrolling container. +/// +/// ## Obscured Input +/// +/// {@tool dartpad} +/// This example shows how to create a [TextField] that will obscure input. The +/// [InputDecoration] surrounds the field in a border using [OutlineInputBorder] +/// and adds a label. +/// +/// ** See code in examples/api/lib/material/text_field/text_field.0.dart ** +/// {@end-tool} +/// +/// ## Reading values +/// +/// A common way to read a value from a TextField is to use the [onSubmitted] +/// callback. This callback is applied to the text field's current value when +/// the user finishes editing. +/// +/// {@tool dartpad} +/// This sample shows how to get a value from a TextField via the [onSubmitted] +/// callback. +/// +/// ** See code in examples/api/lib/material/text_field/text_field.1.dart ** +/// {@end-tool} +/// +/// {@macro flutter.widgets.EditableText.lifeCycle} +/// +/// For most applications the [onSubmitted] callback will be sufficient for +/// reacting to user input. +/// +/// The [onEditingComplete] callback also runs when the user finishes editing. +/// It's different from [onSubmitted] because it has a default value which +/// updates the text controller and yields the keyboard focus. Applications that +/// require different behavior can override the default [onEditingComplete] +/// callback. +/// +/// Keep in mind you can also always read the current string from a TextField's +/// [TextEditingController] using [TextEditingController.text]. +/// +/// ## Handling emojis and other complex characters +/// {@macro flutter.widgets.EditableText.onChanged} +/// +/// In the live Dartpad example above, try typing the emoji 👨‍👩‍👦 +/// into the field and submitting. Because the example code measures the length +/// with `value.characters.length`, the emoji is correctly counted as a single +/// character. +/// +/// {@macro flutter.widgets.editableText.showCaretOnScreen} +/// +/// {@macro flutter.widgets.editableText.accessibility} +/// +/// {@tool dartpad} +/// This sample shows how to style a text field to match a filled or outlined +/// Material Design 3 text field. +/// +/// ** See code in examples/api/lib/material/text_field/text_field.2.dart ** +/// {@end-tool} +/// +/// ## Scrolling Considerations +/// +/// If this [TextField] is not a descendant of [Scaffold] and is being used +/// within a [Scrollable] or nested [Scrollable]s, consider placing a +/// [ScrollNotificationObserver] above the root [Scrollable] that contains this +/// [TextField] to ensure proper scroll coordination for [TextField] and its +/// components like [TextSelectionOverlay]. +/// +/// See also: +/// +/// * [TextFormField], which integrates with the [Form] widget. +/// * [InputDecorator], which shows the labels and other visual elements that +/// surround the actual text editing widget. +/// * [EditableText], which is the raw text editing control at the heart of a +/// [TextField]. The [EditableText] widget is rarely used directly unless +/// you are implementing an entirely different design language, such as +/// Cupertino. +/// * +/// * Cookbook: [Create and style a text field](https://docs.flutter.dev/cookbook/forms/text-input) +/// * Cookbook: [Handle changes to a text field](https://docs.flutter.dev/cookbook/forms/text-field-changes) +/// * Cookbook: [Retrieve the value of a text field](https://docs.flutter.dev/cookbook/forms/retrieve-input) +/// * Cookbook: [Focus and text fields](https://docs.flutter.dev/cookbook/forms/focus) +class _TextField extends StatefulWidget { + /// Creates a Material Design text field. + /// + /// If [decoration] is non-null (which is the default), the text field requires + /// one of its ancestors to be a [Material] widget. + /// + /// To remove the decoration entirely (including the extra padding introduced + /// by the decoration to save space for the labels), set the [decoration] to + /// null. + /// + /// The [maxLines] property can be set to null to remove the restriction on + /// the number of lines. By default, it is one, meaning this is a single-line + /// text field. [maxLines] must not be zero. + /// + /// The [maxLength] property is set to null by default, which means the + /// number of characters allowed in the text field is not restricted. If + /// [maxLength] is set a character counter will be displayed below the + /// field showing how many characters have been entered. If the value is + /// set to a positive integer it will also display the maximum allowed + /// number of characters to be entered. If the value is set to + /// [TextField.noMaxLength] then only the current length is displayed. + /// + /// After [maxLength] characters have been input, additional input + /// is ignored, unless [maxLengthEnforcement] is set to + /// [MaxLengthEnforcement.none]. + /// The text field enforces the length with a [LengthLimitingTextInputFormatter], + /// which is evaluated after the supplied [inputFormatters], if any. + /// The [maxLength] value must be either null or greater than zero. + /// + /// If [maxLengthEnforcement] is set to [MaxLengthEnforcement.none], then more + /// than [maxLength] characters may be entered, and the error counter and + /// divider will switch to the [decoration].errorStyle when the limit is + /// exceeded. + /// + /// The text cursor is not shown if [showCursor] is false or if [showCursor] + /// is null (the default) and [readOnly] is true. + /// + /// The [selectionHeightStyle] and [selectionWidthStyle] properties allow + /// changing the shape of the selection highlighting. These properties default + /// to [ui.BoxHeightStyle.tight] and [ui.BoxWidthStyle.tight], respectively. + /// + /// See also: + /// + /// * [maxLength], which discusses the precise meaning of "number of + /// characters" and how it may differ from the intuitive meaning. + const _TextField({ + super.key, + this.groupId = EditableText, + this.controller, + this.focusNode, + this.undoController, + this.decoration = const InputDecoration(), + TextInputType? keyboardType, + this.textInputAction, + this.textCapitalization = TextCapitalization.none, + this.style, + this.strutStyle, + this.textAlign = TextAlign.start, + this.textAlignVertical, + this.textDirection, + this.readOnly = false, + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + this.toolbarOptions, + this.showCursor, + this.autofocus = false, + this.statesController, + this.obscuringCharacter = '•', + this.obscureText = false, + this.autocorrect = true, + SmartDashesType? smartDashesType, + SmartQuotesType? smartQuotesType, + this.enableSuggestions = true, + this.maxLines = 1, + this.minLines, + this.expands = false, + this.maxLength, + this.maxLengthEnforcement, + this.onChanged, + this.onEditingComplete, + this.onSubmitted, + this.onAppPrivateCommand, + this.inputFormatters, + this.enabled, + this.ignorePointers, + this.cursorWidth = 2.0, + this.cursorHeight, + this.cursorRadius, + this.cursorOpacityAnimates, + this.cursorColor, + this.cursorErrorColor, + this.selectionHeightStyle = ui.BoxHeightStyle.tight, + this.selectionWidthStyle = ui.BoxWidthStyle.tight, + this.keyboardAppearance, + this.scrollPadding = const EdgeInsets.all(20.0), + this.dragStartBehavior = DragStartBehavior.start, + bool? enableInteractiveSelection, + this.selectionControls, + this.onTap, + this.onTapAlwaysCalled = false, + this.onTapOutside, + this.mouseCursor, + this.buildCounter, + this.scrollController, + this.scrollPhysics, + this.autofillHints = const [], + this.contentInsertionConfiguration, + this.clipBehavior = Clip.hardEdge, + this.restorationId, + this.scribbleEnabled = true, + this.enableIMEPersonalizedLearning = true, + this.contextMenuBuilder = _defaultContextMenuBuilder, + this.canRequestFocus = true, + this.spellCheckConfiguration, + this.magnifierConfiguration, + }) : assert(obscuringCharacter.length == 1), + smartDashesType = smartDashesType ?? + (obscureText ? SmartDashesType.disabled : SmartDashesType.enabled), + smartQuotesType = smartQuotesType ?? + (obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled), + assert(maxLines == null || maxLines > 0), + assert(minLines == null || minLines > 0), + assert( + (maxLines == null) || (minLines == null) || (maxLines >= minLines), + "minLines can't be greater than maxLines", + ), + assert( + !expands || (maxLines == null && minLines == null), + 'minLines and maxLines must be null when expands is true.', + ), + assert(!obscureText || maxLines == 1, + 'Obscured fields cannot be multiline.'), + assert(maxLength == null || + maxLength == _TextField.noMaxLength || + maxLength > 0), + // Assert the following instead of setting it directly to avoid surprising the user by silently changing the value they set. + assert( + !identical(textInputAction, TextInputAction.newline) || + maxLines == 1 || + !identical(keyboardType, TextInputType.text), + 'Use keyboardType TextInputType.multiline when using TextInputAction.newline on a multiline TextField.', + ), + keyboardType = keyboardType ?? + (maxLines == 1 ? TextInputType.text : TextInputType.multiline), + enableInteractiveSelection = + enableInteractiveSelection ?? (!readOnly || !obscureText); + + /// The configuration for the magnifier of this text field. + /// + /// By default, builds a [CupertinoTextMagnifier] on iOS and [TextMagnifier] + /// on Android, and builds nothing on all other platforms. To suppress the + /// magnifier, consider passing [TextMagnifierConfiguration.disabled]. + /// + /// {@macro flutter.widgets.magnifier.intro} + /// + /// {@tool dartpad} + /// This sample demonstrates how to customize the magnifier that this text field uses. + /// + /// ** See code in examples/api/lib/widgets/text_magnifier/text_magnifier.0.dart ** + /// {@end-tool} + final TextMagnifierConfiguration? magnifierConfiguration; + + /// {@macro flutter.widgets.editableText.groupId} + final Object groupId; + + /// Controls the text being edited. + /// + /// If null, this widget will create its own [TextEditingController]. + final TextEditingController? controller; + + /// Defines the keyboard focus for this widget. + /// + /// The [focusNode] is a long-lived object that's typically managed by a + /// [StatefulWidget] parent. See [FocusNode] for more information. + /// + /// To give the keyboard focus to this widget, provide a [focusNode] and then + /// use the current [FocusScope] to request the focus: + /// + /// ```dart + /// FocusScope.of(context).requestFocus(myFocusNode); + /// ``` + /// + /// This happens automatically when the widget is tapped. + /// + /// To be notified when the widget gains or loses the focus, add a listener + /// to the [focusNode]: + /// + /// ```dart + /// myFocusNode.addListener(() { print(myFocusNode.hasFocus); }); + /// ``` + /// + /// If null, this widget will create its own [FocusNode]. + /// + /// ## Keyboard + /// + /// Requesting the focus will typically cause the keyboard to be shown + /// if it's not showing already. + /// + /// On Android, the user can hide the keyboard - without changing the focus - + /// with the system back button. They can restore the keyboard's visibility + /// by tapping on a text field. The user might hide the keyboard and + /// switch to a physical keyboard, or they might just need to get it + /// out of the way for a moment, to expose something it's + /// obscuring. In this case requesting the focus again will not + /// cause the focus to change, and will not make the keyboard visible. + /// + /// This widget builds an [EditableText] and will ensure that the keyboard is + /// showing when it is tapped by calling [EditableTextState.requestKeyboard()]. + final FocusNode? focusNode; + + /// The decoration to show around the text field. + /// + /// By default, draws a horizontal line under the text field but can be + /// configured to show an icon, label, hint text, and error text. + /// + /// Specify null to remove the decoration entirely (including the + /// extra padding introduced by the decoration to save space for the labels). + final InputDecoration? decoration; + + /// {@macro flutter.widgets.editableText.keyboardType} + final TextInputType keyboardType; + + /// {@template flutter.widgets.TextField.textInputAction} + /// The type of action button to use for the keyboard. + /// + /// Defaults to [TextInputAction.newline] if [keyboardType] is + /// [TextInputType.multiline] and [TextInputAction.done] otherwise. + /// {@endtemplate} + final TextInputAction? textInputAction; + + /// {@macro flutter.widgets.editableText.textCapitalization} + final TextCapitalization textCapitalization; + + /// The style to use for the text being edited. + /// + /// This text style is also used as the base style for the [decoration]. + /// + /// If null, [TextTheme.bodyLarge] will be used. When the text field is disabled, + /// [TextTheme.bodyLarge] with an opacity of 0.38 will be used instead. + /// + /// If null and [ThemeData.useMaterial3] is false, [TextTheme.titleMedium] will + /// be used. When the text field is disabled, [TextTheme.titleMedium] with + /// [ThemeData.disabledColor] will be used instead. + final TextStyle? style; + + /// {@macro flutter.widgets.editableText.strutStyle} + final StrutStyle? strutStyle; + + /// {@macro flutter.widgets.editableText.textAlign} + final TextAlign textAlign; + + /// {@macro flutter.material.InputDecorator.textAlignVertical} + final TextAlignVertical? textAlignVertical; + + /// {@macro flutter.widgets.editableText.textDirection} + final TextDirection? textDirection; + + /// {@macro flutter.widgets.editableText.autofocus} + final bool autofocus; + + /// Represents the interactive "state" of this widget in terms of a set of + /// [MaterialState]s, including [MaterialState.disabled], [MaterialState.hovered], + /// [MaterialState.error], and [MaterialState.focused]. + /// + /// Classes based on this one can provide their own + /// [MaterialStatesController] to which they've added listeners. + /// They can also update the controller's [MaterialStatesController.value] + /// however, this may only be done when it's safe to call + /// [State.setState], like in an event handler. + /// + /// The controller's [MaterialStatesController.value] represents the set of + /// states that a widget's visual properties, typically [MaterialStateProperty] + /// values, are resolved against. It is _not_ the intrinsic state of the widget. + /// The widget is responsible for ensuring that the controller's + /// [MaterialStatesController.value] tracks its intrinsic state. For example + /// one cannot request the keyboard focus for a widget by adding [MaterialState.focused] + /// to its controller. When the widget gains the or loses the focus it will + /// [MaterialStatesController.update] its controller's [MaterialStatesController.value] + /// and notify listeners of the change. + final MaterialStatesController? statesController; + + /// {@macro flutter.widgets.editableText.obscuringCharacter} + final String obscuringCharacter; + + /// {@macro flutter.widgets.editableText.obscureText} + final bool obscureText; + + /// {@macro flutter.widgets.editableText.autocorrect} + final bool autocorrect; + + /// {@macro flutter.services.TextInputConfiguration.smartDashesType} + final SmartDashesType smartDashesType; + + /// {@macro flutter.services.TextInputConfiguration.smartQuotesType} + final SmartQuotesType smartQuotesType; + + /// {@macro flutter.services.TextInputConfiguration.enableSuggestions} + final bool enableSuggestions; + + /// {@macro flutter.widgets.editableText.maxLines} + /// * [expands], which determines whether the field should fill the height of + /// its parent. + final int? maxLines; + + /// {@macro flutter.widgets.editableText.minLines} + /// * [expands], which determines whether the field should fill the height of + /// its parent. + final int? minLines; + + /// {@macro flutter.widgets.editableText.expands} + final bool expands; + + /// {@macro flutter.widgets.editableText.readOnly} + final bool readOnly; + + /// Configuration of toolbar options. + /// + /// If not set, select all and paste will default to be enabled. Copy and cut + /// will be disabled if [obscureText] is true. If [readOnly] is true, + /// paste and cut will be disabled regardless. + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + final ToolbarOptions? toolbarOptions; + + /// {@macro flutter.widgets.editableText.showCursor} + final bool? showCursor; + + /// If [maxLength] is set to this value, only the "current input length" + /// part of the character counter is shown. + static const int noMaxLength = -1; + + /// The maximum number of characters (Unicode grapheme clusters) to allow in + /// the text field. + /// + /// If set, a character counter will be displayed below the + /// field showing how many characters have been entered. If set to a number + /// greater than 0, it will also display the maximum number allowed. If set + /// to [TextField.noMaxLength] then only the current character count is displayed. + /// + /// After [maxLength] characters have been input, additional input + /// is ignored, unless [maxLengthEnforcement] is set to + /// [MaxLengthEnforcement.none]. + /// + /// The text field enforces the length with a [LengthLimitingTextInputFormatter], + /// which is evaluated after the supplied [inputFormatters], if any. + /// + /// This value must be either null, [TextField.noMaxLength], or greater than 0. + /// If null (the default) then there is no limit to the number of characters + /// that can be entered. If set to [TextField.noMaxLength], then no limit will + /// be enforced, but the number of characters entered will still be displayed. + /// + /// Whitespace characters (e.g. newline, space, tab) are included in the + /// character count. + /// + /// If [maxLengthEnforcement] is [MaxLengthEnforcement.none], then more than + /// [maxLength] characters may be entered, but the error counter and divider + /// will switch to the [decoration]'s [InputDecoration.errorStyle] when the + /// limit is exceeded. + /// + /// {@macro flutter.services.lengthLimitingTextInputFormatter.maxLength} + final int? maxLength; + + /// Determines how the [maxLength] limit should be enforced. + /// + /// {@macro flutter.services.textFormatter.effectiveMaxLengthEnforcement} + /// + /// {@macro flutter.services.textFormatter.maxLengthEnforcement} + final MaxLengthEnforcement? maxLengthEnforcement; + + /// {@macro flutter.widgets.editableText.onChanged} + /// + /// See also: + /// + /// * [inputFormatters], which are called before [onChanged] + /// runs and can validate and change ("format") the input value. + /// * [onEditingComplete], [onSubmitted]: + /// which are more specialized input change notifications. + final ValueChanged? onChanged; + + /// {@macro flutter.widgets.editableText.onEditingComplete} + final VoidCallback? onEditingComplete; + + /// {@macro flutter.widgets.editableText.onSubmitted} + /// + /// See also: + /// + /// * [TextInputAction.next] and [TextInputAction.previous], which + /// automatically shift the focus to the next/previous focusable item when + /// the user is done editing. + final ValueChanged? onSubmitted; + + /// {@macro flutter.widgets.editableText.onAppPrivateCommand} + final AppPrivateCommandCallback? onAppPrivateCommand; + + /// {@macro flutter.widgets.editableText.inputFormatters} + final List? inputFormatters; + + /// If false the text field is "disabled": it ignores taps and its + /// [decoration] is rendered in grey. + /// + /// If non-null this property overrides the [decoration]'s + /// [InputDecoration.enabled] property. + final bool? enabled; + + /// Determines whether this widget ignores pointer events. + /// + /// Defaults to null, and when null, does nothing. + final bool? ignorePointers; + + /// {@macro flutter.widgets.editableText.cursorWidth} + final double cursorWidth; + + /// {@macro flutter.widgets.editableText.cursorHeight} + final double? cursorHeight; + + /// {@macro flutter.widgets.editableText.cursorRadius} + final Radius? cursorRadius; + + /// {@macro flutter.widgets.editableText.cursorOpacityAnimates} + final bool? cursorOpacityAnimates; + + /// The color of the cursor. + /// + /// The cursor indicates the current location of text insertion point in + /// the field. + /// + /// If this is null it will default to the ambient + /// [DefaultSelectionStyle.cursorColor]. If that is null, and the + /// [ThemeData.platform] is [TargetPlatform.iOS] or [TargetPlatform.macOS] + /// it will use [CupertinoThemeData.primaryColor]. Otherwise it will use + /// the value of [ColorScheme.primary] of [ThemeData.colorScheme]. + final Color? cursorColor; + + /// The color of the cursor when the [InputDecorator] is showing an error. + /// + /// If this is null it will default to [TextStyle.color] of + /// [InputDecoration.errorStyle]. If that is null, it will use + /// [ColorScheme.error] of [ThemeData.colorScheme]. + final Color? cursorErrorColor; + + /// Controls how tall the selection highlight boxes are computed to be. + /// + /// See [ui.BoxHeightStyle] for details on available styles. + final ui.BoxHeightStyle selectionHeightStyle; + + /// Controls how wide the selection highlight boxes are computed to be. + /// + /// See [ui.BoxWidthStyle] for details on available styles. + final ui.BoxWidthStyle selectionWidthStyle; + + /// The appearance of the keyboard. + /// + /// This setting is only honored on iOS devices. + /// + /// If unset, defaults to [ThemeData.brightness]. + final Brightness? keyboardAppearance; + + /// {@macro flutter.widgets.editableText.scrollPadding} + final EdgeInsets scrollPadding; + + /// {@macro flutter.widgets.editableText.enableInteractiveSelection} + final bool enableInteractiveSelection; + + /// {@macro flutter.widgets.editableText.selectionControls} + final TextSelectionControls? selectionControls; + + /// {@macro flutter.widgets.scrollable.dragStartBehavior} + final DragStartBehavior dragStartBehavior; + + /// {@macro flutter.widgets.editableText.selectionEnabled} + bool get selectionEnabled => enableInteractiveSelection; + + /// {@template flutter.material.textfield.onTap} + /// Called for the first tap in a series of taps. + /// + /// The text field builds a [GestureDetector] to handle input events like tap, + /// to trigger focus requests, to move the caret, adjust the selection, etc. + /// Handling some of those events by wrapping the text field with a competing + /// GestureDetector is problematic. + /// + /// To unconditionally handle taps, without interfering with the text field's + /// internal gesture detector, provide this callback. + /// + /// If the text field is created with [enabled] false, taps will not be + /// recognized. + /// + /// To be notified when the text field gains or loses the focus, provide a + /// [focusNode] and add a listener to that. + /// + /// To listen to arbitrary pointer events without competing with the + /// text field's internal gesture detector, use a [Listener]. + /// {@endtemplate} + /// + /// If [onTapAlwaysCalled] is enabled, this will also be called for consecutive + /// taps. + final GestureTapCallback? onTap; + + /// Whether [onTap] should be called for every tap. + /// + /// Defaults to false, so [onTap] is only called for each distinct tap. When + /// enabled, [onTap] is called for every tap including consecutive taps. + final bool onTapAlwaysCalled; + + /// {@macro flutter.widgets.editableText.onTapOutside} + /// + /// {@tool dartpad} + /// This example shows how to use a `TextFieldTapRegion` to wrap a set of + /// "spinner" buttons that increment and decrement a value in the [TextField] + /// without causing the text field to lose keyboard focus. + /// + /// This example includes a generic `SpinnerField` class that you can copy + /// into your own project and customize. + /// + /// ** See code in examples/api/lib/widgets/tap_region/text_field_tap_region.0.dart ** + /// {@end-tool} + /// + /// See also: + /// + /// * [TapRegion] for how the region group is determined. + final TapRegionCallback? onTapOutside; + + /// The cursor for a mouse pointer when it enters or is hovering over the + /// widget. + /// + /// If [mouseCursor] is a [MaterialStateProperty], + /// [MaterialStateProperty.resolve] is used for the following [MaterialState]s: + /// + /// * [MaterialState.error]. + /// * [MaterialState.hovered]. + /// * [MaterialState.focused]. + /// * [MaterialState.disabled]. + /// + /// If this property is null, [MaterialStateMouseCursor.textable] will be used. + /// + /// The [mouseCursor] is the only property of [TextField] that controls the + /// appearance of the mouse pointer. All other properties related to "cursor" + /// stand for the text cursor, which is usually a blinking vertical line at + /// the editing position. + final MouseCursor? mouseCursor; + + /// Callback that generates a custom [InputDecoration.counter] widget. + /// + /// See [InputCounterWidgetBuilder] for an explanation of the passed in + /// arguments. The returned widget will be placed below the line in place of + /// the default widget built when [InputDecoration.counterText] is specified. + /// + /// The returned widget will be wrapped in a [Semantics] widget for + /// accessibility, but it also needs to be accessible itself. For example, + /// if returning a Text widget, set the [Text.semanticsLabel] property. + /// + /// {@tool snippet} + /// ```dart + /// Widget counter( + /// BuildContext context, + /// { + /// required int currentLength, + /// required int? maxLength, + /// required bool isFocused, + /// } + /// ) { + /// return Text( + /// '$currentLength of $maxLength characters', + /// semanticsLabel: 'character count', + /// ); + /// } + /// ``` + /// {@end-tool} + /// + /// If buildCounter returns null, then no counter and no Semantics widget will + /// be created at all. + final InputCounterWidgetBuilder? buildCounter; + + /// {@macro flutter.widgets.editableText.scrollPhysics} + final ScrollPhysics? scrollPhysics; + + /// {@macro flutter.widgets.editableText.scrollController} + final ScrollController? scrollController; + + /// {@macro flutter.widgets.editableText.autofillHints} + /// {@macro flutter.services.AutofillConfiguration.autofillHints} + final Iterable? autofillHints; + + /// {@macro flutter.material.Material.clipBehavior} + /// + /// Defaults to [Clip.hardEdge]. + final Clip clipBehavior; + + /// {@template flutter.material.textfield.restorationId} + /// Restoration ID to save and restore the state of the text field. + /// + /// If non-null, the text field will persist and restore its current scroll + /// offset and - if no [controller] has been provided - the content of the + /// text field. If a [controller] has been provided, it is the responsibility + /// of the owner of that controller to persist and restore it, e.g. by using + /// a [RestorableTextEditingController]. + /// + /// The state of this widget is persisted in a [RestorationBucket] claimed + /// from the surrounding [RestorationScope] using the provided restoration ID. + /// + /// See also: + /// + /// * [RestorationManager], which explains how state restoration works in + /// Flutter. + /// {@endtemplate} + final String? restorationId; + + /// {@macro flutter.widgets.editableText.scribbleEnabled} + final bool scribbleEnabled; + + /// {@macro flutter.services.TextInputConfiguration.enableIMEPersonalizedLearning} + final bool enableIMEPersonalizedLearning; + + /// {@macro flutter.widgets.editableText.contentInsertionConfiguration} + final ContentInsertionConfiguration? contentInsertionConfiguration; + + /// {@macro flutter.widgets.EditableText.contextMenuBuilder} + /// + /// If not provided, will build a default menu based on the platform. + /// + /// See also: + /// + /// * [AdaptiveTextSelectionToolbar], which is built by default. + final EditableTextContextMenuBuilder? contextMenuBuilder; + + /// Determine whether this text field can request the primary focus. + /// + /// Defaults to true. If false, the text field will not request focus + /// when tapped, or when its context menu is displayed. If false it will not + /// be possible to move the focus to the text field with tab key. + final bool canRequestFocus; + + /// {@macro flutter.widgets.undoHistory.controller} + final UndoHistoryController? undoController; + + static Widget _defaultContextMenuBuilder( + BuildContext context, EditableTextState editableTextState) { + return AdaptiveTextSelectionToolbar.editableText( + editableTextState: editableTextState, + ); + } + + /// {@macro flutter.widgets.EditableText.spellCheckConfiguration} + /// + /// If [SpellCheckConfiguration.misspelledTextStyle] is not specified in this + /// configuration, then [materialMisspelledTextStyle] is used by default. + final SpellCheckConfiguration? spellCheckConfiguration; + + /// The [TextStyle] used to indicate misspelled words in the Material style. + /// + /// See also: + /// * [_SpellCheckConfiguration.misspelledTextStyle], the style configured to + /// mark misspelled words with. + /// * [CupertinoTextField.cupertinoMisspelledTextStyle], the style configured + /// to mark misspelled words with in the Cupertino style. + static const TextStyle materialMisspelledTextStyle = TextStyle( + decoration: TextDecoration.underline, + decorationColor: Colors.red, + decorationStyle: TextDecorationStyle.wavy, + ); + + /// Default builder for [TextField]'s spell check suggestions toolbar. + /// + /// On Apple platforms, builds an iOS-style toolbar. Everywhere else, builds + /// an Android-style toolbar. + /// + /// See also: + /// * [spellCheckConfiguration], where this is typically specified for + /// [TextField]. + /// * [SpellCheckConfiguration.spellCheckSuggestionsToolbarBuilder], the + /// parameter for which this is the default value for [TextField]. + /// * [CupertinoTextField.defaultSpellCheckSuggestionsToolbarBuilder], which + /// is like this but specifies the default for [CupertinoTextField]. + @visibleForTesting + static Widget defaultSpellCheckSuggestionsToolbarBuilder( + BuildContext context, + EditableTextState editableTextState, + ) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + return CupertinoSpellCheckSuggestionsToolbar.editableText( + editableTextState: editableTextState, + ); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + return SpellCheckSuggestionsToolbar.editableText( + editableTextState: editableTextState, + ); + } + } + + /// Returns a new [SpellCheckConfiguration] where the given configuration has + /// had any missing values replaced with their defaults for the Android + /// platform. + static _SpellCheckConfiguration inferAndroidSpellCheckConfiguration( + _SpellCheckConfiguration? configuration, + ) { + if (configuration == null || + configuration == const _SpellCheckConfiguration.disabled()) { + return const _SpellCheckConfiguration.disabled(); + } + return configuration.copyWith( + misspelledTextStyle: configuration.misspelledTextStyle ?? + _TextField.materialMisspelledTextStyle, + spellCheckSuggestionsToolbarBuilder: + configuration.spellCheckSuggestionsToolbarBuilder ?? + _TextField.defaultSpellCheckSuggestionsToolbarBuilder, + ); + } + + @override + State<_TextField> createState() => _TextFieldState(); + + @override + void debugFillProperties(DiagnosticPropertiesBuilder properties) { + super.debugFillProperties(properties); + properties.add(DiagnosticsProperty( + 'controller', controller, + defaultValue: null)); + properties.add(DiagnosticsProperty('focusNode', focusNode, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'undoController', undoController, + defaultValue: null)); + properties + .add(DiagnosticsProperty('enabled', enabled, defaultValue: null)); + properties.add(DiagnosticsProperty( + 'decoration', decoration, + defaultValue: const InputDecoration())); + properties.add(DiagnosticsProperty( + 'keyboardType', keyboardType, + defaultValue: TextInputType.text)); + properties.add( + DiagnosticsProperty('style', style, defaultValue: null)); + properties.add( + DiagnosticsProperty('autofocus', autofocus, defaultValue: false)); + properties.add(DiagnosticsProperty( + 'obscuringCharacter', obscuringCharacter, + defaultValue: '•')); + properties.add(DiagnosticsProperty('obscureText', obscureText, + defaultValue: false)); + properties.add(DiagnosticsProperty('autocorrect', autocorrect, + defaultValue: true)); + properties.add(EnumProperty( + 'smartDashesType', smartDashesType, + defaultValue: + obscureText ? SmartDashesType.disabled : SmartDashesType.enabled)); + properties.add(EnumProperty( + 'smartQuotesType', smartQuotesType, + defaultValue: + obscureText ? SmartQuotesType.disabled : SmartQuotesType.enabled)); + properties.add(DiagnosticsProperty( + 'enableSuggestions', enableSuggestions, + defaultValue: true)); + properties.add(IntProperty('maxLines', maxLines, defaultValue: 1)); + properties.add(IntProperty('minLines', minLines, defaultValue: null)); + properties.add( + DiagnosticsProperty('expands', expands, defaultValue: false)); + properties.add(IntProperty('maxLength', maxLength, defaultValue: null)); + properties.add(EnumProperty( + 'maxLengthEnforcement', maxLengthEnforcement, + defaultValue: null)); + properties.add(EnumProperty( + 'textInputAction', textInputAction, + defaultValue: null)); + properties.add(EnumProperty( + 'textCapitalization', textCapitalization, + defaultValue: TextCapitalization.none)); + properties.add(EnumProperty('textAlign', textAlign, + defaultValue: TextAlign.start)); + properties.add(DiagnosticsProperty( + 'textAlignVertical', textAlignVertical, + defaultValue: null)); + properties.add(EnumProperty('textDirection', textDirection, + defaultValue: null)); + properties + .add(DoubleProperty('cursorWidth', cursorWidth, defaultValue: 2.0)); + properties + .add(DoubleProperty('cursorHeight', cursorHeight, defaultValue: null)); + properties.add(DiagnosticsProperty('cursorRadius', cursorRadius, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'cursorOpacityAnimates', cursorOpacityAnimates, + defaultValue: null)); + properties + .add(ColorProperty('cursorColor', cursorColor, defaultValue: null)); + properties.add(ColorProperty('cursorErrorColor', cursorErrorColor, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'keyboardAppearance', keyboardAppearance, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollPadding', scrollPadding, + defaultValue: const EdgeInsets.all(20.0))); + properties.add(FlagProperty('selectionEnabled', + value: selectionEnabled, + defaultValue: true, + ifFalse: 'selection disabled')); + properties.add(DiagnosticsProperty( + 'selectionControls', selectionControls, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollController', scrollController, + defaultValue: null)); + properties.add(DiagnosticsProperty( + 'scrollPhysics', scrollPhysics, + defaultValue: null)); + properties.add(DiagnosticsProperty('clipBehavior', clipBehavior, + defaultValue: Clip.hardEdge)); + properties.add(DiagnosticsProperty('scribbleEnabled', scribbleEnabled, + defaultValue: true)); + properties.add(DiagnosticsProperty( + 'enableIMEPersonalizedLearning', enableIMEPersonalizedLearning, + defaultValue: true)); + properties.add(DiagnosticsProperty( + 'spellCheckConfiguration', spellCheckConfiguration, + defaultValue: null)); + properties.add(DiagnosticsProperty>('contentCommitMimeTypes', + contentInsertionConfiguration?.allowedMimeTypes ?? const [], + defaultValue: contentInsertionConfiguration == null + ? const [] + : kDefaultContentInsertionMimeTypes)); + } +} + +class _TextFieldState extends State<_TextField> + with RestorationMixin + implements _TextSelectionGestureDetectorBuilderDelegate, AutofillClient { + RestorableTextEditingController? _controller; + TextEditingController get _effectiveController => + widget.controller ?? _controller!.value; + + FocusNode? _focusNode; + FocusNode get _effectiveFocusNode => + widget.focusNode ?? (_focusNode ??= FocusNode()); + + MaxLengthEnforcement get _effectiveMaxLengthEnforcement => + widget.maxLengthEnforcement ?? + LengthLimitingTextInputFormatter.getDefaultMaxLengthEnforcement( + Theme.of(context).platform); + + bool _isHovering = false; + + bool get needsCounter => + widget.maxLength != null && + widget.decoration != null && + widget.decoration!.counterText == null; + + bool _showSelectionHandles = false; + + late _TextFieldSelectionGestureDetectorBuilder + _selectionGestureDetectorBuilder; + + // API for TextSelectionGestureDetectorBuilderDelegate. + @override + late bool forcePressEnabled; + + // zmtzawqlp + @override + final GlobalKey<_EditableTextState> editableTextKey = + GlobalKey<_EditableTextState>(); + + @override + bool get selectionEnabled => widget.selectionEnabled && _isEnabled; + // End of API for TextSelectionGestureDetectorBuilderDelegate. + + bool get _isEnabled => widget.enabled ?? widget.decoration?.enabled ?? true; + + int get _currentLength => _effectiveController.value.text.characters.length; + + bool get _hasIntrinsicError => + widget.maxLength != null && + widget.maxLength! > 0 && + (widget.controller == null + ? !restorePending && + _effectiveController.value.text.characters.length > + widget.maxLength! + : _effectiveController.value.text.characters.length > + widget.maxLength!); + + bool get _hasError => + widget.decoration?.errorText != null || + widget.decoration?.error != null || + _hasIntrinsicError; + + Color get _errorColor => + widget.cursorErrorColor ?? + _getEffectiveDecoration().errorStyle?.color ?? + Theme.of(context).colorScheme.error; + + InputDecoration _getEffectiveDecoration() { + final MaterialLocalizations localizations = + MaterialLocalizations.of(context); + final ThemeData themeData = Theme.of(context); + final InputDecoration effectiveDecoration = + (widget.decoration ?? const InputDecoration()) + .applyDefaults(themeData.inputDecorationTheme) + .copyWith( + enabled: _isEnabled, + hintMaxLines: widget.decoration?.hintMaxLines ?? widget.maxLines, + ); + + // No need to build anything if counter or counterText were given directly. + if (effectiveDecoration.counter != null || + effectiveDecoration.counterText != null) { + return effectiveDecoration; + } + + // If buildCounter was provided, use it to generate a counter widget. + Widget? counter; + final int currentLength = _currentLength; + if (effectiveDecoration.counter == null && + effectiveDecoration.counterText == null && + widget.buildCounter != null) { + final bool isFocused = _effectiveFocusNode.hasFocus; + final Widget? builtCounter = widget.buildCounter!( + context, + currentLength: currentLength, + maxLength: widget.maxLength, + isFocused: isFocused, + ); + // If buildCounter returns null, don't add a counter widget to the field. + if (builtCounter != null) { + counter = Semantics( + container: true, + liveRegion: isFocused, + child: builtCounter, + ); + } + return effectiveDecoration.copyWith(counter: counter); + } + + if (widget.maxLength == null) { + return effectiveDecoration; + } // No counter widget + + String counterText = '$currentLength'; + String semanticCounterText = ''; + + // Handle a real maxLength (positive number) + if (widget.maxLength! > 0) { + // Show the maxLength in the counter + counterText += '/${widget.maxLength}'; + final int remaining = + (widget.maxLength! - currentLength).clamp(0, widget.maxLength!); + semanticCounterText = + localizations.remainingTextFieldCharacterCount(remaining); + } + + if (_hasIntrinsicError) { + return effectiveDecoration.copyWith( + errorText: effectiveDecoration.errorText ?? '', + counterStyle: effectiveDecoration.errorStyle ?? + (themeData.useMaterial3 + ? _m3CounterErrorStyle(context) + : _m2CounterErrorStyle(context)), + counterText: counterText, + semanticCounterText: semanticCounterText, + ); + } + + return effectiveDecoration.copyWith( + counterText: counterText, + semanticCounterText: semanticCounterText, + ); + } + + @override + void initState() { + super.initState(); + _selectionGestureDetectorBuilder = + _TextFieldSelectionGestureDetectorBuilder(state: this); + if (widget.controller == null) { + _createLocalController(); + } + _effectiveFocusNode.canRequestFocus = widget.canRequestFocus && _isEnabled; + _effectiveFocusNode.addListener(_handleFocusChanged); + _initStatesController(); + } + + bool get _canRequestFocus { + final NavigationMode mode = + MediaQuery.maybeNavigationModeOf(context) ?? NavigationMode.traditional; + return switch (mode) { + NavigationMode.traditional => widget.canRequestFocus && _isEnabled, + NavigationMode.directional => true, + }; + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + _effectiveFocusNode.canRequestFocus = _canRequestFocus; + } + + @override + void didUpdateWidget(_TextField oldWidget) { + super.didUpdateWidget(oldWidget); + if (widget.controller == null && oldWidget.controller != null) { + _createLocalController(oldWidget.controller!.value); + } else if (widget.controller != null && oldWidget.controller == null) { + unregisterFromRestoration(_controller!); + _controller!.dispose(); + _controller = null; + } + + if (widget.focusNode != oldWidget.focusNode) { + (oldWidget.focusNode ?? _focusNode)?.removeListener(_handleFocusChanged); + (widget.focusNode ?? _focusNode)?.addListener(_handleFocusChanged); + } + + _effectiveFocusNode.canRequestFocus = _canRequestFocus; + + if (_effectiveFocusNode.hasFocus && + widget.readOnly != oldWidget.readOnly && + _isEnabled) { + if (_effectiveController.selection.isCollapsed) { + _showSelectionHandles = !widget.readOnly; + } + } + + if (widget.statesController == oldWidget.statesController) { + _statesController.update(MaterialState.disabled, !_isEnabled); + _statesController.update(MaterialState.hovered, _isHovering); + _statesController.update( + MaterialState.focused, _effectiveFocusNode.hasFocus); + _statesController.update(MaterialState.error, _hasError); + } else { + oldWidget.statesController?.removeListener(_handleStatesControllerChange); + if (widget.statesController != null) { + _internalStatesController?.dispose(); + _internalStatesController = null; + } + _initStatesController(); + } + } + + @override + void restoreState(RestorationBucket? oldBucket, bool initialRestore) { + if (_controller != null) { + _registerController(); + } + } + + void _registerController() { + assert(_controller != null); + registerForRestoration(_controller!, 'controller'); + } + + void _createLocalController([TextEditingValue? value]) { + assert(_controller == null); + _controller = value == null + ? RestorableTextEditingController() + : RestorableTextEditingController.fromValue(value); + if (!restorePending) { + _registerController(); + } + } + + @override + String? get restorationId => widget.restorationId; + + @override + void dispose() { + _effectiveFocusNode.removeListener(_handleFocusChanged); + _focusNode?.dispose(); + _controller?.dispose(); + _statesController.removeListener(_handleStatesControllerChange); + _internalStatesController?.dispose(); + super.dispose(); + } + + /// zmtzawqlp + _EditableTextState? get _editableText => editableTextKey.currentState; + + void _requestKeyboard() { + _editableText?.requestKeyboard(); + } + + bool _shouldShowSelectionHandles(SelectionChangedCause? cause) { + // When the text field is activated by something that doesn't trigger the + // selection overlay, we shouldn't show the handles either. + if (!_selectionGestureDetectorBuilder.shouldShowSelectionToolbar) { + return false; + } + + if (cause == SelectionChangedCause.keyboard) { + return false; + } + + if (widget.readOnly && _effectiveController.selection.isCollapsed) { + return false; + } + + if (!_isEnabled) { + return false; + } + + if (cause == SelectionChangedCause.longPress || + cause == SelectionChangedCause.scribble) { + return true; + } + + if (_effectiveController.text.isNotEmpty) { + return true; + } + + return false; + } + + void _handleFocusChanged() { + setState(() { + // Rebuild the widget on focus change to show/hide the text selection + // highlight. + }); + _statesController.update( + MaterialState.focused, _effectiveFocusNode.hasFocus); + } + + void _handleSelectionChanged( + TextSelection selection, SelectionChangedCause? cause) { + final bool willShowSelectionHandles = _shouldShowSelectionHandles(cause); + if (willShowSelectionHandles != _showSelectionHandles) { + setState(() { + _showSelectionHandles = willShowSelectionHandles; + }); + } + + switch (Theme.of(context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + case TargetPlatform.fuchsia: + case TargetPlatform.android: + if (cause == SelectionChangedCause.longPress) { + _editableText?.bringIntoView(selection.extent); + } + } + + switch (Theme.of(context).platform) { + case TargetPlatform.iOS: + case TargetPlatform.fuchsia: + case TargetPlatform.android: + break; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + if (cause == SelectionChangedCause.drag) { + _editableText?.hideToolbar(); + } + } + } + + /// Toggle the toolbar when a selection handle is tapped. + void _handleSelectionHandleTapped() { + if (_effectiveController.selection.isCollapsed) { + _editableText!.toggleToolbar(); + } + } + + void _handleHover(bool hovering) { + if (hovering != _isHovering) { + setState(() { + _isHovering = hovering; + }); + _statesController.update(MaterialState.hovered, _isHovering); + } + } + + // Material states controller. + MaterialStatesController? _internalStatesController; + + void _handleStatesControllerChange() { + // Force a rebuild to resolve MaterialStateProperty properties. + setState(() {}); + } + + MaterialStatesController get _statesController => + widget.statesController ?? _internalStatesController!; + + void _initStatesController() { + if (widget.statesController == null) { + _internalStatesController = MaterialStatesController(); + } + _statesController.update(MaterialState.disabled, !_isEnabled); + _statesController.update(MaterialState.hovered, _isHovering); + _statesController.update( + MaterialState.focused, _effectiveFocusNode.hasFocus); + _statesController.update(MaterialState.error, _hasError); + _statesController.addListener(_handleStatesControllerChange); + } + + // AutofillClient implementation start. + @override + String get autofillId => _editableText!.autofillId; + + @override + void autofill(TextEditingValue newEditingValue) => + _editableText!.autofill(newEditingValue); + + @override + TextInputConfiguration get textInputConfiguration { + final List? autofillHints = + widget.autofillHints?.toList(growable: false); + final AutofillConfiguration autofillConfiguration = autofillHints != null + ? AutofillConfiguration( + uniqueIdentifier: autofillId, + autofillHints: autofillHints, + currentEditingValue: _effectiveController.value, + hintText: (widget.decoration ?? const InputDecoration()).hintText, + ) + : AutofillConfiguration.disabled; + + return _editableText!.textInputConfiguration + .copyWith(autofillConfiguration: autofillConfiguration); + } + // AutofillClient implementation end. + + TextStyle _getInputStyleForState(TextStyle style) { + final ThemeData theme = Theme.of(context); + final TextStyle stateStyle = MaterialStateProperty.resolveAs( + theme.useMaterial3 + ? _m3StateInputStyle(context)! + : _m2StateInputStyle(context)!, + _statesController.value); + final TextStyle providedStyle = + MaterialStateProperty.resolveAs(style, _statesController.value); + return providedStyle.merge(stateStyle); + } + + @override + Widget build(BuildContext context) { + assert(debugCheckHasMaterial(context)); + assert(debugCheckHasMaterialLocalizations(context)); + assert(debugCheckHasDirectionality(context)); + assert( + !(widget.style != null && + !widget.style!.inherit && + (widget.style!.fontSize == null || + widget.style!.textBaseline == null)), + 'inherit false style must supply fontSize and textBaseline', + ); + + final ThemeData theme = Theme.of(context); + final DefaultSelectionStyle selectionStyle = + DefaultSelectionStyle.of(context); + final TextStyle? providedStyle = + MaterialStateProperty.resolveAs(widget.style, _statesController.value); + final TextStyle style = _getInputStyleForState(theme.useMaterial3 + ? _m3InputStyle(context) + : theme.textTheme.titleMedium!) + .merge(providedStyle); + final Brightness keyboardAppearance = + widget.keyboardAppearance ?? theme.brightness; + final TextEditingController controller = _effectiveController; + final FocusNode focusNode = _effectiveFocusNode; + final List formatters = [ + ...?widget.inputFormatters, + if (widget.maxLength != null) + LengthLimitingTextInputFormatter( + widget.maxLength, + maxLengthEnforcement: _effectiveMaxLengthEnforcement, + ), + ]; + + // Set configuration as disabled if not otherwise specified. If specified, + // ensure that configuration uses the correct style for misspelled words for + // the current platform, unless a custom style is specified. + final SpellCheckConfiguration spellCheckConfiguration; + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + spellCheckConfiguration = + CupertinoTextField.inferIOSSpellCheckConfiguration( + widget.spellCheckConfiguration, + ); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + spellCheckConfiguration = TextField.inferAndroidSpellCheckConfiguration( + widget.spellCheckConfiguration, + ); + } + + TextSelectionControls? textSelectionControls = widget.selectionControls; + final bool paintCursorAboveText; + bool? cursorOpacityAnimates = widget.cursorOpacityAnimates; + Offset? cursorOffset; + final Color cursorColor; + final Color selectionColor; + Color? autocorrectionTextRectColor; + Radius? cursorRadius = widget.cursorRadius; + VoidCallback? handleDidGainAccessibilityFocus; + VoidCallback? handleDidLoseAccessibilityFocus; + + switch (theme.platform) { + case TargetPlatform.iOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = true; + textSelectionControls ??= cupertinoTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates ??= true; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + autocorrectionTextRectColor = selectionColor; + + case TargetPlatform.macOS: + final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context); + forcePressEnabled = false; + textSelectionControls ??= cupertinoDesktopTextSelectionHandleControls; + paintCursorAboveText = true; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + cupertinoTheme.primaryColor; + selectionColor = selectionStyle.selectionColor ?? + cupertinoTheme.primaryColor.withOpacity(0.40); + cursorRadius ??= const Radius.circular(2.0); + cursorOffset = Offset( + iOSHorizontalOffset / MediaQuery.devicePixelRatioOf(context), 0); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + + case TargetPlatform.android: + case TargetPlatform.fuchsia: + forcePressEnabled = false; + textSelectionControls ??= materialTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + + case TargetPlatform.linux: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + + case TargetPlatform.windows: + forcePressEnabled = false; + textSelectionControls ??= desktopTextSelectionHandleControls; + paintCursorAboveText = false; + cursorOpacityAnimates ??= false; + cursorColor = _hasError + ? _errorColor + : widget.cursorColor ?? + selectionStyle.cursorColor ?? + theme.colorScheme.primary; + selectionColor = selectionStyle.selectionColor ?? + theme.colorScheme.primary.withOpacity(0.40); + handleDidGainAccessibilityFocus = () { + // Automatically activate the TextField when it receives accessibility focus. + if (!_effectiveFocusNode.hasFocus && + _effectiveFocusNode.canRequestFocus) { + _effectiveFocusNode.requestFocus(); + } + }; + handleDidLoseAccessibilityFocus = () { + _effectiveFocusNode.unfocus(); + }; + } + + Widget child = RepaintBoundary( + child: UnmanagedRestorationScope( + bucket: bucket, + child: EditableText( + key: editableTextKey, + readOnly: widget.readOnly || !_isEnabled, + toolbarOptions: widget.toolbarOptions, + showCursor: widget.showCursor, + showSelectionHandles: _showSelectionHandles, + controller: controller, + focusNode: focusNode, + undoController: widget.undoController, + keyboardType: widget.keyboardType, + textInputAction: widget.textInputAction, + textCapitalization: widget.textCapitalization, + style: style, + strutStyle: widget.strutStyle, + textAlign: widget.textAlign, + textDirection: widget.textDirection, + autofocus: widget.autofocus, + obscuringCharacter: widget.obscuringCharacter, + obscureText: widget.obscureText, + autocorrect: widget.autocorrect, + smartDashesType: widget.smartDashesType, + smartQuotesType: widget.smartQuotesType, + enableSuggestions: widget.enableSuggestions, + maxLines: widget.maxLines, + minLines: widget.minLines, + expands: widget.expands, + // Only show the selection highlight when the text field is focused. + selectionColor: focusNode.hasFocus ? selectionColor : null, + selectionControls: + widget.selectionEnabled ? textSelectionControls : null, + onChanged: widget.onChanged, + onSelectionChanged: _handleSelectionChanged, + onEditingComplete: widget.onEditingComplete, + onSubmitted: widget.onSubmitted, + onAppPrivateCommand: widget.onAppPrivateCommand, + groupId: widget.groupId, + onSelectionHandleTapped: _handleSelectionHandleTapped, + onTapOutside: widget.onTapOutside, + inputFormatters: formatters, + rendererIgnoresPointer: true, + mouseCursor: MouseCursor.defer, // TextField will handle the cursor + cursorWidth: widget.cursorWidth, + cursorHeight: widget.cursorHeight, + cursorRadius: cursorRadius, + cursorColor: cursorColor, + selectionHeightStyle: widget.selectionHeightStyle, + selectionWidthStyle: widget.selectionWidthStyle, + cursorOpacityAnimates: cursorOpacityAnimates, + cursorOffset: cursorOffset, + paintCursorAboveText: paintCursorAboveText, + backgroundCursorColor: CupertinoColors.inactiveGray, + scrollPadding: widget.scrollPadding, + keyboardAppearance: keyboardAppearance, + enableInteractiveSelection: widget.enableInteractiveSelection, + dragStartBehavior: widget.dragStartBehavior, + scrollController: widget.scrollController, + scrollPhysics: widget.scrollPhysics, + autofillClient: this, + autocorrectionTextRectColor: autocorrectionTextRectColor, + clipBehavior: widget.clipBehavior, + restorationId: 'editable', + scribbleEnabled: widget.scribbleEnabled, + enableIMEPersonalizedLearning: widget.enableIMEPersonalizedLearning, + contentInsertionConfiguration: widget.contentInsertionConfiguration, + contextMenuBuilder: widget.contextMenuBuilder, + spellCheckConfiguration: spellCheckConfiguration, + magnifierConfiguration: widget.magnifierConfiguration ?? + TextMagnifier.adaptiveMagnifierConfiguration, + ), + ), + ); + + if (widget.decoration != null) { + child = AnimatedBuilder( + animation: Listenable.merge([focusNode, controller]), + builder: (BuildContext context, Widget? child) { + return InputDecorator( + decoration: _getEffectiveDecoration(), + baseStyle: widget.style, + textAlign: widget.textAlign, + textAlignVertical: widget.textAlignVertical, + isHovering: _isHovering, + isFocused: focusNode.hasFocus, + isEmpty: controller.value.text.isEmpty, + expands: widget.expands, + child: child, + ); + }, + child: child, + ); + } + final MouseCursor effectiveMouseCursor = + MaterialStateProperty.resolveAs( + widget.mouseCursor ?? MaterialStateMouseCursor.textable, + _statesController.value, + ); + + final int? semanticsMaxValueLength; + if (_effectiveMaxLengthEnforcement != MaxLengthEnforcement.none && + widget.maxLength != null && + widget.maxLength! > 0) { + semanticsMaxValueLength = widget.maxLength; + } else { + semanticsMaxValueLength = null; + } + + return MouseRegion( + cursor: effectiveMouseCursor, + onEnter: (PointerEnterEvent event) => _handleHover(true), + onExit: (PointerExitEvent event) => _handleHover(false), + child: TextFieldTapRegion( + child: IgnorePointer( + ignoring: widget.ignorePointers ?? !_isEnabled, + child: AnimatedBuilder( + animation: controller, // changes the _currentLength + builder: (BuildContext context, Widget? child) { + return Semantics( + enabled: _isEnabled, + maxValueLength: semanticsMaxValueLength, + currentValueLength: _currentLength, + onTap: widget.readOnly + ? null + : () { + if (!_effectiveController.selection.isValid) { + _effectiveController.selection = + TextSelection.collapsed( + offset: _effectiveController.text.length); + } + _requestKeyboard(); + }, + onDidGainAccessibilityFocus: handleDidGainAccessibilityFocus, + onDidLoseAccessibilityFocus: handleDidLoseAccessibilityFocus, + onFocus: _isEnabled + ? () { + assert( + _effectiveFocusNode.canRequestFocus, + 'Received SemanticsAction.focus from the engine. However, the FocusNode ' + 'of this text field cannot gain focus. This likely indicates a bug. ' + 'If this text field cannot be focused (e.g. because it is not ' + 'enabled), then its corresponding semantics node must be configured ' + 'such that the assistive technology cannot request focus on it.'); + + if (_effectiveFocusNode.canRequestFocus && + !_effectiveFocusNode.hasFocus) { + _effectiveFocusNode.requestFocus(); + } else if (!widget.readOnly) { + // If the platform requested focus, that means that previously the + // platform believed that the text field did not have focus (even + // though Flutter's widget system believed otherwise). This likely + // means that the on-screen keyboard is hidden, or more generally, + // there is no current editing session in this field. To correct + // that, keyboard must be requested. + // + // A concrete scenario where this can happen is when the user + // dismisses the keyboard on the web. The editing session is + // closed by the engine, but the text field widget stays focused + // in the framework. + _requestKeyboard(); + } + } + : null, + child: child, + ); + }, + child: _selectionGestureDetectorBuilder.buildGestureDetector( + behavior: HitTestBehavior.translucent, + child: child, + ), + ), + ), + ), + ); + } +} + +TextStyle? _m2StateInputStyle(BuildContext context) => + MaterialStateTextStyle.resolveWith((Set states) { + final ThemeData theme = Theme.of(context); + if (states.contains(MaterialState.disabled)) { + return TextStyle(color: theme.disabledColor); + } + return TextStyle(color: theme.textTheme.titleMedium?.color); + }); + +TextStyle _m2CounterErrorStyle(BuildContext context) => Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Theme.of(context).colorScheme.error); + +// BEGIN GENERATED TOKEN PROPERTIES - TextField + +// Do not edit by hand. The code between the "BEGIN GENERATED" and +// "END GENERATED" comments are generated from data in the Material +// Design token database by the script: +// dev/tools/gen_defaults/bin/gen_defaults.dart. + +TextStyle? _m3StateInputStyle(BuildContext context) => + MaterialStateTextStyle.resolveWith((Set states) { + if (states.contains(MaterialState.disabled)) { + return TextStyle( + color: Theme.of(context) + .textTheme + .bodyLarge! + .color + ?.withOpacity(0.38)); + } + return TextStyle(color: Theme.of(context).textTheme.bodyLarge!.color); + }); + +TextStyle _m3InputStyle(BuildContext context) => + Theme.of(context).textTheme.bodyLarge!; + +TextStyle _m3CounterErrorStyle(BuildContext context) => Theme.of(context) + .textTheme + .bodySmall! + .copyWith(color: Theme.of(context).colorScheme.error); + +// END GENERATED TOKEN PROPERTIES - TextField diff --git a/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_selection.dart b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_selection.dart new file mode 100644 index 0000000..fc02e60 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/lib/src/official/widgets/text_selection.dart @@ -0,0 +1,2996 @@ +part of 'package:extended_text_field/src/extended/widgets/text_field.dart'; + +/// [TextSelectionOverlay] +/// An object that manages a pair of text selection handles for a +/// [RenderEditable]. +/// +/// This class is a wrapper of [SelectionOverlay] to provide APIs specific for +/// [RenderEditable]s. To manage selection handles for custom widgets, use +/// [SelectionOverlay] instead. +class _TextSelectionOverlay { + /// Creates an object that manages overlay entries for selection handles. + /// + /// The [context] must have an [Overlay] as an ancestor. + _TextSelectionOverlay({ + required TextEditingValue value, + required this.context, + Widget? debugRequiredFor, + required LayerLink toolbarLayerLink, + required LayerLink startHandleLayerLink, + required LayerLink endHandleLayerLink, + required this.renderObject, + this.selectionControls, + bool handlesVisible = false, + required this.selectionDelegate, + DragStartBehavior dragStartBehavior = DragStartBehavior.start, + VoidCallback? onSelectionHandleTapped, + ClipboardStatusNotifier? clipboardStatus, + this.contextMenuBuilder, + required TextMagnifierConfiguration magnifierConfiguration, + }) : _handlesVisible = handlesVisible, + _value = value { + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + FlutterMemoryAllocations.instance.dispatchObjectCreated( + library: 'package:flutter/widgets.dart', + className: '$TextSelectionOverlay', + object: this, + ); + } + renderObject.selectionStartInViewport + .addListener(_updateTextSelectionOverlayVisibilities); + renderObject.selectionEndInViewport + .addListener(_updateTextSelectionOverlayVisibilities); + _updateTextSelectionOverlayVisibilities(); + _selectionOverlay = _SelectionOverlay( + magnifierConfiguration: magnifierConfiguration, + context: context, + debugRequiredFor: debugRequiredFor, + // The metrics will be set when show handles. + startHandleType: TextSelectionHandleType.collapsed, + startHandlesVisible: _effectiveStartHandleVisibility, + lineHeightAtStart: 0.0, + onStartHandleDragStart: _handleSelectionStartHandleDragStart, + onStartHandleDragUpdate: _handleSelectionStartHandleDragUpdate, + onEndHandleDragEnd: _handleAnyDragEnd, + endHandleType: TextSelectionHandleType.collapsed, + endHandlesVisible: _effectiveEndHandleVisibility, + lineHeightAtEnd: 0.0, + onEndHandleDragStart: _handleSelectionEndHandleDragStart, + onEndHandleDragUpdate: _handleSelectionEndHandleDragUpdate, + onStartHandleDragEnd: _handleAnyDragEnd, + toolbarVisible: _effectiveToolbarVisibility, + selectionEndpoints: const [], + selectionControls: selectionControls, + selectionDelegate: selectionDelegate, + clipboardStatus: clipboardStatus, + startHandleLayerLink: startHandleLayerLink, + endHandleLayerLink: endHandleLayerLink, + toolbarLayerLink: toolbarLayerLink, + onSelectionHandleTapped: onSelectionHandleTapped, + dragStartBehavior: dragStartBehavior, + toolbarLocation: renderObject.lastSecondaryTapDownPosition, + ); + } + + /// {@template flutter.widgets.SelectionOverlay.context} + /// The context in which the selection UI should appear. + /// + /// This context must have an [Overlay] as an ancestor because this object + /// will display the text selection handles in that [Overlay]. + /// {@endtemplate} + final BuildContext context; + + // TODO(mpcomplete): what if the renderObject is removed or replaced, or + // moves? Not sure what cases I need to handle, or how to handle them. + /// The editable line in which the selected text is being displayed. + /// zmtzawqlp + final _RenderEditable renderObject; + + /// {@macro flutter.widgets.SelectionOverlay.selectionControls} + final TextSelectionControls? selectionControls; + + /// {@macro flutter.widgets.SelectionOverlay.selectionDelegate} + final TextSelectionDelegate selectionDelegate; + + /// zmtzawqlp + late final _SelectionOverlay _selectionOverlay; + + /// {@macro flutter.widgets.EditableText.contextMenuBuilder} + /// + /// If not provided, no context menu will be built. + final WidgetBuilder? contextMenuBuilder; + + /// Retrieve current value. + @visibleForTesting + TextEditingValue get value => _value; + + TextEditingValue _value; + + TextSelection get _selection => _value.selection; + + final ValueNotifier _effectiveStartHandleVisibility = + ValueNotifier(false); + final ValueNotifier _effectiveEndHandleVisibility = + ValueNotifier(false); + final ValueNotifier _effectiveToolbarVisibility = + ValueNotifier(false); + + void _updateTextSelectionOverlayVisibilities() { + _effectiveStartHandleVisibility.value = + _handlesVisible && renderObject.selectionStartInViewport.value; + _effectiveEndHandleVisibility.value = + _handlesVisible && renderObject.selectionEndInViewport.value; + _effectiveToolbarVisibility.value = + renderObject.selectionStartInViewport.value || + renderObject.selectionEndInViewport.value; + } + + /// Whether selection handles are visible. + /// + /// Set to false if you want to hide the handles. Use this property to show or + /// hide the handle without rebuilding them. + /// + /// Defaults to false. + bool get handlesVisible => _handlesVisible; + bool _handlesVisible = false; + set handlesVisible(bool visible) { + if (_handlesVisible == visible) { + return; + } + _handlesVisible = visible; + _updateTextSelectionOverlayVisibilities(); + } + + /// {@macro flutter.widgets.SelectionOverlay.showHandles} + void showHandles() { + _updateSelectionOverlay(); + _selectionOverlay.showHandles(); + } + + /// {@macro flutter.widgets.SelectionOverlay.hideHandles} + void hideHandles() => _selectionOverlay.hideHandles(); + + /// {@macro flutter.widgets.SelectionOverlay.showToolbar} + void showToolbar() { + _updateSelectionOverlay(); + + if (selectionControls != null && + selectionControls is! TextSelectionHandleControls) { + _selectionOverlay.showToolbar(); + return; + } + + if (contextMenuBuilder == null) { + return; + } + + assert(context.mounted); + _selectionOverlay.showToolbar( + context: context, + contextMenuBuilder: contextMenuBuilder, + ); + return; + } + + /// Shows toolbar with spell check suggestions of misspelled words that are + /// available for click-and-replace. + void showSpellCheckSuggestionsToolbar( + WidgetBuilder spellCheckSuggestionsToolbarBuilder) { + _updateSelectionOverlay(); + assert(context.mounted); + _selectionOverlay.showSpellCheckSuggestionsToolbar( + context: context, + builder: spellCheckSuggestionsToolbarBuilder, + ); + hideHandles(); + } + + /// {@macro flutter.widgets.SelectionOverlay.showMagnifier} + void showMagnifier(Offset positionToShow) { + final TextPosition position = + renderObject.getPositionForPoint(positionToShow); + _updateSelectionOverlay(); + _selectionOverlay.showMagnifier( + _buildMagnifier( + currentTextPosition: position, + globalGesturePosition: positionToShow, + renderEditable: renderObject, + ), + ); + } + + /// {@macro flutter.widgets.SelectionOverlay.updateMagnifier} + void updateMagnifier(Offset positionToShow) { + final TextPosition position = + renderObject.getPositionForPoint(positionToShow); + _updateSelectionOverlay(); + _selectionOverlay.updateMagnifier( + _buildMagnifier( + currentTextPosition: position, + globalGesturePosition: positionToShow, + renderEditable: renderObject, + ), + ); + } + + /// {@macro flutter.widgets.SelectionOverlay.hideMagnifier} + void hideMagnifier() { + _selectionOverlay.hideMagnifier(); + } + + /// Updates the overlay after the selection has changed. + /// + /// If this method is called while the [SchedulerBinding.schedulerPhase] is + /// [SchedulerPhase.persistentCallbacks], i.e. during the build, layout, or + /// paint phases (see [WidgetsBinding.drawFrame]), then the update is delayed + /// until the post-frame callbacks phase. Otherwise the update is done + /// synchronously. This means that it is safe to call during builds, but also + /// that if you do call this during a build, the UI will not update until the + /// next frame (i.e. many milliseconds later). + void update(TextEditingValue newValue) { + if (_value == newValue) { + return; + } + _value = newValue; + _updateSelectionOverlay(); + // _updateSelectionOverlay may not rebuild the selection overlay if the + // text metrics and selection doesn't change even if the text has changed. + // This rebuild is needed for the toolbar to update based on the latest text + // value. + _selectionOverlay.markNeedsBuild(); + } + + void _updateSelectionOverlay() { + _selectionOverlay + // Update selection handle metrics. + ..startHandleType = _chooseType( + renderObject.textDirection, + TextSelectionHandleType.left, + TextSelectionHandleType.right, + ) + ..lineHeightAtStart = _getStartGlyphHeight() + ..endHandleType = _chooseType( + renderObject.textDirection, + TextSelectionHandleType.right, + TextSelectionHandleType.left, + ) + ..lineHeightAtEnd = _getEndGlyphHeight() + // Update selection toolbar metrics. + ..selectionEndpoints = renderObject.getEndpointsForSelection(_selection) + ..toolbarLocation = renderObject.lastSecondaryTapDownPosition; + } + + /// Causes the overlay to update its rendering. + /// + /// This is intended to be called when the [renderObject] may have changed its + /// text metrics (e.g. because the text was scrolled). + void updateForScroll() { + _updateSelectionOverlay(); + // This method may be called due to windows metrics changes. In that case, + // non of the properties in _selectionOverlay will change, but a rebuild is + // still needed. + _selectionOverlay.markNeedsBuild(); + } + + /// Whether the handles are currently visible. + bool get handlesAreVisible => + _selectionOverlay._handles != null && handlesVisible; + + /// {@macro flutter.widgets.SelectionOverlay.toolbarIsVisible} + /// + /// See also: + /// + /// * [spellCheckToolbarIsVisible], which is only whether the spell check menu + /// specifically is visible. + bool get toolbarIsVisible => _selectionOverlay.toolbarIsVisible; + + /// Whether the magnifier is currently visible. + bool get magnifierIsVisible => _selectionOverlay._magnifierController.shown; + + /// Whether the spell check menu is currently visible. + /// + /// See also: + /// + /// * [toolbarIsVisible], which is whether any toolbar is visible. + bool get spellCheckToolbarIsVisible => + _selectionOverlay._spellCheckToolbarController.isShown; + + /// {@macro flutter.widgets.SelectionOverlay.hide} + void hide() => _selectionOverlay.hide(); + + /// {@macro flutter.widgets.SelectionOverlay.hideToolbar} + void hideToolbar() => _selectionOverlay.hideToolbar(); + + /// {@macro flutter.widgets.SelectionOverlay.dispose} + void dispose() { + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); + } + _selectionOverlay.dispose(); + renderObject.selectionStartInViewport + .removeListener(_updateTextSelectionOverlayVisibilities); + renderObject.selectionEndInViewport + .removeListener(_updateTextSelectionOverlayVisibilities); + _effectiveToolbarVisibility.dispose(); + _effectiveStartHandleVisibility.dispose(); + _effectiveEndHandleVisibility.dispose(); + hideToolbar(); + } + + double _getStartGlyphHeight() { + final String currText = selectionDelegate.textEditingValue.text; + final int firstSelectedGraphemeExtent; + Rect? startHandleRect; + // Only calculate handle rects if the text in the previous frame + // is the same as the text in the current frame. This is done because + // widget.renderObject contains the renderEditable from the previous frame. + // If the text changed between the current and previous frames then + // widget.renderObject.getRectForComposingRange might fail. In cases where + // the current frame is different from the previous we fall back to + // renderObject.preferredLineHeight. + if (renderObject.plainText == currText && + _selection.isValid && + !_selection.isCollapsed) { + final String selectedGraphemes = _selection.textInside(currText); + firstSelectedGraphemeExtent = selectedGraphemes.characters.first.length; + startHandleRect = renderObject.getRectForComposingRange(TextRange( + start: _selection.start, + end: _selection.start + firstSelectedGraphemeExtent)); + } + return startHandleRect?.height ?? renderObject.preferredLineHeight; + } + + double _getEndGlyphHeight() { + final String currText = selectionDelegate.textEditingValue.text; + final int lastSelectedGraphemeExtent; + Rect? endHandleRect; + // See the explanation in _getStartGlyphHeight. + if (renderObject.plainText == currText && + _selection.isValid && + !_selection.isCollapsed) { + final String selectedGraphemes = _selection.textInside(currText); + lastSelectedGraphemeExtent = selectedGraphemes.characters.last.length; + endHandleRect = renderObject.getRectForComposingRange(TextRange( + start: _selection.end - lastSelectedGraphemeExtent, + end: _selection.end)); + } + return endHandleRect?.height ?? renderObject.preferredLineHeight; + } + + MagnifierInfo _buildMagnifier({ + // zmtzawqlp + required _RenderEditable renderEditable, + required Offset globalGesturePosition, + required TextPosition currentTextPosition, + }) { + final TextSelection lineAtOffset = + renderEditable.getLineAtOffset(currentTextPosition); + + final TextPosition positionAtEndOfLine = TextPosition( + offset: lineAtOffset.extentOffset, + affinity: TextAffinity.upstream, + ); + + // Default affinity is downstream. + final TextPosition positionAtBeginningOfLine = TextPosition( + offset: lineAtOffset.baseOffset, + ); + + final Rect localLineBoundaries = Rect.fromPoints( + renderEditable.getLocalRectForCaret(positionAtBeginningOfLine).topCenter, + renderEditable.getLocalRectForCaret(positionAtEndOfLine).bottomCenter, + ); + final RenderBox? overlay = Overlay.of(context, rootOverlay: true) + .context + .findRenderObject() as RenderBox?; + final Matrix4 transformToOverlay = renderEditable.getTransformTo(overlay); + final Rect overlayLineBoundaries = MatrixUtils.transformRect( + transformToOverlay, + localLineBoundaries, + ); + + final Rect localCaretRect = + renderEditable.getLocalRectForCaret(currentTextPosition); + final Rect overlayCaretRect = MatrixUtils.transformRect( + transformToOverlay, + localCaretRect, + ); + + final Offset overlayGesturePosition = + overlay?.globalToLocal(globalGesturePosition) ?? globalGesturePosition; + + return MagnifierInfo( + fieldBounds: MatrixUtils.transformRect( + transformToOverlay, renderEditable.paintBounds), + globalGesturePosition: overlayGesturePosition, + caretRect: overlayCaretRect, + currentLineBoundaries: overlayLineBoundaries, + ); + } + + // The contact position of the gesture at the current end handle location, in + // global coordinates. Updated when the handle moves. + late double _endHandleDragPosition; + + // The distance from _endHandleDragPosition to the center of the line that it + // corresponds to, in global coordinates. + late double _endHandleDragTarget; + + void _handleSelectionEndHandleDragStart(DragStartDetails details) { + if (!renderObject.attached) { + return; + } + + _endHandleDragPosition = details.globalPosition.dy; + + // Use local coordinates when dealing with line height. because in case of a + // scale transformation, the line height will also be scaled. + final double centerOfLineLocal = + _selectionOverlay.selectionEndpoints.last.point.dy - + renderObject.preferredLineHeight / 2; + final double centerOfLineGlobal = renderObject + .localToGlobal( + Offset(0.0, centerOfLineLocal), + ) + .dy; + _endHandleDragTarget = centerOfLineGlobal - details.globalPosition.dy; + // Instead of finding the TextPosition at the handle's location directly, + // use the vertical center of the line that it points to. This is because + // selection handles typically hang above or below the line that they point + // to. + final TextPosition position = renderObject.getPositionForPoint( + Offset( + details.globalPosition.dx, + centerOfLineGlobal, + ), + ); + + _selectionOverlay.showMagnifier( + _buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + ), + ); + } + + /// Given a handle position and drag position, returns the position of handle + /// after the drag. + /// + /// The handle jumps instantly between lines when the drag reaches a full + /// line's height away from the original handle position. In other words, the + /// line jump happens when the contact point would be located at the same + /// place on the handle at the new line as when the gesture started, for both + /// directions. + /// + /// This is not the same as just maintaining an offset from the target and the + /// contact point. There is no point at which moving the drag up and down a + /// small sub-line-height distance will cause the cursor to jump up and down + /// between lines. The drag distance must be a full line height for the cursor + /// to change lines, for both directions. + /// + /// Both parameters must be in local coordinates because the untransformed + /// line height is used, and the return value is in local coordinates as well. + double _getHandleDy(double dragDy, double handleDy) { + final double distanceDragged = dragDy - handleDy; + final int dragDirection = distanceDragged < 0.0 ? -1 : 1; + final int linesDragged = dragDirection * + (distanceDragged.abs() / renderObject.preferredLineHeight).floor(); + return handleDy + linesDragged * renderObject.preferredLineHeight; + } + + void _handleSelectionEndHandleDragUpdate(DragUpdateDetails details) { + if (!renderObject.attached) { + return; + } + + // This is NOT the same as details.localPosition. That is relative to the + // selection handle, whereas this is relative to the RenderEditable. + final Offset localPosition = + renderObject.globalToLocal(details.globalPosition); + + final double nextEndHandleDragPositionLocal = _getHandleDy( + localPosition.dy, + renderObject.globalToLocal(Offset(0.0, _endHandleDragPosition)).dy, + ); + _endHandleDragPosition = renderObject + .localToGlobal( + Offset(0.0, nextEndHandleDragPositionLocal), + ) + .dy; + + final Offset handleTargetGlobal = Offset( + details.globalPosition.dx, + _endHandleDragPosition + _endHandleDragTarget, + ); + + final TextPosition position = + renderObject.getPositionForPoint(handleTargetGlobal); + + if (_selection.isCollapsed) { + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + )); + + final TextSelection currentSelection = + TextSelection.fromPosition(position); + _handleSelectionHandleChanged(currentSelection); + return; + } + + final TextSelection newSelection; + switch (defaultTargetPlatform) { + // On Apple platforms, dragging the base handle makes it the extent. + case TargetPlatform.iOS: + case TargetPlatform.macOS: + newSelection = TextSelection( + extentOffset: position.offset, + baseOffset: _selection.start, + ); + if (position.offset <= _selection.start) { + return; // Don't allow order swapping. + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + newSelection = TextSelection( + baseOffset: _selection.baseOffset, + extentOffset: position.offset, + ); + if (newSelection.baseOffset >= newSelection.extentOffset) { + return; // Don't allow order swapping. + } + } + + _handleSelectionHandleChanged(newSelection); + + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: newSelection.extent, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + )); + } + + // The contact position of the gesture at the current start handle location, + // in global coordinates. Updated when the handle moves. + late double _startHandleDragPosition; + + // The distance from _startHandleDragPosition to the center of the line that + // it corresponds to, in global coordinates. + late double _startHandleDragTarget; + + void _handleSelectionStartHandleDragStart(DragStartDetails details) { + if (!renderObject.attached) { + return; + } + + _startHandleDragPosition = details.globalPosition.dy; + + // Use local coordinates when dealing with line height. because in case of a + // scale transformation, the line height will also be scaled. + final double centerOfLineLocal = + _selectionOverlay.selectionEndpoints.first.point.dy - + renderObject.preferredLineHeight / 2; + final double centerOfLineGlobal = renderObject + .localToGlobal( + Offset(0.0, centerOfLineLocal), + ) + .dy; + _startHandleDragTarget = centerOfLineGlobal - details.globalPosition.dy; + // Instead of finding the TextPosition at the handle's location directly, + // use the vertical center of the line that it points to. This is because + // selection handles typically hang above or below the line that they point + // to. + final TextPosition position = renderObject.getPositionForPoint( + Offset( + details.globalPosition.dx, + centerOfLineGlobal, + ), + ); + + _selectionOverlay.showMagnifier( + _buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + ), + ); + } + + void _handleSelectionStartHandleDragUpdate(DragUpdateDetails details) { + if (!renderObject.attached) { + return; + } + + // This is NOT the same as details.localPosition. That is relative to the + // selection handle, whereas this is relative to the RenderEditable. + final Offset localPosition = + renderObject.globalToLocal(details.globalPosition); + final double nextStartHandleDragPositionLocal = _getHandleDy( + localPosition.dy, + renderObject.globalToLocal(Offset(0.0, _startHandleDragPosition)).dy, + ); + _startHandleDragPosition = renderObject + .localToGlobal( + Offset(0.0, nextStartHandleDragPositionLocal), + ) + .dy; + final Offset handleTargetGlobal = Offset( + details.globalPosition.dx, + _startHandleDragPosition + _startHandleDragTarget, + ); + final TextPosition position = + renderObject.getPositionForPoint(handleTargetGlobal); + + if (_selection.isCollapsed) { + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: position, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + )); + + final TextSelection currentSelection = + TextSelection.fromPosition(position); + _handleSelectionHandleChanged(currentSelection); + return; + } + + final TextSelection newSelection; + switch (defaultTargetPlatform) { + // On Apple platforms, dragging the base handle makes it the extent. + case TargetPlatform.iOS: + case TargetPlatform.macOS: + newSelection = TextSelection( + extentOffset: position.offset, + baseOffset: _selection.end, + ); + if (newSelection.extentOffset >= _selection.end) { + return; // Don't allow order swapping. + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + newSelection = TextSelection( + baseOffset: position.offset, + extentOffset: _selection.extentOffset, + ); + if (newSelection.baseOffset >= newSelection.extentOffset) { + return; // Don't allow order swapping. + } + } + + _selectionOverlay.updateMagnifier(_buildMagnifier( + currentTextPosition: newSelection.extent.offset < newSelection.base.offset + ? newSelection.extent + : newSelection.base, + globalGesturePosition: details.globalPosition, + renderEditable: renderObject, + )); + + _handleSelectionHandleChanged(newSelection); + } + + void _handleAnyDragEnd(DragEndDetails details) { + if (!context.mounted) { + return; + } + if (selectionControls is! TextSelectionHandleControls) { + _selectionOverlay.hideMagnifier(); + if (!_selection.isCollapsed) { + _selectionOverlay.showToolbar(); + } + return; + } + _selectionOverlay.hideMagnifier(); + if (!_selection.isCollapsed) { + _selectionOverlay.showToolbar( + context: context, + contextMenuBuilder: contextMenuBuilder, + ); + } + } + + void _handleSelectionHandleChanged(TextSelection newSelection) { + selectionDelegate.userUpdateTextEditingValue( + _value.copyWith(selection: newSelection), + SelectionChangedCause.drag, + ); + } + + TextSelectionHandleType _chooseType( + TextDirection textDirection, + TextSelectionHandleType ltrType, + TextSelectionHandleType rtlType, + ) { + if (_selection.isCollapsed) { + return TextSelectionHandleType.collapsed; + } + + return switch (textDirection) { + TextDirection.ltr => ltrType, + TextDirection.rtl => rtlType, + }; + } +} + +/// An object that manages a pair of selection handles and a toolbar. +/// +/// The selection handles are displayed in the [Overlay] that most closely +/// encloses the given [BuildContext]. +class _SelectionOverlay { + /// Creates an object that manages overlay entries for selection handles. + /// + /// The [context] must have an [Overlay] as an ancestor. + _SelectionOverlay({ + required this.context, + this.debugRequiredFor, + required TextSelectionHandleType startHandleType, + required double lineHeightAtStart, + this.startHandlesVisible, + this.onStartHandleDragStart, + this.onStartHandleDragUpdate, + this.onStartHandleDragEnd, + required TextSelectionHandleType endHandleType, + required double lineHeightAtEnd, + this.endHandlesVisible, + this.onEndHandleDragStart, + this.onEndHandleDragUpdate, + this.onEndHandleDragEnd, + this.toolbarVisible, + required List selectionEndpoints, + required this.selectionControls, + @Deprecated( + 'Use `contextMenuBuilder` in `showToolbar` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + required this.selectionDelegate, + required this.clipboardStatus, + required this.startHandleLayerLink, + required this.endHandleLayerLink, + required this.toolbarLayerLink, + this.dragStartBehavior = DragStartBehavior.start, + this.onSelectionHandleTapped, + @Deprecated( + 'Use `contextMenuBuilder` in `showToolbar` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + Offset? toolbarLocation, + this.magnifierConfiguration = TextMagnifierConfiguration.disabled, + }) : _startHandleType = startHandleType, + _lineHeightAtStart = lineHeightAtStart, + _endHandleType = endHandleType, + _lineHeightAtEnd = lineHeightAtEnd, + _selectionEndpoints = selectionEndpoints, + _toolbarLocation = toolbarLocation, + assert(debugCheckHasOverlay(context)) { + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + FlutterMemoryAllocations.instance.dispatchObjectCreated( + library: 'package:flutter/widgets.dart', + className: '$SelectionOverlay', + object: this, + ); + } + } + + /// {@macro flutter.widgets.SelectionOverlay.context} + final BuildContext context; + + final ValueNotifier _magnifierInfo = + ValueNotifier(MagnifierInfo.empty); + + // [MagnifierController.show] and [MagnifierController.hide] should not be + // called directly, except from inside [showMagnifier] and [hideMagnifier]. If + // it is desired to show or hide the magnifier, call [showMagnifier] or + // [hideMagnifier]. This is because the magnifier needs to orchestrate with + // other properties in [SelectionOverlay]. + final MagnifierController _magnifierController = MagnifierController(); + + /// The configuration for the magnifier. + /// + /// By default, [SelectionOverlay]'s [TextMagnifierConfiguration] is disabled. + /// + /// {@macro flutter.widgets.magnifier.intro} + final TextMagnifierConfiguration magnifierConfiguration; + + /// {@template flutter.widgets.SelectionOverlay.toolbarIsVisible} + /// Whether the toolbar is currently visible. + /// + /// Includes both the text selection toolbar and the spell check menu. + /// {@endtemplate} + bool get toolbarIsVisible { + return selectionControls is TextSelectionHandleControls + ? _contextMenuController.isShown || _spellCheckToolbarController.isShown + : _toolbar != null || _spellCheckToolbarController.isShown; + } + + /// {@template flutter.widgets.SelectionOverlay.showMagnifier} + /// Shows the magnifier, and hides the toolbar if it was showing when [showMagnifier] + /// was called. This is safe to call on platforms not mobile, since + /// a magnifierBuilder will not be provided, or the magnifierBuilder will return null + /// on platforms not mobile. + /// + /// This is NOT the source of truth for if the magnifier is up or not, + /// since magnifiers may hide themselves. If this info is needed, check + /// [MagnifierController.shown]. + /// {@endtemplate} + void showMagnifier(MagnifierInfo initialMagnifierInfo) { + if (toolbarIsVisible) { + hideToolbar(); + } + + // Start from empty, so we don't utilize any remnant values. + _magnifierInfo.value = initialMagnifierInfo; + + // Pre-build the magnifiers so we can tell if we've built something + // or not. If we don't build a magnifiers, then we should not + // insert anything in the overlay. + final Widget? builtMagnifier = magnifierConfiguration.magnifierBuilder( + context, + _magnifierController, + _magnifierInfo, + ); + + if (builtMagnifier == null) { + return; + } + + _magnifierController.show( + context: context, + below: magnifierConfiguration.shouldDisplayHandlesInMagnifier + ? null + : _handles?.start, + builder: (_) => builtMagnifier, + ); + } + + /// {@template flutter.widgets.SelectionOverlay.hideMagnifier} + /// Hide the current magnifier. + /// + /// This does nothing if there is no magnifier. + /// {@endtemplate} + void hideMagnifier() { + // This cannot be a check on `MagnifierController.shown`, since + // it's possible that the magnifier is still in the overlay, but + // not shown in cases where the magnifier hides itself. + if (_magnifierController.overlayEntry == null) { + return; + } + + _magnifierController.hide(); + } + + /// The type of start selection handle. + /// + /// Changing the value while the handles are visible causes them to rebuild. + TextSelectionHandleType get startHandleType => _startHandleType; + TextSelectionHandleType _startHandleType; + set startHandleType(TextSelectionHandleType value) { + if (_startHandleType == value) { + return; + } + _startHandleType = value; + markNeedsBuild(); + } + + /// The line height at the selection start. + /// + /// This value is used for calculating the size of the start selection handle. + /// + /// Changing the value while the handles are visible causes them to rebuild. + double get lineHeightAtStart => _lineHeightAtStart; + double _lineHeightAtStart; + set lineHeightAtStart(double value) { + if (_lineHeightAtStart == value) { + return; + } + _lineHeightAtStart = value; + markNeedsBuild(); + } + + bool _isDraggingStartHandle = false; + + /// Whether the start handle is visible. + /// + /// If the value changes, the start handle uses [FadeTransition] to transition + /// itself on and off the screen. + /// + /// If this is null, the start selection handle will always be visible. + final ValueListenable? startHandlesVisible; + + /// Called when the users start dragging the start selection handles. + final ValueChanged? onStartHandleDragStart; + + void _handleStartHandleDragStart(DragStartDetails details) { + assert(!_isDraggingStartHandle); + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + _isDraggingStartHandle = false; + return; + } + _isDraggingStartHandle = details.kind == PointerDeviceKind.touch; + onStartHandleDragStart?.call(details); + } + + void _handleStartHandleDragUpdate(DragUpdateDetails details) { + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + _isDraggingStartHandle = false; + return; + } + onStartHandleDragUpdate?.call(details); + } + + /// Called when the users drag the start selection handles to new locations. + final ValueChanged? onStartHandleDragUpdate; + + /// Called when the users lift their fingers after dragging the start selection + /// handles. + final ValueChanged? onStartHandleDragEnd; + + void _handleStartHandleDragEnd(DragEndDetails details) { + _isDraggingStartHandle = false; + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + return; + } + onStartHandleDragEnd?.call(details); + } + + /// The type of end selection handle. + /// + /// Changing the value while the handles are visible causes them to rebuild. + TextSelectionHandleType get endHandleType => _endHandleType; + TextSelectionHandleType _endHandleType; + set endHandleType(TextSelectionHandleType value) { + if (_endHandleType == value) { + return; + } + _endHandleType = value; + markNeedsBuild(); + } + + /// The line height at the selection end. + /// + /// This value is used for calculating the size of the end selection handle. + /// + /// Changing the value while the handles are visible causes them to rebuild. + double get lineHeightAtEnd => _lineHeightAtEnd; + double _lineHeightAtEnd; + set lineHeightAtEnd(double value) { + if (_lineHeightAtEnd == value) { + return; + } + _lineHeightAtEnd = value; + markNeedsBuild(); + } + + bool _isDraggingEndHandle = false; + + /// Whether the end handle is visible. + /// + /// If the value changes, the end handle uses [FadeTransition] to transition + /// itself on and off the screen. + /// + /// If this is null, the end selection handle will always be visible. + final ValueListenable? endHandlesVisible; + + /// Called when the users start dragging the end selection handles. + final ValueChanged? onEndHandleDragStart; + + void _handleEndHandleDragStart(DragStartDetails details) { + assert(!_isDraggingEndHandle); + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + _isDraggingEndHandle = false; + return; + } + _isDraggingEndHandle = details.kind == PointerDeviceKind.touch; + onEndHandleDragStart?.call(details); + } + + void _handleEndHandleDragUpdate(DragUpdateDetails details) { + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + _isDraggingEndHandle = false; + return; + } + onEndHandleDragUpdate?.call(details); + } + + /// Called when the users drag the end selection handles to new locations. + final ValueChanged? onEndHandleDragUpdate; + + /// Called when the users lift their fingers after dragging the end selection + /// handles. + final ValueChanged? onEndHandleDragEnd; + + void _handleEndHandleDragEnd(DragEndDetails details) { + _isDraggingEndHandle = false; + // Calling OverlayEntry.remove may not happen until the following frame, so + // it's possible for the handles to receive a gesture after calling remove. + if (_handles == null) { + return; + } + onEndHandleDragEnd?.call(details); + } + + /// Whether the toolbar is visible. + /// + /// If the value changes, the toolbar uses [FadeTransition] to transition + /// itself on and off the screen. + /// + /// If this is null the toolbar will always be visible. + final ValueListenable? toolbarVisible; + + /// The text selection positions of selection start and end. + List get selectionEndpoints => _selectionEndpoints; + List _selectionEndpoints; + set selectionEndpoints(List value) { + if (!listEquals(_selectionEndpoints, value)) { + markNeedsBuild(); + if (_isDraggingEndHandle || _isDraggingStartHandle) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + HapticFeedback.selectionClick(); + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + break; + } + } + } + _selectionEndpoints = value; + } + + /// Debugging information for explaining why the [Overlay] is required. + final Widget? debugRequiredFor; + + /// The object supplied to the [CompositedTransformTarget] that wraps the text + /// field. + final LayerLink toolbarLayerLink; + + /// The objects supplied to the [CompositedTransformTarget] that wraps the + /// location of start selection handle. + final LayerLink startHandleLayerLink; + + /// The objects supplied to the [CompositedTransformTarget] that wraps the + /// location of end selection handle. + final LayerLink endHandleLayerLink; + + /// {@template flutter.widgets.SelectionOverlay.selectionControls} + /// Builds text selection handles and toolbar. + /// {@endtemplate} + final TextSelectionControls? selectionControls; + + /// {@template flutter.widgets.SelectionOverlay.selectionDelegate} + /// The delegate for manipulating the current selection in the owning + /// text field. + /// {@endtemplate} + @Deprecated( + 'Use `contextMenuBuilder` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + final TextSelectionDelegate? selectionDelegate; + + /// Determines the way that drag start behavior is handled. + /// + /// If set to [DragStartBehavior.start], handle drag behavior will + /// begin at the position where the drag gesture won the arena. If set to + /// [DragStartBehavior.down] it will begin at the position where a down + /// event is first detected. + /// + /// In general, setting this to [DragStartBehavior.start] will make drag + /// animation smoother and setting it to [DragStartBehavior.down] will make + /// drag behavior feel slightly more reactive. + /// + /// By default, the drag start behavior is [DragStartBehavior.start]. + /// + /// See also: + /// + /// * [DragGestureRecognizer.dragStartBehavior], which gives an example for the different behaviors. + final DragStartBehavior dragStartBehavior; + + /// {@template flutter.widgets.SelectionOverlay.onSelectionHandleTapped} + /// A callback that's optionally invoked when a selection handle is tapped. + /// + /// The [TextSelectionControls.buildHandle] implementation the text field + /// uses decides where the handle's tap "hotspot" is, or whether the + /// selection handle supports tap gestures at all. For instance, + /// [MaterialTextSelectionControls] calls [onSelectionHandleTapped] when the + /// selection handle's "knob" is tapped, while + /// [CupertinoTextSelectionControls] builds a handle that's not sufficiently + /// large for tapping (as it's not meant to be tapped) so it does not call + /// [onSelectionHandleTapped] even when tapped. + /// {@endtemplate} + // See https://github.com/flutter/flutter/issues/39376#issuecomment-848406415 + // for provenance. + final VoidCallback? onSelectionHandleTapped; + + /// Maintains the status of the clipboard for determining if its contents can + /// be pasted or not. + /// + /// Useful because the actual value of the clipboard can only be checked + /// asynchronously (see [Clipboard.getData]). + final ClipboardStatusNotifier? clipboardStatus; + + /// The location of where the toolbar should be drawn in relative to the + /// location of [toolbarLayerLink]. + /// + /// If this is null, the toolbar is drawn based on [selectionEndpoints] and + /// the rect of render object of [context]. + /// + /// This is useful for displaying toolbars at the mouse right-click locations + /// in desktop devices. + @Deprecated( + 'Use the `contextMenuBuilder` parameter in `showToolbar` instead. ' + 'This feature was deprecated after v3.3.0-0.5.pre.', + ) + Offset? get toolbarLocation => _toolbarLocation; + Offset? _toolbarLocation; + set toolbarLocation(Offset? value) { + if (_toolbarLocation == value) { + return; + } + _toolbarLocation = value; + markNeedsBuild(); + } + + /// Controls the fade-in and fade-out animations for the toolbar and handles. + // static const Duration fadeDuration = Duration(milliseconds: 150); + + /// A pair of handles. If this is non-null, there are always 2, though the + /// second is hidden when the selection is collapsed. + ({OverlayEntry start, OverlayEntry end})? _handles; + + /// A copy/paste toolbar. + OverlayEntry? _toolbar; + + // Manages the context menu. Not necessarily visible when non-null. + final ContextMenuController _contextMenuController = ContextMenuController(); + + final ContextMenuController _spellCheckToolbarController = + ContextMenuController(); + + /// {@template flutter.widgets.SelectionOverlay.showHandles} + /// Builds the handles by inserting them into the [context]'s overlay. + /// {@endtemplate} + void showHandles() { + if (_handles != null) { + return; + } + + final OverlayState overlay = Overlay.of(context, + rootOverlay: true, debugRequiredFor: debugRequiredFor); + + final CapturedThemes capturedThemes = InheritedTheme.capture( + from: context, + to: overlay.context, + ); + + _handles = ( + start: OverlayEntry(builder: (BuildContext context) { + return capturedThemes.wrap(_buildStartHandle(context)); + }), + end: OverlayEntry(builder: (BuildContext context) { + return capturedThemes.wrap(_buildEndHandle(context)); + }), + ); + overlay.insertAll([_handles!.start, _handles!.end]); + } + + /// {@template flutter.widgets.SelectionOverlay.hideHandles} + /// Destroys the handles by removing them from overlay. + /// {@endtemplate} + void hideHandles() { + if (_handles != null) { + _handles!.start.remove(); + _handles!.start.dispose(); + _handles!.end.remove(); + _handles!.end.dispose(); + _handles = null; + } + } + + /// {@template flutter.widgets.SelectionOverlay.showToolbar} + /// Shows the toolbar by inserting it into the [context]'s overlay. + /// {@endtemplate} + void showToolbar({ + BuildContext? context, + WidgetBuilder? contextMenuBuilder, + }) { + if (contextMenuBuilder == null) { + if (_toolbar != null) { + return; + } + _toolbar = OverlayEntry(builder: _buildToolbar); + Overlay.of(this.context, + rootOverlay: true, debugRequiredFor: debugRequiredFor) + .insert(_toolbar!); + return; + } + + if (context == null) { + return; + } + + final RenderBox renderBox = context.findRenderObject()! as RenderBox; + _contextMenuController.show( + context: context, + contextMenuBuilder: (BuildContext context) { + return _SelectionToolbarWrapper( + visibility: toolbarVisible, + layerLink: toolbarLayerLink, + offset: -renderBox.localToGlobal(Offset.zero), + child: contextMenuBuilder(context), + ); + }, + ); + } + + /// Shows toolbar with spell check suggestions of misspelled words that are + /// available for click-and-replace. + void showSpellCheckSuggestionsToolbar({ + BuildContext? context, + required WidgetBuilder builder, + }) { + if (context == null) { + return; + } + + final RenderBox renderBox = context.findRenderObject()! as RenderBox; + _spellCheckToolbarController.show( + context: context, + contextMenuBuilder: (BuildContext context) { + return _SelectionToolbarWrapper( + layerLink: toolbarLayerLink, + offset: -renderBox.localToGlobal(Offset.zero), + child: builder(context), + ); + }, + ); + } + + bool _buildScheduled = false; + + /// Rebuilds the selection toolbar or handles if they are present. + void markNeedsBuild() { + if (_handles == null && _toolbar == null) { + return; + } + // If we are in build state, it will be too late to update visibility. + // We will need to schedule the build in next frame. + if (SchedulerBinding.instance.schedulerPhase == + SchedulerPhase.persistentCallbacks) { + if (_buildScheduled) { + return; + } + _buildScheduled = true; + SchedulerBinding.instance.addPostFrameCallback((Duration duration) { + _buildScheduled = false; + if (_handles != null) { + _handles!.start.markNeedsBuild(); + _handles!.end.markNeedsBuild(); + } + _toolbar?.markNeedsBuild(); + if (_contextMenuController.isShown) { + _contextMenuController.markNeedsBuild(); + } else if (_spellCheckToolbarController.isShown) { + _spellCheckToolbarController.markNeedsBuild(); + } + }, debugLabel: 'SelectionOverlay.markNeedsBuild'); + } else { + if (_handles != null) { + _handles!.start.markNeedsBuild(); + _handles!.end.markNeedsBuild(); + } + _toolbar?.markNeedsBuild(); + if (_contextMenuController.isShown) { + _contextMenuController.markNeedsBuild(); + } else if (_spellCheckToolbarController.isShown) { + _spellCheckToolbarController.markNeedsBuild(); + } + } + } + + /// {@template flutter.widgets.SelectionOverlay.hide} + /// Hides the entire overlay including the toolbar and the handles. + /// {@endtemplate} + void hide() { + _magnifierController.hide(); + hideHandles(); + if (_toolbar != null || + _contextMenuController.isShown || + _spellCheckToolbarController.isShown) { + hideToolbar(); + } + } + + /// {@template flutter.widgets.SelectionOverlay.hideToolbar} + /// Hides the toolbar part of the overlay. + /// + /// To hide the whole overlay, see [hide]. + /// {@endtemplate} + void hideToolbar() { + _contextMenuController.remove(); + _spellCheckToolbarController.remove(); + if (_toolbar == null) { + return; + } + _toolbar?.remove(); + _toolbar?.dispose(); + _toolbar = null; + } + + /// {@template flutter.widgets.SelectionOverlay.dispose} + /// Disposes this object and release resources. + /// {@endtemplate} + void dispose() { + // TODO(polina-c): stop duplicating code across disposables + // https://github.com/flutter/flutter/issues/137435 + if (kFlutterMemoryAllocationsEnabled) { + FlutterMemoryAllocations.instance.dispatchObjectDisposed(object: this); + } + hide(); + _magnifierInfo.dispose(); + } + + Widget _buildStartHandle(BuildContext context) { + final Widget handle; + final TextSelectionControls? selectionControls = this.selectionControls; + if (selectionControls == null) { + handle = const SizedBox.shrink(); + } else { + handle = _SelectionHandleOverlay( + type: _startHandleType, + handleLayerLink: startHandleLayerLink, + onSelectionHandleTapped: onSelectionHandleTapped, + onSelectionHandleDragStart: _handleStartHandleDragStart, + onSelectionHandleDragUpdate: _handleStartHandleDragUpdate, + onSelectionHandleDragEnd: _handleStartHandleDragEnd, + selectionControls: selectionControls, + visibility: startHandlesVisible, + preferredLineHeight: _lineHeightAtStart, + dragStartBehavior: dragStartBehavior, + ); + } + return TextFieldTapRegion( + child: ExcludeSemantics( + child: handle, + ), + ); + } + + Widget _buildEndHandle(BuildContext context) { + final Widget handle; + final TextSelectionControls? selectionControls = this.selectionControls; + if (selectionControls == null || + _startHandleType == TextSelectionHandleType.collapsed) { + // Hide the second handle when collapsed. + handle = const SizedBox.shrink(); + } else { + handle = _SelectionHandleOverlay( + type: _endHandleType, + handleLayerLink: endHandleLayerLink, + onSelectionHandleTapped: onSelectionHandleTapped, + onSelectionHandleDragStart: _handleEndHandleDragStart, + onSelectionHandleDragUpdate: _handleEndHandleDragUpdate, + onSelectionHandleDragEnd: _handleEndHandleDragEnd, + selectionControls: selectionControls, + visibility: endHandlesVisible, + preferredLineHeight: _lineHeightAtEnd, + dragStartBehavior: dragStartBehavior, + ); + } + return TextFieldTapRegion( + child: ExcludeSemantics( + child: handle, + ), + ); + } + + // Build the toolbar via TextSelectionControls. + Widget _buildToolbar(BuildContext context) { + if (selectionControls == null) { + return const SizedBox.shrink(); + } + assert(selectionDelegate != null, + 'If not using contextMenuBuilder, must pass selectionDelegate.'); + + final RenderBox renderBox = this.context.findRenderObject()! as RenderBox; + + final Rect editingRegion = Rect.fromPoints( + renderBox.localToGlobal(Offset.zero), + renderBox.localToGlobal(renderBox.size.bottomRight(Offset.zero)), + ); + + final bool isMultiline = + selectionEndpoints.last.point.dy - selectionEndpoints.first.point.dy > + lineHeightAtEnd / 2; + + // If the selected text spans more than 1 line, horizontally center the toolbar. + // Derived from both iOS and Android. + final double midX = isMultiline + ? editingRegion.width / 2 + : (selectionEndpoints.first.point.dx + + selectionEndpoints.last.point.dx) / + 2; + + final Offset midpoint = Offset( + midX, + // The y-coordinate won't be made use of most likely. + selectionEndpoints.first.point.dy - lineHeightAtStart, + ); + + return _SelectionToolbarWrapper( + visibility: toolbarVisible, + layerLink: toolbarLayerLink, + offset: -editingRegion.topLeft, + child: Builder( + builder: (BuildContext context) { + return selectionControls!.buildToolbar( + context, + editingRegion, + lineHeightAtStart, + midpoint, + selectionEndpoints, + selectionDelegate!, + clipboardStatus, + toolbarLocation, + ); + }, + ), + ); + } + + /// {@template flutter.widgets.SelectionOverlay.updateMagnifier} + /// Update the current magnifier with new selection data, so the magnifier + /// can respond accordingly. + /// + /// If the magnifier is not shown, this still updates the magnifier position + /// because the magnifier may have hidden itself and is looking for a cue to reshow + /// itself. + /// + /// If there is no magnifier in the overlay, this does nothing. + /// {@endtemplate} + void updateMagnifier(MagnifierInfo magnifierInfo) { + if (_magnifierController.overlayEntry == null) { + return; + } + + _magnifierInfo.value = magnifierInfo; + } +} + +// TODO(justinmc): Currently this fades in but not out on all platforms. It +// should follow the correct fading behavior for the current platform, then be +// made public and de-duplicated with widgets/selectable_region.dart. +// https://github.com/flutter/flutter/issues/107732 +// Wrap the given child in the widgets common to both contextMenuBuilder and +// TextSelectionControls.buildToolbar. +class _SelectionToolbarWrapper extends StatefulWidget { + const _SelectionToolbarWrapper({ + this.visibility, + required this.layerLink, + required this.offset, + required this.child, + }); + + final Widget child; + final Offset offset; + final LayerLink layerLink; + final ValueListenable? visibility; + + @override + State<_SelectionToolbarWrapper> createState() => + _SelectionToolbarWrapperState(); +} + +class _SelectionToolbarWrapperState extends State<_SelectionToolbarWrapper> + with SingleTickerProviderStateMixin { + late AnimationController _controller; + Animation get _opacity => _controller.view; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + duration: SelectionOverlay.fadeDuration, vsync: this); + + _toolbarVisibilityChanged(); + widget.visibility?.addListener(_toolbarVisibilityChanged); + } + + @override + void didUpdateWidget(_SelectionToolbarWrapper oldWidget) { + super.didUpdateWidget(oldWidget); + if (oldWidget.visibility == widget.visibility) { + return; + } + oldWidget.visibility?.removeListener(_toolbarVisibilityChanged); + _toolbarVisibilityChanged(); + widget.visibility?.addListener(_toolbarVisibilityChanged); + } + + @override + void dispose() { + widget.visibility?.removeListener(_toolbarVisibilityChanged); + _controller.dispose(); + super.dispose(); + } + + void _toolbarVisibilityChanged() { + if (widget.visibility?.value ?? true) { + _controller.forward(); + } else { + _controller.reverse(); + } + } + + @override + Widget build(BuildContext context) { + return TextFieldTapRegion( + child: Directionality( + textDirection: Directionality.of(this.context), + child: FadeTransition( + opacity: _opacity, + child: CompositedTransformFollower( + link: widget.layerLink, + showWhenUnlinked: false, + offset: widget.offset, + child: widget.child, + ), + ), + ), + ); + } +} + +/// This widget represents a single draggable selection handle. +class _SelectionHandleOverlay extends StatefulWidget { + /// Create selection overlay. + const _SelectionHandleOverlay({ + required this.type, + required this.handleLayerLink, + this.onSelectionHandleTapped, + this.onSelectionHandleDragStart, + this.onSelectionHandleDragUpdate, + this.onSelectionHandleDragEnd, + required this.selectionControls, + this.visibility, + required this.preferredLineHeight, + this.dragStartBehavior = DragStartBehavior.start, + }); + + final LayerLink handleLayerLink; + final VoidCallback? onSelectionHandleTapped; + final ValueChanged? onSelectionHandleDragStart; + final ValueChanged? onSelectionHandleDragUpdate; + final ValueChanged? onSelectionHandleDragEnd; + final TextSelectionControls selectionControls; + final ValueListenable? visibility; + final double preferredLineHeight; + final TextSelectionHandleType type; + final DragStartBehavior dragStartBehavior; + + @override + State<_SelectionHandleOverlay> createState() => + _SelectionHandleOverlayState(); +} + +class _SelectionHandleOverlayState extends State<_SelectionHandleOverlay> + with SingleTickerProviderStateMixin { + late AnimationController _controller; + Animation get _opacity => _controller.view; + + @override + void initState() { + super.initState(); + + _controller = AnimationController( + duration: SelectionOverlay.fadeDuration, vsync: this); + + _handleVisibilityChanged(); + widget.visibility?.addListener(_handleVisibilityChanged); + } + + void _handleVisibilityChanged() { + if (widget.visibility?.value ?? true) { + _controller.forward(); + } else { + _controller.reverse(); + } + } + + @override + void didUpdateWidget(_SelectionHandleOverlay oldWidget) { + super.didUpdateWidget(oldWidget); + oldWidget.visibility?.removeListener(_handleVisibilityChanged); + _handleVisibilityChanged(); + widget.visibility?.addListener(_handleVisibilityChanged); + } + + @override + void dispose() { + widget.visibility?.removeListener(_handleVisibilityChanged); + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final Offset handleAnchor = widget.selectionControls.getHandleAnchor( + widget.type, + widget.preferredLineHeight, + ); + final Size handleSize = widget.selectionControls.getHandleSize( + widget.preferredLineHeight, + ); + + final Rect handleRect = Rect.fromLTWH( + -handleAnchor.dx, + -handleAnchor.dy, + handleSize.width, + handleSize.height, + ); + + // Make sure the GestureDetector is big enough to be easily interactive. + final Rect interactiveRect = handleRect.expandToInclude( + Rect.fromCircle( + center: handleRect.center, radius: kMinInteractiveDimension / 2), + ); + final RelativeRect padding = RelativeRect.fromLTRB( + math.max((interactiveRect.width - handleRect.width) / 2, 0), + math.max((interactiveRect.height - handleRect.height) / 2, 0), + math.max((interactiveRect.width - handleRect.width) / 2, 0), + math.max((interactiveRect.height - handleRect.height) / 2, 0), + ); + + // Make sure a drag is eagerly accepted. This is used on iOS to match the + // behavior where a drag directly on a collapse handle will always win against + // other drag gestures. + final bool eagerlyAcceptDragWhenCollapsed = + widget.type == TextSelectionHandleType.collapsed && + defaultTargetPlatform == TargetPlatform.iOS; + + return CompositedTransformFollower( + link: widget.handleLayerLink, + offset: interactiveRect.topLeft, + showWhenUnlinked: false, + child: FadeTransition( + opacity: _opacity, + child: Container( + alignment: Alignment.topLeft, + width: interactiveRect.width, + height: interactiveRect.height, + child: RawGestureDetector( + behavior: HitTestBehavior.translucent, + gestures: { + PanGestureRecognizer: + GestureRecognizerFactoryWithHandlers( + () => PanGestureRecognizer( + debugOwner: this, + // Mouse events select the text and do not drag the cursor. + supportedDevices: { + PointerDeviceKind.touch, + PointerDeviceKind.stylus, + PointerDeviceKind.unknown, + }, + ), + (PanGestureRecognizer instance) { + instance + ..dragStartBehavior = widget.dragStartBehavior + ..gestureSettings = eagerlyAcceptDragWhenCollapsed + ? const DeviceGestureSettings(touchSlop: 1.0) + : null + ..onStart = widget.onSelectionHandleDragStart + ..onUpdate = widget.onSelectionHandleDragUpdate + ..onEnd = widget.onSelectionHandleDragEnd; + }, + ), + }, + child: Padding( + padding: EdgeInsets.only( + left: padding.left, + top: padding.top, + right: padding.right, + bottom: padding.bottom, + ), + child: widget.selectionControls.buildHandle( + context, + widget.type, + widget.preferredLineHeight, + widget.onSelectionHandleTapped, + ), + ), + ), + ), + ), + ); + } +} + +/// Delegate interface for the [TextSelectionGestureDetectorBuilder]. +/// +/// The interface is usually implemented by the [State] of text field +/// implementations wrapping [EditableText], so that they can use a +/// [TextSelectionGestureDetectorBuilder] to build a +/// [TextSelectionGestureDetector] for their [EditableText]. The delegate +/// provides the builder with information about the current state of the text +/// field. Based on that information, the builder adds the correct gesture +/// handlers to the gesture detector. +/// +/// See also: +/// +/// * [TextField], which implements this delegate for the Material text field. +/// * [CupertinoTextField], which implements this delegate for the Cupertino +/// text field. +abstract class _TextSelectionGestureDetectorBuilderDelegate { + /// [GlobalKey] to the [EditableText] for which the + /// [TextSelectionGestureDetectorBuilder] will build a [TextSelectionGestureDetector]. + GlobalKey<_EditableTextState> get editableTextKey; + + /// Whether the text field should respond to force presses. + bool get forcePressEnabled; + + /// Whether the user may select text in the text field. + bool get selectionEnabled; +} + +/// Builds a [TextSelectionGestureDetector] to wrap an [EditableText]. +/// +/// The class implements sensible defaults for many user interactions +/// with an [EditableText] (see the documentation of the various gesture handler +/// methods, e.g. [onTapDown], [onForcePressStart], etc.). Subclasses of +/// [TextSelectionGestureDetectorBuilder] can change the behavior performed in +/// responds to these gesture events by overriding the corresponding handler +/// methods of this class. +/// +/// The resulting [TextSelectionGestureDetector] to wrap an [EditableText] is +/// obtained by calling [buildGestureDetector]. +/// +/// A [TextSelectionGestureDetectorBuilder] must be provided a +/// [TextSelectionGestureDetectorBuilderDelegate], from which information about +/// the [EditableText] may be obtained. Typically, the [State] of the widget +/// that builds the [EditableText] implements this interface, and then passes +/// itself as the [delegate]. +/// +/// See also: +/// +/// * [TextField], which uses a subclass to implement the Material-specific +/// gesture logic of an [EditableText]. +/// * [CupertinoTextField], which uses a subclass to implement the +/// Cupertino-specific gesture logic of an [EditableText]. +class _TextSelectionGestureDetectorBuilder { + /// Creates a [TextSelectionGestureDetectorBuilder]. + _TextSelectionGestureDetectorBuilder({ + required this.delegate, + }); + + /// The delegate for this [TextSelectionGestureDetectorBuilder]. + /// + /// The delegate provides the builder with information about what actions can + /// currently be performed on the text field. Based on this, the builder adds + /// the correct gesture handlers to the gesture detector. + /// + /// Typically implemented by a [State] of a widget that builds an + /// [EditableText]. + @protected + final _TextSelectionGestureDetectorBuilderDelegate delegate; + + // Shows the magnifier on supported platforms at the given offset, currently + // only Android and iOS. + void _showMagnifierIfSupportedByPlatform(Offset positionToShow) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.iOS: + editableText.showMagnifier(positionToShow); + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + } + } + + // Hides the magnifier on supported platforms, currently only Android and iOS. + void _hideMagnifierIfSupportedByPlatform() { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.iOS: + editableText.hideMagnifier(); + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + } + } + + /// Returns true if lastSecondaryTapDownPosition was on selection. + bool get _lastSecondaryTapWasOnSelection { + assert(renderEditable.lastSecondaryTapDownPosition != null); + if (renderEditable.selection == null) { + return false; + } + + final TextPosition textPosition = renderEditable.getPositionForPoint( + renderEditable.lastSecondaryTapDownPosition!, + ); + + return renderEditable.selection!.start <= textPosition.offset && + renderEditable.selection!.end >= textPosition.offset; + } + + bool _positionWasOnSelectionExclusive(TextPosition textPosition) { + final TextSelection? selection = renderEditable.selection; + if (selection == null) { + return false; + } + + return selection.start < textPosition.offset && + selection.end > textPosition.offset; + } + + bool _positionWasOnSelectionInclusive(TextPosition textPosition) { + final TextSelection? selection = renderEditable.selection; + if (selection == null) { + return false; + } + + return selection.start <= textPosition.offset && + selection.end >= textPosition.offset; + } + + // Expand the selection to the given global position. + // + // Either base or extent will be moved to the last tapped position, whichever + // is closest. The selection will never shrink or pivot, only grow. + // + // If fromSelection is given, will expand from that selection instead of the + // current selection in renderEditable. + // + // See also: + // + // * [_extendSelection], which is similar but pivots the selection around + // the base. + void _expandSelection(Offset offset, SelectionChangedCause cause, + [TextSelection? fromSelection]) { + assert(renderEditable.selection?.baseOffset != null); + + final TextPosition tappedPosition = + renderEditable.getPositionForPoint(offset); + final TextSelection selection = fromSelection ?? renderEditable.selection!; + final bool baseIsCloser = + (tappedPosition.offset - selection.baseOffset).abs() < + (tappedPosition.offset - selection.extentOffset).abs(); + final TextSelection nextSelection = selection.copyWith( + baseOffset: baseIsCloser ? selection.extentOffset : selection.baseOffset, + extentOffset: tappedPosition.offset, + ); + + editableText.userUpdateTextEditingValue( + editableText.textEditingValue.copyWith( + selection: nextSelection, + ), + cause, + ); + } + + // Extend the selection to the given global position. + // + // Holds the base in place and moves the extent. + // + // See also: + // + // * [_expandSelection], which is similar but always increases the size of + // the selection. + void _extendSelection(Offset offset, SelectionChangedCause cause) { + assert(renderEditable.selection?.baseOffset != null); + + final TextPosition tappedPosition = + renderEditable.getPositionForPoint(offset); + final TextSelection selection = renderEditable.selection!; + final TextSelection nextSelection = selection.copyWith( + extentOffset: tappedPosition.offset, + ); + + editableText.userUpdateTextEditingValue( + editableText.textEditingValue.copyWith( + selection: nextSelection, + ), + cause, + ); + } + + /// Whether to show the selection toolbar. + /// + /// It is based on the signal source when a [onTapDown] is called. This getter + /// will return true if current [onTapDown] event is triggered by a touch or + /// a stylus. + bool get shouldShowSelectionToolbar => _shouldShowSelectionToolbar; + bool _shouldShowSelectionToolbar = true; + + /// The [State] of the [EditableText] for which the builder will provide a + /// [TextSelectionGestureDetector]. + @protected + + /// zmtzawqlp + _EditableTextState get editableText => delegate.editableTextKey.currentState!; + + /// The [RenderObject] of the [EditableText] for which the builder will + /// provide a [TextSelectionGestureDetector]. + @protected + // zmtzawqlp + _RenderEditable get renderEditable => editableText.renderEditable; + + /// Whether the Shift key was pressed when the most recent [PointerDownEvent] + /// was tracked by the [BaseTapAndDragGestureRecognizer]. + bool _isShiftPressed = false; + + /// The viewport offset pixels of any [Scrollable] containing the + /// [RenderEditable] at the last drag start. + double _dragStartScrollOffset = 0.0; + + /// The viewport offset pixels of the [RenderEditable] at the last drag start. + double _dragStartViewportOffset = 0.0; + + double get _scrollPosition { + final ScrollableState? scrollableState = + delegate.editableTextKey.currentContext == null + ? null + : Scrollable.maybeOf(delegate.editableTextKey.currentContext!); + return scrollableState == null ? 0.0 : scrollableState.position.pixels; + } + + AxisDirection? get _scrollDirection { + final ScrollableState? scrollableState = + delegate.editableTextKey.currentContext == null + ? null + : Scrollable.maybeOf(delegate.editableTextKey.currentContext!); + return scrollableState?.axisDirection; + } + + // For a shift + tap + drag gesture, the TextSelection at the point of the + // tap. Mac uses this value to reset to the original selection when an + // inversion of the base and offset happens. + TextSelection? _dragStartSelection; + + // For iOS long press behavior when the field is not focused. iOS uses this value + // to determine if a long press began on a field that was not focused. + // + // If the field was not focused when the long press began, a long press will select + // the word and a long press move will select word-by-word. If the field was + // focused, the cursor moves to the long press position. + bool _longPressStartedWithoutFocus = false; + + /// Handler for [TextSelectionGestureDetector.onTapTrackStart]. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onTapTrackStart], which triggers this + /// callback. + @protected + void onTapTrackStart() { + _isShiftPressed = HardwareKeyboard.instance.logicalKeysPressed + .intersection({ + LogicalKeyboardKey.shiftLeft, + LogicalKeyboardKey.shiftRight + }).isNotEmpty; + } + + /// Handler for [TextSelectionGestureDetector.onTapTrackReset]. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onTapTrackReset], which triggers this + /// callback. + @protected + void onTapTrackReset() { + _isShiftPressed = false; + } + + /// Handler for [TextSelectionGestureDetector.onTapDown]. + /// + /// By default, it forwards the tap to [RenderEditable.handleTapDown] and sets + /// [shouldShowSelectionToolbar] to true if the tap was initiated by a finger or stylus. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onTapDown], which triggers this callback. + @protected + void onTapDown(TapDragDownDetails details) { + if (!delegate.selectionEnabled) { + return; + } + // TODO(Renzo-Olivares): Migrate text selection gestures away from saving state + // in renderEditable. The gesture callbacks can use the details objects directly + // in callbacks variants that provide them [TapGestureRecognizer.onSecondaryTap] + // vs [TapGestureRecognizer.onSecondaryTapUp] instead of having to track state in + // renderEditable. When this migration is complete we should remove this hack. + // See https://github.com/flutter/flutter/issues/115130. + renderEditable + .handleTapDown(TapDownDetails(globalPosition: details.globalPosition)); + // The selection overlay should only be shown when the user is interacting + // through a touch screen (via either a finger or a stylus). A mouse shouldn't + // trigger the selection overlay. + // For backwards-compatibility, we treat a null kind the same as touch. + final PointerDeviceKind? kind = details.kind; + // TODO(justinmc): Should a desktop platform show its selection toolbar when + // receiving a tap event? Say a Windows device with a touchscreen. + // https://github.com/flutter/flutter/issues/106586 + _shouldShowSelectionToolbar = kind == null || + kind == PointerDeviceKind.touch || + kind == PointerDeviceKind.stylus; + + // It is impossible to extend the selection when the shift key is pressed, if the + // renderEditable.selection is invalid. + final bool isShiftPressedValid = + _isShiftPressed && renderEditable.selection?.baseOffset != null; + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + // On mobile platforms the selection is set on tap up. + break; + case TargetPlatform.macOS: + editableText.hideToolbar(); + // On macOS, a shift-tapped unfocused field expands from 0, not from the + // previous selection. + if (isShiftPressedValid) { + final TextSelection? fromSelection = renderEditable.hasFocus + ? null + : const TextSelection.collapsed(offset: 0); + _expandSelection( + details.globalPosition, + SelectionChangedCause.tap, + fromSelection, + ); + return; + } + // On macOS, a tap/click places the selection in a precise position. + // This differs from iOS/iPadOS, where if the gesture is done by a touch + // then the selection moves to the closest word edge, instead of a + // precise position. + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + case TargetPlatform.linux: + case TargetPlatform.windows: + editableText.hideToolbar(); + if (isShiftPressedValid) { + _extendSelection(details.globalPosition, SelectionChangedCause.tap); + return; + } + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + } + } + + /// Handler for [TextSelectionGestureDetector.onForcePressStart]. + /// + /// By default, it selects the word at the position of the force press, + /// if selection is enabled. + /// + /// This callback is only applicable when force press is enabled. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onForcePressStart], which triggers this + /// callback. + @protected + void onForcePressStart(ForcePressDetails details) { + assert(delegate.forcePressEnabled); + _shouldShowSelectionToolbar = true; + if (delegate.selectionEnabled) { + renderEditable.selectWordsInRange( + from: details.globalPosition, + cause: SelectionChangedCause.forcePress, + ); + } + } + + /// Handler for [TextSelectionGestureDetector.onForcePressEnd]. + /// + /// By default, it selects words in the range specified in [details] and shows + /// toolbar if it is necessary. + /// + /// This callback is only applicable when force press is enabled. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onForcePressEnd], which triggers this + /// callback. + @protected + void onForcePressEnd(ForcePressDetails details) { + assert(delegate.forcePressEnabled); + renderEditable.selectWordsInRange( + from: details.globalPosition, + cause: SelectionChangedCause.forcePress, + ); + if (shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + } + + /// Whether the provided [onUserTap] callback should be dispatched on every + /// tap or only non-consecutive taps. + /// + /// Defaults to false. + @protected + bool get onUserTapAlwaysCalled => false; + + /// Handler for [TextSelectionGestureDetector.onUserTap]. + /// + /// By default, it serves as placeholder to enable subclass override. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onUserTap], which triggers this + /// callback. + /// * [TextSelectionGestureDetector.onUserTapAlwaysCalled], which controls + /// whether this callback is called only on the first tap in a series + /// of taps. + @protected + void onUserTap() {/* Subclass should override this method if needed. */} + + /// Handler for [TextSelectionGestureDetector.onSingleTapUp]. + /// + /// By default, it selects word edge if selection is enabled. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSingleTapUp], which triggers + /// this callback. + @protected + void onSingleTapUp(TapDragUpDetails details) { + if (delegate.selectionEnabled) { + // It is impossible to extend the selection when the shift key is pressed, if the + // renderEditable.selection is invalid. + final bool isShiftPressedValid = + _isShiftPressed && renderEditable.selection?.baseOffset != null; + switch (defaultTargetPlatform) { + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + break; + // On desktop platforms the selection is set on tap down. + case TargetPlatform.android: + editableText.hideToolbar(false); + if (isShiftPressedValid) { + _extendSelection(details.globalPosition, SelectionChangedCause.tap); + return; + } + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + editableText.showSpellCheckSuggestionsToolbar(); + case TargetPlatform.fuchsia: + editableText.hideToolbar(false); + if (isShiftPressedValid) { + _extendSelection(details.globalPosition, SelectionChangedCause.tap); + return; + } + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + case TargetPlatform.iOS: + if (isShiftPressedValid) { + // On iOS, a shift-tapped unfocused field expands from 0, not from + // the previous selection. + final TextSelection? fromSelection = renderEditable.hasFocus + ? null + : const TextSelection.collapsed(offset: 0); + _expandSelection( + details.globalPosition, + SelectionChangedCause.tap, + fromSelection, + ); + return; + } + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + // TODO(camsim99): Determine spell check toolbar behavior in these cases: + // https://github.com/flutter/flutter/issues/119573. + // Precise devices should place the cursor at a precise position if the + // word at the text position is not misspelled. + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + // If the word that was tapped is misspelled, select the word and show the spell check suggestions + // toolbar once. If additional taps are made on a misspelled word, toggle the toolbar. If the word + // is not misspelled, default to the following behavior: + // + // Toggle the toolbar if the `previousSelection` is collapsed, the tap is on the selection, the + // TextAffinity remains the same, and the editable is focused. The TextAffinity is important when the + // cursor is on the boundary of a line wrap, if the affinity is different (i.e. it is downstream), the + // selection should move to the following line and not toggle the toolbar. + // + // Toggle the toolbar when the tap is exclusively within the bounds of a non-collapsed `previousSelection`, + // and the editable is focused. + // + // Selects the word edge closest to the tap when the editable is not focused, or if the tap was neither exclusively + // or inclusively on `previousSelection`. If the selection remains the same after selecting the word edge, then we + // toggle the toolbar. If the selection changes then we hide the toolbar. + final TextSelection previousSelection = + renderEditable.selection ?? + editableText.textEditingValue.selection; + final TextPosition textPosition = + renderEditable.getPositionForPoint(details.globalPosition); + final bool isAffinityTheSame = + textPosition.affinity == previousSelection.affinity; + final bool wordAtCursorIndexIsMisspelled = editableText + .findSuggestionSpanAtCursorIndex(textPosition.offset) != + null; + + if (wordAtCursorIndexIsMisspelled) { + renderEditable.selectWord(cause: SelectionChangedCause.tap); + if (previousSelection != + editableText.textEditingValue.selection) { + editableText.showSpellCheckSuggestionsToolbar(); + } else { + editableText.toggleToolbar(false); + } + } else if (((_positionWasOnSelectionExclusive(textPosition) && + !previousSelection.isCollapsed) || + (_positionWasOnSelectionInclusive(textPosition) && + previousSelection.isCollapsed && + isAffinityTheSame)) && + renderEditable.hasFocus) { + editableText.toggleToolbar(false); + } else { + renderEditable.selectWordEdge(cause: SelectionChangedCause.tap); + if (previousSelection == + editableText.textEditingValue.selection && + renderEditable.hasFocus) { + editableText.toggleToolbar(false); + } else { + editableText.hideToolbar(false); + } + } + } + } + } + editableText.requestKeyboard(); + } + + /// Handler for [TextSelectionGestureDetector.onSingleTapCancel]. + /// + /// By default, it serves as placeholder to enable subclass override. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSingleTapCancel], which triggers + /// this callback. + @protected + void onSingleTapCancel() { + /* Subclass should override this method if needed. */ + } + + /// Handler for [TextSelectionGestureDetector.onSingleLongTapStart]. + /// + /// By default, it selects text position specified in [details] if selection + /// is enabled. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSingleLongTapStart], which triggers + /// this callback. + @protected + void onSingleLongTapStart(LongPressStartDetails details) { + if (delegate.selectionEnabled) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + if (!renderEditable.hasFocus) { + _longPressStartedWithoutFocus = true; + renderEditable.selectWord(cause: SelectionChangedCause.longPress); + } else { + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress, + ); + // Show the floating cursor. + final RawFloatingCursorPoint cursorPoint = RawFloatingCursorPoint( + state: FloatingCursorDragState.Start, + startLocation: ( + renderEditable.globalToLocal(details.globalPosition), + TextPosition( + offset: editableText.textEditingValue.selection.baseOffset, + affinity: editableText.textEditingValue.selection.affinity, + ), + ), + offset: Offset.zero, + ); + editableText.updateFloatingCursor(cursorPoint); + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + renderEditable.selectWord(cause: SelectionChangedCause.longPress); + } + + _showMagnifierIfSupportedByPlatform(details.globalPosition); + + _dragStartViewportOffset = renderEditable.offset.pixels; + _dragStartScrollOffset = _scrollPosition; + } + } + + /// Handler for [TextSelectionGestureDetector.onSingleLongTapMoveUpdate]. + /// + /// By default, it updates the selection location specified in [details] if + /// selection is enabled. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSingleLongTapMoveUpdate], which + /// triggers this callback. + @protected + void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) { + if (delegate.selectionEnabled) { + // Adjust the drag start offset for possible viewport offset changes. + final Offset editableOffset = renderEditable.maxLines == 1 + ? Offset(renderEditable.offset.pixels - _dragStartViewportOffset, 0.0) + : Offset( + 0.0, renderEditable.offset.pixels - _dragStartViewportOffset); + final Offset scrollableOffset = + switch (axisDirectionToAxis(_scrollDirection ?? AxisDirection.left)) { + Axis.horizontal => + Offset(_scrollPosition - _dragStartScrollOffset, 0.0), + Axis.vertical => Offset(0.0, _scrollPosition - _dragStartScrollOffset), + }; + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + if (_longPressStartedWithoutFocus) { + renderEditable.selectWordsInRange( + from: details.globalPosition - + details.offsetFromOrigin - + editableOffset - + scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.longPress, + ); + } else { + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.longPress, + ); + // Update the floating cursor. + final RawFloatingCursorPoint cursorPoint = RawFloatingCursorPoint( + state: FloatingCursorDragState.Update, + offset: details.offsetFromOrigin, + ); + editableText.updateFloatingCursor(cursorPoint); + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + renderEditable.selectWordsInRange( + from: details.globalPosition - + details.offsetFromOrigin - + editableOffset - + scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.longPress, + ); + } + + _showMagnifierIfSupportedByPlatform(details.globalPosition); + } + } + + /// Handler for [TextSelectionGestureDetector.onSingleLongTapEnd]. + /// + /// By default, it shows toolbar if necessary. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSingleLongTapEnd], which triggers this + /// callback. + @protected + void onSingleLongTapEnd(LongPressEndDetails details) { + _hideMagnifierIfSupportedByPlatform(); + if (shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + _longPressStartedWithoutFocus = false; + _dragStartViewportOffset = 0.0; + _dragStartScrollOffset = 0.0; + if (defaultTargetPlatform == TargetPlatform.iOS && + delegate.selectionEnabled && + editableText.textEditingValue.selection.isCollapsed) { + // Update the floating cursor. + final RawFloatingCursorPoint cursorPoint = + RawFloatingCursorPoint(state: FloatingCursorDragState.End); + editableText.updateFloatingCursor(cursorPoint); + } + } + + /// Handler for [TextSelectionGestureDetector.onSecondaryTap]. + /// + /// By default, selects the word if possible and shows the toolbar. + @protected + void onSecondaryTap() { + if (!delegate.selectionEnabled) { + return; + } + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + if (!_lastSecondaryTapWasOnSelection || !renderEditable.hasFocus) { + renderEditable.selectWord(cause: SelectionChangedCause.tap); + } + if (shouldShowSelectionToolbar) { + editableText.hideToolbar(); + editableText.showToolbar(); + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + if (!renderEditable.hasFocus) { + renderEditable.selectPosition(cause: SelectionChangedCause.tap); + } + editableText.toggleToolbar(); + } + } + + /// Handler for [TextSelectionGestureDetector.onSecondaryTapDown]. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onSecondaryTapDown], which triggers this + /// callback. + /// * [onSecondaryTap], which is typically called after this. + @protected + void onSecondaryTapDown(TapDownDetails details) { + // TODO(Renzo-Olivares): Migrate text selection gestures away from saving state + // in renderEditable. The gesture callbacks can use the details objects directly + // in callbacks variants that provide them [TapGestureRecognizer.onSecondaryTap] + // vs [TapGestureRecognizer.onSecondaryTapUp] instead of having to track state in + // renderEditable. When this migration is complete we should remove this hack. + // See https://github.com/flutter/flutter/issues/115130. + renderEditable.handleSecondaryTapDown( + TapDownDetails(globalPosition: details.globalPosition)); + _shouldShowSelectionToolbar = true; + } + + /// Handler for [TextSelectionGestureDetector.onDoubleTapDown]. + /// + /// By default, it selects a word through [RenderEditable.selectWord] if + /// selectionEnabled and shows toolbar if necessary. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onDoubleTapDown], which triggers this + /// callback. + @protected + void onDoubleTapDown(TapDragDownDetails details) { + if (delegate.selectionEnabled) { + renderEditable.selectWord(cause: SelectionChangedCause.doubleTap); + if (shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + } + } + + // Selects the set of paragraphs in a document that intersect a given range of + // global positions. + void _selectParagraphsInRange( + {required Offset from, Offset? to, SelectionChangedCause? cause}) { + final TextBoundary paragraphBoundary = + ParagraphBoundary(editableText.textEditingValue.text); + _selectTextBoundariesInRange( + boundary: paragraphBoundary, from: from, to: to, cause: cause); + } + + // Selects the set of lines in a document that intersect a given range of + // global positions. + void _selectLinesInRange( + {required Offset from, Offset? to, SelectionChangedCause? cause}) { + final TextBoundary lineBoundary = LineBoundary(renderEditable); + _selectTextBoundariesInRange( + boundary: lineBoundary, from: from, to: to, cause: cause); + } + + // Returns the location of a text boundary at `extent`. When `extent` is at + // the end of the text, returns the previous text boundary's location. + TextRange _moveToTextBoundary( + TextPosition extent, TextBoundary textBoundary) { + assert(extent.offset >= 0); + // Use extent.offset - 1 when `extent` is at the end of the text to retrieve + // the previous text boundary's location. + final int start = textBoundary.getLeadingTextBoundaryAt( + extent.offset == editableText.textEditingValue.text.length + ? extent.offset - 1 + : extent.offset) ?? + 0; + final int end = textBoundary.getTrailingTextBoundaryAt(extent.offset) ?? + editableText.textEditingValue.text.length; + return TextRange(start: start, end: end); + } + + // Selects the set of text boundaries in a document that intersect a given + // range of global positions. + // + // The set of text boundaries selected are not strictly bounded by the range + // of global positions. + // + // The first and last endpoints of the selection will always be at the + // beginning and end of a text boundary respectively. + void _selectTextBoundariesInRange( + {required TextBoundary boundary, + required Offset from, + Offset? to, + SelectionChangedCause? cause}) { + final TextPosition fromPosition = renderEditable.getPositionForPoint(from); + final TextRange fromRange = _moveToTextBoundary(fromPosition, boundary); + final TextPosition toPosition = + to == null ? fromPosition : renderEditable.getPositionForPoint(to); + final TextRange toRange = toPosition == fromPosition + ? fromRange + : _moveToTextBoundary(toPosition, boundary); + final bool isFromBoundaryBeforeToBoundary = fromRange.start < toRange.end; + + final TextSelection newSelection = isFromBoundaryBeforeToBoundary + ? TextSelection(baseOffset: fromRange.start, extentOffset: toRange.end) + : TextSelection(baseOffset: fromRange.end, extentOffset: toRange.start); + + editableText.userUpdateTextEditingValue( + editableText.textEditingValue.copyWith(selection: newSelection), + cause, + ); + } + + /// Handler for [TextSelectionGestureDetector.onTripleTapDown]. + /// + /// By default, it selects a paragraph if + /// [TextSelectionGestureDetectorBuilderDelegate.selectionEnabled] is true + /// and shows the toolbar if necessary. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onTripleTapDown], which triggers this + /// callback. + @protected + void onTripleTapDown(TapDragDownDetails details) { + if (!delegate.selectionEnabled) { + return; + } + if (renderEditable.maxLines == 1) { + editableText.selectAll(SelectionChangedCause.tap); + } else { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + case TargetPlatform.macOS: + case TargetPlatform.windows: + _selectParagraphsInRange( + from: details.globalPosition, cause: SelectionChangedCause.tap); + case TargetPlatform.linux: + _selectLinesInRange( + from: details.globalPosition, cause: SelectionChangedCause.tap); + } + } + if (shouldShowSelectionToolbar) { + editableText.showToolbar(); + } + } + + /// Handler for [TextSelectionGestureDetector.onDragSelectionStart]. + /// + /// By default, it selects a text position specified in [details]. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onDragSelectionStart], which triggers + /// this callback. + @protected + void onDragSelectionStart(TapDragStartDetails details) { + if (!delegate.selectionEnabled) { + return; + } + final PointerDeviceKind? kind = details.kind; + _shouldShowSelectionToolbar = kind == null || + kind == PointerDeviceKind.touch || + kind == PointerDeviceKind.stylus; + + _dragStartSelection = renderEditable.selection; + _dragStartScrollOffset = _scrollPosition; + _dragStartViewportOffset = renderEditable.offset.pixels; + + if (_TextSelectionGestureDetectorState._getEffectiveConsecutiveTapCount( + details.consecutiveTapCount) > + 1) { + // Do not set the selection on a consecutive tap and drag. + return; + } + + if (_isShiftPressed && + renderEditable.selection != null && + renderEditable.selection!.isValid) { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + case TargetPlatform.macOS: + _expandSelection(details.globalPosition, SelectionChangedCause.drag); + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + case TargetPlatform.windows: + _extendSelection(details.globalPosition, SelectionChangedCause.drag); + } + } else { + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + case null: + } + case TargetPlatform.android: + case TargetPlatform.fuchsia: + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + // For Android, Fuchsia, and iOS platforms, a touch drag + // does not initiate unless the editable has focus. + if (renderEditable.hasFocus) { + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + _showMagnifierIfSupportedByPlatform(details.globalPosition); + } + case null: + } + case TargetPlatform.linux: + case TargetPlatform.macOS: + case TargetPlatform.windows: + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + } + } + } + + /// Handler for [TextSelectionGestureDetector.onDragSelectionUpdate]. + /// + /// By default, it updates the selection location specified in the provided + /// details objects. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onDragSelectionUpdate], which triggers + /// this callback./lib/src/material/text_field.dart + @protected + void onDragSelectionUpdate(TapDragUpdateDetails details) { + if (!delegate.selectionEnabled) { + return; + } + + if (!_isShiftPressed) { + // Adjust the drag start offset for possible viewport offset changes. + final Offset editableOffset = renderEditable.maxLines == 1 + ? Offset(renderEditable.offset.pixels - _dragStartViewportOffset, 0.0) + : Offset( + 0.0, renderEditable.offset.pixels - _dragStartViewportOffset); + final Offset scrollableOffset = + switch (axisDirectionToAxis(_scrollDirection ?? AxisDirection.left)) { + Axis.horizontal => + Offset(_scrollPosition - _dragStartScrollOffset, 0.0), + Axis.vertical => Offset(0.0, _scrollPosition - _dragStartScrollOffset), + }; + final Offset dragStartGlobalPosition = + details.globalPosition - details.offsetFromOrigin; + + // Select word by word. + if (_TextSelectionGestureDetectorState._getEffectiveConsecutiveTapCount( + details.consecutiveTapCount) == + 2) { + renderEditable.selectWordsInRange( + from: dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + + switch (details.kind) { + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + return _showMagnifierIfSupportedByPlatform(details.globalPosition); + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + case null: + return; + } + } + + // Select paragraph-by-paragraph. + if (_TextSelectionGestureDetectorState._getEffectiveConsecutiveTapCount( + details.consecutiveTapCount) == + 3) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.iOS: + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + return _selectParagraphsInRange( + from: dragStartGlobalPosition - + editableOffset - + scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + case null: + // Triple tap to drag is not present on these platforms when using + // non-precise pointer devices at the moment. + break; + } + return; + case TargetPlatform.linux: + return _selectLinesInRange( + from: dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case TargetPlatform.windows: + case TargetPlatform.macOS: + return _selectParagraphsInRange( + from: dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + } + } + + switch (defaultTargetPlatform) { + case TargetPlatform.iOS: + // With a mouse device, a drag should select the range from the origin of the drag + // to the current position of the drag. + // + // With a touch device, nothing should happen. + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + return renderEditable.selectPositionAt( + from: + dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + case null: + break; + } + return; + case TargetPlatform.android: + case TargetPlatform.fuchsia: + // With a precise pointer device, such as a mouse, trackpad, or stylus, + // the drag will select the text spanning the origin of the drag to the end of the drag. + // With a touch device, the cursor should move with the drag. + switch (details.kind) { + case PointerDeviceKind.mouse: + case PointerDeviceKind.trackpad: + case PointerDeviceKind.stylus: + case PointerDeviceKind.invertedStylus: + return renderEditable.selectPositionAt( + from: + dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + case PointerDeviceKind.touch: + case PointerDeviceKind.unknown: + if (renderEditable.hasFocus) { + renderEditable.selectPositionAt( + from: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + return _showMagnifierIfSupportedByPlatform( + details.globalPosition); + } + case null: + break; + } + return; + case TargetPlatform.macOS: + case TargetPlatform.linux: + case TargetPlatform.windows: + return renderEditable.selectPositionAt( + from: dragStartGlobalPosition - editableOffset - scrollableOffset, + to: details.globalPosition, + cause: SelectionChangedCause.drag, + ); + } + } + + if (_dragStartSelection!.isCollapsed || + (defaultTargetPlatform != TargetPlatform.iOS && + defaultTargetPlatform != TargetPlatform.macOS)) { + return _extendSelection( + details.globalPosition, SelectionChangedCause.drag); + } + + // If the drag inverts the selection, Mac and iOS revert to the initial + // selection. + final TextSelection selection = editableText.textEditingValue.selection; + final TextPosition nextExtent = + renderEditable.getPositionForPoint(details.globalPosition); + final bool isShiftTapDragSelectionForward = + _dragStartSelection!.baseOffset < _dragStartSelection!.extentOffset; + final bool isInverted = isShiftTapDragSelectionForward + ? nextExtent.offset < _dragStartSelection!.baseOffset + : nextExtent.offset > _dragStartSelection!.baseOffset; + if (isInverted && selection.baseOffset == _dragStartSelection!.baseOffset) { + editableText.userUpdateTextEditingValue( + editableText.textEditingValue.copyWith( + selection: TextSelection( + baseOffset: _dragStartSelection!.extentOffset, + extentOffset: nextExtent.offset, + ), + ), + SelectionChangedCause.drag, + ); + } else if (!isInverted && + nextExtent.offset != _dragStartSelection!.baseOffset && + selection.baseOffset != _dragStartSelection!.baseOffset) { + editableText.userUpdateTextEditingValue( + editableText.textEditingValue.copyWith( + selection: TextSelection( + baseOffset: _dragStartSelection!.baseOffset, + extentOffset: nextExtent.offset, + ), + ), + SelectionChangedCause.drag, + ); + } else { + _extendSelection(details.globalPosition, SelectionChangedCause.drag); + } + } + + /// Handler for [TextSelectionGestureDetector.onDragSelectionEnd]. + /// + /// By default, it cleans up the state used for handling certain + /// built-in behaviors. + /// + /// See also: + /// + /// * [TextSelectionGestureDetector.onDragSelectionEnd], which triggers this + /// callback. + @protected + void onDragSelectionEnd(TapDragEndDetails details) { + if (_shouldShowSelectionToolbar && + _TextSelectionGestureDetectorState._getEffectiveConsecutiveTapCount( + details.consecutiveTapCount) == + 2) { + editableText.showToolbar(); + } + + if (_isShiftPressed) { + _dragStartSelection = null; + } + + _hideMagnifierIfSupportedByPlatform(); + } + + /// Returns a [TextSelectionGestureDetector] configured with the handlers + /// provided by this builder. + /// + /// The [child] or its subtree should contain an [EditableText] whose key is + /// the [GlobalKey] provided by the [delegate]'s + /// [TextSelectionGestureDetectorBuilderDelegate.editableTextKey]. + Widget buildGestureDetector({ + Key? key, + HitTestBehavior? behavior, + required Widget child, + }) { + return TextSelectionGestureDetector( + key: key, + onTapTrackStart: onTapTrackStart, + onTapTrackReset: onTapTrackReset, + onTapDown: onTapDown, + onForcePressStart: delegate.forcePressEnabled ? onForcePressStart : null, + onForcePressEnd: delegate.forcePressEnabled ? onForcePressEnd : null, + onSecondaryTap: onSecondaryTap, + onSecondaryTapDown: onSecondaryTapDown, + onSingleTapUp: onSingleTapUp, + onSingleTapCancel: onSingleTapCancel, + onUserTap: onUserTap, + onSingleLongTapStart: onSingleLongTapStart, + onSingleLongTapMoveUpdate: onSingleLongTapMoveUpdate, + onSingleLongTapEnd: onSingleLongTapEnd, + onDoubleTapDown: onDoubleTapDown, + onTripleTapDown: onTripleTapDown, + onDragSelectionStart: onDragSelectionStart, + onDragSelectionUpdate: onDragSelectionUpdate, + onDragSelectionEnd: onDragSelectionEnd, + onUserTapAlwaysCalled: onUserTapAlwaysCalled, + behavior: behavior, + child: child, + ); + } +} + +class _TextSelectionGestureDetectorState { + _TextSelectionGestureDetectorState._(); + // Converts the details.consecutiveTapCount from a TapAndDrag*Details object, + // which can grow to be infinitely large, to a value between 1 and 3. The value + // that the raw count is converted to is based on the default observed behavior + // on the native platforms. + // + // This method should be used in all instances when details.consecutiveTapCount + // would be used. + static int _getEffectiveConsecutiveTapCount(int rawCount) { + switch (defaultTargetPlatform) { + case TargetPlatform.android: + case TargetPlatform.fuchsia: + case TargetPlatform.linux: + // From observation, these platform's reset their tap count to 0 when + // the number of consecutive taps exceeds 3. For example on Debian Linux + // with GTK, when going past a triple click, on the fourth click the + // selection is moved to the precise click position, on the fifth click + // the word at the position is selected, and on the sixth click the + // paragraph at the position is selected. + return rawCount <= 3 + ? rawCount + : (rawCount % 3 == 0 ? 3 : rawCount % 3); + case TargetPlatform.iOS: + case TargetPlatform.macOS: + // From observation, these platform's either hold their tap count at 3. + // For example on macOS, when going past a triple click, the selection + // should be retained at the paragraph that was first selected on triple + // click. + return math.min(rawCount, 3); + case TargetPlatform.windows: + // From observation, this platform's consecutive tap actions alternate + // between double click and triple click actions. For example, after a + // triple click has selected a paragraph, on the next click the word at + // the clicked position will be selected, and on the next click the + // paragraph at the position is selected. + return rawCount < 2 ? rawCount : 2 + rawCount % 2; + } + } +} diff --git a/local_packages/extended_text_field-16.0.2-patched/pubspec.yaml b/local_packages/extended_text_field-16.0.2-patched/pubspec.yaml new file mode 100644 index 0000000..4ec32c5 --- /dev/null +++ b/local_packages/extended_text_field-16.0.2-patched/pubspec.yaml @@ -0,0 +1,66 @@ +name: extended_text_field +description: Extended official text field to build special text like inline image, @somebody, custom background etc quickly.It also support to build custom seleciton toolbar and handles. +version: 16.0.2 +repository: https://github.com/fluttercandies/extended_text_field +issue_tracker: https://github.com/fluttercandies/extended_text_field/issues +topics: + - extended-text-field + - rich-text + +environment: + sdk: '>=3.5.0 <4.0.0' + flutter: ">=3.24.0" +dependencies: + + extended_text_library: ^12.0.0 + # extended_text_library: + # version: ^11.0.0-dev.1 + # hosted: "https://pub.dev" + flutter: + sdk: flutter +dev_dependencies: + flutter_test: + sdk: flutter + +dependency_overrides: + #extended_text_library: + # git: + # url: https://github.com/fluttercandies/extended_text_library.git + # ref: refactor + #path: ../extended_text_library +# For information on the generic Dart part of this file, see the +# following page: https://www.dartlang.org/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + + # To add assets to your package, add an assets section, like this: + # assets: + # - images/a_dot_burr.jpeg + # - images/a_dot_ham.jpeg + # + # For details regarding assets in packages, see + # https://flutter.io/assets-and-images/#from-packages + # + # An image asset can refer to one or more resolution-specific "variants", see + # https://flutter.io/assets-and-images/#resolution-aware. + + # To add custom fonts to your package, add a fonts section here, + # in this "flutter" section. Each entry in this list should have a + # "family" key with the font family name, and a "fonts" key with a + # list giving the asset and other descriptors for the font. For + # example: + # fonts: + # - family: Schyler + # fonts: + # - asset: fonts/Schyler-Regular.ttf + # - asset: fonts/Schyler-Italic.ttf + # style: italic + # - family: Trajan Pro + # fonts: + # - asset: fonts/TrajanPro.ttf + # - asset: fonts/TrajanPro_Bold.ttf + # weight: 700 + # + # For details regarding fonts in packages, see + # https://flutter.io/custom-fonts/#from-packages diff --git a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/OnAudioQueryPlugin.kt b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/OnAudioQueryPlugin.kt index 768c35b..f3365ff 100644 --- a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/OnAudioQueryPlugin.kt +++ b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/OnAudioQueryPlugin.kt @@ -131,16 +131,17 @@ class OnAudioQueryPlugin : FlutterPlugin, MethodCallHandler, ActivityAware { val hasPermission = permissionController.permissionStatus() Log.d(TAG, "Application has permissions: $hasPermission") - if (!hasPermission) { - Log.w(TAG, "The application doesn't have access to the library") - result.error( - "MissingPermissions", - "Application doesn't have access to the library", - "Call the [permissionsRequest] method or install a external plugin to handle the app permission." - ) - } - - methodController.find() + if (!hasPermission) { + Log.w(TAG, "The application doesn't have access to the library") + result.error( + "MissingPermissions", + "Application doesn't have access to the library", + "Call the [permissionsRequest] method or install a external plugin to handle the app permission." + ) + return + } + + methodController.find() } } diff --git a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/controllers/PermissionController.kt b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/controllers/PermissionController.kt index 0da869d..b310168 100644 --- a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/controllers/PermissionController.kt +++ b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/controllers/PermissionController.kt @@ -21,18 +21,12 @@ class PermissionController : PermissionManagerInterface, var retryRequest: Boolean = false - private var permissions: Array = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - arrayOf( - Manifest.permission.READ_MEDIA_AUDIO, - Manifest.permission.READ_MEDIA_IMAGES - ) - } else { - arrayOf( - Manifest.permission.READ_EXTERNAL_STORAGE, - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) - } + private var permissions: Array = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + arrayOf(Manifest.permission.READ_MEDIA_AUDIO) + } else { + arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) + } override fun permissionStatus(): Boolean = permissions.all { // After "leaving" this class, context will be null so, we need this context argument to @@ -51,14 +45,14 @@ class PermissionController : PermissionManagerInterface, } // Second requestPermission, this one with the option "Never Ask Again". - override fun retryRequestPermission() { - val activity = PluginProvider.activity() - if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[0]) - || ActivityCompat.shouldShowRequestPermissionRationale(activity, permissions[1]) - ) { - Log.d(TAG, "Retrying permission request") - retryRequest = false - requestPermission() + override fun retryRequestPermission() { + val activity = PluginProvider.activity() + if (permissions.any { + ActivityCompat.shouldShowRequestPermissionRationale(activity, it) + }) { + Log.d(TAG, "Retrying permission request") + retryRequest = false + requestPermission() } } @@ -90,4 +84,4 @@ class PermissionController : PermissionManagerInterface, // result and Android should not continue executing other registered handlers. return true } -} \ No newline at end of file +} diff --git a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/queries/AudioQuery.kt b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/queries/AudioQuery.kt index 7457ac9..3b653cf 100644 --- a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/queries/AudioQuery.kt +++ b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/queries/AudioQuery.kt @@ -61,41 +61,52 @@ class AudioQuery : ViewModel() { Log.d(TAG, "\tselection: $selection") Log.d(TAG, "\turi: $uri") - // Query everything in background for a better performance. - viewModelScope.launch { - val queryResult = loadSongs() - result.success(queryResult) - } + // Query everything in background for a better performance. + viewModelScope.launch { + try { + val queryResult = loadSongs() + result.success(queryResult) + } catch (error: Exception) { + Log.e(TAG, "Unable to query songs", error) + result.error( + "QuerySongsFailed", + error.message ?: "Unable to query songs", + error.javaClass.name + ) + } + } } //Loading in Background private suspend fun loadSongs(): ArrayList> = withContext(Dispatchers.IO) { // Setup the cursor with 'uri', 'projection' and 'sortType'. - val cursor = resolver.query(uri, songProjection(), selection, null, sortType) - - val songList: ArrayList> = ArrayList() - - Log.d(TAG, "Cursor count: ${cursor?.count}") - - // For each item(song) inside this "cursor", take one and "format" - // into a 'Map'. - while (cursor != null && cursor.moveToNext()) { - val tempData: MutableMap = HashMap() - - for (audioMedia in cursor.columnNames) { - tempData[audioMedia] = helper.loadSongItem(audioMedia, cursor) - } - - //Get a extra information from audio, e.g: extension, uri, etc.. - val tempExtraData = helper.loadSongExtraInfo(uri, tempData) - tempData.putAll(tempExtraData) - - songList.add(tempData) - } - - // Close cursor to avoid memory leaks. - cursor?.close() - return@withContext songList - } -} + val cursor = resolver.query(uri, songProjection(), selection, null, sortType) + try { + val songList: ArrayList> = ArrayList() + + Log.d(TAG, "Cursor count: ${cursor?.count}") + + // For each item(song) inside this "cursor", take one and "format" + // into a 'Map'. + while (cursor != null && cursor.moveToNext()) { + val tempData: MutableMap = HashMap() + + for (audioMedia in cursor.columnNames) { + tempData[audioMedia] = helper.loadSongItem(audioMedia, cursor) + } + + //Get a extra information from audio, e.g: extension, uri, etc.. + val tempExtraData = helper.loadSongExtraInfo(uri, tempData) + tempData.putAll(tempExtraData) + + songList.add(tempData) + } + + return@withContext songList + } finally { + // Close cursor even when an OEM MediaProvider returns malformed data. + cursor?.close() + } + } +} diff --git a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/utils/CursorProjection.kt b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/utils/CursorProjection.kt index be0bd2a..b3777ac 100644 --- a/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/utils/CursorProjection.kt +++ b/local_packages/on_audio_query_android-1.1.0/android/src/main/kotlin/com/lucasjosino/on_audio_query/utils/CursorProjection.kt @@ -12,11 +12,10 @@ fun songProjection(): Array { val tmpProjection = arrayListOf( MediaStore.Audio.Media.DATA, // TODO: Deprecated MediaStore.Audio.Media.DISPLAY_NAME, - MediaStore.Audio.Media._ID, - MediaStore.Audio.Media.SIZE, - MediaStore.Audio.Media.ALBUM, - MediaStore.Audio.Media.ALBUM_ARTIST, - MediaStore.Audio.Media.ALBUM_ID, + MediaStore.Audio.Media._ID, + MediaStore.Audio.Media.SIZE, + MediaStore.Audio.Media.ALBUM, + MediaStore.Audio.Media.ALBUM_ID, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ARTIST_ID, MediaStore.Audio.Media.BOOKMARK, @@ -37,10 +36,11 @@ fun songProjection(): Array { if (Build.VERSION.SDK_INT >= 29) { tmpProjection.add(MediaStore.Audio.Media.IS_AUDIOBOOK) // Only Api >= 29 } - - if (Build.VERSION.SDK_INT >= 30) { - tmpProjection.add(MediaStore.Audio.Media.GENRE) // Only Api >= 30 - tmpProjection.add(MediaStore.Audio.Media.GENRE_ID) // Only Api >= 30 + + if (Build.VERSION.SDK_INT >= 30) { + tmpProjection.add(MediaStore.Audio.Media.ALBUM_ARTIST) // Only Api >= 30 + tmpProjection.add(MediaStore.Audio.Media.GENRE) // Only Api >= 30 + tmpProjection.add(MediaStore.Audio.Media.GENRE_ID) // Only Api >= 30 } return tmpProjection.toTypedArray() @@ -70,4 +70,4 @@ val artistProjection = arrayOf( val genreProjection = arrayOf( MediaStore.Audio.Genres._ID, MediaStore.Audio.Genres.NAME -) \ No newline at end of file +) diff --git a/pubspec.lock b/pubspec.lock index b390fe9..2b3970d 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -6,7 +6,7 @@ packages: description: name: _flutterfire_internals sha256: ff0a84a2734d9e1089f8aedd5c0af0061b82fb94e95260d943404e0ef2134b11 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.59" app_links: @@ -14,7 +14,7 @@ packages: description: name: app_links sha256: "5f88447519add627fe1cbcab4fd1da3d4fed15b9baf29f28b22535c95ecee3e8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.4.1" app_links_linux: @@ -22,23 +22,23 @@ packages: description: name: app_links_linux sha256: f5f7173a78609f3dfd4c2ff2c95bd559ab43c80a87dc6a095921d96c05688c81 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.3" app_links_platform_interface: dependency: transitive description: name: app_links_platform_interface - sha256: "05f5379577c513b534a29ddea68176a4d4802c46180ee8e2e966257158772a3f" - url: "https://pub.flutter-io.cn" + sha256: "78a18580eecac98108d1eef52a7db668bc317714f5205e616973363326efe333" + url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" app_links_web: dependency: transitive description: name: app_links_web sha256: af060ed76183f9e2b87510a9480e56a5352b6c249778d07bd2c95fc35632a555 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.4" archive: @@ -46,7 +46,7 @@ packages: description: name: archive sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.9" args: @@ -54,7 +54,7 @@ packages: description: name: args sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.7.0" async: @@ -62,79 +62,79 @@ packages: description: name: async sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.13.1" audio_session: dependency: "direct main" description: name: audio_session - sha256: "7217b229db57cc4dc577a8abb56b7429a5a212b978517a5be578704bfe5e568b" - url: "https://pub.flutter-io.cn" + sha256: f9e7711a0e24ca8b40f5d7ac374c3c6e55016f3157912badd18199cdbbca5c4d + url: "https://pub.dev" source: hosted - version: "0.2.3" + version: "0.2.4" audioplayers: dependency: "direct main" description: name: audioplayers - sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70 - url: "https://pub.flutter-io.cn" + sha256: "2ba4bb2944baacbdd5372ff8254a8e7feb8c10d7739545e392f5605a8f618745" + url: "https://pub.dev" source: hosted - version: "6.6.0" + version: "6.8.1" audioplayers_android: dependency: transitive description: name: audioplayers_android - sha256: "60a6728277228413a85755bd3ffd6fab98f6555608923813ce383b190a360605" - url: "https://pub.flutter-io.cn" + sha256: f5ff5b15620fbab8cb0849e9636c48e2b96c3f0f71723bbbe2ad3c761b205f05 + url: "https://pub.dev" source: hosted - version: "5.2.1" + version: "5.3.0" audioplayers_darwin: dependency: transitive description: name: audioplayers_darwin - sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91 - url: "https://pub.flutter-io.cn" + sha256: "1ca553add991384ecf421b9569da850f3ab2472ffb83f6970b0416365abc51be" + url: "https://pub.dev" source: hosted - version: "6.4.0" + version: "6.5.0" audioplayers_linux: dependency: transitive description: name: audioplayers_linux - sha256: f75bce1ce864170ef5e6a2c6a61cd3339e1a17ce11e99a25bae4474ea491d001 - url: "https://pub.flutter-io.cn" + sha256: "15178b726b7cdee5364d0463c8d445630c4e0fb7d26612b73c767e7d25de9417" + url: "https://pub.dev" source: hosted - version: "4.2.1" + version: "4.3.0" audioplayers_platform_interface: dependency: transitive description: name: audioplayers_platform_interface - sha256: "0e2f6a919ab56d0fec272e801abc07b26ae7f31980f912f24af4748763e5a656" - url: "https://pub.flutter-io.cn" + sha256: "765f6f0e6dca55cb471c9483fc77700564b3484d19198aca4ebb5147c6c85acb" + url: "https://pub.dev" source: hosted - version: "7.1.1" + version: "7.2.0" audioplayers_web: dependency: transitive description: name: audioplayers_web - sha256: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9 - url: "https://pub.flutter-io.cn" + sha256: ae1e0103c865a03e273f6d13d97b93f5595eac09915729cd5e37ef96e2857319 + url: "https://pub.dev" source: hosted - version: "5.2.0" + version: "5.3.0" audioplayers_windows: dependency: transitive description: name: audioplayers_windows - sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734 - url: "https://pub.flutter-io.cn" + sha256: a70ae82bba2dfcb6eb03dd4815d737a2d46d33ea5a96a03f535cfcaac490e413 + url: "https://pub.dev" source: hosted - version: "4.3.0" + version: "4.4.1" back_button_interceptor: dependency: "direct main" description: name: back_button_interceptor sha256: b85977faabf4aeb95164b3b8bf81784bed4c54ea1aef90a036ab6927ecf80c5a - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.0.4" badges: @@ -142,7 +142,7 @@ packages: description: name: badges sha256: cf1c88fb3777df69ccd630b80de5267f54efa4a39381b0404a7c03d56cb7c041 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.0" boolean_selector: @@ -150,7 +150,7 @@ packages: description: name: boolean_selector sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.2" cached_network_image: @@ -158,7 +158,7 @@ packages: description: name: cached_network_image sha256: "7c1183e361e5c8b0a0f21a28401eecdbde252441106a9816400dd4c2b2424916" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.4.1" cached_network_image_platform_interface: @@ -166,7 +166,7 @@ packages: description: name: cached_network_image_platform_interface sha256: "35814b016e37fbdc91f7ae18c8caf49ba5c88501813f73ce8a07027a395e2829" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.1.1" cached_network_image_web: @@ -174,7 +174,7 @@ packages: description: name: cached_network_image_web sha256: "980842f4e8e2535b8dbd3d5ca0b1f0ba66bf61d14cc3a17a9b4788a3685ba062" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.1" carousel_slider: @@ -182,7 +182,7 @@ packages: description: name: carousel_slider sha256: febf4b0163e0242adc13d7a863b04965351f59e7dfea56675c7c2caa7bcd7476 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.1.2" characters: @@ -190,7 +190,7 @@ packages: description: name: characters sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.1" checked_yaml: @@ -198,7 +198,7 @@ packages: description: name: checked_yaml sha256: "959525d3162f249993882720d52b7e0c833978df229be20702b33d48d91de70f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.4" cli_util: @@ -206,7 +206,7 @@ packages: description: name: cli_util sha256: ff6785f7e9e3c38ac98b2fb035701789de90154024a75b6cb926445e83197d1c - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.2" clock: @@ -214,7 +214,7 @@ packages: description: name: clock sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.2" collection: @@ -222,7 +222,7 @@ packages: description: name: collection sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.19.1" cookie_jar: @@ -230,23 +230,23 @@ packages: description: name: cookie_jar sha256: "963da02c1ef64cb5ac20de948c9e5940aa351f1e34a12b1d327c83d85b7e8fff" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.0.9" cross_file: dependency: transitive description: name: cross_file - sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" - url: "https://pub.flutter-io.cn" + sha256: "92c9c43c383bfa1c32079d3bc492d55d6d4318044b7b47edaff8971cbb555c51" + url: "https://pub.dev" source: hosted - version: "0.3.5+2" + version: "0.3.5+4" crypto: dependency: transitive description: name: crypto sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.7" csslib: @@ -254,7 +254,7 @@ packages: description: name: csslib sha256: "09bad715f418841f976c77db72d5398dc1253c21fb9c0c7f0b0b985860b2d58e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" cupertino_icons: @@ -262,23 +262,23 @@ packages: description: name: cupertino_icons sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.9" dbus: dependency: transitive description: name: dbus - sha256: d0c98dcd4f5169878b6cf8f6e0a52403a9dff371a3e2f019697accbf6f44a270 - url: "https://pub.flutter-io.cn" + sha256: "0ce9b0a839e6dee59a37a623d2fc26a35bbbe6404213e419b0d6411023d62645" + url: "https://pub.dev" source: hosted - version: "0.7.12" + version: "0.7.14" device_info_plus: dependency: "direct main" description: name: device_info_plus sha256: a7fd703482b391a87d60b6061d04dfdeab07826b96f9abd8f5ed98068acc0074 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "10.1.2" device_info_plus_platform_interface: @@ -286,31 +286,31 @@ packages: description: name: device_info_plus_platform_interface sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.3" dio: dependency: "direct main" description: name: dio - sha256: aff32c08f92787a557dd5c0145ac91536481831a01b4648136373cddb0e64f8c - url: "https://pub.flutter-io.cn" + sha256: ea2bad3c89a27635ce2d85cce4d6b199da49a5a48ec77b03e45b65a3b90922b0 + url: "https://pub.dev" source: hosted - version: "5.9.2" + version: "5.10.0" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "2f9e64323a7c3c7ef69567d5c800424a11f8337b8b228bad02524c9fb3c1f340" - url: "https://pub.flutter-io.cn" + sha256: dd58dc3861eb36edb13b217efc006a1c21e5bbc341de8c229b85634fa5e362e4 + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.2.0" event_bus: dependency: "direct main" description: name: event_bus sha256: "1a55e97923769c286d295240048fc180e7b0768902c3c2e869fe059aafa15304" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.1" extended_image: @@ -318,7 +318,7 @@ packages: description: name: extended_image sha256: f6cbb1d798f51262ed1a3d93b4f1f2aa0d76128df39af18ecb77fa740f88b2e0 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "10.0.1" extended_image_library: @@ -326,7 +326,7 @@ packages: description: name: extended_image_library sha256: "1f9a24d3a00c2633891c6a7b5cab2807999eb2d5b597e5133b63f49d113811fe" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.1" extended_nested_scroll_view: @@ -334,7 +334,7 @@ packages: description: name: extended_nested_scroll_view sha256: "835580d40c2c62b448bd14adecd316acba469ba61f1510ef559d17668a85e777" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.2.1" extended_text: @@ -342,23 +342,22 @@ packages: description: name: extended_text sha256: d8f4a6e2676505b54dc0d5f5e8de9020667b402e9c1b3a8b030a83e568c99654 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "15.0.2" extended_text_field: dependency: "direct main" description: - name: extended_text_field - sha256: "3996195c117c6beb734026a7bc0ba80d7e4e84e4edd4728caa544d8209ab4d7d" - url: "https://pub.flutter-io.cn" - source: hosted + path: "local_packages/extended_text_field-16.0.2-patched" + relative: true + source: path version: "16.0.2" extended_text_library: dependency: transitive description: name: extended_text_library sha256: "13d99f8a10ead472d5e2cf4770d3d047203fe5054b152e9eb5dc692a71befbba" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "12.0.1" fading_edge_scrollview: @@ -366,7 +365,7 @@ packages: description: name: fading_edge_scrollview sha256: "1f84fe3ea8e251d00d5735e27502a6a250e4aa3d3b330d3fdcb475af741464ef" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.1.1" fake_async: @@ -374,7 +373,7 @@ packages: description: name: fake_async sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.3" ffi: @@ -382,7 +381,7 @@ packages: description: name: ffi sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" file: @@ -390,7 +389,7 @@ packages: description: name: file sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.1" file_picker: @@ -398,7 +397,7 @@ packages: description: name: file_picker sha256: f13a03000d942e476bc1ff0a736d2e9de711d2f89a95cd4c1d88f861c3348387 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "11.0.2" file_selector_linux: @@ -406,7 +405,7 @@ packages: description: name: file_selector_linux sha256: "2567f398e06ac72dcf2e98a0c95df2a9edd03c2c2e0cacd4780f20cdf56263a0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.4" file_selector_macos: @@ -414,7 +413,7 @@ packages: description: name: file_selector_macos sha256: "5e0bbe9c312416f1787a68259ea1505b52f258c587f12920422671807c4d618a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.5" file_selector_platform_interface: @@ -422,7 +421,7 @@ packages: description: name: file_selector_platform_interface sha256: "35e0bd61ebcdb91a3505813b055b09b79dfdc7d0aee9c09a7ba59ae4bb13dc85" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.7.0" file_selector_windows: @@ -430,7 +429,7 @@ packages: description: name: file_selector_windows sha256: "62197474ae75893a62df75939c777763d39c2bc5f73ce5b88497208bc269abfd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.9.3+5" firebase_auth: @@ -438,7 +437,7 @@ packages: description: name: firebase_auth sha256: "0fed2133bee1369ee1118c1fef27b2ce0d84c54b7819a2b17dada5cfec3b03ff" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.7.0" firebase_auth_platform_interface: @@ -446,7 +445,7 @@ packages: description: name: firebase_auth_platform_interface sha256: "871c9df4ec9a754d1a793f7eb42fa3b94249d464cfb19152ba93e14a5966b386" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.7.3" firebase_auth_web: @@ -454,7 +453,7 @@ packages: description: name: firebase_auth_web sha256: d9ada769c43261fd1b18decf113186e915c921a811bd5014f5ea08f4cf4bc57e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.15.3" firebase_core: @@ -462,7 +461,7 @@ packages: description: name: firebase_core sha256: "7be63a3f841fc9663342f7f3a011a42aef6a61066943c90b1c434d79d5c995c5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.15.2" firebase_core_platform_interface: @@ -470,7 +469,7 @@ packages: description: name: firebase_core_platform_interface sha256: "0ecda14c1bfc9ed8cac303dd0f8d04a320811b479362a9a4efb14fd331a473ce" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.3" firebase_core_web: @@ -478,7 +477,7 @@ packages: description: name: firebase_core_web sha256: "0ed0dc292e8f9ac50992e2394e9d336a0275b6ae400d64163fdf0a8a8b556c37" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.24.1" firebase_crashlytics: @@ -486,7 +485,7 @@ packages: description: name: firebase_crashlytics sha256: "662ae6443da91bca1fb0be8aeeac026fa2975e8b7ddfca36e4d90ebafa35dde1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.3.10" firebase_crashlytics_platform_interface: @@ -494,7 +493,7 @@ packages: description: name: firebase_crashlytics_platform_interface sha256: "7222a8a40077c79f6b8b3f3439241c9f2b34e9ddfde8381ffc512f7b2e61f7eb" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.8.10" fixnum: @@ -502,7 +501,7 @@ packages: description: name: fixnum sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" fluro: @@ -510,7 +509,7 @@ packages: description: name: fluro sha256: "24d07d0b285b213ec2045b83e85d076185fa5c23651e44dae0ac6755784b97d0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.5" flutter: @@ -523,7 +522,7 @@ packages: description: name: flutter_cache_manager sha256: "400b6592f16a4409a7f2bb929a9a7e38c72cceb8ffb99ee57bbf2cb2cecf8386" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.4.1" flutter_debouncer: @@ -531,7 +530,7 @@ packages: description: name: flutter_debouncer sha256: "89f98f874e6abbb212f3027a7a27d5ce42c5b6544c8f5967d91140c0ae06ae22" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.1" flutter_image_compress: @@ -539,7 +538,7 @@ packages: description: name: flutter_image_compress sha256: "51d23be39efc2185e72e290042a0da41aed70b14ef97db362a6b5368d0523b27" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.0" flutter_image_compress_common: @@ -547,7 +546,7 @@ packages: description: name: flutter_image_compress_common sha256: c5c5d50c15e97dd7dc72ff96bd7077b9f791932f2076c5c5b6c43f2c88607bfb - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.6" flutter_image_compress_macos: @@ -555,7 +554,7 @@ packages: description: name: flutter_image_compress_macos sha256: "20019719b71b743aba0ef874ed29c50747461e5e8438980dfa5c2031898f7337" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.3" flutter_image_compress_ohos: @@ -563,7 +562,7 @@ packages: description: name: flutter_image_compress_ohos sha256: e76b92bbc830ee08f5b05962fc78a532011fcd2041f620b5400a593e96da3f51 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.0.3" flutter_image_compress_platform_interface: @@ -571,7 +570,7 @@ packages: description: name: flutter_image_compress_platform_interface sha256: "579cb3947fd4309103afe6442a01ca01e1e6f93dc53bb4cbd090e8ce34a41889" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.5" flutter_image_compress_web: @@ -579,7 +578,7 @@ packages: description: name: flutter_image_compress_web sha256: b9b141ac7c686a2ce7bb9a98176321e1182c9074650e47bb140741a44b6f5a96 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.1.5" flutter_launcher_icons: @@ -587,7 +586,7 @@ packages: description: name: flutter_launcher_icons sha256: "10f13781741a2e3972126fae08393d3c4e01fa4cd7473326b94b72cf594195e7" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.14.4" flutter_lints: @@ -595,7 +594,7 @@ packages: description: name: flutter_lints sha256: "5398f14efa795ffb7a33e9b6a08798b26a180edac4ad7db3f231e40f82ce11e1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.0" flutter_localizations: @@ -607,16 +606,16 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "38d1c268de9097ff59cf0e844ac38759fc78f76836d37edad06fa21e182055a0" - url: "https://pub.flutter-io.cn" + sha256: "3854fe5e3bff0b113c658f260b90c95dea17c92db0f2addeac2e343dd9969785" + url: "https://pub.dev" source: hosted - version: "2.0.34" + version: "2.0.35" flutter_screenutil: dependency: "direct main" description: name: flutter_screenutil sha256: "8239210dd68bee6b0577aa4a090890342d04a136ce1c81f98ee513fc0ce891de" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.9.3" flutter_smart_dialog: @@ -624,7 +623,7 @@ packages: description: name: flutter_smart_dialog sha256: "72762b20c25f8e12d490332004c9cca327f39dfc1fcba66124c6b7c108b68850" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.9.8+10" flutter_staggered_grid_view: @@ -632,7 +631,7 @@ packages: description: name: flutter_staggered_grid_view sha256: "19e7abb550c96fbfeb546b23f3ff356ee7c59a019a651f8f102a4ba9b7349395" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.7.0" flutter_svg: @@ -640,7 +639,7 @@ packages: description: name: flutter_svg sha256: "35882981abcbfb8c15b286f0cd690ff25bac12d95eff3e25ee207f37d4c42e7f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.0" flutter_svga: @@ -665,7 +664,7 @@ packages: description: name: fluttertoast sha256: "90778fe0497fe3a09166e8cf2e0867310ff434b794526589e77ec03cf08ba8e8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.2.14" google_identity_services_web: @@ -673,7 +672,7 @@ packages: description: name: google_identity_services_web sha256: "5d187c46dc59e02646e10fe82665fc3884a9b71bc1c90c2b8b749316d33ee454" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.3.3+1" google_sign_in: @@ -681,7 +680,7 @@ packages: description: name: google_sign_in sha256: d0a2c3bcb06e607bb11e4daca48bd4b6120f0bbc4015ccebbe757d24ea60ed2a - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.3.0" google_sign_in_android: @@ -689,7 +688,7 @@ packages: description: name: google_sign_in_android sha256: d5e23c56a4b84b6427552f1cf3f98f716db3b1d1a647f16b96dbb5b93afa2805 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.2.1" google_sign_in_ios: @@ -697,7 +696,7 @@ packages: description: name: google_sign_in_ios sha256: "102005f498ce18442e7158f6791033bbc15ad2dcc0afa4cf4752e2722a516c96" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.9.0" google_sign_in_platform_interface: @@ -705,7 +704,7 @@ packages: description: name: google_sign_in_platform_interface sha256: "5f6f79cf139c197261adb6ac024577518ae48fdff8e53205c5373b5f6430a8aa" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.5.0" google_sign_in_web: @@ -713,7 +712,7 @@ packages: description: name: google_sign_in_web sha256: "460547beb4962b7623ac0fb8122d6b8268c951cf0b646dd150d60498430e4ded" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.12.4+4" gtk: @@ -721,7 +720,7 @@ packages: description: name: gtk sha256: "4ff85b2a16724029dd9e5bbb5a94b6918f9973f74ba571c949d2002801879cf5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" html: @@ -729,7 +728,7 @@ packages: description: name: html sha256: "6d1264f2dffa1b1101c25a91dff0dc2daee4c18e87cd8538729773c073dbf602" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.15.6" http: @@ -737,7 +736,7 @@ packages: description: name: http sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.6.0" http_client_helper: @@ -745,7 +744,7 @@ packages: description: name: http_client_helper sha256: "8a9127650734da86b5c73760de2b404494c968a3fd55602045ffec789dac3cb1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" http_parser: @@ -753,7 +752,7 @@ packages: description: name: http_parser sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.1.2" id3: @@ -761,7 +760,7 @@ packages: description: name: id3 sha256: "24176a6e08db6297c8450079e94569cd8387f913c817e5e3d862be7dc191e0b8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.2" image: @@ -769,7 +768,7 @@ packages: description: name: image sha256: f9881ff4998044947ec38d098bc7c8316ae1186fa786eddffdb867b9bc94dfce - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.8.0" image_cropper: @@ -784,7 +783,7 @@ packages: description: name: image_cropper_for_web sha256: "865d798b5c9d826f1185b32e5d0018c4183ddb77b7b82a931e1a06aa3b74974e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" image_cropper_platform_interface: @@ -792,31 +791,31 @@ packages: description: name: image_cropper_platform_interface sha256: ee160d686422272aa306125f3b6fb1c1894d9b87a5e20ed33fa008e7285da11e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.0.0" image_picker: dependency: "direct main" description: name: image_picker - sha256: "91c025426c2881c551100bce834e201c835a170151545f58d17da5180ca7d9ac" - url: "https://pub.flutter-io.cn" + sha256: d8402284df184bc05f4a2210c6c23983b0720f4cd87cbd05c5390a78af602667 + url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.3" image_picker_android: dependency: transitive description: name: image_picker_android - sha256: d5b3e1774af29c9ab00103afb0d4614070f924d2e0057ac867ec98800114793f - url: "https://pub.flutter-io.cn" + sha256: "6f3a1995eafb000333174fae92202622033b0ee7fd917a6cd3730295264df84a" + url: "https://pub.dev" source: hosted - version: "0.8.13+17" + version: "0.8.13+19" image_picker_for_web: dependency: transitive description: name: image_picker_for_web sha256: "66257a3191ab360d23a55c8241c91a6e329d31e94efa7be9cf7a212e65850214" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.1" image_picker_ios: @@ -824,7 +823,7 @@ packages: description: name: image_picker_ios sha256: b9c4a438a9ff4f60808c9cf0039b93a42bb6c2211ef6ebb647394b2b3fa84588 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.8.13+6" image_picker_linux: @@ -832,7 +831,7 @@ packages: description: name: image_picker_linux sha256: "1f81c5f2046b9ab724f85523e4af65be1d47b038160a8c8deed909762c308ed4" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2" image_picker_macos: @@ -840,7 +839,7 @@ packages: description: name: image_picker_macos sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2+1" image_picker_platform_interface: @@ -848,7 +847,7 @@ packages: description: name: image_picker_platform_interface sha256: "567e056716333a1647c64bb6bd873cff7622233a5c3f694be28a583d4715690c" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.11.1" image_picker_windows: @@ -856,47 +855,47 @@ packages: description: name: image_picker_windows sha256: d248c86554a72b5495a31c56f060cf73a41c7ff541689327b1a7dbccc33adfae - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.2" in_app_purchase: dependency: "direct main" description: name: in_app_purchase - sha256: "5cddd7f463f3bddb1d37a72b95066e840d5822d66291331d7f8f05ce32c24b6c" - url: "https://pub.flutter-io.cn" + sha256: ad59b45d998868b8ace0f606e09b348ffd888952a3cf8ff9f7956aaf4844e6e2 + url: "https://pub.dev" source: hosted - version: "3.2.3" + version: "3.2.4" in_app_purchase_android: dependency: "direct main" description: name: in_app_purchase_android - sha256: "634bee4734b17fe55f370f0ac07a22431a9666e0f3a870c6d20350856e8bbf71" - url: "https://pub.flutter-io.cn" + sha256: "518b48a385dfc1aa278080472969c6cee0c3d41ef8b9511b0071dd015473ecf1" + url: "https://pub.dev" source: hosted - version: "0.4.0+10" + version: "0.4.0+11" in_app_purchase_platform_interface: dependency: transitive description: name: in_app_purchase_platform_interface - sha256: "1d353d38251da5b9fea6635c0ebfc6bb17a2d28d0e86ea5e083bf64244f1fb4c" - url: "https://pub.flutter-io.cn" + sha256: "0b0076cac8ce4fa7048f01e76af8b123aeb6a7c4e0dea2a5206d6664454f3e36" + url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" in_app_purchase_storekit: dependency: transitive description: name: in_app_purchase_storekit - sha256: "1d512809edd9f12ff88fce4596a13a18134e2499013f4d6a8894b04699363c93" - url: "https://pub.flutter-io.cn" + sha256: "47d63717270133fcfa1ff8e144f6aaf9d498fa3884de43e24909737da55aedd8" + url: "https://pub.dev" source: hosted - version: "0.4.8+1" + version: "0.4.10+1" intl: dependency: transitive description: name: intl sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.20.2" isolate_easy_pool: @@ -904,7 +903,7 @@ packages: description: name: isolate_easy_pool sha256: f0204cfdecbb84d61c46240a603bb21c3b2ac925475faf3f4afe18526fcb8f64 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.0.8" jni: @@ -912,7 +911,7 @@ packages: description: name: jni sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.0" jni_flutter: @@ -920,7 +919,7 @@ packages: description: name: jni_flutter sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" js: @@ -928,7 +927,7 @@ packages: description: name: js sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.6.7" json_annotation: @@ -936,23 +935,23 @@ packages: description: name: json_annotation sha256: "2a743920d81b7910627f68ee2c9ac1fc0bfee32b9fc3403587d7c6791ca12f80" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.12.0" just_audio: dependency: "direct main" description: name: just_audio - sha256: "9694e4734f515f2a052493d1d7e0d6de219ee0427c7c29492e246ff32a219908" - url: "https://pub.flutter-io.cn" + sha256: e60aa97b233ddea025e13dfac59195207f528fa5e9e4a4a49a8c0766701e5fe6 + url: "https://pub.dev" source: hosted - version: "0.10.5" + version: "0.10.6" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface sha256: "2532c8d6702528824445921c5ff10548b518b13f808c2e34c2fd54793b999a6a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.6.0" just_audio_web: @@ -960,7 +959,7 @@ packages: description: name: just_audio_web sha256: "6ba8a2a7e87d57d32f0f7b42856ade3d6a9fbe0f1a11fabae0a4f00bb73f0663" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.16" leak_tracker: @@ -968,7 +967,7 @@ packages: description: name: leak_tracker sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "11.0.2" leak_tracker_flutter_testing: @@ -976,7 +975,7 @@ packages: description: name: leak_tracker_flutter_testing sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.10" leak_tracker_testing: @@ -984,7 +983,7 @@ packages: description: name: leak_tracker_testing sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.2" lints: @@ -992,7 +991,7 @@ packages: description: name: lints sha256: c35bb79562d980e9a453fc715854e1ed39e24e7d0297a880ef54e17f9874a9d7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.1.1" marquee: @@ -1000,7 +999,7 @@ packages: description: name: marquee sha256: a87e7e80c5d21434f90ad92add9f820cf68be374b226404fe881d2bba7be0862 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.0" matcher: @@ -1008,7 +1007,7 @@ packages: description: name: matcher sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.12.19" material_color_utilities: @@ -1016,23 +1015,23 @@ packages: description: name: material_color_utilities sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.13.0" meta: dependency: transitive description: name: meta - sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394" - url: "https://pub.flutter-io.cn" + sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349" + url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.18.0" mime: dependency: transitive description: name: mime sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" mime_type: @@ -1040,7 +1039,7 @@ packages: description: name: mime_type sha256: d652b613e84dac1af28030a9fba82c0999be05b98163f9e18a0849c6e63838bb - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" nested: @@ -1048,7 +1047,7 @@ packages: description: name: nested sha256: "03bac4c528c64c95c722ec99280375a6f2fc708eec17c7b3f07253b626cd2a20" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.0" octo_image: @@ -1056,7 +1055,7 @@ packages: description: name: octo_image sha256: "34faa6639a78c7e3cbe79be6f9f96535867e879748ade7d17c9b1ae7536293bd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.0" on_audio_query: @@ -1078,7 +1077,7 @@ packages: description: name: on_audio_query_ios sha256: "9b3efa39a656fa3720980e3c6a1f55b7257d0032a45ffeb3f70eaa2c7f10f929" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" on_audio_query_platform_interface: @@ -1086,7 +1085,7 @@ packages: description: name: on_audio_query_platform_interface sha256: c23e019a31bd0774828476e428fd33b0dd1d82c9d4791dba80429358fc65dcd3 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.7.0" on_audio_query_web: @@ -1094,7 +1093,7 @@ packages: description: name: on_audio_query_web sha256: "990efa52d879e6caffa97f24b34acd9caa1ce2c4c4cb873fe5a899a9b1af02c7" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.6.0" package_config: @@ -1102,7 +1101,7 @@ packages: description: name: package_config sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" package_info_plus: @@ -1110,7 +1109,7 @@ packages: description: name: package_info_plus sha256: "16eee997588c60225bda0488b6dcfac69280a6b7a3cf02c741895dd370a02968" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.3.1" package_info_plus_platform_interface: @@ -1118,7 +1117,7 @@ packages: description: name: package_info_plus_platform_interface sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.1" pag: @@ -1133,7 +1132,7 @@ packages: description: name: path sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.9.1" path_drawing: @@ -1141,7 +1140,7 @@ packages: description: name: path_drawing sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.0.1" path_parsing: @@ -1149,23 +1148,23 @@ packages: description: name: path_parsing sha256: "883402936929eac138ee0a45da5b0f2c80f89913e6dc3bf77eb65b84b409c6ca" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" path_provider: dependency: "direct main" description: name: path_provider - sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd" - url: "https://pub.flutter-io.cn" + sha256: a7f4874f987173da295a61c181b8ee71dab59b332a486b391babf26a1b884825 + url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" path_provider_android: dependency: transitive description: name: path_provider_android sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.1" path_provider_foundation: @@ -1173,63 +1172,63 @@ packages: description: name: path_provider_foundation sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.2" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 - url: "https://pub.flutter-io.cn" + sha256: "58c2005f147315b11e9b4a7bc889cd5203e250cba8e3f012dae259b4972b5c16" + url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" - url: "https://pub.flutter-io.cn" + sha256: "484838772624c3a4b94f1e44a3e19897fee738f2d5c4ce448443b0417f7c9dda" + url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.1.3" path_provider_windows: dependency: transitive description: name: path_provider_windows sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.0" permission_handler: dependency: "direct main" description: name: permission_handler - sha256: bc917da36261b00137bbc8896bf1482169cd76f866282368948f032c8c1caae1 - url: "https://pub.flutter-io.cn" + sha256: fe54465bcc62a4564c6e4db337bbaded6c0c0fa6e10487414436d163114784f6 + url: "https://pub.dev" source: hosted - version: "12.0.1" + version: "12.0.3" permission_handler_android: dependency: transitive description: name: permission_handler_android sha256: "1e3bc410ca1bf84662104b100eb126e066cb55791b7451307f9708d4007350e6" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "13.0.1" permission_handler_apple: dependency: transitive description: name: permission_handler_apple - sha256: f000131e755c54cf4d84a5d8bd6e4149e262cc31c5a8b1d698de1ac85fa41023 - url: "https://pub.flutter-io.cn" + sha256: "79dfa1df734798aa3cfdad166d3a3698c206d8813de13516ea1071b5d7e2f420" + url: "https://pub.dev" source: hosted - version: "9.4.7" + version: "9.4.10" permission_handler_html: dependency: transitive description: name: permission_handler_html sha256: "38f000e83355abb3392140f6bc3030660cfaef189e1f87824facb76300b4ff24" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.1.3+5" permission_handler_platform_interface: @@ -1237,7 +1236,7 @@ packages: description: name: permission_handler_platform_interface sha256: eb99b295153abce5d683cac8c02e22faab63e50679b937fa1bf67d58bb282878 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.3.0" permission_handler_windows: @@ -1245,7 +1244,7 @@ packages: description: name: permission_handler_windows sha256: "1a790728016f79a41216d88672dbc5df30e686e811ad4e698bfc51f76ad91f1e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.2.1" petitparser: @@ -1253,7 +1252,7 @@ packages: description: name: petitparser sha256: "91bd59303e9f769f108f8df05e371341b15d59e995e6806aefab827b58336675" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.2" photo_view: @@ -1261,7 +1260,7 @@ packages: description: name: photo_view sha256: "1fc3d970a91295fbd1364296575f854c9863f225505c28c46e0a03e48960c75e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.15.0" platform: @@ -1269,7 +1268,7 @@ packages: description: name: platform sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.6" plugin_platform_interface: @@ -1277,7 +1276,7 @@ packages: description: name: plugin_platform_interface sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.8" posix: @@ -1285,7 +1284,7 @@ packages: description: name: posix sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.5.0" pretty_dio_logger: @@ -1293,7 +1292,7 @@ packages: description: name: pretty_dio_logger sha256: "36f2101299786d567869493e2f5731de61ce130faa14679473b26905a92b6407" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" protobuf: @@ -1301,7 +1300,7 @@ packages: description: name: protobuf sha256: "75ec242d22e950bdcc79ee38dd520ce4ee0bc491d7fadc4ea47694604d22bf06" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.0.0" provider: @@ -1309,7 +1308,7 @@ packages: description: name: provider sha256: "4e82183fa20e5ca25703ead7e05de9e4cceed1fbd1eadc1ac3cb6f565a09f272" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.1.5+1" pull_to_refresh: @@ -1317,7 +1316,7 @@ packages: description: name: pull_to_refresh sha256: bbadd5a931837b57739cf08736bea63167e284e71fb23b218c8c9a6e042aad12 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" readmore: @@ -1325,7 +1324,7 @@ packages: description: name: readmore sha256: e8fca2bd397b86342483b409e2ec26f06560a5963aceaa39b27f30722b506187 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" rxdart: @@ -1333,7 +1332,7 @@ packages: description: name: rxdart sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.28.0" shared_preferences: @@ -1341,23 +1340,23 @@ packages: description: name: shared_preferences sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.5.5" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: e8d4762b1e2e8578fc4d0fd548cebf24afd24f49719c08974df92834565e2c53 - url: "https://pub.flutter-io.cn" + sha256: "93ae5884a9df5d3bb696825bceb3a17590754548b5d740eba51500afc8d088f5" + url: "https://pub.dev" source: hosted - version: "2.4.23" + version: "2.4.26" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.5.6" shared_preferences_linux: @@ -1365,7 +1364,7 @@ packages: description: name: shared_preferences_linux sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.1" shared_preferences_platform_interface: @@ -1373,7 +1372,7 @@ packages: description: name: shared_preferences_platform_interface sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.2" shared_preferences_web: @@ -1381,7 +1380,7 @@ packages: description: name: shared_preferences_web sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.3" shared_preferences_windows: @@ -1389,7 +1388,7 @@ packages: description: name: shared_preferences_windows sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.1" sign_in_with_apple: @@ -1397,7 +1396,7 @@ packages: description: name: sign_in_with_apple sha256: "8bd875c8e8748272749eb6d25b896f768e7e9d60988446d543fe85a37a2392b8" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "7.0.1" sign_in_with_apple_platform_interface: @@ -1405,7 +1404,7 @@ packages: description: name: sign_in_with_apple_platform_interface sha256: "981bca52cf3bb9c3ad7ef44aace2d543e5c468bb713fd8dda4275ff76dfa6659" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.0.0" sign_in_with_apple_web: @@ -1413,7 +1412,7 @@ packages: description: name: sign_in_with_apple_web sha256: f316400827f52cafcf50d00e1a2e8a0abc534ca1264e856a81c5f06bd5b10fed - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.0.0" sky_engine: @@ -1426,55 +1425,55 @@ packages: description: name: source_span sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.10.2" sqflite: dependency: transitive description: name: sqflite - sha256: "564cfed0746fe53140c23b70b308e045c3b31f17778f2f326ccb7d804ea0250a" - url: "https://pub.flutter-io.cn" + sha256: "58a799e6ac17dd32fbab93813d39ed835a75ccc0f8f85b8955fe318c6712b082" + url: "https://pub.dev" source: hosted - version: "2.4.2+1" + version: "2.4.3" sqflite_android: dependency: transitive description: name: sqflite_android - sha256: "881e28efdcc9950fd8e9bb42713dcf1103e62a2e7168f23c9338d82db13dec40" - url: "https://pub.flutter-io.cn" + sha256: d0548f9d7422a2dae99ec6f8b0a3074463b132d216fa5ba0d230eeefc901983b + url: "https://pub.dev" source: hosted - version: "2.4.2+3" + version: "2.4.3" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: "1581ffbf7a0e333b380d6a30737d78516b826cb35beb7fb0bf8a3ea0c678b465" - url: "https://pub.flutter-io.cn" + sha256: "5bf6a55c166e73bf651ba7ec3ed486e577620e3dc8f3a9c6a258a8031b624590" + url: "https://pub.dev" source: hosted - version: "2.5.8" + version: "2.5.11" sqflite_darwin: dependency: transitive description: name: sqflite_darwin - sha256: "279832e5cde3fe99e8571879498c9211f3ca6391b0d818df4e17d9fff5c6ccb3" - url: "https://pub.flutter-io.cn" + sha256: c86ca18b8f666bbf903924687fe21cc16fc385d086005067e26619ca530bef9f + url: "https://pub.dev" source: hosted - version: "2.4.2" + version: "2.4.3+1" sqflite_platform_interface: dependency: transitive description: name: sqflite_platform_interface - sha256: "8dd4515c7bdcae0a785b0062859336de775e8c65db81ae33dd5445f35be61920" - url: "https://pub.flutter-io.cn" + sha256: f84939f84350d92d04416f8bc4dc52d3896aec7716cc9e80cf0146342139dc50 + url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" stack_trace: dependency: transitive description: name: stack_trace sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.12.1" stream_channel: @@ -1482,7 +1481,7 @@ packages: description: name: stream_channel sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.1.4" string_scanner: @@ -1490,17 +1489,17 @@ packages: description: name: string_scanner sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.1" synchronized: dependency: transitive description: name: synchronized - sha256: "63896c27e81b28f8cb4e69ead0d3e8f03f1d1e5fc531a3e579cabed6a2c7c9e5" - url: "https://pub.flutter-io.cn" + sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153" + url: "https://pub.dev" source: hosted - version: "3.4.0+1" + version: "3.4.1" tancent_vap: dependency: "direct main" description: @@ -1513,39 +1512,39 @@ packages: description: name: tencent_cloud_chat_sdk sha256: fb930c86017fa4a546f3d0c15bc5a54197f07f003934737e80cf2f9a70cab1ba - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "8.3.6498+3" tencent_rtc_sdk: dependency: "direct main" description: name: tencent_rtc_sdk - sha256: "928b91ff2642b7e254aba2f4228b8c273aae34357fe4a74e7172aabf604d3df5" - url: "https://pub.flutter-io.cn" + sha256: a7b34506b429721e9439fd4fc642ebf97f6033e83702c3fb182d1ce35ccbabed + url: "https://pub.dev" source: hosted - version: "13.2.2" + version: "13.4.0" term_glyph: dependency: transitive description: name: term_glyph sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.2" test_api: dependency: transitive description: name: test_api - sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a" - url: "https://pub.flutter-io.cn" + sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e" + url: "https://pub.dev" source: hosted - version: "0.7.10" + version: "0.7.11" typed_data: dependency: transitive description: name: typed_data sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.4.0" universal_io: @@ -1553,7 +1552,7 @@ packages: description: name: universal_io sha256: f63cbc48103236abf48e345e07a03ce5757ea86285ed313a6a032596ed9301e2 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.1" url_launcher: @@ -1561,23 +1560,23 @@ packages: description: name: url_launcher sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.3.2" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "3bb000251e55d4a209aa0e2e563309dc9bb2befea2295fd0cec1f51760aac572" - url: "https://pub.flutter-io.cn" + sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32 + url: "https://pub.dev" source: hosted - version: "6.3.29" + version: "6.3.32" url_launcher_ios: dependency: transitive description: name: url_launcher_ios sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.4.1" url_launcher_linux: @@ -1585,7 +1584,7 @@ packages: description: name: url_launcher_linux sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.2" url_launcher_macos: @@ -1593,7 +1592,7 @@ packages: description: name: url_launcher_macos sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.2.5" url_launcher_platform_interface: @@ -1601,7 +1600,7 @@ packages: description: name: url_launcher_platform_interface sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.3.2" url_launcher_web: @@ -1609,7 +1608,7 @@ packages: description: name: url_launcher_web sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.3" url_launcher_windows: @@ -1617,7 +1616,7 @@ packages: description: name: url_launcher_windows sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.5" uuid: @@ -1625,7 +1624,7 @@ packages: description: name: uuid sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.5.3" vector_graphics: @@ -1633,7 +1632,7 @@ packages: description: name: vector_graphics sha256: "2306c03da2ba81724afeb589c351ebbc0aa7d86005925be8f8735856dbe5e42d" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.2.2" vector_graphics_codec: @@ -1641,23 +1640,23 @@ packages: description: name: vector_graphics_codec sha256: "99fd9fbd34d9f9a32efd7b6a6aae14125d8237b10403b422a6a6dfeac2806146" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.13" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: b9b3f391857781aa96acacef96066f2f49b4cd03cf9fce3ca4d8da2ef5ea129e - url: "https://pub.flutter-io.cn" + sha256: "142a9146f447d15b10bdc00e21d5f4d83e5b32bb5f8f8f5a04c75311344923a3" + url: "https://pub.dev" source: hosted - version: "1.2.3" + version: "1.2.6" vector_math: dependency: transitive description: name: vector_math sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.2.0" video_player: @@ -1665,39 +1664,39 @@ packages: description: name: video_player sha256: "48a7bdaa38a3d50ec10c78627abdbfad863fdf6f0d6e08c7c3c040cfd80ae36f" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.11.1" video_player_android: dependency: transitive description: name: video_player_android - sha256: "877a6c7ba772456077d7bfd71314629b3fe2b73733ce503fc77c3314d43a0ca0" - url: "https://pub.flutter-io.cn" + sha256: "15bfd0598f8d8946bf0e2d50e2ca1a0db9491589a8bb7f6f9a388c0b48aef764" + url: "https://pub.dev" source: hosted - version: "2.9.5" + version: "2.10.0" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: "9338f3ec22774f88146b22f13273a446719b1da010fd200c4d1d97802156ac58" - url: "https://pub.flutter-io.cn" + sha256: "76097729ef0c976937945afa53f1ca3afa9b50c9a95909ba347bcf93270466fd" + url: "https://pub.dev" source: hosted - version: "2.9.7" + version: "2.10.0" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: "16eaed5268c571c31840dc58ef8da5f0cd4db2a98490c3b8f1cf70122546c6e0" - url: "https://pub.flutter-io.cn" + sha256: "92c0fbabe20c788e71fd10d26cea998d0d253282e65d145aed0818731cf593ce" + url: "https://pub.dev" source: hosted - version: "6.7.0" + version: "6.9.0" video_player_web: dependency: transitive description: name: video_player_web sha256: "9f3c00be2ef9b76a95d94ac5119fb843dca6f2c69e6c9968f6f2b6c9e7afbdeb" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.4.0" video_thumbnail: @@ -1705,7 +1704,7 @@ packages: description: name: video_thumbnail sha256: "181a0c205b353918954a881f53a3441476b9e301641688a581e0c13f00dc588b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.5.6" visibility_detector: @@ -1713,7 +1712,7 @@ packages: description: name: visibility_detector sha256: dd5cc11e13494f432d15939c3aa8ae76844c42b723398643ce9addb88a5ed420 - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "0.4.0+2" vm_service: @@ -1721,7 +1720,7 @@ packages: description: name: vm_service sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "15.2.0" wakelock_plus: @@ -1729,7 +1728,7 @@ packages: description: name: wakelock_plus sha256: "61713aa82b7f85c21c9f4cd0a148abd75f38a74ec645fcb1e446f882c82fd09b" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.3.3" wakelock_plus_platform_interface: @@ -1737,7 +1736,7 @@ packages: description: name: wakelock_plus_platform_interface sha256: b13f99e992e7ae6a152e16c5559d3c07ff445b13330192662494e614ca3e7d7b - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.5.1" web: @@ -1745,7 +1744,7 @@ packages: description: name: web sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.1" webview_flutter: @@ -1753,7 +1752,7 @@ packages: description: name: webview_flutter sha256: "42393b4492e629aa3a88618530a4a00de8bb46e50e7b3993fedbfdc5352f0dbf" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "4.4.2" webview_flutter_android: @@ -1761,7 +1760,7 @@ packages: description: name: webview_flutter_android sha256: "47a8da40d02befda5b151a26dba71f47df471cddd91dfdb7802d0a87c5442558" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.16.9" webview_flutter_platform_interface: @@ -1769,23 +1768,23 @@ packages: description: name: webview_flutter_platform_interface sha256: "1221c1b12f5278791042f2ec2841743784cf25c5a644e23d6680e5d718824f04" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "2.15.1" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: "82648217f537573e1ca9ae9952d3eacedca6ab5aee69dc84445fc763766dcea2" - url: "https://pub.flutter-io.cn" + sha256: c879dd64b87c452aa84381b244d5469da57ba7e8cca6884c7b1e0d406372c12d + url: "https://pub.dev" source: hosted - version: "3.25.1" + version: "3.26.0" win32: dependency: transitive description: name: win32 sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "5.15.0" win32_registry: @@ -1793,7 +1792,7 @@ packages: description: name: win32_registry sha256: "21ec76dfc731550fd3e2ce7a33a9ea90b828fdf19a5c3bcf556fa992cfa99852" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.5" xdg_directories: @@ -1801,7 +1800,7 @@ packages: description: name: xdg_directories sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "1.1.0" xml: @@ -1809,7 +1808,7 @@ packages: description: name: xml sha256: "971043b3a0d3da28727e40ed3e0b5d18b742fa5a68665cca88e74b7876d5e025" - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "6.6.1" yaml: @@ -1817,9 +1816,9 @@ packages: description: name: yaml sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce - url: "https://pub.flutter-io.cn" + url: "https://pub.dev" source: hosted version: "3.1.3" sdks: - dart: ">=3.11.0 <4.0.0" - flutter: ">=3.38.0" + dart: ">=3.12.0 <4.0.0" + flutter: ">=3.44.0" diff --git a/pubspec.yaml b/pubspec.yaml index ebcb6bb..091094b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 1.6.3+1631 +version: 2.0.1+2001 environment: @@ -146,13 +146,15 @@ dev_dependencies: sdk: flutter flutter_lints: ^5.0.0 -dependency_overrides: - # path_provider_foundation 2.6.0 pulls in objective_c native assets that are - # currently packaged as simulator frameworks and rejected by App Store upload. - path_provider_foundation: 2.4.2 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec +dependency_overrides: + # path_provider_foundation 2.6.0 pulls in objective_c native assets that are + # currently packaged as simulator frameworks and rejected by App Store upload. + path_provider_foundation: 2.4.2 + extended_text_field: + path: ./local_packages/extended_text_field-16.0.2-patched + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. flutter: diff --git a/sc_images/index/sc_home_shell_bg.png b/sc_images/index/sc_home_shell_bg.png new file mode 100644 index 0000000000000000000000000000000000000000..60e7e22e2147c60b2f7403d0345941e631bc2f97 GIT binary patch literal 334396 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

0S4ru|Dyq36uo}W5 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≷^{(Aff)P=Q!GUV@(}k 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

saMkk4LFqx(cHWj@wRqe*5%;%Gh5tdmFL?a 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 mP9OnFVPIE%TR;qG{jwM>qJgDFmWD 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 literal 0 HcmV?d00001 diff --git a/sc_images/index/sc_icon_me_admin.svg b/sc_images/index/sc_icon_me_admin.svg new file mode 100644 index 0000000..3403847 --- /dev/null +++ b/sc_images/index/sc_icon_me_admin.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sc_images/index/sc_icon_me_agency_center.svg b/sc_images/index/sc_icon_me_agency_center.svg new file mode 100644 index 0000000..a12003c --- /dev/null +++ b/sc_images/index/sc_icon_me_agency_center.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sc_images/index/sc_icon_me_host_center.svg b/sc_images/index/sc_icon_me_host_center.svg new file mode 100644 index 0000000..22ce77c --- /dev/null +++ b/sc_images/index/sc_icon_me_host_center.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sc_images/index/sc_icon_me_language.svg b/sc_images/index/sc_icon_me_language.svg new file mode 100644 index 0000000..36c7260 --- /dev/null +++ b/sc_images/index/sc_icon_me_language.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/sc_images/index/sc_icon_me_manager_center.svg b/sc_images/index/sc_icon_me_manager_center.svg new file mode 100644 index 0000000..f20dcf7 --- /dev/null +++ b/sc_images/index/sc_icon_me_manager_center.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/sc_images/index/sc_icon_me_recharge_agency.svg b/sc_images/index/sc_icon_me_recharge_agency.svg new file mode 100644 index 0000000..567f508 --- /dev/null +++ b/sc_images/index/sc_icon_me_recharge_agency.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/sc_images/index/sc_icon_me_settings.svg b/sc_images/index/sc_icon_me_settings.svg new file mode 100644 index 0000000..5e9c623 --- /dev/null +++ b/sc_images/index/sc_icon_me_settings.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/sc_images/index/sc_icon_serach.png b/sc_images/index/sc_icon_serach.png index 38d428a8982166ee7e1ab1700b507c3a074eeea3..3b55ae52b0a23fcd56104bb17cedaca2ace2e694 100644 GIT binary patch literal 5870 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 Ef(9xx4*&oF literal 7361 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 diff --git a/sc_images/index/sc_icon_task_game.png b/sc_images/index/sc_icon_task_game.png index 60b25f72e488a495803ea7408e4ef46f76e469fb..f9558ab6360a0454c47ab044f8d5552d394b38be 100644 GIT binary patch literal 120360 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