Repository: appinioGmbH/flutter_packages Branch: main Commit: 67d5fee625da Files: 618 Total size: 1.0 MB Directory structure: gitextract_6dy26xrp/ ├── .github/ │ └── ISSUE_TEMPLATE/ │ ├── bug_report.md │ └── feature_request.md ├── .gitignore ├── CODEOWNERS ├── README.md └── packages/ ├── appinio_animated_toggle_tab/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ └── main.dart │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ └── web/ │ │ ├── index.html │ │ └── manifest.json │ ├── lib/ │ │ └── appinio_animated_toggle_tab.dart │ └── pubspec.yaml ├── appinio_social_share/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── android/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ │ ├── gradlew │ │ ├── gradlew.bat │ │ ├── settings.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── appinio/ │ │ └── socialshare/ │ │ └── appinio_social_share/ │ │ ├── AppinioSocialSharePlugin.java │ │ └── utils/ │ │ └── SocialShareUtil.java │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Podfile │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ └── main.dart │ │ ├── linux/ │ │ │ ├── .gitignore │ │ │ ├── CMakeLists.txt │ │ │ ├── flutter/ │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── generated_plugin_registrant.cc │ │ │ │ ├── generated_plugin_registrant.h │ │ │ │ └── generated_plugins.cmake │ │ │ ├── main.cc │ │ │ ├── my_application.cc │ │ │ └── my_application.h │ │ ├── macos/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── Flutter-Debug.xcconfig │ │ │ │ ├── Flutter-Release.xcconfig │ │ │ │ └── GeneratedPluginRegistrant.swift │ │ │ ├── Podfile │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ └── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ ├── Base.lproj/ │ │ │ │ │ └── MainMenu.xib │ │ │ │ ├── Configs/ │ │ │ │ │ ├── AppInfo.xcconfig │ │ │ │ │ ├── Debug.xcconfig │ │ │ │ │ ├── Release.xcconfig │ │ │ │ │ └── Warnings.xcconfig │ │ │ │ ├── DebugProfile.entitlements │ │ │ │ ├── Info.plist │ │ │ │ ├── MainFlutterWindow.swift │ │ │ │ └── Release.entitlements │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ ├── web/ │ │ │ ├── index.html │ │ │ └── manifest.json │ │ └── windows/ │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── flutter/ │ │ │ ├── CMakeLists.txt │ │ │ ├── generated_plugin_registrant.cc │ │ │ ├── generated_plugin_registrant.h │ │ │ └── generated_plugins.cmake │ │ └── runner/ │ │ ├── CMakeLists.txt │ │ ├── Runner.rc │ │ ├── flutter_window.cpp │ │ ├── flutter_window.h │ │ ├── main.cpp │ │ ├── resource.h │ │ ├── runner.exe.manifest │ │ ├── utils.cpp │ │ ├── utils.h │ │ ├── win32_window.cpp │ │ └── win32_window.h │ ├── ios/ │ │ ├── .gitignore │ │ ├── Assets/ │ │ │ └── .gitkeep │ │ ├── Classes/ │ │ │ ├── AppinioSocialSharePlugin.h │ │ │ ├── AppinioSocialSharePlugin.m │ │ │ ├── MyActivityItemSource.swift │ │ │ ├── ShareUtil.swift │ │ │ └── SwiftAppinioSocialSharePlugin.swift │ │ └── appinio_social_share.podspec │ ├── lib/ │ │ ├── appinio_social_share.dart │ │ ├── appinio_social_share_method_channel.dart │ │ ├── appinio_social_share_platform_interface.dart │ │ └── platforms/ │ │ ├── android.dart │ │ └── ios.dart │ └── pubspec.yaml ├── appinio_swiper/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ ├── example_buttons.dart │ │ │ ├── example_candidate_model.dart │ │ │ ├── example_card.dart │ │ │ └── main.dart │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ └── web/ │ │ ├── index.html │ │ └── manifest.json │ ├── lib/ │ │ ├── appinio_swiper.dart │ │ ├── enums.dart │ │ └── types.dart │ ├── pubspec.yaml │ └── test/ │ └── appinio_swiper_test.dart ├── appinio_video_player/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Podfile │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ └── main.dart │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ └── web/ │ │ ├── index.html │ │ └── manifest.json │ ├── lib/ │ │ ├── appinio_video_player.dart │ │ └── src/ │ │ ├── controls/ │ │ │ ├── all_controls_overlay.dart │ │ │ ├── control_bar.dart │ │ │ ├── fullscreen_button.dart │ │ │ ├── mute_button.dart │ │ │ ├── play_button.dart │ │ │ ├── progress_bar.dart │ │ │ ├── progress_bar_indicator.dart │ │ │ ├── seeker.dart │ │ │ ├── video_settings_button.dart │ │ │ └── video_settings_popup/ │ │ │ ├── video_settings_dialog.dart │ │ │ ├── video_settings_dialog_item.dart │ │ │ ├── video_settings_playback_speed_dialog.dart │ │ │ └── video_settings_quality_dialog.dart │ │ ├── custom_video_player.dart │ │ ├── custom_video_player_controller.dart │ │ ├── embedded_video_player.dart │ │ ├── fullscreen_video_player.dart │ │ ├── models/ │ │ │ ├── custom_video_player_popup_settings.dart │ │ │ ├── custom_video_player_progress_bar_settings.dart │ │ │ └── custom_video_player_settings.dart │ │ ├── seek_buttons.dart │ │ ├── thumbnail.dart │ │ ├── volume_control.dart │ │ └── web_video_player/ │ │ ├── conditional_native_web_video_player/ │ │ │ ├── conditional_native_web_video_player.dart │ │ │ ├── conditional_native_web_video_player_base.dart │ │ │ ├── conditional_native_web_video_player_mobile.dart │ │ │ └── conditional_native_web_video_player_web.dart │ │ ├── custom_video_player_web.dart │ │ ├── custom_video_player_web_controller.dart │ │ ├── native_web_video_player.dart │ │ └── web_video_player_settings.dart │ ├── pubspec.yaml │ └── test/ │ └── custom_video_player_test.dart ├── disable_screenshot/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── analysis_options.yaml │ ├── android/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ └── gradle-wrapper.properties │ │ ├── settings.gradle │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── appinio/ │ │ └── disable_screenshot/ │ │ └── DisableScreenshotPlugin.java │ ├── example/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── appinio/ │ │ │ │ │ │ └── disable_screenshot_example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Podfile │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ └── main.dart │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── widget_test.dart │ ├── ios/ │ │ ├── .gitignore │ │ ├── Assets/ │ │ │ └── .gitkeep │ │ ├── Classes/ │ │ │ ├── DisableScreenshotPlugin.h │ │ │ ├── DisableScreenshotPlugin.m │ │ │ └── SwiftDisableScreenshotPlugin.swift │ │ └── disable_screenshot.podspec │ ├── lib/ │ │ ├── disable_screenshot.dart │ │ ├── disable_screenshot_method_channel.dart │ │ └── disable_screenshot_platform_interface.dart │ ├── pubspec.yaml │ └── test/ │ ├── disable_screenshot_method_channel_test.dart │ └── disable_screenshot_test.dart ├── flutter_onboarding_slider/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── analysis_options.yaml │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── java/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.java │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ ├── main.dart │ │ │ └── screens/ │ │ │ ├── login_page.dart │ │ │ └── register_page.dart │ │ ├── pubspec.yaml │ │ └── test/ │ │ └── widget_test.dart │ ├── lib/ │ │ ├── background.dart │ │ ├── background_body.dart │ │ ├── background_controller.dart │ │ ├── background_final_button.dart │ │ ├── background_image.dart │ │ ├── flutter_onboarding_slider.dart │ │ ├── onboarding_navigation_bar.dart │ │ └── page_offset_provider.dart │ ├── pubspec.yaml │ └── test/ │ └── page_slider_test.dart ├── flutter_timer_countdown/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values/ │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ ├── main.dart │ │ │ ├── timer_basic.dart │ │ │ └── timer_frame.dart │ │ ├── pubspec.yaml │ │ ├── test/ │ │ │ └── widget_test.dart │ │ └── web/ │ │ ├── index.html │ │ └── manifest.json │ ├── lib/ │ │ └── flutter_timer_countdown.dart │ ├── pubspec.yaml │ └── test/ │ └── flutter_timer_countdown_test.dart ├── profile_sliver/ │ ├── .gitignore │ ├── .metadata │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── example/ │ │ ├── .gitignore │ │ ├── .metadata │ │ ├── README.md │ │ ├── android/ │ │ │ ├── .gitignore │ │ │ ├── app/ │ │ │ │ ├── build.gradle │ │ │ │ └── src/ │ │ │ │ ├── debug/ │ │ │ │ │ └── AndroidManifest.xml │ │ │ │ ├── main/ │ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ └── com/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── example/ │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ │ └── res/ │ │ │ │ │ ├── drawable/ │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ └── values/ │ │ │ │ │ └── styles.xml │ │ │ │ └── profile/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── build.gradle │ │ │ ├── gradle/ │ │ │ │ └── wrapper/ │ │ │ │ └── gradle-wrapper.properties │ │ │ ├── gradle.properties │ │ │ └── settings.gradle │ │ ├── ios/ │ │ │ ├── .gitignore │ │ │ ├── Flutter/ │ │ │ │ ├── AppFrameworkInfo.plist │ │ │ │ ├── Debug.xcconfig │ │ │ │ └── Release.xcconfig │ │ │ ├── Runner/ │ │ │ │ ├── AppDelegate.swift │ │ │ │ ├── Assets.xcassets/ │ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ │ └── Contents.json │ │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ │ ├── Contents.json │ │ │ │ │ └── README.md │ │ │ │ ├── Base.lproj/ │ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ │ └── Main.storyboard │ │ │ │ ├── Info.plist │ │ │ │ └── Runner-Bridging-Header.h │ │ │ ├── Runner.xcodeproj/ │ │ │ │ ├── project.pbxproj │ │ │ │ ├── project.xcworkspace/ │ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ │ └── xcshareddata/ │ │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ │ └── xcshareddata/ │ │ │ │ └── xcschemes/ │ │ │ │ └── Runner.xcscheme │ │ │ └── Runner.xcworkspace/ │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata/ │ │ │ └── WorkspaceSettings.xcsettings │ │ ├── lib/ │ │ │ └── main.dart │ │ └── pubspec.yaml │ ├── lib/ │ │ ├── profile_sliver.dart │ │ └── src/ │ │ ├── profile_sliver.dart │ │ ├── profile_sliver_element.dart │ │ └── profile_sliver_render_object.dart │ └── pubspec.yaml └── widget_zoom/ ├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example/ │ ├── .gitignore │ ├── .metadata │ ├── README.md │ ├── analysis_options.yaml │ ├── android/ │ │ ├── .gitignore │ │ ├── app/ │ │ │ ├── build.gradle │ │ │ └── src/ │ │ │ ├── debug/ │ │ │ │ └── AndroidManifest.xml │ │ │ ├── main/ │ │ │ │ ├── AndroidManifest.xml │ │ │ │ ├── kotlin/ │ │ │ │ │ └── com/ │ │ │ │ │ └── example/ │ │ │ │ │ └── example/ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── res/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable-v21/ │ │ │ │ │ └── launch_background.xml │ │ │ │ ├── values/ │ │ │ │ │ └── styles.xml │ │ │ │ └── values-night/ │ │ │ │ └── styles.xml │ │ │ └── profile/ │ │ │ └── AndroidManifest.xml │ │ ├── build.gradle │ │ ├── gradle/ │ │ │ └── wrapper/ │ │ │ └── gradle-wrapper.properties │ │ ├── gradle.properties │ │ └── settings.gradle │ ├── ios/ │ │ ├── .gitignore │ │ ├── Flutter/ │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ └── Release.xcconfig │ │ ├── Runner/ │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets/ │ │ │ │ ├── AppIcon.appiconset/ │ │ │ │ │ └── Contents.json │ │ │ │ └── LaunchImage.imageset/ │ │ │ │ ├── Contents.json │ │ │ │ └── README.md │ │ │ ├── Base.lproj/ │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── Runner-Bridging-Header.h │ │ ├── Runner.xcodeproj/ │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace/ │ │ │ │ ├── contents.xcworkspacedata │ │ │ │ └── xcshareddata/ │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── xcshareddata/ │ │ │ └── xcschemes/ │ │ │ └── Runner.xcscheme │ │ └── Runner.xcworkspace/ │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata/ │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ ├── lib/ │ │ └── main.dart │ ├── linux/ │ │ ├── .gitignore │ │ ├── CMakeLists.txt │ │ ├── flutter/ │ │ │ ├── CMakeLists.txt │ │ │ ├── generated_plugin_registrant.cc │ │ │ ├── generated_plugin_registrant.h │ │ │ └── generated_plugins.cmake │ │ ├── main.cc │ │ ├── my_application.cc │ │ └── my_application.h │ ├── pubspec.yaml │ ├── test/ │ │ └── widget_test.dart │ ├── web/ │ │ ├── index.html │ │ └── manifest.json │ └── windows/ │ ├── .gitignore │ ├── CMakeLists.txt │ ├── flutter/ │ │ ├── CMakeLists.txt │ │ ├── generated_plugin_registrant.cc │ │ ├── generated_plugin_registrant.h │ │ └── generated_plugins.cmake │ └── runner/ │ ├── CMakeLists.txt │ ├── Runner.rc │ ├── flutter_window.cpp │ ├── flutter_window.h │ ├── main.cpp │ ├── resource.h │ ├── runner.exe.manifest │ ├── utils.cpp │ ├── utils.h │ ├── win32_window.cpp │ └── win32_window.h ├── lib/ │ ├── src/ │ │ ├── widget_zoom.dart │ │ └── widget_zoom_full_screen.dart │ └── widget_zoom.dart ├── pubspec.yaml └── test/ └── widget_zoom_test.dart ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Create a report to help us improve title: "[ BUG ] : A clear and concise title of the bug" labels: '' assignees: khanmujeeb687 --- **Plugin name** For e.g. - Appinio social share , Appinio Swiper etc. **Describe the bug** A clear and concise description of what the bug is. **To Reproduce** Steps to reproduce the behavior: 1. Step 1 2. Step 2 3. Step 3 4. Step 4 **Expected behavior** A clear and concise description of what you expected to happen. **Screenshots** If applicable, add screenshots to help explain your problem. **Desktop (please complete the following information):** - OS: [e.g. iOS] - Browser [e.g. chrome, safari] - Version [e.g. 22] **Smartphone (please complete the following information):** - Device: [e.g. iPhone6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] **Additional context** Add any other context about the problem here. ================================================ FILE: .github/ISSUE_TEMPLATE/feature_request.md ================================================ --- name: Feature request about: Suggest an idea for this project title: "[Feature] : A concise title of the feature" labels: '' assignees: khanmujeeb687 --- **Plugin name** Plugin name for e.g. Appinio social share, Appinio Swiper etc. **Is your feature request related to a problem? Please describe.** A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] **Describe the solution you'd like** A clear and concise description of what you want to happen. **Describe alternatives you've considered** A clear and concise description of any alternative solutions or features you've considered. **Screenshots** Some screenshots or pictures if available. **Additional context** Add any other context or screenshots about the feature request here. ================================================ FILE: .gitignore ================================================ /.idea /publish.md /.DS_Store /.idea/ /.idea/libraries /.idea/libraries/ ================================================ FILE: CODEOWNERS ================================================ # These owners will be the default owners for everything in the repo. * @bilalhamud @hamzahayak @javi-appinio @festelo @Modi-gh @bernat-gomez @nambiarAswathi @dtengeri ================================================ FILE: README.md ================================================ # Flutter packages Flutter packages maintained and used by [Appinio](https://appinio.com). # Packages list - [flutter_timer_countdown](packages/flutter_timer_countdown/) - [flutter_onboarding_slider](packages/flutter_onboarding_slider/) - [appinio_video_player](packages/appinio_video_player/) - [appinio_animated_toggle_tab](packages/appinio_animated_toggle_tab/) - [appinio_swiper](packages/appinio_swiper/) - [appinio_social_share](packages/appinio_social_share/) ================================================ FILE: packages/appinio_animated_toggle_tab/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/appinio_animated_toggle_tab/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: ffb2ecea5223acdd139a5039be2f9c796962833d channel: stable project_type: package ================================================ FILE: packages/appinio_animated_toggle_tab/CHANGELOG.md ================================================ ## [1.0.3] - 2024.01.25 * Added initial index for AppinioAnimatedToggleTab. ## [1.0.2] - 2022.09.25 * Updating Readme. ## [1.0.1] - 2022.04.21 * UI improvements for WebApp. ## [1.0.0] - 2021.10.04 * Initial version. ================================================ FILE: packages/appinio_animated_toggle_tab/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2021 APPINIO GmbH 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. ================================================ FILE: packages/appinio_animated_toggle_tab/README.md ================================================ ```AppinioAnimatedToggleTab``` is a Flutter package for creating a custom tab viewer with built-in animation. ✨ Supporting Android, iOS & WebApp. ## Why? We build this package because we wanted to: - have a tabviewer ready to be customized - be able to animate between switching tabs ## Show Cases Switching between tabs. ## Installation Create a new project with the command ```yaml flutter create MyApp ``` Add ```yaml dependencies: ... appinio_tanimated_toggle_tab: ``` to your `pubspec.yaml` of your flutter project. **OR** run ```yaml flutter pub add appinio_tanimated_toggle_tab ``` in your project's root directory. In your library add the following import: ```dart import 'package:appinio_animated_toggle_tab/appinio_animated_toggle_tab.dart'; ``` For help getting started with Flutter, view the online [documentation](https://flutter.io/). ## Usage You can place your `AppinioAnimatedToggleTab` inside of a `MaterialApp` like we did here. Optional parameters can be defined to enable different features. See the following example.. ```dart class TabsViewer extends StatelessWidget { @override Widget build(BuildContext context) { return CupertinoApp( home: AppinioAnimatedToggleTab( callback: (int i) {}, tabTexts: const [ 'make', 'your', 'tabs :)', ], height: 40, width: 300, boxDecoration: BoxDecoration(color: Color(0xFFc3d2db),), animatedBoxDecoration: BoxDecoration( boxShadow: [ BoxShadow( color: const Color(0xFFc3d2db).withOpacity(0.1), spreadRadius: 1, blurRadius: 5, offset: const Offset(2, 2), ), ], color: kDarkBlueColor, borderRadius: const BorderRadius.all( Radius.circular(5), ), border: Border.all( color: Colors.grey, width: 1, ), ), activeStyle: const TextStyle( color: Colors.blue,), inactiveStyle: const TextStyle( color: Colors.black,), ); } } ``` ## Constructor #### Basic | Parameter | Default | Description | Required | | ------------- |:-------------|:-----|:-----:| | callback | - | function(int) for call back and control the view of tabs | true | tabTexts | - | a list of texts displayed on the tabs | true | height | - | height of the tab | true | width | - | width of the tab | true | boxDecoration | - | decoration of the tab | true | animatedBoxDecoration | - | the decoration of animated box used to toggle | true | activeStyle | - | style of text when active | true | inactiveStyle | - | style of text when inactive | true | initialIndex | 0 | initial tabbar index | false
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/appinio_animated_toggle_tab/analysis_options.yaml ================================================ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_animated_toggle_tab/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/appinio_animated_toggle_tab/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: ffb2ecea5223acdd139a5039be2f9c796962833d channel: stable project_type: app ================================================ FILE: packages/appinio_animated_toggle_tab/example/README.md ================================================ # example A new Flutter project. ## 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. ================================================ FILE: packages/appinio_animated_toggle_tab/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 30 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" minSdkVersion 16 targetSdkVersion 30 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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.3.50' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/appinio_animated_toggle_tab/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/.gitignore ================================================ *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Info.plist ================================================ 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 ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 = 1020; 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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 = 9.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)"; DEVELOPMENT_TEAM = 996DW24DKV; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.chenhui.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 = 9.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 = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; 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)"; DEVELOPMENT_TEAM = 996DW24DKV; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.chenhui.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)"; DEVELOPMENT_TEAM = 996DW24DKV; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.chenhui.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 */; } ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_animated_toggle_tab/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_animated_toggle_tab/example/lib/main.dart ================================================ import 'package:appinio_animated_toggle_tab/appinio_animated_toggle_tab.dart'; import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Animated Toggle Tab'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key, required this.title}) : super(key: key); final String title; @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { final Color kDarkBlueColor = const Color(0xFF053149); final BoxShadow kDefaultBoxshadow = const BoxShadow( color: Color(0xFFDFDFDF), spreadRadius: 1, blurRadius: 10, offset: Offset(2, 2), ); int currentIndex = 0; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( backgroundColor: kDarkBlueColor, title: Text(widget.title), ), body: Center( child: Column( children: [ const SizedBox( height: 200, ), AppinioAnimatedToggleTab( duration: const Duration(milliseconds: 150), offset: 0, callback: (int index) { setState(() { currentIndex = index; }); }, tabTexts: const [ 'make', 'your', 'tabs :)', ], height: 40, width: 300, boxDecoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(5), boxShadow: [ kDefaultBoxshadow, ], ), animatedBoxDecoration: BoxDecoration( boxShadow: [ BoxShadow( color: const Color(0xFFc3d2db).withOpacity(0.1), spreadRadius: 1, blurRadius: 5, offset: const Offset(2, 2), ), ], color: kDarkBlueColor, borderRadius: const BorderRadius.all( Radius.circular(5), ), border: Border.all( color: Colors.grey, width: 1, ), ), activeStyle: const TextStyle( fontSize: 16, color: Colors.white, fontWeight: FontWeight.w600, ), inactiveStyle: const TextStyle( fontSize: 16, color: Colors.black, fontWeight: FontWeight.w400, ), ), const SizedBox( height: 70, ), Text( 'Current Index: $currentIndex', style: TextStyle( fontSize: 20, color: kDarkBlueColor, ), ), ], ), ), ); } } ================================================ FILE: packages/appinio_animated_toggle_tab/example/pubspec.yaml ================================================ name: example description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # 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: ">=2.12.0 <3.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter appinio_animated_toggle_tab: path: ../ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^1.0.0 # 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. 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 # 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 ================================================ FILE: packages/appinio_animated_toggle_tab/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility that Flutter provides. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/appinio_animated_toggle_tab/example/web/index.html ================================================ example ================================================ FILE: packages/appinio_animated_toggle_tab/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/appinio_animated_toggle_tab/lib/appinio_animated_toggle_tab.dart ================================================ library appinio_animated_toggle_tab; import 'package:flutter/material.dart'; class AppinioAnimatedToggleTab extends StatefulWidget { /// function(int) for call back and control the view of tabs final Function(int) callback; /// a list of texts displayed on the tabs final List tabTexts; /// style of text when active final TextStyle activeStyle; /// style of text when inactive final TextStyle inactiveStyle; /// height of the tab final double height; /// decoration of the tab final BoxDecoration boxDecoration; /// the decoration of animated box used to toggle final BoxDecoration animatedBoxDecoration; /// width of the tab final double width; /// offset of the area to toggle final double offset; /// animation duration for the toggling final Duration duration; final int initialIndex; const AppinioAnimatedToggleTab({ Key? key, required this.callback, required this.tabTexts, required this.height, required this.boxDecoration, required this.animatedBoxDecoration, required this.activeStyle, required this.inactiveStyle, required this.width, this.offset = 0.02, this.duration = const Duration(milliseconds: 300), this.initialIndex = 0, }) : super(key: key); @override State createState() => _AppinioAnimatedToggleTabState(); } class _AppinioAnimatedToggleTabState extends State { late int index; _AppinioAnimatedToggleTabState() : super(); @override void initState() { super.initState(); index = widget.initialIndex; } @override Widget build(BuildContext context) { return Container( height: widget.height, width: widget.width, decoration: widget.boxDecoration, child: Stack(children: [ AnimatedAlign( alignment: Alignment( (index / (widget.tabTexts.length - 1) * (2 - 2 * widget.offset)) - 1 + widget.offset, 0), duration: widget.duration, child: Container( width: (widget.width / widget.tabTexts.length), height: widget.height * 0.9, decoration: widget.animatedBoxDecoration, ), ), Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ for (int i = 0; i < widget.tabTexts.length; i++) _buildSwitchTab( i == index, widget.tabTexts[i], i == index ? widget.activeStyle : widget.inactiveStyle, i, ), ], ), ]), ); } /// building and returning one item of the tab Widget _buildSwitchTab( bool isLeft, String title, TextStyle style, int i, ) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () { setState(() { index = i; widget.callback(i); }); }, child: Expanded( child: Container( alignment: Alignment.center, width: widget.width / widget.tabTexts.length, height: widget.height, child: Text( title, textAlign: TextAlign.center, style: style, )), ), ); } } ================================================ FILE: packages/appinio_animated_toggle_tab/pubspec.yaml ================================================ name: appinio_animated_toggle_tab description: A custom tab viewer with built-in animation and different design from default `TabViewer`. version: 1.0.3 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/appinio_animated_toggle_tab environment: sdk: ">=2.12.0 <4.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 # 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. 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.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/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.dev/custom-fonts/#from-packages ================================================ FILE: packages/appinio_social_share/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. /pubspec.lock **/doc/api/ .dart_tool/ .packages build/ ================================================ FILE: packages/appinio_social_share/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled. version: revision: f1875d570e39de09040c8f79aa13cc56baab8db1 channel: stable project_type: plugin # Tracks metadata for the flutter migrate command migration: platforms: - platform: root create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: android create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: ios create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 # User provided section # List of Local paths (relative to this file) that should be # ignored by the migrate tool. # # Files that are not part of the templates will be ignored by default. unmanaged_files: - 'lib/main.dart' - 'ios/Runner.xcodeproj/project.pbxproj' ================================================ FILE: packages/appinio_social_share/CHANGELOG.md ================================================ ## [0.3.2] - 2024.08.01 * Many bug fixes and improvements. * Version upgrades for dependencies. ## [0.3.1] - 2024.04.15 * Many bug fixes and improvements. * Refactoring: - Now you will have to choose platform while sharing. - For example: AppinioSocialShare().android.shareToWhatsapp(message, file) ## [0.3.0] - 2023.12.21 * Enhancement: - Facebook Android Sdk updated to 16.0.0. * Features: - Now you can share multiple files to whatsapp, telegram, facebook and other apps. ## [0.2.6] - 2023.09.25 * Enhancements: - Updating FB SDK to 16.1.3 ## [0.2.5] - 2023.08.23 * Bug Fix: - Bug fixes in facebook story sharing ## [0.2.4] - 2023.06.19 * Bug Fix: - share to instagram story not working. ## [0.2.3] - 2023.05.31 * Bug Fix: - System sheet crashing for iOS on sharing text without file. ## [0.2.2] - 2023.04.27 * Enhancements: - Updating Readme. ## [0.2.1] - 2023.03.13 * Enhancements: - updating FB SDK to 15.1.0 ## [0.2.0] - 2022.11.08 * Features: - Adding support to share to Instagram Feed-Posts & Reels. - Adding support to share to TikTok Status. ## [0.1.4] - 2022.10.18 * Enhancements: - removing unnecessary twitter SDK. ## [0.1.3] - 2022.10.13 * Enhancements: - updating FB SDK to 14.1.0 ## [0.1.2] - 2022.10.06 * Enhancements: - allowing to share background image to facebook story without having to share a sticker image. ## [0.1.1] - 2022.09.27 * Features: - adding Facebook Lite and Messenger Lite apps support. ## [0.1.0] - 2022.09.25 * Initial version. ================================================ FILE: packages/appinio_social_share/LICENSE ================================================ MIT License Copyright (c) 2022 APPINIO GmbH 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. ================================================ FILE: packages/appinio_social_share/README.md ================================================ ```appinio_social_share``` supports sharing files to social media (Facebook, Instagram, Instagram Story, Messenger, Telegram, WhatsApp, Twitter, Tiktok, SMS, System, etc.). If you want to share text, file, image, text with image or text with files then this plugin is all you need.
## Top Sharing Features - Facebook Post - Facebook Stories - Instagram Chat - Instgaram Feed - Instgaram Reel - Instagram Stories - Messenger - Telegram - WhatsApp - Twitter - Tiktok Status - Tiktok video - SMS - System ShareSheet - Copy to clipboard - Check if these apps are installed ## Some Example Previews #Android #iOS **Simply use AppinioSocialShare class and call the method of which platform you want to share. ## Android Paste the following attribute in the manifest tag in the AndroidManifest.xml ```xml ``` For example: ```xml ``` Add these permissions and queries to your AndroidManifest.xml ```xml ``` ## NOTE: MANAGE_EXTERNAL_STORAGE requires additional permissions from google. So do not add it if you are not planning to access external storage. Check this for more info. https://support.google.com/googleplay/android-developer/answer/10467955?hl=en Create xml folder and add a provider path file to it (for example: provider_paths_app.xml) in android/app/src/main/res and add the lines below to the created xml file ```xml ``` After created your own file provider and define your own path paste them into this and add to your AndroidManifest.xml ```xml ``` ### Facebook app register + In /android/app/src/main/values folder create a strings.xml file and add your facebook app id and facebook client token. + To get the facebook client token: Open your app on Meta for developer ([link](https://developers.facebook.com)) > Settings > Advanced > Security > Application code + To get the facebook app id follow the Meta link above and go to your app Settings > Basic information > App ID ```xml [facebook_app_id] [facebook_client_token] ``` + Add this inside the application tag in android manifest. ```xml ``` + After complete the step above add these xml tags to your AndroidManifest.xml ## iOS ***Open Xcode and change your deployment target to iOS 11*** Add these lines to your Info.plist file ```xml CFBundleURLTypes CFBundleURLSchemes fb[your_facebook_app_id] LSApplicationQueriesSchemes instagram fb fbauth2 fbshareextension fbapi facebook-reels facebook-stories fb-messenger-share-api fb-messenger tg whatsapp twitter NSPhotoLibraryUsageDescription $(PRODUCT_NAME) needs permission to access photos and videos on your device NSMicrophoneUsageDescription $(PRODUCT_NAME) does not require access to the microphone. NSCameraUsageDescription $(PRODUCT_NAME) requires access to the camera. NSAppleMusicUsageDescription $(PRODUCT_NAME) requires access to play music FacebookAppID [your_facebook_app_id] FacebookClientToken [your_facebook_client_token] FacebookDisplayName [your_facebook_app_display_name] NSBonjourServices _dartobservatory._tcp ``` ***The facebook app id and facebook client token you can get by complete the steps mentioned on Android config*** Add these lines to the AppDelegate.swift file ``` import FBSDKCoreKit // Put these lines in the application function FBSDKCoreKit.ApplicationDelegate.shared.application( application, didFinishLaunchingWithOptions: launchOptions ) ```
***If you want to share files to tiktok (iOS), you can follow the steps below. For sharing to android you don't need these steps.*** Step 1 - Install Tiktok Sdk ``` Add the library to your XCode project as a Swift Package: 1- In XCode, click File -> Add Packages... 2- Paste the repository URL: https://github.com/tiktok/tiktok-opensdk-ios 3- Select Dependency Rule -> Up to Next Major Version and input the major version you want (i.e. 2.2.0 You can find the latest release here.) 4- Select Add to Project -> Your project 5- Click Copy Dependency and select the TikTokOpenShareSDK, TiktokOpenCoreSdk libraries. ``` Step 2 - Configure your project -Configure your Xcode project -Open your Info.plist file and add or update the following key-value pairs: -Add the following values to LSApplicationQueriesSchemes: 1. tiktokopensdk for Login Kit. 2. tiktoksharesdk for Share Kit. 3. snssdk1233 and snssdk1180 to check if TikTok is installed on your device. 4. Add TikTokClientKey key with your app's client key, obtained from the TikTok for Developers website, as the value. 5. Add your app's client key to CFBundleURLSchemes. ```plist LSApplicationQueriesSchemes tiktokopensdk tiktoksharesdk snssdk1180 snssdk1233 TikTokClientKey $TikTokClientKey CFBundleURLTypes CFBundleURLSchemes $TikTokClientKey ``` Step 3 - Add the following code to your app's AppDelegate: ```swift import UIKit import Flutter import TikTokOpenSDKCore import TikTokOpenShareSDK import Foundation import Photos @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { let cntrl : FlutterViewController = self.window?.rootViewController as! FlutterViewController let tiktok_channel = FlutterMethodChannel(name: "appinio_social_share_tiktok", binaryMessenger: cntrl.binaryMessenger) tiktok_channel.setMethodCallHandler( { (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in if call.method == "tiktok_post" { let args = call.arguments as? [String: Any?] self.shareVideoToTiktok(args: args!, result: result) }else{ result("Not implemented!") } }) GeneratedPluginRegistrant.register(with: self) if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate } return super.application(application, didFinishLaunchingWithOptions: launchOptions) } override func application(_ app: UIApplication,open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { if (TikTokURLHandler.handleOpenURL(url)) { return true } return false } override func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if (TikTokURLHandler.handleOpenURL(userActivity.webpageURL)) { return true } return false } func shareVideoToTiktok(args : [String: Any?],result: @escaping FlutterResult) { let videoFile = args["videoFile"] as? String let redirectUrl = args["redirectUrl"] as? String let fileType = args["fileType"] as? String let videoData = try? Data(contentsOf: URL(fileURLWithPath: videoFile!)) as NSData PHPhotoLibrary.shared().performChanges({ let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]; let filePath = "\(documentsPath)/\(Date().description)" + (fileType == "image" ? ".jpeg" : ".mp4") videoData!.write(toFile: filePath, atomically: true) if fileType == "image" { PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: URL(fileURLWithPath: filePath)) }else { PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: filePath)) } }, completionHandler: { success, error in if success { let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let fetchResult = PHAsset.fetchAssets(with: fileType == "image" ? .image : .video, options: fetchOptions) if let lastAsset = fetchResult.firstObject { let localIdentifier = lastAsset.localIdentifier let shareRequest = TikTokShareRequest(localIdentifiers: [localIdentifier], mediaType: fileType == "image" ? .image : .video, redirectURI: redirectUrl!) shareRequest.shareFormat = .normal DispatchQueue.main.async { shareRequest.send() result("success") } } } else if let error = error { print(error.localizedDescription) } else { result("Error getting the files!") } }) } } private func registerPlugins(registry: FlutterPluginRegistry) { } ``` Step 3 - Create a tiktok app on tiktok [developer portal] (https://developers.tiktok.com/apps/) and get a client key and add it in info.plist acc to step 2. Obtain the [client_key](https://developers.tiktok.com/apps/) located in the Appdetails section of your app on the TikTok for Developers website. Then add Share Kit to your app by navigating to the Manage apps page, and clicking + Add products. Screenshot 2023-12-06 at 09 55 38 Your app must have access to the user's photo library to successfully share videos to TikTok. Done ✅ - Now shareToTiktokPost will start working for IOS as well. ## Usage ```dart class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State createState() => _MyAppState(); } class _MyAppState extends State { AppinioSocialShare appinioSocialShare = AppinioSocialShare(); @override Widget build(BuildContext context) { return MaterialApp( title: "Share Feature", home: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( child: const Text("ShareToWhatsapp"), onPressed: () async { FilePickerResult? result = await FilePicker.platform .pickFiles(type: FileType.image, allowMultiple: false); if (result != null && result.paths.isNotEmpty) { shareToWhatsApp( "message", result.paths[0]!); } }, ), ], ), )); } shareToWhatsApp(String message, String filePath) async { await appinioSocialShare.android.shareToSMS(message, filePath); } } ```
| Method | iOS | Android | Parameters | Description |:-------------|:-------------:|:-------:|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:------------- | getInstalledApps |✔️| ✔️ | - | Get a Map of all the apps with a boolean value. | shareToWhatsapp |✔️| ✔️ | String message, {List? filePaths} | Share Image and text to Whatsapp. For Ios only text works. | shareToTelegram |✔️| ✔️ | String message, {List? filePaths} | Share Image and text to Telegram. For Ios only text works. | shareToInstagramDirect |✔️| ✔️ | String message | Share text message to Instagram. | shareToInstagramFeed |✔️| ✔️ | List imagePaths | Share image to Instagram feed. | shareToInstagramReel |✔️| ✔️ | List videoPaths | Share video to Instagram Reel. | shareToInstagramStory |✔️| ✔️ | String facebookAppId, String stickerImage,{String? backgroundImage,String? backgroundVideo, String? backgroundTopColor,String? backgroundBottomColor,String? attributionURL} | Share background image, movable sticker, background colors to Instagram Story. | shareToFacebook |✔️| ✔️ | String message, List filePaths | Share text hashtag and image to Facebook. | shareToFacebookStory |✔️| ✔️ | String stickerImage,String appId,{String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL} | Share background image, movable sticker, background colors to Facebook Story. | shareToMessenger |✔️| ✔️ | String message | Share text message to Messenger. | shareToTiktokStatus |❌ | ✔️ | List filePaths | ShaShare image to Tiktok Story. | shareToTiktokPost |❌ | ✔️ | String videoPath | Share video to tiktok. | shareToTwitter | ✔️ | ✔️ | String message, {List? filePaths} | Share Image and text to Twitter. | shareToSMS |✔️| ✔️ | String message, {List? filePaths} | Share Image and text to default sms app. | copyToClipBoard |✔️| ✔️ | String message | To Copy text to clipboard. | shareToSystem |✔️| ✔️ | String title,String message, {List? filePaths} | Open default System sheet, to share text and image. | shareImageToWhatsApp |✔️| ❌ | String filePaths | Share image to whatsapp
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/appinio_social_share/analysis_options.yaml ================================================ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_social_share/android/.gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures .cxx ================================================ FILE: packages/appinio_social_share/android/build.gradle ================================================ group 'com.appinio.socialshare.appinio_social_share' version '1.0' buildscript { repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' } } rootProject.allprojects { repositories { google() mavenCentral() } } apply plugin: 'com.android.library' android { if (project.android.hasProperty("namespace")) { namespace 'com.appinio.socialshare.appinio_social_share' } compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion 16 } } dependencies { implementation 'com.facebook.android:facebook-share:17.0.0' } ================================================ FILE: packages/appinio_social_share/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: packages/appinio_social_share/android/gradlew ================================================ #!/bin/sh # # Copyright © 2015-2021 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ############################################################################## # # Gradle start up script for POSIX generated by Gradle. # # Important for running: # # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is # noncompliant, but you have some other compliant shell such as ksh or # bash, then to run this script, type that shell name before the whole # command line, like: # # ksh Gradle # # Busybox and similar reduced shells will NOT work, because this script # requires all of these POSIX shell features: # * functions; # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», # «${var#prefix}», «${var%suffix}», and «$( cmd )»; # * compound commands having a testable exit status, especially «case»; # * various built-in commands including «command», «set», and «ulimit». # # Important for patching: # # (2) This script targets any POSIX shell, so it avoids extensions provided # by Bash, Ksh, etc; in particular arrays are avoided. # # The "traditional" practice of packing multiple parameters into a # space-separated string is a well documented source of bugs and security # problems, so this is (mostly) avoided, by progressively accumulating # options in "$@", and eventually passing that to Java. # # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; # see the in-line comments for details. # # There are tweaks for specific operating systems such as AIX, CygWin, # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. # ############################################################################## # Attempt to set APP_HOME # Resolve links: $0 may be a link app_path=$0 # Need this for daisy-chained symlinks. while APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path [ -h "$app_path" ] do ls=$( ls -ld "$app_path" ) link=${ls#*' -> '} case $link in #( /*) app_path=$link ;; #( *) app_path=$APP_HOME$link ;; esac done # This is normally unused # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum warn () { echo "$*" } >&2 die () { echo echo "$*" echo exit 1 } >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false case "$( uname )" in #( CYGWIN* ) cygwin=true ;; #( Darwin* ) darwin=true ;; #( MSYS* | MINGW* ) msys=true ;; #( NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD=$JAVA_HOME/jre/sh/java else JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else JAVACMD=java if ! command -v java >/dev/null 2>&1 then die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac fi # Collect all arguments for the java command, stacking in reverse order: # * args from the command line # * the main class name # * -classpath # * -D...appname settings # * --module-path (only if needed) # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) # Now convert the arguments - kludge to limit ourselves to /bin/sh for arg do if case $arg in #( -*) false ;; # don't mess with options #( /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath [ -e "$t" ] ;; #( *) false ;; esac then arg=$( cygpath --path --ignore --mixed "$arg" ) fi # Roll the args list around exactly as many times as the number of # args, so each arg winds up back in the position where it started, but # possibly modified. # # NB: a `for` loop captures its iteration list before it begins, so # changing the positional parameters here affects neither the number of # iterations, nor the values presented in `arg`. shift # remove old arg set -- "$@" "$arg" # push replacement arg done fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ org.gradle.wrapper.GradleWrapperMain \ "$@" # Stop when "xargs" is not available. if ! command -v xargs >/dev/null 2>&1 then die "xargs is not available" fi # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. # # In Bash we could simply go: # # readarray ARGS < <( xargs -n1 <<<"$var" ) && # set -- "${ARGS[@]}" "$@" # # but POSIX shell has neither arrays nor command substitution, so instead we # post-process each arg (as a line of input to sed) to backslash-escape any # character that might be a shell metacharacter, then use eval to reverse # that process (while maintaining the separation between arguments), and wrap # the whole thing up as a single "set" statement. # # This will of course break if any of these variables contains a newline or # an unmatched quote. # eval "set -- $( printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | xargs -n1 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | tr '\n' ' ' )" '"$@"' exec "$JAVACMD" "$@" ================================================ FILE: packages/appinio_social_share/android/gradlew.bat ================================================ @rem @rem Copyright 2015 the original author or authors. @rem @rem Licensed under the Apache License, Version 2.0 (the "License"); @rem you may not use this file except in compliance with the License. @rem You may obtain a copy of the License at @rem @rem https://www.apache.org/licenses/LICENSE-2.0 @rem @rem Unless required by applicable law or agreed to in writing, software @rem distributed under the License is distributed on an "AS IS" BASIS, @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @rem See the License for the specific language governing permissions and @rem limitations under the License. @rem @if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @rem @rem ########################################################################## @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @rem Resolve any "." and ".." in APP_HOME to make it shorter. for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo. echo Please set the JAVA_HOME variable in your environment to match the echo location of your Java installation. goto fail :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! set EXIT_CODE=%ERRORLEVEL% if %EXIT_CODE% equ 0 set EXIT_CODE=1 if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal :omega ================================================ FILE: packages/appinio_social_share/android/settings.gradle ================================================ rootProject.name = 'appinio_social_share' ================================================ FILE: packages/appinio_social_share/android/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_social_share/android/src/main/java/com/appinio/socialshare/appinio_social_share/AppinioSocialSharePlugin.java ================================================ package com.appinio.socialshare.appinio_social_share; import android.app.Activity; import android.content.Context; import android.util.Log; import androidx.annotation.NonNull; import com.appinio.socialshare.appinio_social_share.utils.SocialShareUtil; import java.util.ArrayList; import java.util.Map; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; /** * AppinioSocialSharePlugin */ public class AppinioSocialSharePlugin implements FlutterPlugin, MethodCallHandler, ActivityAware { private final String INSTALLED_APPS = "installed_apps"; private final String INSTAGRAM_DIRECT = "instagram_direct"; private final String INSTAGRAM_FEED = "instagram_post"; private final String INSTAGRAM_FEED_FILES = "instagram_post_files"; private final String INSTAGRAM_STORIES = "instagram_stories"; private final String FACEBOOK = "facebook"; private final String MESSENGER = "messenger"; private final String FACEBOOK_STORIES = "facebook_stories"; private final String WHATSAPP_ANDROID = "whatsapp_android"; private final String WHATSAPP_ANDROID_MULTIFILES = "whatsapp_android_multifiles"; private final String TWITTER_ANDROID = "twitter_android"; private final String TWITTER_ANDROID_MULTIFILES = "twitter_android_multifiles"; private final String SMS_ANDROID = "sms_android"; private final String SMS_ANDROID_MULTIFILES = "sms_android_multifiles"; private final String TIKTOK = "tiktok_status"; private final String SYSTEM_SHARE_ANDROID = "system_share_android"; private final String SYSTEM_SHARE_ANDROID_MULTIFILES = "system_share_android_multifiles"; private final String COPY_TO_CLIPBOARD = "copy_to_clipboard"; private final String TELEGRAM_ANDROID = "telegram_android"; private final String TELEGRAM_ANDROID_MULTIFILES = "telegram_android_multifiles"; private SocialShareUtil socialShareUtil; private MethodChannel channel; private Activity activity; private Context activeContext; private Context context; @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { context = flutterPluginBinding.getApplicationContext(); channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "appinio_social_share"); channel.setMethodCallHandler(this); socialShareUtil = new SocialShareUtil(); } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { try { String response = decideApp(call, result); if (response != null) { result.success(response); } } catch (Exception e) { Log.d("error", e.getLocalizedMessage()); result.success(e.getLocalizedMessage()); } } public String decideApp(@NonNull MethodCall call, @NonNull Result result) { activeContext = (activity != null) ? activity.getApplicationContext() : context; String title = call.argument("title"); String message = call.argument("message"); String appId = call.argument("appId"); ArrayList imagePaths = call.argument("imagePaths"); String stickerImage = call.argument("stickerImage"); String imagePath = call.argument("imagePath"); String attributionURL = call.argument("attributionURL"); String backgroundImage = call.argument("backgroundImage"); String backgroundTopColor = call.argument("backgroundTopColor"); String backgroundBottomColor = call.argument("backgroundBottomColor"); switch (call.method) { case INSTALLED_APPS: Map response = socialShareUtil.getInstalledApps(activeContext); result.success(response); return null; case INSTAGRAM_DIRECT: return socialShareUtil.shareToInstagramDirect(message, activeContext); case INSTAGRAM_FEED: return socialShareUtil.shareToInstagramFeed(imagePath, message, activeContext, message); case INSTAGRAM_FEED_FILES: return socialShareUtil.shareToInstagramFeedFiles(imagePaths, activeContext,message); case INSTAGRAM_STORIES: return socialShareUtil.shareToInstagramStory(appId, stickerImage, backgroundImage, backgroundTopColor, backgroundBottomColor, attributionURL, activeContext); case FACEBOOK_STORIES: return socialShareUtil.shareToFaceBookStory(appId, stickerImage, backgroundImage, backgroundTopColor, backgroundBottomColor, attributionURL, activeContext); case MESSENGER: return socialShareUtil.shareToMessenger(message, activeContext); case FACEBOOK: if (activity == null) return SocialShareUtil.UNKNOWN_ERROR; socialShareUtil.shareToFacebook(imagePaths, message, activity, result); return null; case WHATSAPP_ANDROID: return socialShareUtil.shareToWhatsApp(imagePath, message, activeContext); case WHATSAPP_ANDROID_MULTIFILES: return socialShareUtil.shareToWhatsAppFiles(imagePaths, activeContext); case TELEGRAM_ANDROID: return socialShareUtil.shareToTelegram(imagePath, activeContext, message); case TELEGRAM_ANDROID_MULTIFILES: return socialShareUtil.shareToTelegramFiles(imagePaths, activeContext); case TWITTER_ANDROID: return socialShareUtil.shareToTwitter(imagePath, activeContext, message); case TWITTER_ANDROID_MULTIFILES: return socialShareUtil.shareToTwitterFiles(imagePaths, activeContext); case COPY_TO_CLIPBOARD: return socialShareUtil.copyToClipBoard(message, activeContext); case SYSTEM_SHARE_ANDROID: return socialShareUtil.shareToSystem(title, message, imagePath, title, context); case SYSTEM_SHARE_ANDROID_MULTIFILES: return socialShareUtil.shareToSystemFiles(title, imagePaths, title, context); case TIKTOK: return socialShareUtil.shareToTikTok(imagePaths, activeContext); case SMS_ANDROID: return socialShareUtil.shareToSMS(message, activeContext, imagePath); case SMS_ANDROID_MULTIFILES: return socialShareUtil.shareToSMSFiles(activeContext, imagePaths); default: return null; } } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { channel.setMethodCallHandler(null); } @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { activity = binding.getActivity(); } @Override public void onDetachedFromActivityForConfigChanges() { activity = null; } @Override public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { activity = binding.getActivity(); } @Override public void onDetachedFromActivity() { activity = null; } } ================================================ FILE: packages/appinio_social_share/android/src/main/java/com/appinio/socialshare/appinio_social_share/utils/SocialShareUtil.java ================================================ package com.appinio.socialshare.appinio_social_share.utils; import android.app.Activity; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.provider.Settings; import android.provider.Telephony; import androidx.core.content.FileProvider; import com.facebook.CallbackManager; import com.facebook.FacebookCallback; import com.facebook.FacebookException; import com.facebook.FacebookSdk; import com.facebook.share.Sharer; import com.facebook.share.model.ShareHashtag; import com.facebook.share.model.SharePhoto; import com.facebook.share.model.SharePhotoContent; import com.facebook.share.widget.ShareDialog; import java.io.File; import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import io.flutter.Log; import io.flutter.plugin.common.MethodChannel; public class SocialShareUtil { public static final String ERROR_APP_NOT_AVAILABLE = "ERROR_APP_NOT_AVAILABLE"; public static final String ERROR_CANCELLED = "error : cancelled"; public static final String UNKNOWN_ERROR = "unknown error"; public static final String SUCCESS = "SUCCESS"; //packages private final String INSTAGRAM_PACKAGE = "com.instagram.android"; private final String TWITTER_PACKAGE = "com.twitter.android"; private final String INSTAGRAM_STORY_PACKAGE = "com.instagram.share.ADD_TO_STORY"; private final String INSTAGRAM_FEED_PACKAGE = "com.instagram.share.ADD_TO_FEED"; private final String WHATSAPP_PACKAGE = "com.whatsapp"; private final String TELEGRAM_PACKAGE = "org.telegram.messenger"; private final String TIKTOK_PACKAGE = "com.zhiliaoapp.musically"; private final String FACEBOOK_STORY_PACKAGE = "com.facebook.stories.ADD_TO_STORY"; private final String FACEBOOK_PACKAGE = "com.facebook.katana"; private final String FACEBOOK_LITE_PACKAGE = "com.facebook.lite"; private final String FACEBOOK_MESSENGER_PACKAGE = "com.facebook.orca"; private final String FACEBOOK_MESSENGER_LITE_PACKAGE = "com.facebook.mlite"; private final String SMS_DEFAULT_APPLICATION = "sms_default_application"; private static CallbackManager callbackManager; public String shareToWhatsApp(String imagePath, String msg, Context context) { return shareFileAndTextToPackage(imagePath, msg, context, WHATSAPP_PACKAGE); } public String shareToWhatsAppFiles(ArrayList imagePaths, Context context) { return shareFilesToPackage(imagePaths, context, WHATSAPP_PACKAGE); } public String shareToInstagramDirect(String text, Context activity) { return shareTextToPackage(text, activity, INSTAGRAM_PACKAGE); } public String shareToInstagramFeed(String imagePath, String message, Context activity, String text) { return shareFileAndTextToPackage(imagePath, text, activity, INSTAGRAM_PACKAGE); } public String shareToInstagramFeedFiles(ArrayList imagePaths, Context activity, String text) { return shareFilesToPackage(imagePaths, activity, INSTAGRAM_PACKAGE); } public String shareToTikTok(ArrayList imagePaths, Context activity) { return shareFilesToPackage(imagePaths, activity, TIKTOK_PACKAGE); } public String shareToTwitter(String imagePath, Context activity, String text) { return shareFileAndTextToPackage(imagePath, text, activity, TWITTER_PACKAGE); } public String shareToTwitterFiles(ArrayList imagePaths, Context activity) { return shareFilesToPackage(imagePaths, activity, TWITTER_PACKAGE); } public String shareToTelegram(String imagePath, Context activity, String text) { return shareFileAndTextToPackage(imagePath, text, activity, TELEGRAM_PACKAGE); } public String shareToTelegramFiles(ArrayList imagePaths, Context activity) { return shareFilesToPackage(imagePaths, activity, TELEGRAM_PACKAGE); } public String shareToMessenger(String text, Context activity) { Map apps = getInstalledApps(activity); String packageName; if (apps.get("messenger")) { packageName = FACEBOOK_MESSENGER_PACKAGE; } else if (apps.get("messenger-lite")) { packageName = FACEBOOK_MESSENGER_LITE_PACKAGE; } else { return ERROR_APP_NOT_AVAILABLE; } return shareTextToPackage(text, activity, packageName); } public String copyToClipBoard(String content, Context activity) { try { ClipboardManager clipboard = (ClipboardManager) activity.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("", content); clipboard.setPrimaryClip(clip); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } public String shareToSMS(String content, Context activity, String imagePath) { String defaultApplication; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { defaultApplication = Telephony.Sms.getDefaultSmsPackage(activity); } else { defaultApplication = Settings.Secure.getString(activity.getContentResolver(), SMS_DEFAULT_APPLICATION); } return shareFileAndTextToPackage(imagePath, content, activity, defaultApplication); } public String shareToSMSFiles( Context activity, ArrayList imagePaths) { String defaultApplication; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { defaultApplication = Telephony.Sms.getDefaultSmsPackage(activity); } else { defaultApplication = Settings.Secure.getString(activity.getContentResolver(), SMS_DEFAULT_APPLICATION); } return shareFilesToPackage(imagePaths, activity, defaultApplication); } public String shareToSystemFiles(String title, ArrayList filePaths, String chooserTitle, Context activity) { try { if (filePaths == null || filePaths.isEmpty()) return "No files to share"; Intent intent = new Intent(); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_SEND_MULTIPLE); ArrayList files = new ArrayList(); for (int i = 0; i < filePaths.size(); i++) { Uri fileUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(filePaths.get(i))); files.add(fileUri); } intent.setType(getMimeTypeOfFile(filePaths.get(0))); intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files); intent.putExtra(Intent.EXTRA_SUBJECT, title); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Intent chooserIntent = Intent.createChooser(intent, chooserTitle); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); chooserIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(chooserIntent); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } public String shareToSystem(String title, String message, String filePath, String chooserTitle, Context activity) { try { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction(Intent.ACTION_SEND); if (filePath != null) { Uri fileUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(filePath)); intent.setType(getMimeTypeOfFile(filePath)); intent.putExtra(Intent.EXTRA_STREAM, fileUri); } else { intent.setType("text/plain"); } intent.putExtra(Intent.EXTRA_TEXT, message); intent.putExtra(Intent.EXTRA_SUBJECT, title); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); Intent chooserIntent = Intent.createChooser(intent, chooserTitle); chooserIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); chooserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); activity.startActivity(chooserIntent); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } public String shareToInstagramStory(String appId, String stickerImage, String backgroundImage, String backgroundTopColor, String backgroundBottomColor, String attributionURL, Context activity) { try { Intent shareIntent = new Intent(INSTAGRAM_STORY_PACKAGE); shareIntent.setType("image/*"); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (stickerImage != null) { File file = new File(stickerImage); Uri stickerImageUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", file); shareIntent.putExtra("interactive_asset_uri", stickerImageUri); activity.grantUriPermission("com.instagram.android", stickerImageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } if (backgroundImage != null) { File file1 = new File(backgroundImage); Uri backgroundImageUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", file1); shareIntent.setDataAndType(backgroundImageUri, getMimeTypeOfFile(backgroundImage)); activity.grantUriPermission("com.instagram.android", backgroundImageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } shareIntent.putExtra("source_application", appId); shareIntent.putExtra("content_url", attributionURL); shareIntent.putExtra("top_background_color", backgroundTopColor); shareIntent.putExtra("bottom_background_color", backgroundBottomColor); activity.startActivity(shareIntent); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } public void shareToFacebook(List filePaths, String text, Activity activity, MethodChannel.Result result) { FacebookSdk.fullyInitialize(); FacebookSdk.setApplicationId(getFacebookAppId(activity)); callbackManager = callbackManager == null ? CallbackManager.Factory.create() : callbackManager; ShareDialog shareDialog = new ShareDialog(activity); shareDialog.registerCallback(callbackManager, new FacebookCallback() { @Override public void onSuccess(Sharer.Result result1) { System.out.println("---------------onSuccess"); result.success(SUCCESS); } @Override public void onCancel() { result.success(ERROR_CANCELLED); } @Override public void onError(FacebookException error) { System.out.println("---------------onError"); result.success(error.getLocalizedMessage()); } }); List sharePhotos = new ArrayList<>(); for (int i = 0; i < filePaths.size(); i++) { Uri fileUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".provider", new File(filePaths.get(i))); sharePhotos.add(new SharePhoto.Builder().setImageUrl(fileUri).build()); } SharePhotoContent content = new SharePhotoContent.Builder() .setShareHashtag(new ShareHashtag.Builder().setHashtag(text).build()) .setPhotos(sharePhotos) .build(); if (ShareDialog.canShow(SharePhotoContent.class)) { shareDialog.show(content); } } public String shareToFaceBookStory(String appId, String stickerImage, String backgroundImage, String backgroundTopColor, String backgroundBottomColor, String attributionURL, Context activity) { try { Map apps = getInstalledApps(activity); String packageName; if (apps.get("facebook")) { packageName = FACEBOOK_PACKAGE; } else if (apps.get("facebook-lite")) { packageName = FACEBOOK_LITE_PACKAGE; } else { return ERROR_APP_NOT_AVAILABLE; } Intent intent = new Intent(FACEBOOK_STORY_PACKAGE); intent.setType("image/*"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra("com.facebook.platform.extra.APPLICATION_ID", appId); if (stickerImage != null) { File file = new File(stickerImage); Uri stickerImageFile = FileProvider.getUriForFile(activity, activity.getPackageName() + ".provider", file); intent.putExtra("interactive_asset_uri", stickerImageFile); activity.grantUriPermission(packageName, stickerImageFile, Intent.FLAG_GRANT_READ_URI_PERMISSION); } intent.putExtra("content_url", attributionURL); intent.putExtra("top_background_color", backgroundTopColor); intent.putExtra("bottom_background_color", backgroundBottomColor); if (backgroundImage != null) { File file1 = new File(backgroundImage); Uri backgroundImageUri = FileProvider.getUriForFile(activity, activity.getPackageName() + ".provider", file1); intent.setDataAndType(backgroundImageUri, getMimeTypeOfFile(backgroundImage)); activity.grantUriPermission(packageName, backgroundImageUri, Intent.FLAG_GRANT_READ_URI_PERMISSION); } activity.startActivity(intent); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } private String shareTextToPackage( String text, Context context, String packageName ) { try { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.putExtra(Intent.EXTRA_TEXT, text); intent.putExtra("content_url", text); intent.putExtra("source_application", context.getPackageName()); intent.putExtra(Intent.EXTRA_TITLE, text); intent.putExtra("com.facebook.platform.extra.APPLICATION_ID", getFacebookAppId(context)); intent.setPackage(packageName); context.startActivity(intent); return SUCCESS; } catch (Exception e) { return e.getLocalizedMessage(); } } private String shareFilesToPackage(List imagePaths, Context activity, String packageName) { if (imagePaths == null || imagePaths.isEmpty()) return "No files to share"; Intent shareIntent = new Intent(Intent.ACTION_SEND_MULTIPLE); ArrayList files = new ArrayList(); for (int i = 0; i < imagePaths.size(); i++) { Uri fileUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(imagePaths.get(i))); files.add(fileUri); } shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files); shareIntent.setType(getMimeTypeOfFile(imagePaths.get(0))); shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setPackage(packageName); // if (packageName.equals(INSTAGRAM_PACKAGE) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // shareIntent.setComponent(ComponentName.createRelative(packageName, "com.instagram.share.handleractivity.ShareHandlerActivity")); //open instagram feed // } try { activity.startActivity(shareIntent); return SUCCESS; } catch (Exception e) { e.printStackTrace(); return e.getLocalizedMessage(); } } private String shareFileAndTextToPackage(String imagePath, String message, Context activity, String packageName) { Intent shareIntent = new Intent(Intent.ACTION_SEND); if (imagePath != null) { Uri fileUri = FileProvider.getUriForFile(activity, activity.getApplicationContext().getPackageName() + ".provider", new File(imagePath)); shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri); shareIntent.setType(getMimeTypeOfFile(imagePath)); } else { shareIntent.setType("text/plain"); } shareIntent.putExtra(Intent.EXTRA_TEXT, message); shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.setPackage(packageName); if (packageName.equals(INSTAGRAM_PACKAGE) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { shareIntent.setComponent(ComponentName.createRelative(packageName, "com.instagram.share.handleractivity.ShareHandlerActivity")); //open instagram feed } try { activity.startActivity(shareIntent); return SUCCESS; } catch (Exception e) { e.printStackTrace(); return e.getLocalizedMessage(); } } public Map getInstalledApps(Context context) { Map appsMap = new HashMap(); appsMap.put("instagram", INSTAGRAM_PACKAGE); appsMap.put("facebook_stories", FACEBOOK_PACKAGE); appsMap.put("whatsapp", WHATSAPP_PACKAGE); appsMap.put("telegram", TELEGRAM_PACKAGE); appsMap.put("messenger", FACEBOOK_MESSENGER_PACKAGE); appsMap.put("messenger-lite", FACEBOOK_MESSENGER_LITE_PACKAGE); appsMap.put("facebook", FACEBOOK_PACKAGE); appsMap.put("facebook-lite", FACEBOOK_LITE_PACKAGE); appsMap.put("instagram_stories", INSTAGRAM_PACKAGE); appsMap.put("twitter", TWITTER_PACKAGE); appsMap.put("tiktok", TIKTOK_PACKAGE); Map apps = new HashMap(); PackageManager pm = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_SENDTO).addCategory(Intent.CATEGORY_DEFAULT); intent.setType("vnd.android-dir/mms-sms"); intent.setData(Uri.parse("sms:")); List resolvedActivities = pm.queryIntentActivities(intent, 0); apps.put("message", !resolvedActivities.isEmpty()); String[] appNames = {"instagram", "facebook_stories", "whatsapp", "telegram", "messenger", "facebook", "facebook-lite", "messenger-lite", "instagram_stories", "twitter", "tiktok"}; for (int i = 0; i < appNames.length; i++) { try { pm.getPackageInfo(appsMap.get(appNames[i]), PackageManager.GET_META_DATA); apps.put(appNames[i], true); } catch (Exception e) { apps.put(appNames[i], false); } } return apps; } private static String getMimeTypeOfFile(String pathName) { try { Path path; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { path = new File(pathName).toPath(); String mimeType = Files.probeContentType(path); return mimeType; } return "*/*"; } catch (Exception e) { return ""; } } String getFacebookAppId(Context activity) { String appId = ""; try { ApplicationInfo appInfo = activity.getPackageManager().getApplicationInfo( activity.getPackageName(), PackageManager.GET_META_DATA); Bundle metaData = appInfo.metaData; if (metaData != null) { appId = metaData.getString("com.facebook.sdk.ApplicationId"); Log.d("FB_APP_ID", appId); } } catch (PackageManager.NameNotFoundException e) { // Handle the exception if needed } return appId; } } ================================================ FILE: packages/appinio_social_share/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/appinio_social_share/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled. version: revision: f1875d570e39de09040c8f79aa13cc56baab8db1 channel: stable project_type: app # Tracks metadata for the flutter migrate command migration: platforms: - platform: root create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: android create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: ios create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: linux create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: macos create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: web create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: windows create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 # User provided section # List of Local paths (relative to this file) that should be # ignored by the migrate tool. # # Files that are not part of the templates will be ignored by default. unmanaged_files: - 'lib/main.dart' - 'ios/Runner.xcodeproj/project.pbxproj' ================================================ FILE: packages/appinio_social_share/example/README.md ================================================ # appinio_social_share_example Demonstrates how to use the appinio_social_share plugin. ## 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://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) For help getting started with Flutter development, view the [online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: packages/appinio_social_share/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_social_share/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/appinio_social_share/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { 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-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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/appinio_social_share/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_social_share/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' 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') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/appinio_social_share/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip ================================================ FILE: packages/appinio_social_share/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/appinio_social_share/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/appinio_social_share/example/ios/.gitignore ================================================ **/dgph *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/appinio_social_share/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/appinio_social_share/example/ios/Flutter/Debug.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/appinio_social_share/example/ios/Flutter/Release.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/appinio_social_share/example/ios/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.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 ================================================ FILE: packages/appinio_social_share/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName Example 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 ================================================ FILE: packages/appinio_social_share/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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 = 9.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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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 = 9.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 = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; 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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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 */; } ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_social_share/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_social_share/example/lib/main.dart ================================================ import 'package:file_picker/file_picker.dart'; import 'package:flutter/material.dart'; import 'package:appinio_social_share/appinio_social_share.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override State createState() => _MyAppState(); } class _MyAppState extends State { AppinioSocialShare appinioSocialShare = AppinioSocialShare(); @override Widget build(BuildContext context) { return MaterialApp( title: "Share Feature", home: Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( child: const Text("ShareToWhatsapp"), onPressed: () async { FilePickerResult? result = await FilePicker.platform .pickFiles(type: FileType.image, allowMultiple: false); if (result != null && result.paths.isNotEmpty) { shareToWhatsApp("message", result.paths[0]!); } }, ), ], ), )); } shareToWhatsApp(String message, String filePath) async { await appinioSocialShare.android.shareToSMS(message, filePath); } } ================================================ FILE: packages/appinio_social_share/example/linux/.gitignore ================================================ flutter/ephemeral ================================================ FILE: packages/appinio_social_share/example/linux/CMakeLists.txt ================================================ # Project-level configuration. cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "example") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "com.example.example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(SET CMP0063 NEW) # Load bundled libraries from the lib/ directory relative to the binary. set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") # Root filesystem for cross-building. if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() # Define build configuration options. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() # Compilation settings that should be applied to most targets. # # Be cautious about adding new options here, as plugins use this function by # default. In most cases, you should add new options to specific targets instead # of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") endfunction() # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") # Define the application target. To change its name, change BINARY_NAME above, # not the value here, or `flutter run` will no longer work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of # the default top-level location. set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ================================================ FILE: packages/appinio_social_share/example/linux/flutter/CMakeLists.txt ================================================ # This file controls Flutter-level build steps. It should not be edited. cmake_minimum_required(VERSION 3.10) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. # Serves the same purpose as list(TRANSFORM ... PREPEND ...), # which isn't available in 3.10. function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() # === Flutter Library === # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) # === Flutter tool backend === # _phony_ is a non-existent file to force this command to run every time, # since currently there's no way to get a full input/output list from the # flutter tool. add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ================================================ FILE: packages/appinio_social_share/example/linux/flutter/generated_plugin_registrant.cc ================================================ // // Generated file. Do not edit. // // clang-format off #include "generated_plugin_registrant.h" void fl_register_plugins(FlPluginRegistry* registry) { } ================================================ FILE: packages/appinio_social_share/example/linux/flutter/generated_plugin_registrant.h ================================================ // // Generated file. Do not edit. // // clang-format off #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ #include // Registers Flutter plugins. void fl_register_plugins(FlPluginRegistry* registry); #endif // GENERATED_PLUGIN_REGISTRANT_ ================================================ FILE: packages/appinio_social_share/example/linux/flutter/generated_plugins.cmake ================================================ # # Generated file, do not edit. # list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST ) set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) endforeach(ffi_plugin) ================================================ FILE: packages/appinio_social_share/example/linux/main.cc ================================================ #include "my_application.h" int main(int argc, char** argv) { g_autoptr(MyApplication) app = my_application_new(); return g_application_run(G_APPLICATION(app), argc, argv); } ================================================ FILE: packages/appinio_social_share/example/linux/my_application.cc ================================================ #include "my_application.h" #include #ifdef GDK_WINDOWING_X11 #include #endif #include "flutter/generated_plugin_registrant.h" struct _MyApplication { GtkApplication parent_instance; char** dart_entrypoint_arguments; }; G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) // Implements GApplication::activate. static void my_application_activate(GApplication* application) { MyApplication* self = MY_APPLICATION(application); GtkWindow* window = GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); // Use a header bar when running in GNOME as this is the common style used // by applications and is the setup most users will be using (e.g. Ubuntu // desktop). // If running on X and not using GNOME then just use a traditional title bar // in case the window manager does more exotic layout, e.g. tiling. // If running on Wayland assume the header bar will work (may need changing // if future cases occur). gboolean use_header_bar = TRUE; #ifdef GDK_WINDOWING_X11 GdkScreen* screen = gtk_window_get_screen(window); if (GDK_IS_X11_SCREEN(screen)) { const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); if (g_strcmp0(wm_name, "GNOME Shell") != 0) { use_header_bar = FALSE; } } #endif if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); gtk_header_bar_set_title(header_bar, "example"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { gtk_window_set_title(window, "example"); } gtk_window_set_default_size(window, 1280, 720); gtk_widget_show(GTK_WIDGET(window)); g_autoptr(FlDartProject) project = fl_dart_project_new(); fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); FlView* view = fl_view_new(project); gtk_widget_show(GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); fl_register_plugins(FL_PLUGIN_REGISTRY(view)); gtk_widget_grab_focus(GTK_WIDGET(view)); } // Implements GApplication::local_command_line. static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { MyApplication* self = MY_APPLICATION(application); // Strip out the first argument as it is the binary name. self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); g_autoptr(GError) error = nullptr; if (!g_application_register(application, nullptr, &error)) { g_warning("Failed to register: %s", error->message); *exit_status = 1; return TRUE; } g_application_activate(application); *exit_status = 0; return TRUE; } // Implements GObject::dispose. static void my_application_dispose(GObject* object) { MyApplication* self = MY_APPLICATION(object); g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); G_OBJECT_CLASS(my_application_parent_class)->dispose(object); } static void my_application_class_init(MyApplicationClass* klass) { G_APPLICATION_CLASS(klass)->activate = my_application_activate; G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; G_OBJECT_CLASS(klass)->dispose = my_application_dispose; } static void my_application_init(MyApplication* self) {} MyApplication* my_application_new() { return MY_APPLICATION(g_object_new(my_application_get_type(), "application-id", APPLICATION_ID, "flags", G_APPLICATION_NON_UNIQUE, nullptr)); } ================================================ FILE: packages/appinio_social_share/example/linux/my_application.h ================================================ #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ #include G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, GtkApplication) /** * my_application_new: * * Creates a new Flutter-based application. * * Returns: a new #MyApplication. */ MyApplication* my_application_new(); #endif // FLUTTER_MY_APPLICATION_H_ ================================================ FILE: packages/appinio_social_share/example/macos/.gitignore ================================================ # Flutter-related **/Flutter/ephemeral/ **/Pods/ # Xcode-related **/dgph **/xcuserdata/ ================================================ FILE: packages/appinio_social_share/example/macos/Flutter/Flutter-Debug.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" ================================================ FILE: packages/appinio_social_share/example/macos/Flutter/Flutter-Release.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "ephemeral/Flutter-Generated.xcconfig" ================================================ FILE: packages/appinio_social_share/example/macos/Flutter/GeneratedPluginRegistrant.swift ================================================ // // Generated file. Do not edit. // import FlutterMacOS import Foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { } ================================================ FILE: packages/appinio_social_share/example/macos/Podfile ================================================ platform :osx, '10.11' # 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 ================================================ FILE: packages/appinio_social_share/example/macos/Runner/AppDelegate.swift ================================================ import Cocoa import FlutterMacOS @NSApplicationMain class AppDelegate: FlutterAppDelegate { override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { return true } } ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Base.lproj/MainMenu.xib ================================================ ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Configs/AppInfo.xcconfig ================================================ // 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. ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Configs/Debug.xcconfig ================================================ #include "../../Flutter/Flutter-Debug.xcconfig" #include "Warnings.xcconfig" ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Configs/Release.xcconfig ================================================ #include "../../Flutter/Flutter-Release.xcconfig" #include "Warnings.xcconfig" ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Configs/Warnings.xcconfig ================================================ 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 ================================================ FILE: packages/appinio_social_share/example/macos/Runner/DebugProfile.entitlements ================================================ com.apple.security.app-sandbox com.apple.security.cs.allow-jit com.apple.security.network.server ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Info.plist ================================================ 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 ================================================ FILE: packages/appinio_social_share/example/macos/Runner/MainFlutterWindow.swift ================================================ 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() } } ================================================ FILE: packages/appinio_social_share/example/macos/Runner/Release.entitlements ================================================ com.apple.security.app-sandbox ================================================ FILE: packages/appinio_social_share/example/macos/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 51; objects = { /* Begin PBXAggregateTarget section */ 33CC111A2044C6BA0003C045 /* Flutter Assemble */ = { isa = PBXAggregateTarget; buildConfigurationList = 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */; buildPhases = ( 33CC111E2044C6BF0003C045 /* ShellScript */, ); dependencies = ( ); name = "Flutter Assemble"; productName = FLX; }; /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; /* 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 = ""; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 33CC10EA2044A3C60003C045 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); 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 */, ); 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 = ( ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 33CC10EC2044A3C60003C045 /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 33CC10E92044A3C60003C045 /* Sources */, 33CC10EA2044A3C60003C045 /* Frameworks */, 33CC10EB2044A3C60003C045 /* Resources */, 33CC110E2044A8840003C045 /* Bundle Framework */, 3399D490228B24CF009A79C7 /* ShellScript */, ); 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; 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"; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 33CC10E92044A3C60003C045 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */, 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */, 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; targetProxy = 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ 33CC10F42044A3C60003C045 /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( 33CC10F52044A3C60003C045 /* Base */, ); name = MainMenu.xib; path = Runner; sourceTree = ""; }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ 338D0CE9231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Profile; }; 338D0CEA231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; name = Profile; }; 338D0CEB231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Manual; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Profile; }; 33CC10F92044A3C60003C045 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; GCC_OPTIMIZATION_LEVEL = 0; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = macosx; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; }; name = Debug; }; 33CC10FA2044A3C60003C045 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CODE_SIGN_IDENTITY = "-"; COPY_PHASE_STRIP = NO; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; }; name = Release; }; 33CC10FC2044A3C60003C045 /* Debug */ = { isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/DebugProfile.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; }; name = Debug; }; 33CC10FD2044A3C60003C045 /* Release */ = { isa = XCBuildConfiguration; baseConfigurationReference = 33E5194F232828860026EE4D /* AppInfo.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; CODE_SIGN_ENTITLEMENTS = Runner/Release.entitlements; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", ); PROVISIONING_PROFILE_SPECIFIER = ""; SWIFT_VERSION = 5.0; }; name = Release; }; 33CC111C2044C6BA0003C045 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Manual; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; }; 33CC111D2044C6BA0003C045 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 33CC10F92044A3C60003C045 /* Debug */, 33CC10FA2044A3C60003C045 /* Release */, 338D0CE9231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( 33CC10FC2044A3C60003C045 /* Debug */, 33CC10FD2044A3C60003C045 /* Release */, 338D0CEA231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; 33CC111B2044C6BA0003C045 /* Build configuration list for PBXAggregateTarget "Flutter Assemble" */ = { isa = XCConfigurationList; buildConfigurations = ( 33CC111C2044C6BA0003C045 /* Debug */, 33CC111D2044C6BA0003C045 /* Release */, 338D0CEB231458BD00FA5F75 /* Profile */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; /* End XCConfigurationList section */ }; rootObject = 33CC10E52044A3C60003C045 /* Project object */; } ================================================ FILE: packages/appinio_social_share/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_social_share/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/appinio_social_share/example/macos/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_social_share/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_social_share/example/pubspec.yaml ================================================ name: appinio_social_share_example description: Demonstrates how to use the appinio_social_share plugin. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: sdk: ">=2.17.6 <3.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter file_picker: ^6.1.1 appinio_social_share: # When depending on this package from a real application you should use: # appinio_social_share: ^x.y.z # See https://dart.dev/tools/pub/dependencies#version-constraints # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 # 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: # 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 # 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 ================================================ FILE: packages/appinio_social_share/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility in the flutter_test package. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:appinio_social_share_example/main.dart'; void main() { testWidgets('Verify Platform version', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that platform version is retrieved. expect( find.byWidgetPredicate( (Widget widget) => widget is Text && widget.data!.startsWith('Running on:'), ), findsOneWidget, ); }); } ================================================ FILE: packages/appinio_social_share/example/web/index.html ================================================ example ================================================ FILE: packages/appinio_social_share/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/appinio_social_share/example/windows/.gitignore ================================================ flutter/ephemeral/ # Visual Studio user-specific files. *.suo *.user *.userosscache *.sln.docstates # Visual Studio build-related files. x64/ x86/ # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ ================================================ FILE: packages/appinio_social_share/example/windows/CMakeLists.txt ================================================ # Project-level configuration. cmake_minimum_required(VERSION 3.14) project(example LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(SET CMP0063 NEW) # Define build configuration option. 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() # Define settings for the Profile build mode. 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. # # Be cautious about adding new options here, as plugins use this function by # default. In most cases, you should add new options to specific targets instead # of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_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() # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build; see runner/CMakeLists.txt. 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) ================================================ FILE: packages/appinio_social_share/example/windows/flutter/CMakeLists.txt ================================================ # This file controls Flutter-level build steps. It should not be edited. cmake_minimum_required(VERSION 3.14) 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" "flutter_texture_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} ) ================================================ FILE: packages/appinio_social_share/example/windows/flutter/generated_plugin_registrant.cc ================================================ // // Generated file. Do not edit. // // clang-format off #include "generated_plugin_registrant.h" void RegisterPlugins(flutter::PluginRegistry* registry) { } ================================================ FILE: packages/appinio_social_share/example/windows/flutter/generated_plugin_registrant.h ================================================ // // 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_ ================================================ FILE: packages/appinio_social_share/example/windows/flutter/generated_plugins.cmake ================================================ # # Generated file, do not edit. # list(APPEND FLUTTER_PLUGIN_LIST ) 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) ================================================ FILE: packages/appinio_social_share/example/windows/runner/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ================================================ FILE: packages/appinio_social_share/example/windows/runner/Runner.rc ================================================ // 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", "example" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "example" "\0" VALUE "LegalCopyright", "Copyright (C) 2022 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 ================================================ FILE: packages/appinio_social_share/example/windows/runner/flutter_window.cpp ================================================ #include "flutter_window.h" #include #include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow(const flutter::DartProject& project) : 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()); SetChildContent(flutter_controller_->view()->GetNativeWindow()); return true; } void FlutterWindow::OnDestroy() { if (flutter_controller_) { 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 opportunity 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); } ================================================ FILE: packages/appinio_social_share/example/windows/runner/flutter_window.h ================================================ #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ #include #include #include #include "win32_window.h" // A window that does nothing but host a Flutter view. class FlutterWindow : public Win32Window { public: // Creates a new FlutterWindow hosting a Flutter view running |project|. explicit FlutterWindow(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 project to run. flutter::DartProject project_; // The Flutter instance hosted by this window. std::unique_ptr flutter_controller_; }; #endif // RUNNER_FLUTTER_WINDOW_H_ ================================================ FILE: packages/appinio_social_share/example/windows/runner/main.cpp ================================================ #include #include #include #include "flutter_window.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); flutter::DartProject project(L"data"); std::vector command_line_arguments = GetCommandLineArguments(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); if (!window.CreateAndShow(L"example", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); ::MSG msg; while (::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } ::CoUninitialize(); return EXIT_SUCCESS; } ================================================ FILE: packages/appinio_social_share/example/windows/runner/resource.h ================================================ //{{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 ================================================ FILE: packages/appinio_social_share/example/windows/runner/runner.exe.manifest ================================================ PerMonitorV2 ================================================ FILE: packages/appinio_social_share/example/windows/runner/utils.cpp ================================================ #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(); } } std::vector GetCommandLineArguments() { // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. int argc; wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); if (argv == nullptr) { return std::vector(); } std::vector command_line_arguments; // Skip the first argument as it's the binary name. for (int i = 1; i < argc; i++) { command_line_arguments.push_back(Utf8FromUtf16(argv[i])); } ::LocalFree(argv); return command_line_arguments; } std::string Utf8FromUtf16(const wchar_t* utf16_string) { if (utf16_string == nullptr) { return std::string(); } int target_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, nullptr, 0, nullptr, nullptr); std::string utf8_string; if (target_length == 0 || target_length > utf8_string.max_size()) { return utf8_string; } utf8_string.resize(target_length); int converted_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, utf8_string.data(), target_length, nullptr, nullptr); if (converted_length == 0) { return std::string(); } return utf8_string; } ================================================ FILE: packages/appinio_social_share/example/windows/runner/utils.h ================================================ #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ #include #include // Creates a console for the process, and redirects stdout and stderr to // it for both the runner and the Flutter library. void CreateAndAttachConsole(); // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string // encoded in UTF-8. Returns an empty std::string on failure. std::string Utf8FromUtf16(const wchar_t* utf16_string); // Gets the command line arguments passed in as a std::vector, // encoded in UTF-8. Returns an empty std::vector on failure. std::vector GetCommandLineArguments(); #endif // RUNNER_UTILS_H_ ================================================ FILE: packages/appinio_social_share/example/windows/runner/win32_window.cpp ================================================ #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. } ================================================ FILE: packages/appinio_social_share/example/windows/runner/win32_window.h ================================================ #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_ ================================================ FILE: packages/appinio_social_share/ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m .generated/ *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/Generated.xcconfig /Flutter/ephemeral/ /Flutter/flutter_export_environment.sh ================================================ FILE: packages/appinio_social_share/ios/Assets/.gitkeep ================================================ ================================================ FILE: packages/appinio_social_share/ios/Classes/AppinioSocialSharePlugin.h ================================================ #import @interface AppinioSocialSharePlugin : NSObject @end ================================================ FILE: packages/appinio_social_share/ios/Classes/AppinioSocialSharePlugin.m ================================================ #import "AppinioSocialSharePlugin.h" #if __has_include() #import #else // Support project import fallback if the generated compatibility header // is not copied when this plugin is created as a library. // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 #import "appinio_social_share-Swift.h" #endif @implementation AppinioSocialSharePlugin + (void)registerWithRegistrar:(NSObject*)registrar { [SwiftAppinioSocialSharePlugin registerWithRegistrar:registrar]; } @end ================================================ FILE: packages/appinio_social_share/ios/Classes/MyActivityItemSource.swift ================================================ // // MyActivityItemSource.swift // appinio_social_share // // Created by Mujeeb khan on 23.09.22. // import Foundation import LinkPresentation @available(iOS 13,*) class MyActivityItemSource: NSObject, UIActivityItemSource { var title: String var text: String var filePath: String init(title: String, text: String, filePath: String) { self.title = title self.text = text self.filePath = filePath super.init() } func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any { return text } func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? { return text } func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String { return title } func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata { let metadata = LPLinkMetadata() metadata.title = title metadata.iconProvider = NSItemProvider(object: UIImage(contentsOfFile: filePath)!) //This is a bit ugly, though I could not find other ways to show text content below title. //https://stackoverflow.com/questions/60563773/ios-13-share-sheet-changing-subtitle-item-description //You may need to escape some special characters like "/". metadata.originalURL = URL(fileURLWithPath: text) return metadata } } ================================================ FILE: packages/appinio_social_share/ios/Classes/ShareUtil.swift ================================================ import Photos import FBSDKCoreKit import FBSDKShareKit import Social import MobileCoreServices public class ShareUtil{ public let SUCCESS: String = "SUCCESS" public let ERROR_APP_NOT_AVAILABLE: String = "ERROR_APP_NOT_AVAILABLE" public let ERROR_FEATURE_NOT_AVAILABLE_FOR_THIS_VERSON: String = "ERROR_FEATURE_NOT_AVAILABLE_FOR_THIS_VERSON" public let ERROR: String = "ERROR" public let NOT_IMPLEMENTED: String = "NOT_IMPLEMENTED" let argAttributionURL: String = "attributionURL"; let argImagePaths: String = "imagePaths"; let argImagePath: String = "imagePath"; let argbackgroundImage: String = "backgroundImage"; let argMessage: String = "message"; let argTitle: String = "title"; let argstickerImage: String = "stickerImage"; let argAppId: String = "appId"; let argBackgroundTopColor: String = "backgroundTopColor"; let argBackgroundBottomColor: String = "backgroundBottomColor"; let argImages: String = "images"; let argVideoFile: String = "videoFile"; public func getInstalledApps(result: @escaping FlutterResult){ let apps = [["instagram","instagram"],["facebook-stories","facebook_stories"],["whatsapp","whatsapp"],["tg","telegram"],["fb-messenger","messenger"],["tiktok","snssdk1233"],["instagram-stories","instagram_stories"],["twitter","twitter"],["sms","message"]] var output:[String: Bool] = [:] for app in apps { if(UIApplication.shared.canOpenURL(URL(string:(app[0])+"://")!)){ if(app[0] == "facebook-stories"){ output["facebook"] = true } output[app[1]] = true }else{ output[app[1]] = false } } result(output) } public func canOpenUrl(appName:String) -> Bool{ return UIApplication.shared.canOpenURL(URL(string:appName+"://")!) } public func shareToInstagramFeed(args : [String: Any?],result: @escaping FlutterResult) { let filePath = args[argImagePath] as? String if(!isImage(filePath: filePath!)) { return shareVideoToInstagramFeed(args: args, result:result) } else{ return shareImageToInstagramFeed(args: args, result:result) } } func isImage(filePath:String)->Bool{ let ext = NSURL(fileURLWithPath: filePath).pathExtension let uti = UTTypeCreatePreferredIdentifierForTag( kUTTagClassFilenameExtension, ext! as CFString, nil) if UTTypeConformsTo((uti?.takeRetainedValue())!, kUTTypeImage) { return true } return false } func shareVideoToInstagramFeed(args : [String: Any?],result: @escaping FlutterResult) { let videoFile = args[argImagePath] as? String let backgroundVideoUrl = URL(fileURLWithPath: videoFile!) let videoData = try? Data(contentsOf: backgroundVideoUrl) as NSData getLibraryPermissionIfNecessary { granted in guard granted else { result(self.ERROR) return } } PHPhotoLibrary.shared().performChanges({ let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]; let filePath = "\(documentsPath)/\(Date().description).mp4" videoData!.write(toFile: filePath, atomically: true) PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: URL(fileURLWithPath: filePath)) }, completionHandler: { success, error in if success { let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions) if let lastAsset = fetchResult.firstObject { let localIdentifier = lastAsset.localIdentifier let urlFeed = "instagram://library?LocalIdentifier=" + localIdentifier guard let url = URL(string: urlFeed) else { result(self.ERROR_APP_NOT_AVAILABLE) return } DispatchQueue.main.async { if UIApplication.shared.canOpenURL(url) { if #available(iOS 10.0, *) { UIApplication.shared.open(url, options: [:], completionHandler: { (success) in result(self.SUCCESS) }) } else { UIApplication.shared.openURL(url) result(self.SUCCESS) } } else { result(self.ERROR) } } } } else if let error = error { print(error.localizedDescription) } else { result(self.ERROR) } }) } func shareImageToInstagramFeed(args : [String: Any?],result: @escaping FlutterResult) { let videoFile = args[argImagePath] as? String let backgroundVideoUrl = URL(fileURLWithPath: videoFile!) let videoData = try? Data(contentsOf: backgroundVideoUrl) as NSData getLibraryPermissionIfNecessary { granted in guard granted else { result(self.ERROR) return } } PHPhotoLibrary.shared().performChanges({ let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]; let filePath:String filePath = "\(documentsPath)/\(Date().description).jpeg" videoData!.write(toFile: filePath, atomically: true) PHAssetChangeRequest.creationRequestForAssetFromImage(atFileURL: URL(fileURLWithPath: filePath)) }, completionHandler: { success, error in if success { let fetchOptions = PHFetchOptions() fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)] let type:PHAssetMediaType; type = PHAssetMediaType.image let fetchResult = PHAsset.fetchAssets(with: type, options: fetchOptions) if let lastAsset = fetchResult.firstObject { let localIdentifier = lastAsset.localIdentifier let urlFeed = "instagram://library?LocalIdentifier=" + localIdentifier guard let url = URL(string: urlFeed) else { result(self.ERROR_APP_NOT_AVAILABLE) return } DispatchQueue.main.async { if UIApplication.shared.canOpenURL(url) { if #available(iOS 10.0, *) { UIApplication.shared.open(url, options: [:], completionHandler: { (success) in result(self.SUCCESS) }) } else { UIApplication.shared.openURL(url) result(self.SUCCESS) } } else { result(self.ERROR) } } } } else if let error = error { print(error.localizedDescription) } else { result(self.ERROR) } }) } func getLibraryPermissionIfNecessary(completionHandler: @escaping (Bool) -> Void) { guard PHPhotoLibrary.authorizationStatus() != .authorized else { completionHandler(true) return } PHPhotoLibrary.requestAuthorization { status in completionHandler(status == .authorized) } } public func shareToSystem(args : [String: Any?],result: @escaping FlutterResult) { let text = args[argMessage] as? String let filePaths = args[argImagePaths] as? [String] var data : [Any] = [text!]; if filePaths != nil{ for filePath in filePaths!{ data.append(URL(fileURLWithPath: filePath)) } } let activityViewController = UIActivityViewController(activityItems: data, applicationActivities: nil) UIApplication.topViewController()?.present(activityViewController, animated: true, completion: nil) result(SUCCESS) } func copyToClipboard(args : [String: Any?],result: @escaping FlutterResult){ let message = args[self.argMessage] as? String UIPasteboard.general.string = message! result(SUCCESS) } func shareToWhatsApp(args : [String: Any?],result: @escaping FlutterResult) { let message = args[self.argMessage] as? String let whatsURL = "whatsapp://send?text="+message! var characterSet = CharacterSet.urlQueryAllowed characterSet.insert(charactersIn: "?&") let whatsAppURL = NSURL(string: whatsURL.addingPercentEncoding(withAllowedCharacters: characterSet)!) if UIApplication.shared.canOpenURL(whatsAppURL! as URL) { UIApplication.shared.open(whatsAppURL! as URL) result(SUCCESS); } else { result(ERROR_APP_NOT_AVAILABLE); } } func shareToFacebookPost(args : [String: Any?],result: @escaping FlutterResult, delegate: SharingDelegate) { let message = args[self.argMessage] as? String let imagePaths = args[self.argImagePaths] as? [String] let content = SharePhotoContent() var photos : [SharePhoto] = [] for image in imagePaths! { let photo = SharePhoto(image: UIImage.init(contentsOfFile: image)!, isUserGenerated: true) photos.append(photo) } content.photos = photos content.hashtag = Hashtag(message!) let dialog = ShareDialog( viewController: UIApplication.shared.windows.first!.rootViewController, content: content, delegate: delegate ) do { try dialog.validate() } catch { result(ERROR) } dialog.show() result(self.SUCCESS) } func shareToTelegram(args : [String: Any?],result: @escaping FlutterResult) { let message = args[self.argMessage] as? String guard let telegramURL = URL(string: "https://telegram.me") else { result(ERROR_APP_NOT_AVAILABLE) return } guard let mess = message else { result(ERROR) return } if (UIApplication.shared.canOpenURL(telegramURL)) { let urlString = "tg://msg?text=\(mess)" let tgUrl = URL.init(string: urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!) if UIApplication.shared.canOpenURL(tgUrl!) { UIApplication.shared.open(tgUrl!) result(SUCCESS) } else { result(ERROR_APP_NOT_AVAILABLE) } } else { result(ERROR_APP_NOT_AVAILABLE) } } public func shareToInstagramDirect(args : [String: Any?],result: @escaping FlutterResult){ if #available(iOS 10, *){ let message = args[self.argMessage] as? String let urlString = "instagram://sharesheet?text=\(message!)" if(!canOpenUrl(appName: "instagram")){ result(ERROR_APP_NOT_AVAILABLE) return } if let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!) { UIApplication.shared.open(url, options: [:], completionHandler: nil) result(SUCCESS) }else{ result(ERROR) } }else{ result(ERROR_FEATURE_NOT_AVAILABLE_FOR_THIS_VERSON) } } public func shareToMessenger(args : [String: Any?],result: @escaping FlutterResult){ if #available(iOS 10, *){ let message = args[self.argMessage] as? String let urlString = "fb-messenger://share/?link=\(message!)" if(!canOpenUrl(appName: "fb-messenger")){ result(ERROR_APP_NOT_AVAILABLE) return } if let url = URL(string: urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!) { UIApplication.shared.open(url, options: [:], completionHandler: nil) result(SUCCESS) }else{ result(ERROR) } }else{ result(ERROR_FEATURE_NOT_AVAILABLE_FOR_THIS_VERSON) } } public func shareToSms(args : [String: Any?],result: @escaping FlutterResult){ let message = args[self.argMessage] as? String if #available(iOS 10, *){ let urlString = "sms:?&body=\(message!)" if(!canOpenUrl(appName: "sms")){ result(ERROR_APP_NOT_AVAILABLE) return } let tgUrl = URL.init(string: urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)!) UIApplication.shared.open(tgUrl!, options: [:], completionHandler: nil) } result(SUCCESS) } public func shareToFacebookStory(args : [String: Any?],result: @escaping FlutterResult) { let appId = args[self.argAppId] as? String let imagePath = args[self.argbackgroundImage] as? String let argVideoFile = args[self.argVideoFile] as? String let imagePathSticker = args[self.argstickerImage] as? String let backgroundTopColor = args[self.argBackgroundTopColor] as? String let backgroundBottomColor = args[self.argBackgroundBottomColor] as? String let attributionURL = args[self.argAttributionURL] as? String guard let facebookURL = URL(string: "facebook-stories://share") else { result(ERROR_APP_NOT_AVAILABLE) return } if (UIApplication.shared.canOpenURL(facebookURL)) { var pasteboardItems = [ "com.facebook.sharedSticker.attributionURL": [attributionURL ?? ""], "com.facebook.sharedSticker.backgroundTopColor": backgroundTopColor ?? "", "com.facebook.sharedSticker.backgroundBottomColor": backgroundBottomColor ?? "", "com.facebook.sharedSticker.appID": appId as Any, ] var backgroundImage: UIImage?; if(!(imagePath==nil)){ backgroundImage = UIImage.init(contentsOfFile: imagePath!) if (backgroundImage != nil) { pasteboardItems["com.facebook.sharedSticker.backgroundImage"] = backgroundImage } } var stickerImage: UIImage?; if(!(imagePathSticker==nil)){ stickerImage = UIImage.init(contentsOfFile: imagePathSticker!) if (stickerImage != nil) { pasteboardItems["com.facebook.sharedSticker.stickerImage"] = stickerImage } } var backgroundVideoData:Any?; if(!(argVideoFile==nil)){ let backgroundVideoUrl = URL(fileURLWithPath: argVideoFile!) backgroundVideoData = try? Data(contentsOf: backgroundVideoUrl) if (backgroundVideoData != nil) { pasteboardItems["com.facebook.sharedSticker.backgroundVideo"] = backgroundVideoData } } if #available(iOS 10, *){ let pasteboardOptions = [ UIPasteboard.OptionsKey.expirationDate: Date().addingTimeInterval(60 * 5) ] UIPasteboard.general.setItems([pasteboardItems], options: pasteboardOptions) UIApplication.shared.open(facebookURL, options: [:]) } result(self.SUCCESS) return } else { result(ERROR_APP_NOT_AVAILABLE) } } func shareToTwitter(args : [String: Any?],result: @escaping FlutterResult) { let title = args[self.argMessage] as? String let images = args[self.argImagePaths] as? [String] if(!canOpenUrl(appName: "twitter")){ result(ERROR_APP_NOT_AVAILABLE) return } let composeCtl = SLComposeViewController(forServiceType: SLServiceTypeTwitter) if #unavailable(iOS 16) { composeCtl?.add(URL(string: title!)) } if(!(images==nil)){ for image in images! { composeCtl?.add(UIImage.init(contentsOfFile: image)) } } composeCtl?.setInitialText(title!) UIApplication.topViewController()?.present(composeCtl!,animated:true,completion:nil); result(SUCCESS) } func shareToInstagramStory(args : [String: Any?],result: @escaping FlutterResult) { if #available(iOS 10.0, *){ let appId = args[self.argAppId] as? String let imagePath = args[self.argbackgroundImage] as? String let argVideoFile = args[self.argVideoFile] as? String let imagePathSticker = args[self.argstickerImage] as? String let backgroundTopColor = args[self.argBackgroundTopColor] as? String let backgroundBottomColor = args[self.argBackgroundBottomColor] as? String let attributionURL = args[self.argAttributionURL] as? String guard let instagramURL = URL(string: "instagram-stories://share?source_application=\(appId!)") else { result(ERROR_APP_NOT_AVAILABLE) return } if (UIApplication.shared.canOpenURL(instagramURL)) { var backgroundImage: UIImage?; if(!(imagePath==nil)){ backgroundImage = UIImage.init(contentsOfFile: imagePath!) } var stickerImage: UIImage?; if(!(imagePathSticker==nil)){ stickerImage = UIImage.init(contentsOfFile: imagePathSticker!) } var backgroundVideoData:Any?; if(!(argVideoFile==nil)){ let backgroundVideoUrl = URL(fileURLWithPath: argVideoFile!) backgroundVideoData = try? Data(contentsOf: backgroundVideoUrl) } let pasteboardItems = [ [ "com.instagram.sharedSticker.attributionURL": attributionURL ?? "", "com.instagram.sharedSticker.stickerImage": stickerImage ?? "", "com.instagram.sharedSticker.backgroundVideo": backgroundVideoData ?? "", "com.instagram.sharedSticker.backgroundImage": backgroundImage ?? "", "com.instagram.sharedSticker.backgroundTopColor": backgroundTopColor ?? "", "com.instagram.sharedSticker.backgroundBottomColor": backgroundBottomColor ?? "", ] ] let pasteboardOptions = [ UIPasteboard.OptionsKey.expirationDate: Date().addingTimeInterval(60 * 5) ] UIPasteboard.general.setItems(pasteboardItems, options: pasteboardOptions) UIApplication.shared.open(instagramURL, options: [:]) result(self.SUCCESS) } else { result(ERROR_APP_NOT_AVAILABLE) } }else{ result(ERROR_FEATURE_NOT_AVAILABLE_FOR_THIS_VERSON) } } public func shareImageToWhatsApp(args : [String: Any?],result: @escaping FlutterResult, delegate: SharingDelegate) { let imagePath = args[self.argImagePath] as? String guard let url = URL(string: imagePath!) else { result(FlutterError(code: "INVALID_PATH", message: "The image path is invalid", details: nil)) return } guard let image = UIImage(contentsOfFile: url.path) else { result(FlutterError(code: "IMAGE_ERROR", message: "Could not load image", details: nil)) return } let urlWhats = "whatsapp://app" if let urlString = urlWhats.addingPercentEncoding(withAllowedCharacters:CharacterSet.urlQueryAllowed) { if let whatsappURL = URL(string: urlString) { if UIApplication.shared.canOpenURL(whatsappURL as URL) { if let imageData = image.jpegData(compressionQuality: 1.0) { let tempFile = URL(fileURLWithPath: NSHomeDirectory()).appendingPathComponent("Documents/whatsAppTmp.wai") do { try imageData.write(to: tempFile, options: .atomic) let documentInteractionController = UIDocumentInteractionController(url: tempFile) documentInteractionController.uti = "net.whatsapp.image" documentInteractionController.presentOpenInMenu(from: CGRect.zero, in: UIApplication.topViewController()!.view, animated: true) } catch { print(error) } } } else { print("Cannot open whatsapp") } } } } } extension UIApplication { class func topViewController(controller: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? { if let navigationController = controller as? UINavigationController { return topViewController(controller: navigationController.visibleViewController) } if let tabController = controller as? UITabBarController { if let selected = tabController.selectedViewController { return topViewController(controller: selected) } } if let presented = controller?.presentedViewController { return topViewController(controller: presented) } return controller } } class TransparentViewController: UIViewController { override func viewDidLoad() { view.backgroundColor = UIColor.clear view.isOpaque = false } } ================================================ FILE: packages/appinio_social_share/ios/Classes/SwiftAppinioSocialSharePlugin.swift ================================================ import Flutter import UIKit import FBSDKCoreKit import FBSDKShareKit import Photos public class SwiftAppinioSocialSharePlugin: NSObject, FlutterPlugin, SharingDelegate { private let INSTAGRAM_DIRECT:String = "instagram_direct"; private let INSTAGRAM_STORIES:String = "instagram_stories"; private let INSTAGRAM_POST:String = "instagram_post"; private let FACEBOOK:String = "facebook"; private let FACEBOOK_STORIES = "facebook_stories"; private let MESSENGER = "messenger"; private let WHATSAPP:String = "whatsapp"; private let WHATSAPP_IMG_IOS:String = "whatsapp_img_ios"; private let TWITTER:String = "twitter"; private let SMS:String = "sms"; private let SYSTEM_SHARE:String = "system_share"; private let COPY_TO_CLIPBOARD:String = "copy_to_clipboard"; private let TELEGRAM:String = "telegram"; private let INSTALLED_APPS:String = "installed_apps"; var shareUtil = ShareUtil() var flutterResult: FlutterResult! public static func register(with registrar: FlutterPluginRegistrar) { let channel = FlutterMethodChannel(name: "appinio_social_share", binaryMessenger: registrar.messenger()) let instance = SwiftAppinioSocialSharePlugin() registrar.addMethodCallDelegate(instance, channel: channel) } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { do { flutterResult = result let args = call.arguments as? [String: Any?] switch (call.method) { case INSTALLED_APPS: shareUtil.getInstalledApps(result: result) break case INSTAGRAM_DIRECT: shareUtil.shareToInstagramDirect(args:args!,result: result) break case INSTAGRAM_POST: shareUtil.shareToInstagramFeed(args:args!,result: result) break case INSTAGRAM_STORIES: shareUtil.shareToInstagramStory(args:args!,result:result) break case FACEBOOK_STORIES: shareUtil.shareToFacebookStory(args:args!,result:result) break case WHATSAPP_IMG_IOS: shareUtil.shareImageToWhatsApp(args:args!, result:result,delegate: self) break case WHATSAPP: shareUtil.shareToWhatsApp(args:args!, result:result) break case TWITTER: shareUtil.shareToTwitter(args:args!,result:result) break case SMS: shareUtil.shareToSms(args: args!, result: result) break case SYSTEM_SHARE: shareUtil.shareToSystem(args:args!,result: result) break case COPY_TO_CLIPBOARD: shareUtil.copyToClipboard(args: args!, result: result) break case FACEBOOK: shareUtil.shareToFacebookPost(args:args!, result: result,delegate: self) break case TELEGRAM: shareUtil.shareToTelegram(args:args!, result:result) break case MESSENGER: shareUtil.shareToMessenger(args: args!, result: result) break default: result(shareUtil.ERROR) } } catch { result(shareUtil.ERROR) } } public func sharer(_ sharer: Sharing, didCompleteWithResults results: [String : Any]) { flutterResult(shareUtil.SUCCESS) } public func sharer(_ sharer: Sharing, didFailWithError error: Error) { flutterResult(shareUtil.ERROR) } public func sharerDidCancel(_ sharer: Sharing) { flutterResult(shareUtil.ERROR) } } ================================================ FILE: packages/appinio_social_share/ios/appinio_social_share.podspec ================================================ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. # Run `pod lib lint appinio_social_share.podspec` to validate before publishing. # Pod::Spec.new do |s| s.name = 'appinio_social_share' s.version = '0.0.1' s.summary = 'A new Flutter project.' s.description = <<-DESC A new Flutter project. DESC s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' s.dependency 'FBSDKCoreKit', '17.0.2' s.dependency 'FBSDKShareKit', '17.0.2' s.static_framework = true s.platform = :ios, '9.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.swift_version = '5.0' end ================================================ FILE: packages/appinio_social_share/lib/appinio_social_share.dart ================================================ import 'package:appinio_social_share/appinio_social_share_platform_interface.dart'; import 'package:appinio_social_share/platforms/android.dart'; import 'package:appinio_social_share/platforms/ios.dart'; class AppinioSocialShare { Android android = Android(); IOS iOS = IOS(); Future> getInstalledApps() async { return AppinioSocialSharePlatform.instance.getInstalledApps(); } } ================================================ FILE: packages/appinio_social_share/lib/appinio_social_share_method_channel.dart ================================================ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'appinio_social_share_platform_interface.dart'; /// An implementation of [AppinioSocialSharePlatform] that uses method channels. class MethodChannelAppinioSocialShare extends AppinioSocialSharePlatform { final String instagramDirect = "instagram_direct"; final String instagramFeed = "instagram_post"; final String instagramFeedFiles = "instagram_post_files"; final String instagramStories = "instagram_stories"; final String facebook = "facebook"; final String messenger = "messenger"; final String facebookStories = "facebook_stories"; final String whatsapp = "whatsapp"; final String whatsappAndroid = "whatsapp_android"; final String whatsappAndroidMultiFiles = "whatsapp_android_multifiles"; final String twitter = "twitter"; final String twitterAndroid = "twitter_android"; final String twitterAndroidMultiFiles = "twitter_android_multifiles"; final String sms = "sms"; final String smsAndroid = "sms_android"; final String smsAndroidMultiFiles = "sms_android_multifiles"; final String tiktokStatus = "tiktok_status"; final String tiktokPost = "tiktok_post"; final String systemShare = "system_share"; final String systemShareAndroid = "system_share_android"; final String systemShareAndroidMultiFiles = "system_share_android_multifiles"; final String copyToClipboard = "copy_to_clipboard"; final String telegram = "telegram"; final String telegramAndroid = "telegram_android"; final String telegramAndroidMultiFiles = "telegram_android_multifiles"; final String installedApps = "installed_apps"; final String whatsappImgIos = "whatsapp_img_ios"; /// The method channel used to interact with the native platform. @visibleForTesting final methodChannel = const MethodChannel('appinio_social_share'); @override Future> getInstalledApps() async { return Map.from( (await methodChannel.invokeMethod(installedApps))); } @override Future shareToTiktokStatus(List filePaths) async { if (Platform.isIOS) return "Not implemented for iOS"; return ((await methodChannel.invokeMethod( tiktokStatus, {"imagePaths": filePaths, "message": ""})) ?? ""); } @override Future shareToTiktokPost(String filePath, String redirectUrl, TiktokFileType tiktokFileType) async { if (Platform.isAndroid) return "Not implemented for android"; String? resp; try { resp = (await const MethodChannel('appinio_social_share_tiktok') .invokeMethod(tiktokPost, { "videoFile": filePath, "redirectUrl": redirectUrl, "fileType": tiktokFileType.value })) ?? ""; } catch (e) { return e.toString(); } return resp; } @override Future shareToTwitter(String message, String? filePath) async { return ((await methodChannel.invokeMethod(twitter, { "imagePaths": filePath == null ? [] : [filePath], "message": message })) ?? ""); } @override Future shareToTwitterAndroid(String message, String? filePath) async { return ((await methodChannel.invokeMethod( twitterAndroid, {"imagePath": filePath, "message": message})) ?? ""); } @override Future shareToTwitterAndroidMultifiles(List filePaths) async { return ((await methodChannel.invokeMethod( twitterAndroidMultiFiles, {"imagePaths": filePaths})) ?? ""); } @override Future shareToTelegram(String message, {List? filePaths}) async { return ((await methodChannel.invokeMethod( telegram, {"imagePaths": filePaths, "message": message})) ?? ""); } @override Future shareToTelegramAndroid( String message, String? filePath) async { return ((await methodChannel.invokeMethod(telegramAndroid, { "imagePath": filePath, "message": message, })) ?? ""); } @override Future shareToTelegramAndroidMultiFiles( List filePaths) async { return ((await methodChannel .invokeMethod(telegramAndroidMultiFiles, { "imagePaths": filePaths, })) ?? ""); } ///for iOS only @override Future shareToWhatsapp(String message, {List? filePaths}) async { return ((await methodChannel.invokeMethod( whatsapp, {"imagePaths": filePaths, "message": message})) ?? ""); } @override Future shareToWhatsappAndroid( String message, String? filePath) async { return ((await methodChannel.invokeMethod( whatsappAndroid, {"imagePath": filePath, "message": message})) ?? ""); } @override Future shareToWhatsappAndroidMultiFiles( List filePaths) async { return ((await methodChannel.invokeMethod( whatsappAndroidMultiFiles, {"imagePaths": filePaths})) ?? ""); } @override Future shareToSMS(String message, {List? filePaths}) async { return ((await methodChannel.invokeMethod( sms, {"message": message, "imagePaths": filePaths})) ?? ""); } @override Future shareToSMSAndroid(String message, String? filePath) async { return ((await methodChannel.invokeMethod( smsAndroid, {"message": message, "imagePath": filePath})) ?? ""); } @override Future shareToSMSAndroidMultifiles(List filePaths) async { return ((await methodChannel.invokeMethod( smsAndroidMultiFiles, {"imagePaths": filePaths})) ?? ""); } @override Future copyToClipBoard(String message) async { return ((await methodChannel .invokeMethod(copyToClipboard, {"message": message})) ?? ""); } @override Future shareToSystem(String title, String message, {List? filePaths}) async { return ((await methodChannel.invokeMethod(systemShare, {"message": message, "title": title, "imagePaths": filePaths})) ?? ""); } @override Future shareToSystemAndroid( String title, String message, String? filePath) async { return ((await methodChannel.invokeMethod(systemShareAndroid, {"message": message, "title": title, "imagePath": filePath})) ?? ""); } @override Future shareToSystemAndroidMultifiles( String title, List filePaths) async { return ((await methodChannel.invokeMethod( systemShareAndroidMultiFiles, {"title": title, "imagePaths": filePaths})) ?? ""); } @override Future shareToInstagramDirect(String message) async { return ((await methodChannel .invokeMethod(instagramDirect, {"message": message})) ?? ""); } @override Future shareToInstagramFeed(String message, String? filePath) async { return ((await methodChannel.invokeMethod( instagramFeed, {"imagePath": filePath, "message": message})) ?? ""); } @override Future shareToInstagramFeedAndroid(List filePaths) async { return ((await methodChannel.invokeMethod(instagramFeedFiles, { "imagePaths": filePaths, })) ?? ""); } @override Future shareToMessenger(String message) async { return ((await methodChannel .invokeMethod(messenger, {"message": message})) ?? ""); } @override Future shareImageToWhatsApp( String filePath, ) async { return ((await methodChannel .invokeMethod(whatsappImgIos, {"imagePath": filePath})) ?? ""); } @override Future shareToInstagramStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) async { return ((await methodChannel.invokeMethod(instagramStories, { "stickerImage": stickerImage, "backgroundImage": backgroundImage ?? (Platform.isAndroid ? backgroundVideo : null), "videoFile": backgroundVideo, "backgroundTopColor": backgroundTopColor, "backgroundBottomColor": backgroundBottomColor, "attributionURL": attributionURL, "appId": appId })) ?? ""); } @override Future shareToFacebookStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) async { return ((await methodChannel.invokeMethod(facebookStories, { "stickerImage": stickerImage, "backgroundImage": backgroundImage ?? (Platform.isAndroid ? backgroundVideo : null), "videoFile": backgroundVideo, "backgroundTopColor": backgroundTopColor, "backgroundBottomColor": backgroundBottomColor, "attributionURL": attributionURL, "appId": appId })) ?? ""); } @override Future shareToFacebook(String hashtag, List filePaths) async { return ((await methodChannel.invokeMethod( facebook, {"imagePaths": filePaths, "message": hashtag})) ?? ""); } } ================================================ FILE: packages/appinio_social_share/lib/appinio_social_share_platform_interface.dart ================================================ import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'appinio_social_share_method_channel.dart'; abstract class AppinioSocialSharePlatform extends PlatformInterface { /// Constructs a AppinioSocialSharePlatform. AppinioSocialSharePlatform() : super(token: _token); static final Object _token = Object(); static AppinioSocialSharePlatform _instance = MethodChannelAppinioSocialShare(); /// The default instance of [AppinioSocialSharePlatform] to use. /// /// Defaults to [MethodChannelAppinioSocialShare]. static AppinioSocialSharePlatform get instance => _instance; /// Platform-specific implementations should set this with their own /// platform-specific class that extends [AppinioSocialSharePlatform] when /// they register themselves. static set instance(AppinioSocialSharePlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; } Future getPlatformVersion() { throw UnimplementedError('platformVersion() has not been implemented.'); } Future> getInstalledApps() { throw UnimplementedError('platformVersion() has not been implemented.'); } ///filaPath only works for android Future shareToWhatsapp(String message, {List? filePaths}) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToInstagramDirect(String message) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToInstagramFeed(String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToInstagramFeedAndroid(List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToMessenger(String message) { throw UnimplementedError('platformVersion() has not been implemented.'); } ///This function only works for android Future shareToTiktokStatus(List filePaths) { throw UnimplementedError('platformVersion() has not been implemented.'); } ///This function only works for iOS Future shareToTiktokPost( String filePath, String redirectUrl, TiktokFileType tiktokFileType) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToTwitter(String message, String? filePath) { throw UnimplementedError('platformVersion() has not been implemented.'); } ///filepath only works for android Future shareToTelegram(String message, {List? filePaths}) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToFacebook(String hashtag, List filePaths) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToInstagramStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToFacebookStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future copyToClipBoard(String message) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToSystem(String title, String message, {List? filePaths}) { throw UnimplementedError('platformVersion() has not been implemented.'); } ///filePath only works for android Future shareToSMS(String message, {List? filePaths}) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToWhatsappAndroid( String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToWhatsappAndroidMultiFiles( List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToTelegramAndroid( String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToTelegramAndroidMultiFiles( List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToTwitterAndroid(String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToTwitterAndroidMultifiles(List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToSMSAndroid(String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToSMSAndroidMultifiles(List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToSystemAndroid( String title, String message, String? filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareImageToWhatsApp(String filePath) async { throw UnimplementedError('platformVersion() has not been implemented.'); } Future shareToSystemAndroidMultifiles( String title, List filePaths) async { throw UnimplementedError('platformVersion() has not been implemented.'); } } enum TiktokFileType { image("image"), video("video"); final String value; const TiktokFileType(this.value); } ================================================ FILE: packages/appinio_social_share/lib/platforms/android.dart ================================================ import 'package:appinio_social_share/appinio_social_share_platform_interface.dart'; class Android { Future shareToWhatsapp(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToWhatsappAndroid(message, filePath); } Future shareFilesToWhatsapp(List filePaths) { return AppinioSocialSharePlatform.instance .shareToWhatsappAndroidMultiFiles(filePaths); } Future shareToTelegram(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToTelegramAndroid(message, filePath); } Future shareFilesToTelegram(List filePaths) { return AppinioSocialSharePlatform.instance .shareToTelegramAndroidMultiFiles(filePaths); } Future shareToTwitter(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToTwitterAndroid(message, filePath); } Future shareToInstagramDirect(String message) { return AppinioSocialSharePlatform.instance.shareToInstagramDirect(message); } Future shareToInstagramFeed(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToInstagramFeed(message, filePath); } Future shareFilesToInstagramFeed(List imagePaths) { return AppinioSocialSharePlatform.instance .shareToInstagramFeedAndroid(imagePaths); } Future shareToInstagramReels(List videoPaths) { return AppinioSocialSharePlatform.instance .shareToInstagramFeedAndroid(videoPaths); } Future shareToMessenger(String message) { return AppinioSocialSharePlatform.instance.shareToMessenger(message); } Future copyToClipBoard(String message) { return AppinioSocialSharePlatform.instance.copyToClipBoard(message); } Future shareToFacebook(String hashtag, List filePaths) { return AppinioSocialSharePlatform.instance .shareToFacebook(hashtag, filePaths); } Future shareToInstagramStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { return AppinioSocialSharePlatform.instance.shareToInstagramStory(appId, stickerImage: stickerImage, backgroundImage: backgroundImage, backgroundVideo: backgroundVideo, backgroundTopColor: backgroundTopColor, backgroundBottomColor: backgroundBottomColor, attributionURL: attributionURL); } Future shareToFacebookStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { return AppinioSocialSharePlatform.instance.shareToFacebookStory(appId, stickerImage: stickerImage, backgroundImage: backgroundImage, backgroundVideo: backgroundVideo, backgroundTopColor: backgroundTopColor, backgroundBottomColor: backgroundBottomColor, attributionURL: attributionURL); } ///works only for android Future shareToTiktokStatus(List filePaths) { return AppinioSocialSharePlatform.instance.shareToTiktokStatus(filePaths); } Future shareToSystem(String title, String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToSystemAndroid(title, message, filePath); } Future shareFilesToSystem(String title, List filePaths) { return AppinioSocialSharePlatform.instance .shareToSystemAndroidMultifiles(title, filePaths); } Future shareToSMS(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToSMSAndroid(message, filePath); } Future shareFilesToSMS(List filePaths) { return AppinioSocialSharePlatform.instance .shareToSMSAndroidMultifiles(filePaths); } } ================================================ FILE: packages/appinio_social_share/lib/platforms/ios.dart ================================================ import 'package:appinio_social_share/appinio_social_share_platform_interface.dart'; class IOS { Future shareToWhatsapp(String message) { return AppinioSocialSharePlatform.instance.shareToWhatsapp(message); } Future shareToTelegram(String message) { return AppinioSocialSharePlatform.instance.shareToTelegram(message); } Future shareImageToWhatsApp(String filePath) { return AppinioSocialSharePlatform.instance.shareImageToWhatsApp(filePath); } Future shareToTwitter(String message, String? filePath) { return AppinioSocialSharePlatform.instance .shareToTwitter(message, filePath); } Future shareToInstagramDirect(String message) { return AppinioSocialSharePlatform.instance.shareToInstagramDirect(message); } Future shareToInstagramFeed(String imagePath) { return AppinioSocialSharePlatform.instance .shareToInstagramFeed("", imagePath); } Future shareToInstagramReels(String videoPath) { return AppinioSocialSharePlatform.instance .shareToInstagramFeed("", videoPath); } Future shareToMessenger(String message) { return AppinioSocialSharePlatform.instance.shareToMessenger(message); } Future copyToClipBoard(String message) { return AppinioSocialSharePlatform.instance.copyToClipBoard(message); } Future shareToFacebook(String hashtag, List filePaths) { return AppinioSocialSharePlatform.instance .shareToFacebook(hashtag, filePaths); } Future shareToInstagramStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { return AppinioSocialSharePlatform.instance.shareToInstagramStory(appId, stickerImage: stickerImage, backgroundImage: backgroundImage, backgroundVideo: backgroundVideo, backgroundTopColor: backgroundTopColor, backgroundBottomColor: backgroundBottomColor, attributionURL: attributionURL); } Future shareToFacebookStory(String appId, {String? stickerImage, String? backgroundImage, String? backgroundVideo, String? backgroundTopColor, String? backgroundBottomColor, String? attributionURL}) { return AppinioSocialSharePlatform.instance.shareToFacebookStory(appId, stickerImage: stickerImage, backgroundImage: backgroundImage, backgroundVideo: backgroundVideo, backgroundTopColor: backgroundTopColor, backgroundBottomColor: backgroundBottomColor, attributionURL: attributionURL); } ///Works only after implementing native code provided here [https://pub.dev/packages/appinio_social_share] Future shareToTiktokPost( String videoFile, String redirectUrl, TiktokFileType tiktokFileType) { return AppinioSocialSharePlatform.instance .shareToTiktokPost(videoFile, redirectUrl, tiktokFileType); } Future shareToSystem(String message, {List? filePaths}) { return AppinioSocialSharePlatform.instance .shareToSystem("", message, filePaths: filePaths); } Future shareToSMS(String message) { return AppinioSocialSharePlatform.instance .shareToSMS(message, filePaths: []); } } ================================================ FILE: packages/appinio_social_share/pubspec.yaml ================================================ name: appinio_social_share description: Supports sharing text, images, files and text with image to social media (Facebook, Instagram, Instagram Story, Messenger, Telegram, WhatsApp, Twitter, Tiktok, SMS, System, etc.). version: 0.3.2 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/appinio_social_share environment: sdk: ">=2.17.6 <4.0.0" flutter: ">=2.5.0" dependencies: flutter: sdk: flutter plugin_platform_interface: ^2.0.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 flutter: plugin: platforms: android: package: com.appinio.socialshare.appinio_social_share pluginClass: AppinioSocialSharePlugin ios: pluginClass: AppinioSocialSharePlugin ================================================ FILE: packages/appinio_swiper/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/appinio_swiper/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 18116933e77adc82f80866c928266a5b4f1ed645 channel: stable project_type: package ================================================ FILE: packages/appinio_swiper/CHANGELOG.md ================================================ ## [2.1.1] - 2024.04.15 * Bug fixes: - Swiper renders the topmost background card for all background positions Appinio swiper - _AppinioSwiperState#b3f89(tickers: tracking 1 ticker) was disposed with an active Ticker. - Failed assertion: line 314 pos 15: 'opacity >= 0.0 && opacity <= 1.0': is not true Appinio swiper - All background cards have the same style ## [2.1.0] - 2023.11.21 * Features: - The controller now exposes all relevant card state (index, card offset+rotation, etc). - The controller now has animateTo to arbitrarily animate the top card’s offset. - Added onSwipeEnd, onSwipeBegin and onCardPositionChanged methods to give the swipe information. - Added SwiperActivity class to give more information during card swipe. - Better documentation, linting and code formatting. ## [2.0.3] - 2023.08.23 * Features: - Custom background card spacing. - onSwipeCancelled event. ## [2.0.2] - 2023.06.19 * Features: - You can pass any combination of SwipeOptions. - You can decide how many background cards you need. ## [2.0.1] - 2023.05.31 * Features: - You can add a listener and check in which direction the card is being swiped. ## [2.0.0] - 2023.03.16 Features: * Breaking change - Replaced the list of cards with cardsBuilder. * Trigger swipe up & down through controller. * Restrict horizontal or vertical swipe. * Set looping for card swipe. ## [1.1.1] - 2022.10.13 Fixes: * NoSuchMethodError When onSwipe method is not provided. ## [1.1.0] - 2022.09.11 Features: * Detect the directi on (left, right, top, bottom) in which the card was swiped away. * Unswipe all cards. ## [1.0.3] - 2022.04.28 * Trigger swipe through controller. ## [1.0.2] - 2021.12.8 * Bug fix. ## [1.0.1] - 2021.12.1 * Feature: Sending Feedback when widget is unswiped. ## [1.0.0] - 2021.11.26 * Initial version ================================================ FILE: packages/appinio_swiper/LICENSE ================================================ MIT License Copyright (c) 2021 APPINIO GmbH 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. ================================================ FILE: packages/appinio_swiper/README.md ================================================ ```appinio_swiper``` is a Flutter package for a Tinder Card Swiper. ✨ It allows swiping in all directions with any Custom Widget (Stateless or Statefull). Very smooth animations supporting Android, iOS & WebApp. ## Why? We build this package because we wanted to: - have a complete customizable slider - be able to swipe in every direction - trigger unswipe however we want - choose our own settings for the swiper such as duration, angle, padding.. - trigger swipe, swipe left/right or swipe up/down however we want - set swipe options and restrict horizontal or vertical swipe. - set loop for infinite scroll - update the list of cards between swipes. - Check in which direction the card is being swiped and modify your widget accordingly.- We can have any number of background cards. - Pass any combination of swipe options. - NEW - check when user is swiping card back before reaching the threshold value. - NEW - Get current card index, offset and rotation - NEW - Programmatically animate card swipe. - NEW - We can have any number of background cards. - NEW - Pass any combination of swipe options. ## ❗NEW Features ❗ ### Animate the top card. Now you can arbitrarily animate the position of the top card using ```AppinioSwiperController.animatTo```. ### Listen to the card offset and rotation. Now you can track the offset and rotation of the top card by listening to the ```AppinioSwiperController```. ### Know when user is coming back without completely swiping the card. Now you can track if user is swiping the card back to the center with the ```CancelSwipe``` ```SwiperActivity```. ### Space background cards as per your requirement. Now you can decide the spacing between the background cards and can also hide them by giving ```backgroundCardOffset = Offset.zero```. ### onSwipeCancelEvent. We have added onSwipeCancel event to check if the card swiped completely or if the swipe got canceled in the middle. ### Add different combinations for swipe options. Now you can provide any combination of swipe options. For example: The user can swipe to the left and bottom but not top, or any possible combination. ### Show any number of background cards. Now you can decide how many background cards you want to show. ### Listen to card swipes Now you can check in which direction the card is being swiped and modify your widget accordingly ### Trigger swipe up and swipe down through controller You can now trigger swipe up and swipe down with our ```AppinioSwiperController``` regardless of the chosen swipe direction (which is still used when ```swipe``` is called through the controller). Just like the swipeLeft and swipeRight call, you can call ```swipeUp``` or ```swipeDown``` through the controller anywhere you want. ### Restrict horizontal or vertical swipe You can now restrict the swipe in either horizontal directions or vertical directions using ```swipeOptions``` property. ### Set looping for card swipe Now you can set the ```loop``` property to ```true``` and make the list infinitely scrollable. ### Update the cards while swiping In this version we have replaced the list of cards with ```cardsBuilder```. Now the widget only renders two cards at a time which makes it lightweight and scalable. So you can perform operations on your card anytime. ## Show Cases Trigger swipe right and swipe left however you want... Unswipe the cards however you want... Customize the angle... Customize the threshold of the swiper, when the card should slide away... ## Installation Create a new project with the command ```yaml flutter create MyApp ``` Add ```yaml appinio_swiper: ... ``` to your `pubspec.yaml` of your flutter project. **OR** run ```yaml flutter pub add appinio_swiper ``` in your project's root directory. In your library add the following import: ```dart import 'package:appinio_swiper/appinio_swiper.dart'; ``` For help getting started with Flutter, view the online [documentation](https://flutter.io/). ## Usage You can place your `AppinioSwiper` inside of a `Scaffold` or `CupertinoPageScaffold` like we did here. Optional parameters can be defined to enable different features. See the following example.. ```dart import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:flutter/cupertino.dart'; class Example extends StatelessWidget { @override Widget build(BuildContext context) { return CupertinoPageScaffold( child: SizedBox( height: MediaQuery .of(context) .size .height * 0.75, child: AppinioSwiper( cardsCount: 10, onSwiping: (AppinioSwiperDirection direction) { print(direction.toString()); }, cardsBuilder: (BuildContext context, int index) { return Container( alignment: Alignment.center, child: const Text(index.toString()), color: CupertinoColors.activeBlue, ); }, ), ), ); } } ``` ## Constructor #### Basic | Parameter | Default | Description | Required | |------------------|:---------------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------|:--------:| | cardCount | - | Number of cards you want to render. | true | | backgroundCardCount | 1 | Number of cards you want to render in background. | false | | backgroundCardScale | .9 | Scale factor for the background card. | false | | backgroundCardOffset | - | Offset for the background card. | false | | cardBuilder | - | Callback of the type CardsBuilder. | true | | swipeOptions | - | value of type AppinioSwipeOptions to restrict swipes. | false | | invertAngleOnBottomDrag | true | Sets whether the card should angle in the opposite direction when it is dragged from the bottom half. | false | | controller | - | Trigger swipe, unSwipe and animateTo. | false | | padding | EdgeInsets.symmetric(horizontal: 20, vertical: 25) | Control swiper padding | false | | duration | 200 milliseconds | The duration that every animation should last | false | | cardsSpacing | 40 | The spacing between background cards. | false | | maxAngle | 30 | Maximum angle the card reaches while swiping | false | | threshold | 50 | Threshold from which the card is swiped away | false | | isDisabled | false | Set to ```true``` if swiping should be disabled, has no impact when triggered from the outside | false | | onTapDisabled | - | Function that get triggered when the swiper is disabled | false | | onSwipeBegin | - | Called when user starts to swipe a card. | false | | onSwipeEnd | - | Called swipe action completes. | false | | onCardPositionChanged | - | Called when card position changes. | false | | onEnd | - | Called when there is no Widget left to be swiped away | false | | defaultDirection | right | Direction in which the card is swiped away when triggered from the outside | false | | allowUnswipe | true | Set to ```false``` if unswipe should be disabled away | false | | unlimitedUnswipe | false | Set to ```true``` if the user can unswipe as many cards as possible | false | | onUnswipe | - | Called with the boolean ```true``` when the last card gets unswiped and with the boolean ```false``` if there is no card to unswipe | false | | onSwipeCancelled | - | Gets called when the user leaves the card before the threshold is reached | false | #### Controller The ```Controller``` is used to control the ```swipeDefault```, ```swipeLeft```, ```swipeRight```, ```swipeUp``` , ```swipeDown``` , ```unswipe``` and ```animateTo``` function of the swiper from outside of the widget. You can create a controller called ```AppinioSwiperController``` and save the instance for further usage. Please have a closer look to our Example for the usage. | Method | Description | |------------|:---------------------------------------------------------------------------------------------------| | swipe | Changes the state of the controller to swipe and swipes the card in your selected direction. | | swipeLeft | Changes the state of the controller to swipe left and swipes the card to the left side. | | swipeRight | Changes the state of the controller to swipe right and swipes the card to the right side. | | swipeUp | Changes the state of the controller to swipe up and swipes the card to the up side. | | swipeDown | Changes the state of the controller to swipe down and swipes the card to the down side. | | unswipe | Changes the state of the controller to unswipe and brings back the last card that was swiped away. | | animateTo | Animates the current offset of the card on top to the required Offset in a given duration. |
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/appinio_swiper/analysis_options.yaml ================================================ #include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options linter: rules: - unawaited_futures ================================================ FILE: packages/appinio_swiper/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/appinio_swiper/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 18116933e77adc82f80866c928266a5b4f1ed645 channel: stable project_type: app ================================================ FILE: packages/appinio_swiper/example/README.md ================================================ # example A new Flutter project. ## 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. ================================================ FILE: packages/appinio_swiper/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. # include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_swiper/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/appinio_swiper/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 33 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" minSdkVersion flutter.minSdkVersion targetSdkVersion 33 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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/appinio_swiper/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_swiper/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.7.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.1.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { delete rootProject.buildDir } ================================================ FILE: packages/appinio_swiper/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists ================================================ FILE: packages/appinio_swiper/example/android/gradle.properties ================================================ # https://stackoverflow.com/questions/76230485/flutter-application-on-android-private-final-java-lang-string-java-io-file-path org.gradle.jvmargs=-Xmx1536M --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/appinio_swiper/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/appinio_swiper/example/ios/.gitignore ================================================ **/dgph *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/appinio_swiper/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/appinio_swiper/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/appinio_swiper/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/appinio_swiper/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Info.plist ================================================ 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 ================================================ FILE: packages/appinio_swiper/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 = 1020; 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 = 9.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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 */; } ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_swiper/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_swiper/example/lib/example_buttons.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:appinio_swiper/appinio_swiper.dart'; //swipe card to the right side Widget swipeRightButton(AppinioSwiperController controller) { // We can listen to the controller to get updated as the card shifts position! return ListenableBuilder( listenable: controller, builder: (context, child) { final SwiperPosition? position = controller.position; final SwiperActivity? activity = controller.swipeActivity; // Lets measure the progress of the swipe iff it is a horizontal swipe. final double progress = (activity is Swipe || activity == null) && position != null && position.offset.toAxisDirection().isHorizontal ? position.progressRelativeToThreshold.clamp(-1, 1) : 0; // Lets animate the button according to the // progress. Here we'll color the button more grey as we swipe away from // it. final Color color = Color.lerp( CupertinoColors.activeGreen, CupertinoColors.systemGrey2, (-1 * progress).clamp(0, 1), )!; return GestureDetector( onTap: () => controller.swipeRight(), child: Transform.scale( scale: 1 + .1 * progress.clamp(0, 1), child: Container( height: 60, width: 60, decoration: BoxDecoration( color: color, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: color.withOpacity(0.9), spreadRadius: -10, blurRadius: 20, offset: const Offset(0, 20), // changes position of shadow ), ], ), alignment: Alignment.center, child: const Icon( Icons.check, color: CupertinoColors.white, size: 40, ), ), ), ); }, ); } //swipe card to the left side Widget swipeLeftButton(AppinioSwiperController controller) { return ListenableBuilder( listenable: controller, builder: (context, child) { final SwiperPosition? position = controller.position; final SwiperActivity? activity = controller.swipeActivity; final double horizontalProgress = (activity is Swipe || activity == null) && position != null && position.offset.toAxisDirection().isHorizontal ? -1 * position.progressRelativeToThreshold.clamp(-1, 1) : 0; final Color color = Color.lerp( const Color(0xFFFF3868), CupertinoColors.systemGrey2, (-1 * horizontalProgress).clamp(0, 1), )!; return GestureDetector( onTap: () => controller.swipeLeft(), child: Transform.scale( // Increase the button size as we swipe towards it. scale: 1 + .1 * horizontalProgress.clamp(0, 1), child: Container( height: 60, width: 60, decoration: BoxDecoration( color: color, shape: BoxShape.circle, boxShadow: [ BoxShadow( color: color.withOpacity(0.9), spreadRadius: -10, blurRadius: 20, offset: const Offset(0, 20), // changes position of shadow ), ], ), alignment: Alignment.center, child: const Icon( Icons.close, color: CupertinoColors.white, ), ), ), ); }, ); } //unswipe card Widget unswipeButton(AppinioSwiperController controller) { return GestureDetector( onTap: () => controller.unswipe(), child: Container( height: 60, width: 60, alignment: Alignment.center, child: const Icon( Icons.rotate_left_rounded, color: CupertinoColors.systemGrey2, ), ), ); } class TutorialAnimationButton extends StatelessWidget { const TutorialAnimationButton(this.onTap, {super.key}); final VoidCallback onTap; @override Widget build(BuildContext context) { return GestureDetector( onTap: onTap, child: const Icon( Icons.question_mark, color: CupertinoColors.systemGrey2, ), ); } } ================================================ FILE: packages/appinio_swiper/example/lib/example_candidate_model.dart ================================================ import 'package:flutter/cupertino.dart'; class ExampleCandidateModel { String? name; String? job; String? city; LinearGradient? color; ExampleCandidateModel({ this.name, this.job, this.city, this.color, }); } List candidates = [ ExampleCandidateModel( name: 'Eight, 8', job: 'Manager', city: 'Town', color: gradientPink, ), ExampleCandidateModel( name: 'Seven, 7', job: 'Manager', city: 'Town', color: gradientBlue, ), ExampleCandidateModel( name: 'Six, 6', job: 'Manager', city: 'Town', color: gradientPurple, ), ExampleCandidateModel( name: 'Five, 5', job: 'Manager', city: 'Town', color: gradientRed, ), ExampleCandidateModel( name: 'Four, 4', job: 'Manager', city: 'Town', color: gradientPink, ), ExampleCandidateModel( name: 'Three, 3', job: 'Manager', city: 'Town', color: gradientBlue, ), ExampleCandidateModel( name: 'Two, 2', job: 'Manager', city: 'Town', color: gradientPurple, ), ExampleCandidateModel( name: 'One, 1', job: 'Manager', city: 'Town', color: gradientRed, ), ]; const LinearGradient gradientRed = LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFFF3868), Color(0xFFFFB49A), ], ); const LinearGradient gradientPurple = LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFF736EFE), Color(0xFF62E4EC), ], ); const LinearGradient gradientBlue = LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFF0BA4E0), Color(0xFFA9E4BD), ], ); const LinearGradient gradientPink = LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFFFF6864), Color(0xFFFFB92F), ], ); const LinearGradient kNewFeedCardColorsIdentityGradient = LinearGradient( begin: Alignment.topCenter, end: Alignment.bottomCenter, colors: [ Color(0xFF7960F1), Color(0xFFE1A5C9), ], ); ================================================ FILE: packages/appinio_swiper/example/lib/example_card.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'example_candidate_model.dart'; class ExampleCard extends StatelessWidget { final ExampleCandidateModel candidate; const ExampleCard({ Key? key, required this.candidate, }) : super(key: key); @override Widget build(BuildContext context) { return Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: CupertinoColors.white, boxShadow: [ BoxShadow( color: CupertinoColors.systemGrey.withOpacity(0.2), spreadRadius: 3, blurRadius: 7, offset: const Offset(0, 3), ) ], ), alignment: Alignment.center, child: Column( children: [ Flexible( child: Container( decoration: BoxDecoration( gradient: candidate.color, borderRadius: const BorderRadius.only( topLeft: Radius.circular(10), topRight: Radius.circular(10), ), ), ), ), Container( padding: const EdgeInsets.all(15), decoration: const BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(10), bottomRight: Radius.circular(10), ), ), child: Row( children: [ Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( candidate.name!, style: const TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 20, ), ), const SizedBox( height: 5, ), Text( candidate.job!, style: const TextStyle( color: Colors.grey, fontSize: 15, ), ), const SizedBox( height: 5, ), Text( candidate.city!, style: const TextStyle( color: Colors.grey, fontSize: 15, ), ) ], ), ], ), ), ], ), ); } } ================================================ FILE: packages/appinio_swiper/example/lib/main.dart ================================================ import 'dart:developer'; import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:example/example_candidate_model.dart'; import 'package:example/example_card.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'example_buttons.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({ Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return const CupertinoApp( debugShowCheckedModeBanner: false, home: Example(), ); } } class Example extends StatefulWidget { const Example({ Key? key, }) : super(key: key); @override State createState() => _ExamplePageState(); } class _ExamplePageState extends State { final AppinioSwiperController controller = AppinioSwiperController(); @override void initState() { Future.delayed(const Duration(seconds: 1)).then((_) { _shakeCard(); }); super.initState(); } @override Widget build(BuildContext context) { return Material( child: CupertinoPageScaffold( child: Column( children: [ const SizedBox( height: 50, ), SizedBox( height: MediaQuery.of(context).size.height * .75, child: Padding( padding: const EdgeInsets.only( left: 25, right: 25, top: 50, bottom: 40, ), child: AppinioSwiper( invertAngleOnBottomDrag: true, backgroundCardCount: 3, swipeOptions: const SwipeOptions.all(), controller: controller, onCardPositionChanged: ( SwiperPosition position, ) { //debugPrint('${position.offset.toAxisDirection()}, ' // '${position.offset}, ' // '${position.angle}'); }, onSwipeEnd: _swipeEnd, onEnd: _onEnd, cardCount: candidates.length, cardBuilder: (BuildContext context, int index) { return ExampleCard(candidate: candidates[index]); }, ), ), ), IconTheme.merge( data: const IconThemeData(size: 40), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ TutorialAnimationButton(_shakeCard), const SizedBox( width: 20, ), swipeLeftButton(controller), const SizedBox( width: 20, ), swipeRightButton(controller), const SizedBox( width: 20, ), unswipeButton(controller), ], ), ) ], ), ), ); } void _swipeEnd(int previousIndex, int targetIndex, SwiperActivity activity) { switch (activity) { case Swipe(): log('The card was swiped to the : ${activity.direction}'); log('previous index: $previousIndex, target index: $targetIndex'); break; case Unswipe(): log('A ${activity.direction.name} swipe was undone.'); log('previous index: $previousIndex, target index: $targetIndex'); break; case CancelSwipe(): log('A swipe was cancelled'); break; case DrivenActivity(): log('Driven Activity'); break; } } void _onEnd() { log('end reached!'); } // Animates the card back and forth to teach the user that it is swipable. Future _shakeCard() async { const double distance = 30; // We can animate back and forth by chaining different animations. await controller.animateTo( const Offset(-distance, 0), duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, ); await controller.animateTo( const Offset(distance, 0), duration: const Duration(milliseconds: 400), curve: Curves.easeInOut, ); // We need to animate back to the center because `animateTo` does not center // the card for us. await controller.animateTo( const Offset(0, 0), duration: const Duration(milliseconds: 200), curve: Curves.easeInOut, ); } } ================================================ FILE: packages/appinio_swiper/example/pubspec.yaml ================================================ name: example description: Example for the Appinio Swiper publish_to: 'none' version: 0.0.1 environment: sdk: ">=3.0.0 <4.0.0" dependencies: flutter: sdk: flutter appinio_swiper: path: ../ dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true assets: - assets/ ================================================ FILE: packages/appinio_swiper/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility that Flutter provides. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/appinio_swiper/example/web/index.html ================================================ example ================================================ FILE: packages/appinio_swiper/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/appinio_swiper/lib/appinio_swiper.dart ================================================ import 'dart:collection'; import 'dart:math'; import 'package:appinio_swiper/types.dart'; import 'package:flutter/material.dart'; import 'enums.dart'; export 'enums.dart'; export 'types.dart'; class AppinioSwiper extends StatefulWidget { /// The indexed widget builder that builds a card for the given index. final IndexedWidgetBuilder cardBuilder; /// The number of cards in the stack. final int cardCount; /// This callback is called when user unswipe the card final void Function(SwiperActivity activity)? onUnSwipe; /// This callback is called when user cancels the swipe before reaching threshold final void Function(SwiperActivity activity)? onSwipeCancelled; /// Allow unswipe. final bool allowUnSwipe; /// Allow unlimited unswipe. final bool allowUnlimitedUnSwipe; /// Background cards count final int backgroundCardCount; /// The amount to scale each successive background card down by, /// /// The difference in scale for each background card is a fixed amount /// relative to the original card. /// /// Defaults to .9. final double backgroundCardScale; /// The amount to offset each successive background card relative to the card /// before it. /// /// Defaults to offsetting each card down by 40 dp. final Offset? backgroundCardOffset; /// A controller that provides programmatic control of the swiper and notifies /// on swiper state changes. final AppinioSwiperController? controller; /// The card index to start the swiper at. /// /// This field is only considered when initializing an [AppinioSwiper]. /// Changing the [initialIndex] to a swiper that is already built will have no /// effect. /// /// If non-null, must be a value between 0 and [cardCount] (inclusive). /// Note that an initial index of [cardCount] will start the swiper at the end /// of the stack with no cards left to swipe. /// /// Defaults to 0. final int? initialIndex; /// The duration of swipe animations. /// /// Swipe animations start after the user lifts their finger or when a drag /// is triggered by [AppinioSwiperController]. final Duration duration; /// A callback that is called with the card's [SwiperPosition] whenever the /// position changes. final void Function(SwiperPosition position)? onCardPositionChanged; /// The maximum angle the card reaches while horizontally swiping. /// /// Cards lean in the direction of the swipe to sell their physicality. Set /// this to 0 to disable the lean. final double maxAngle; /// Sets whether the card should angle in the opposite direction when it is /// dragged from the bottom half. /// /// Defaults to true. final bool invertAngleOnBottomDrag; /// What swipe directions to allow. /// /// Swipes triggered by a controller are always allowed and are not affected /// by [swipeOptions]. final SwipeOptions swipeOptions; /// The minimum distance a user has to pan the card before triggering a swipe /// animation. /// /// If a pan is less than [threshold] the card will animate back to it's /// original position and the card stack will not change. final double threshold; /// Set to true to disable swiping. final bool isDisabled; /// Set to true if you want the card stack to loop back to the beginning when /// the user swipes to the end. /// /// The looped cards will be displayed under the foreground card as if final bool loop; /// Callback that fires with the new swiping activity (eg a user swipes or /// the controller triggers a programmatic swipe). /// /// See [SwiperActivity] for a list of activities. final OnSwipe? onSwipeBegin; /// Callback that fires with a swipe activity after the activity is complete. /// /// See [SwiperActivity] for a list of activities. final OnSwipe? onSwipeEnd; /// Function that is called when the card stack runs out of cards. final VoidCallback? onEnd; /// Function that is called when a user attempts to swipe but swiping is /// disabled. final VoidCallback? onTapDisabled; /// The default direction in which the card gets swiped when triggered by /// controller. /// /// Defaults to [AxisDirection.right]. final AxisDirection defaultDirection; const AppinioSwiper({ Key? key, required this.cardBuilder, required this.cardCount, this.controller, this.initialIndex, this.duration = const Duration(milliseconds: 200), this.maxAngle = 15, this.invertAngleOnBottomDrag = true, this.threshold = 50, this.backgroundCardCount = 1, this.backgroundCardScale = .9, this.backgroundCardOffset, this.isDisabled = false, this.loop = false, this.swipeOptions = const SwipeOptions.all(), this.onTapDisabled, this.onSwipeBegin, this.onSwipeEnd, this.onCardPositionChanged, this.onEnd, this.defaultDirection = AxisDirection.right, this.allowUnSwipe = true, this.allowUnlimitedUnSwipe = true, this.onUnSwipe, this.onSwipeCancelled, }) : assert(maxAngle >= 0), assert(threshold > 0), assert(initialIndex == null || (initialIndex >= 0 && initialIndex <= cardCount)), super(key: key); @override State createState() => _AppinioSwiperState(); } class _AppinioSwiperState extends State with TickerProviderStateMixin { bool _canUnSwipeOnce = false; static const _defaultBackgroundCardOffset = Offset(0, 40); double get _effectiveScaleIncrement => 1 - widget.backgroundCardScale; Offset get _effectiveOffset => widget.backgroundCardOffset ?? _defaultBackgroundCardOffset; SwiperActivity? _swipeActivity; // The future associated with the current swipe activity. Future? _previousActivityFuture; AnimationController get _defaultAnimation => AnimationController( vsync: this, duration: widget.duration, ); late final SwiperPosition _position = SwiperPosition( cardSize: MediaQuery.sizeOf(context), cardCount: widget.cardCount, threshold: widget.threshold, maxAngleRadians: widget.maxAngle, invertAngleOnBottomDrag: widget.invertAngleOnBottomDrag, loop: widget.loop, initialIndex: widget.initialIndex, ); // Keep track of the swiped items to unswipe from the same direction final Queue _activityHistory = Queue(); bool get _canUnswipe => _activityHistory.isNotEmpty && widget.allowUnSwipe; void _setCardIndex(int index) { setState(() { _position._baseIndex = index; }); } Future _onSwipe(AxisDirection direction) async { _canUnSwipeOnce = true; final Swipe swipe = Swipe( _defaultAnimation, begin: _position._offset, end: _directionToTarget(direction), ); await _startActivity(swipe); } Future _onUnswipe() async { if (!_canUnswipe) { return; } if (!widget.allowUnlimitedUnSwipe && !_canUnSwipeOnce) { return; } _canUnSwipeOnce = false; final Swipe swipeToUndo = _activityHistory.removeLast(); final Unswipe unSwipe = Unswipe( _defaultAnimation, begin: _directionToTarget(swipeToUndo.direction), ); await _startActivity(unSwipe); widget.onUnSwipe?.call(unSwipe); } // Moves the card back to starting position when a drag finished without // having reached the threshold. void _onSwipeCancelled(BuildContext context) async { final CancelSwipe cancelSwipe = CancelSwipe( _defaultAnimation, begin: _position._offset, ); await _startActivity(cancelSwipe); widget.onSwipeCancelled?.call(cancelSwipe); } Future _startActivity(SwiperActivity newActivity) async { final int previousIndex = _position.index; final SwiperActivity? oldActivity = _swipeActivity; if (oldActivity != null) { // Cancel the existing animation and wait for it to clean up. oldActivity.animation.stop(); await _previousActivityFuture; } final int targetIndex = _position._baseIndexToEffectiveIndex(switch (newActivity) { Swipe() => _position._baseIndex + 1, Unswipe() => _position._baseIndex - 1, CancelSwipe() => _position._baseIndex, DrivenActivity() => _position._baseIndex, }); _swipeActivity = newActivity; if (newActivity is Swipe) { _activityHistory.add(newActivity); } newActivity.animation.addListener(() { _position.offset = newActivity.currentOffset; setState(() {}); }); widget.onSwipeBegin?.call(_position.index, targetIndex, newActivity); _previousActivityFuture = newActivity.animation .forward() .orCancel .then((_) => false) .onError((error, stackTrace) { if (error is TickerCanceled) { return true; } throw error!; }).then((wasCancelled) { newActivity.animation.dispose(); _swipeActivity = null; _position._rotationPosition = null; _position._baseIndex = targetIndex; _swipeActivity = null; if (!wasCancelled && newActivity is! DrivenActivity) { _position._offset = Offset.zero; } return wasCancelled; }); await _previousActivityFuture; widget.onSwipeEnd?.call(previousIndex, targetIndex, newActivity); if (targetIndex >= widget.cardCount && newActivity is Swipe) { // We reached the end, do not run the activity. if (targetIndex > widget.cardCount && !widget.loop) { return; } widget.onEnd?.call(); } setState(() {}); } Future _animateTo( Offset target, { required Duration duration, required Curve curve, }) async { final DrivenActivity newActivity = DrivenActivity( AnimationController( vsync: this, duration: duration, ), curve: curve, begin: _position.offset, end: target, ); await _startActivity(newActivity); } @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { // Attach the controller after the frame because `_attach` uses `position` // which isn't valid until after `initState` has finished. widget.controller?._attach(this); }); } @override void dispose() { widget.controller?._detach(); _swipeActivity?.animation.dispose(); super.dispose(); } @override void didUpdateWidget(covariant AppinioSwiper oldWidget) { if (oldWidget.cardCount != widget.cardCount || oldWidget.threshold != widget.threshold || oldWidget.maxAngle != widget.maxAngle || oldWidget.invertAngleOnBottomDrag != widget.invertAngleOnBottomDrag || oldWidget.loop != widget.loop) { _position._updateFromWidgetState(widget); } if (oldWidget.controller != widget.controller) { oldWidget.controller?._detach(); widget.controller?._attach(this); } super.didUpdateWidget(oldWidget); } @override void didChangeDependencies() { _position._cardSize = MediaQuery.of(context).size; super.didChangeDependencies(); } @override Widget build(BuildContext context) { // Use the clamp to ensure we don't go past 1. final double maxProgressToThreshold = max( _position._offsetRelativeToSize.dx.abs(), _position._offsetRelativeToSize.dy.abs(), ).clamp(0, 1); // If we're unswiping we need to apply the foreground transformations to the // incoming card item instead of the current index. final int foregroundIndex = _swipeActivity is Unswipe // Add the card count and mod it back out to handle the case where // loop is enabled and we're undoing the first card in the list. ? (_position.index + widget.cardCount - 1) % widget.cardCount : _position.index; final int backgroundIndex = _swipeActivity is Unswipe ? foregroundIndex : (foregroundIndex + 1) % widget.cardCount; final int effectiveBackgroundCardCount = _effectiveBackgroundCardCount(backgroundIndex); return Stack( clipBehavior: Clip.none, fit: StackFit.expand, children: [ if (effectiveBackgroundCardCount > 0) _BackgroundCards( position: _position, indices: List.generate( effectiveBackgroundCardCount, (index) => (foregroundIndex + index + 1) % widget.cardCount, ), builder: widget.cardBuilder, scaleIncrement: _effectiveScaleIncrement, offsetIncrement: _effectiveOffset, initialEffectFactor: 1 - maxProgressToThreshold, fadeLastItem: effectiveBackgroundCardCount > widget.backgroundCardCount, ), if (foregroundIndex < widget.cardCount) Transform.translate( offset: _position.offset, child: GestureDetector( child: Transform.rotate( angle: _position.angleRadians, alignment: _position._rotationAlignment ?? Alignment.bottomCenter, child: Container( child: widget.cardBuilder(context, foregroundIndex), ), ), onTap: () { if (widget.isDisabled) { widget.onTapDisabled?.call(); } }, onPanStart: (tapInfo) { if (widget.isDisabled) { return; } _position._rotationPosition = tapInfo.localPosition; }, onPanUpdate: (tapInfo) { if (widget.isDisabled) { return; } setState(() { final swipeOption = widget.swipeOptions; final canMoveDown = (swipeOption.down || _position.offset.dy < 0) && tapInfo.delta.dy > 0; final canMoveUp = (swipeOption.up || _position.offset.dy > 0) && tapInfo.delta.dy < 0; final canMoveLeft = (swipeOption.left || _position.offset.dx > 0) && tapInfo.delta.dx < 0; final canMoveRight = (swipeOption.right || _position.offset.dx < 0) && tapInfo.delta.dx > 0; final Offset tapDelta = tapInfo.delta; double dx = 0; double dy = 0; if (canMoveUp) { dy = tapDelta.dy; } else if (canMoveDown) { dy = tapDelta.dy; } if (canMoveLeft) { dx = tapDelta.dx; } else if (canMoveRight) { dx = tapDelta.dx; } _position.offset += Offset(dx, dy); }); _onSwiping(); }, onPanEnd: (tapInfo) async { if (!widget.isDisabled) { return _onPanEnd(); } }, ), ), ], ); } int _effectiveBackgroundCardCount(int index) { if (widget.cardCount == 0) { return 0; } // Use one extra card so cards entering the stack can fade in smoothly. final int effectiveCardCount = widget.backgroundCardCount + 1; if (widget.loop) { return effectiveCardCount; } final int remaining = widget.cardCount - _position.index - 1; return (_swipeActivity is Unswipe ? remaining + 1 : remaining) .clamp(0, effectiveCardCount); } Future _onSwiping() async { widget.onCardPositionChanged?.call(_position); } Offset _directionToTarget(AxisDirection direction) { final Size size = MediaQuery.sizeOf(context); return switch (direction) { AxisDirection.up => Offset(0, -size.height), AxisDirection.down => Offset(0, size.height), AxisDirection.left => Offset(-size.width, 0), AxisDirection.right => Offset(size.width, 0), }; } Future _onPanEnd() async { // TODO: Use a ballistic simulation to determine if the swipe should be // triggered or not. // See the snapping behavior from `DraggableScrollableSheet`. if (_position._offsetRelativeToThreshold.dx.abs() < 1 && _position._offsetRelativeToThreshold.dy.abs() < 1) { return _onSwipeCancelled(context); } await _onSwipe(_position.offset.toAxisDirection()); } Future _onSwipeDefault() async { return _onSwipe(widget.defaultDirection); } } class _BackgroundCards extends StatelessWidget { const _BackgroundCards({ required this.position, required this.indices, required this.builder, required this.scaleIncrement, required this.offsetIncrement, required this.initialEffectFactor, required this.fadeLastItem, }); final SwiperPosition position; // The indices in the original card stack. This is a list instead of a start // and count because it may be non-contiguous if `loop` is true. final List indices; final IndexedWidgetBuilder builder; final double scaleIncrement; final Offset offsetIncrement; final double initialEffectFactor; final bool fadeLastItem; @override Widget build(BuildContext context) { return ListenableBuilder( listenable: position, builder: (context, child) { return Stack( children: indices .asMap() .map( (j, index) { final double effectFactor = initialEffectFactor + j; final Offset offset = offsetIncrement * effectFactor; final double scale = 1 - (effectFactor * scaleIncrement); if (scale <= 0) { return MapEntry(j, null); } return MapEntry( j, Opacity( opacity: fadeLastItem && j == indices.length - 1 ? min(1, position.progress) : 1, child: Transform.translate( offset: offset, child: Transform.scale( scale: scale, child: builder(context, index), ), ), ), ); }, ) .values .nonNulls .toList() .reversed .toList(), ); }, ); } } /// A controller used to control an [AppinioSwiper], /// /// The controller notifies listeners when a swipe starts and for each tick of a /// swipe animation. class AppinioSwiperController extends ChangeNotifier { _AppinioSwiperState? _attachedSwiper; /// The current activity of the swiper. /// /// This is non null when: /// 1. The user has finished their drag while manually swiping. /// 2. A programmatic swipe is triggered from this controller. SwiperActivity? get swipeActivity { return _attachedSwiper?._swipeActivity; } /// The position of the swiper. SwiperPosition? get position { return _attachedSwiper?._position; } /// The history of swipes for the swiper widget currently attached to this /// controller. /// /// If the history is empty, un swipes will do nothing. Future?> get activityHistory async { return _attachedSwiper?._activityHistory.toList(growable: false); } /// The current position of the card, as a result of a user drag and/or a /// swipe animation. /// /// This is 0 when there is no active swipe. It increments up to 1 during an /// active swipe and then resets to 0 when the swipe is complete. Offset? get swipeProgress { return position?._offsetRelativeToSize; } /// The index of the card currently on the top. /// /// This cycles to the next card only after the previous card has fully /// animated off the screen. int? get cardIndex { return position?.index; } /// Swipe the card in the default direction. /// /// The default direction is set by the attached [AppinioSwiper] widget. Future swipeDefault() async { _assertIsAttached(); await _attachedSwiper!._onSwipeDefault(); notifyListeners(); } /// Swipe the card to the left side. Future swipeLeft() async { _assertIsAttached(); await _attachedSwiper!._onSwipe(AxisDirection.left); notifyListeners(); } /// Swipe the card to the right side. Future swipeRight() async { _assertIsAttached(); // ignore: unawaited_futures _attachedSwiper!._onSwipe(AxisDirection.right); notifyListeners(); } /// Unswipe the card. Future unswipe() async { _assertIsAttached(); await _attachedSwiper!._onUnswipe(); notifyListeners(); } /// Swipe the card to the top. Future swipeUp() async { _assertIsAttached(); await _attachedSwiper!._onSwipe(AxisDirection.up); notifyListeners(); } /// Swipe the card to the bottom. Future swipeDown() async { _assertIsAttached(); await _attachedSwiper!._onSwipe(AxisDirection.down); notifyListeners(); } /// Animate the card at the top of the stack to the specified offset. /// /// The card will not reset or snap at the end of the animation-it is up to /// the caller to animate the card back to the center. Future animateTo( Offset target, { required Duration duration, required Curve curve, }) async { _assertIsAttached(); await _attachedSwiper!._animateTo( target, duration: duration, curve: curve, ); } void _attach(_AppinioSwiperState swiper) { assert( _attachedSwiper == null, 'Controller can only be attached to one swiper widget at a time.', ); _attachedSwiper = swiper; swiper._position.addListener(notifyListeners); } void _detach() { _attachedSwiper?._position.removeListener(notifyListeners); _attachedSwiper = null; } void _assertIsAttached() { assert(_attachedSwiper != null, 'Controller must be attached.'); } void setCardIndex(int index) { _assertIsAttached(); _attachedSwiper?._setCardIndex(index); notifyListeners(); } } /// The position of the swiper. /// /// This includes the current card index and the offset and rotations applied to /// the top card. You can use this position to coordinate custom animations with /// the swiper state. /// /// The swiper position is exposed by [AppinioSwiperController]. class SwiperPosition with ChangeNotifier { SwiperPosition({ required Size cardSize, required int cardCount, required double threshold, required double maxAngleRadians, required bool invertAngleOnBottomDrag, required bool loop, required int? initialIndex, }) : _cardSize = cardSize, _cardCount = cardCount, _threshold = threshold, _maxAngle = maxAngleRadians, _invertAngleOnBottomDrag = invertAngleOnBottomDrag, _loop = loop, _baseIndex = initialIndex ?? 0; set offset(Offset newOffset) { _offset = newOffset; notifyListeners(); } /// The offset of the card on the top of the stack. Offset get offset => _offset; /// The rotation angle of the card in degrees. /// /// This is 0 when [progress] is 0 and negative or positive /// [AppinioSwiper.maxAngle] when [progress] is 1. /// /// A negative angle indicated counterclockwise rotation, positive clockwise. double get angle { // If we allow inverting the direction and the user is dragging from the // bottom half of the card, angle in the opposite direction. final direction = _invertAngleOnBottomDrag && _rotationAlignment != null && _rotationAlignment!.y > 0 ? -1 : 1; return (direction * _maxAngle * (_offset.dx / _cardSize.width)) .clamp(-_maxAngle, _maxAngle); } /// The rotation angle of the card in radians. /// /// See [angle]. double get angleRadians => angle * (pi / 180); /// The current swiping progress of the top card. /// /// This is 0 when the card is centered and 1 when it is swiped offscreen and /// about to be dismissed. double get progress => max( _offsetRelativeToSize.dx.abs(), _offsetRelativeToSize.dy.abs(), ); /// The current swiping progress relative to the swiping threshold. /// /// This is 0 when the card is centered and greater than 1 when it is swiped /// past the threshold at which a card will swipe off screen instead of /// returning to the center. double get progressRelativeToThreshold { final Offset offset = _offsetRelativeToThreshold; if (offset.dx.abs() > offset.dy) { return offset.dx; } return offset.dy; } /// The pixel size of the top card. /// /// This can be used to convert offsets relative to the card size. Size get cardSize => _cardSize; /// The current index of the swiper. /// /// This is updated after a [SwiperActivity] is completely finished. If /// [AppinioSwiper.loop] is true, this will wrap to 0 at the end of the card /// stack. Otherwise, it will be equal to the length of the card stack when /// the stack is finished. int get index => _baseIndexToEffectiveIndex(_baseIndex); // When the user starts a pan we save the point they tapped. We then rotate // the card around this point as they swipe. // By rotating around the point of their tap we ensure that their finger // stays in the same local position relative to the card. Offset? _rotationPosition; Alignment? get _rotationAlignment => _rotationPosition?.toAlignment(cardSize); // All variables are private so that they can be updated without allowing // external packages to modify them. Offset _offset = Offset.zero; Size _cardSize; int _cardCount; double _threshold; double _maxAngle; bool _loop; bool _invertAngleOnBottomDrag; // This is the index before modulo-ing to account for looping. int _baseIndex = 0; Offset get _offsetRelativeToSize => Offset( _offset.dx / _cardSize.width, _offset.dy / _cardSize.height, ); Offset get _offsetRelativeToThreshold => Offset( _offset.dx / _threshold, _offset.dy / _threshold, ); void _updateFromWidgetState(AppinioSwiper widget) { _cardCount = widget.cardCount; _threshold = widget.threshold; _maxAngle = widget.maxAngle; _invertAngleOnBottomDrag = widget.invertAngleOnBottomDrag; _loop = widget.loop; notifyListeners(); } int _baseIndexToEffectiveIndex(int i) { return _loop ? i % _cardCount : i; } } ================================================ FILE: packages/appinio_swiper/lib/enums.dart ================================================ import 'package:appinio_swiper/appinio_swiper.dart'; import 'package:flutter/material.dart'; /// An activity that moves the top card with a beginning and an end. /// /// All Swiper activities inherit from this class. sealed class SwiperActivity extends Tween { SwiperActivity( this.animation, { required super.begin, required super.end, }); final AnimationController animation; Offset get currentOffset => evaluate(animation); AxisDirection get direction { return (end! - begin!).toAxisDirection(); } } /// A swipe triggered either by the controller or a user drag. class Swipe extends SwiperActivity { Swipe( super.animation, { required super.begin, required super.end, }); } /// An unwwipe which undoes the last [Swipe] activity. /// /// Can only be triggered by [AppinioSwiperController]. class Unswipe extends SwiperActivity { Unswipe( super.animation, { required super.begin, }) : super(end: Offset.zero); @override AxisDirection get direction => super.direction.opposite; } /// A return to center triggered when a user releases a drag without having /// reached [AppinioSwiper.threshold] class CancelSwipe extends SwiperActivity { CancelSwipe( super.animation, { required super.begin, }) : super(end: Offset.zero); @override AxisDirection get direction => super.direction.opposite; } /// An animation triggered by [AppinioSwiperController.animateTo]. class DrivenActivity extends SwiperActivity { DrivenActivity( super.animation, { required this.curve, required super.begin, required super.end, }); final Curve curve; late final Animation curvedAnimation = CurvedAnimation( parent: animation, curve: curve, ); @override Offset get currentOffset => evaluate(curvedAnimation); } class SwipeOptions { final bool up; final bool down; final bool left; final bool right; const SwipeOptions.symmetric({ bool horizontal = false, bool vertical = false, }) : up = vertical, down = vertical, left = horizontal, right = horizontal; /// If horizontal and vertical both are true/false then simply make the allDirections true. const SwipeOptions.only({ this.up = false, this.down = false, this.left = false, this.right = false, }); /// If top, left, right, bottom all are true/false then simply make the allDirections true. const SwipeOptions.all() : up = true, down = true, left = true, right = true; } extension DirectionUtils on AxisDirection { bool get isVertical => this == AxisDirection.up || this == AxisDirection.down; bool get isHorizontal => !isVertical; AxisDirection get opposite => switch (this) { AxisDirection.up => AxisDirection.down, AxisDirection.down => AxisDirection.up, AxisDirection.left => AxisDirection.right, AxisDirection.right => AxisDirection.left, }; } extension OffsetUtils on Offset { Alignment toAlignment(Size size) { return Alignment( 2 * (dx / size.width) - 1, 2 * (dy / size.height) - 1, ); } AxisDirection toAxisDirection() { if (dx.abs() >= dy.abs()) { if (dx.isNegative) { return AxisDirection.left; } return AxisDirection.right; } if (dy.isNegative) { return AxisDirection.up; } return AxisDirection.down; } } ================================================ FILE: packages/appinio_swiper/lib/types.dart ================================================ import 'package:appinio_swiper/appinio_swiper.dart'; typedef OnSwipe = void Function( int previousIndex, int targetIndex, SwiperActivity activity, ); ================================================ FILE: packages/appinio_swiper/pubspec.yaml ================================================ name: appinio_swiper description: An awesome fully custamisable Tinder Card Swiper which allows swiping in all directions with any Custom Widget (Stateless or Statefull). version: 2.1.1 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/appinio_swiper environment: sdk: ">=3.0.0 <4.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter # 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. 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.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/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.dev/custom-fonts/#from-packages ================================================ FILE: packages/appinio_swiper/test/appinio_swiper_test.dart ================================================ void main() {} ================================================ FILE: packages/appinio_video_player/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. .vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/appinio_video_player/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 4cc385b4b84ac2f816d939a49ea1f328c4e0b48e channel: stable project_type: package ================================================ FILE: packages/appinio_video_player/CHANGELOG.md ================================================ ## [1.3.0] - 2024.01.24 - Feat: Cache Network Videos - Feat: Mute or Change volume with swiping on right side of screen. - Feat: Hide Picture in Picture Mode - Many other Bug Fixes ## [1.2.2] - 2023.08.23 - Feat: Jump forward and backward like youtube. - ```showSeekButtons``` and ```seekDuration``` added to ```CustomVideoPlayerSettings``` ## [1.2.1] - 2023.04.26 - Fix: Orientation not switching back to portrait in iOS - Fix: Negative duration on sliding back ## [1.2.0] - 2022.08.22 - New: Native Web Video Player - Native controls with accessability through controller - Working native Fullscreen functionality - Works on all browsers (also on Safari iOS) - Poster / Thumbnail options - Fix: No custom aspect ratio on fullscreen ## [1.1.1] - 2022.06.14 - Bringing back the web support - Support older flutter versions ## [1.1.0] - 2022.06.13 - New video player controls - Switch the video quality - Change the playback speed - Play-video-only-once functionality - Controls fade out - Bugfixes ## [1.0.2] - 2022.04.21 - Removed dependencies from other packages (provider, wakelock) - Restructuring ## [1.0.1] - 2021.10.05 - Bugfix: dispose video values ## [1.0.0] - 2021.10.04 - Initial version ================================================ FILE: packages/appinio_video_player/LICENSE ================================================ MIT License Copyright (c) 2021 APPINIO GmbH 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. ================================================ FILE: packages/appinio_video_player/README.md ================================================ # Custom Video Player This package wraps the official video_player package by flutter and extends it with a fully customisable control bar, a fullscreen mode and adjustable video settings. For every control in this video player you can decide if you want to show it and if so how it should look.
## Top Features - [ NEW ] Change voluming with swiping on right side of screen. - [ NEW ] Mute/Unmute video - [ NEW ] Hide Picture in Picture Mode on Web - [ NEW ] Cache Network Video - Seek forward and backward - Fullscreen Mode - Native controls and fullscreen for web apps - Change Video Quality - Thumbnail / Poster - Adjust Playback Speed - Fully Customizable Controls - Fluid Progress Bar - Prevent Seeking in Progress Bar - Prevent video from being played more than once
## Preview ### Fullscreen
## Getting started - To get started just create a VideoPlayerController as you would for the normal video_player and define a source to use. - Secondly create a CustomVideoPlayerController to access the fullscreen and control bar visibility switches by yourself. Pass the controllers to a CustomVideoPlayer widget to use all its functionality and customisation oppurtunities. - Secondly create a CustomVideoPlayerController and pass it the created VideoPlayerController as well as your custom settings or additional video sources - On the examples tab is a selection of parameters you can customize to your needs. There you can also see how the additional video sources are added in case you want the user to be able to switch between video qualities
## Usage ```dart class _MyHomePageState extends State { late VideoPlayerController videoPlayerController; late CustomVideoPlayerController _customVideoPlayerController; String videoUrl = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; @override void initState() { super.initState(); videoPlayerController = VideoPlayerController.network(videoUrl) ..initialize().then((value) => setState(() {})); _customVideoPlayerController = CustomVideoPlayerController( context: context, videoPlayerController: videoPlayerController, ); } @override void dispose() { _customVideoPlayerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: CupertinoNavigationBar( middle: Text(widget.title), ), child: SafeArea( child: CustomVideoPlayer( customVideoPlayerController: _customVideoPlayerController ), ), ); } } ```
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/appinio_video_player/analysis_options.yaml ================================================ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_video_player/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/appinio_video_player/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 4cc385b4b84ac2f816d939a49ea1f328c4e0b48e channel: stable project_type: app ================================================ FILE: packages/appinio_video_player/example/README.md ================================================ # example A new Flutter project. ## 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. ================================================ FILE: packages/appinio_video_player/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/appinio_video_player/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/appinio_video_player/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 33 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" minSdkVersion 16 targetSdkVersion 30 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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/appinio_video_player/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/appinio_video_player/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.6.21' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() mavenCentral() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(':app') } tasks.register("clean", Delete) { delete rootProject.buildDir } ================================================ FILE: packages/appinio_video_player/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip ================================================ FILE: packages/appinio_video_player/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M --add-exports=java.base/sun.nio.ch=ALL-UNNAMED --add-opens=java.base/java.lang=ALL-UNNAMED --add-opens=java.base/java.lang.reflect=ALL-UNNAMED --add-opens=java.base/java.io=ALL-UNNAMED --add-exports=jdk.unsupported/sun.misc=ALL-UNNAMED android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/appinio_video_player/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/appinio_video_player/example/ios/.gitignore ================================================ *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/appinio_video_player/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/appinio_video_player/example/ios/Flutter/Debug.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/appinio_video_player/example/ios/Flutter/Release.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/appinio_video_player/example/ios/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.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 ================================================ FILE: packages/appinio_video_player/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Info.plist ================================================ NSAppTransportSecurity NSAllowsArbitraryLoads 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 ================================================ FILE: packages/appinio_video_player/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 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 */; }; 8996F6AE23C9031A0740F822 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94BFD2677572FC961CF49C58 /* Pods_Runner.framework */; }; 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 */ 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 = ""; }; 18C44B344C7E73E7B28CBD03 /* 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 = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 66FC296F4F61F0D5010AAEBF /* 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 = ""; }; 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 = ""; }; 94BFD2677572FC961CF49C58 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 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 = ""; }; 9D03D847ADF170A4565E0E84 /* 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 = ( 8996F6AE23C9031A0740F822 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 1142CA42B74D6E1697862505 /* Pods */ = { isa = PBXGroup; children = ( 9D03D847ADF170A4565E0E84 /* Pods-Runner.debug.xcconfig */, 66FC296F4F61F0D5010AAEBF /* Pods-Runner.release.xcconfig */, 18C44B344C7E73E7B28CBD03 /* 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 */, 1142CA42B74D6E1697862505 /* Pods */, E2795FABC6CA4978A514896B /* 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 = ""; }; E2795FABC6CA4978A514896B /* Frameworks */ = { isa = PBXGroup; children = ( 94BFD2677572FC961CF49C58 /* Pods_Runner.framework */, ); name = Frameworks; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( 91C82D11BCA6732A0C6B6F29 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, D676C516686C1D5F628CDEDE /* [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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); name = "Thin Binary"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; 91C82D11BCA6732A0C6B6F29 /* [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; }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; 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"; }; D676C516686C1D5F628CDEDE /* [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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 = 9.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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 */; } ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/appinio_video_player/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/appinio_video_player/example/lib/main.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const CupertinoApp( debugShowCheckedModeBanner: false, theme: CupertinoThemeData( brightness: Brightness.light, ), title: 'Appinio Video Player Demo', home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({Key? key}) : super(key: key); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { late CachedVideoPlayerController _videoPlayerController, _videoPlayerController2, _videoPlayerController3; late CustomVideoPlayerController _customVideoPlayerController; late CustomVideoPlayerWebController _customVideoPlayerWebController; final CustomVideoPlayerSettings _customVideoPlayerSettings = const CustomVideoPlayerSettings(showSeekButtons: true); final CustomVideoPlayerWebSettings _customVideoPlayerWebSettings = CustomVideoPlayerWebSettings( src: longVideo, ); @override void initState() { super.initState(); _videoPlayerController = CachedVideoPlayerController.network( longVideo, )..initialize().then((value) => setState(() {})); _videoPlayerController2 = CachedVideoPlayerController.network(video240); _videoPlayerController3 = CachedVideoPlayerController.network(video480); _customVideoPlayerController = CustomVideoPlayerController( context: context, videoPlayerController: _videoPlayerController, customVideoPlayerSettings: _customVideoPlayerSettings, additionalVideoSources: { "240p": _videoPlayerController2, "480p": _videoPlayerController3, "720p": _videoPlayerController, }, ); _customVideoPlayerWebController = CustomVideoPlayerWebController( webVideoPlayerSettings: _customVideoPlayerWebSettings, ); } @override void dispose() { _customVideoPlayerController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text("Appinio Video Player"), ), child: SafeArea( child: ListView( physics: const NeverScrollableScrollPhysics(), children: [ kIsWeb ? Expanded( child: CustomVideoPlayerWeb( customVideoPlayerWebController: _customVideoPlayerWebController, ), ) : CustomVideoPlayer( customVideoPlayerController: _customVideoPlayerController, ), CupertinoButton( child: const Text("Play Fullscreen"), onPressed: () { if (kIsWeb) { _customVideoPlayerWebController.setFullscreen(true); _customVideoPlayerWebController.play(); } else { _customVideoPlayerController.setFullscreen(true); _customVideoPlayerController.videoPlayerController.play(); } }, ), ], ), ), ); } } String videoUrlLandscape = "https://flutter.github.io/assets-for-api-docs/assets/videos/bee.mp4"; String videoUrlPortrait = 'https://assets.mixkit.co/videos/preview/mixkit-a-girl-blowing-a-bubble-gum-at-an-amusement-park-1226-large.mp4'; String longVideo = "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4"; String video720 = "https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_10mb.mp4"; String video480 = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ForBiggerBlazes.mp4"; String video240 = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4"; ================================================ FILE: packages/appinio_video_player/example/pubspec.yaml ================================================ name: example description: A new Flutter project. publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: sdk: ">=2.12.0 <3.0.0" dependencies: appinio_video_player: path: ../ flutter: sdk: flutter cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 flutter: uses-material-design: true ================================================ FILE: packages/appinio_video_player/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility that Flutter provides. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/appinio_video_player/example/web/index.html ================================================ example ================================================ FILE: packages/appinio_video_player/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/appinio_video_player/lib/appinio_video_player.dart ================================================ library appinio_video_player; export 'package:cached_video_player/cached_video_player.dart'; export 'src/custom_video_player.dart'; export 'src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player.dart'; export 'src/models/custom_video_player_progress_bar_settings.dart'; export 'src/models/custom_video_player_settings.dart'; export 'src/custom_video_player_controller.dart' hide ProtectedCustomVideoPlayerController; // web exports export 'src/web_video_player/custom_video_player_web.dart'; export 'src/web_video_player/custom_video_player_web_controller.dart'; export 'src/web_video_player/web_video_player_settings.dart'; ================================================ FILE: packages/appinio_video_player/lib/src/controls/all_controls_overlay.dart ================================================ import 'package:appinio_video_player/src/controls/video_settings_button.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/src/controls/control_bar.dart'; class AllControlsOverlay extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; final Function updateVideoState; const AllControlsOverlay({ Key? key, required this.customVideoPlayerController, required this.updateVideoState, }) : super(key: key); @override State createState() => _AllControlsOverlayState(); } class _AllControlsOverlayState extends State { bool _controlsVisible = true; int _visibilityToggleCounter = 0; @override void initState() { super.initState(); _fadeOutControls(); widget.customVideoPlayerController.isPlayingNotifier .addListener(_listenToPlayStateChanges); } @override void dispose() { widget.customVideoPlayerController.isPlayingNotifier .removeListener(_listenToPlayStateChanges); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () => _toggleControlsVisibility(context), child: Container( padding: widget.customVideoPlayerController.customVideoPlayerSettings .controlsPadding, width: double.infinity, child: AnimatedSwitcher( duration: const Duration(milliseconds: 300), reverseDuration: const Duration(milliseconds: 300), child: _controlsVisible ? Column( children: [ if (widget.customVideoPlayerController .customVideoPlayerSettings.settingsButtonAvailable) Align( alignment: Alignment.topLeft, child: VideoSettingsButton( customVideoPlayerController: widget.customVideoPlayerController, updateVideoState: widget.updateVideoState, ), ), const Spacer(), if (widget.customVideoPlayerController .customVideoPlayerSettings.controlBarAvailable) CustomVideoPlayerControlBar( customVideoPlayerController: widget.customVideoPlayerController, updateVideoState: widget.updateVideoState, fadeOutOnPlay: _fadeOutControls, ), ], ) : null, ), ), ); } void _listenToPlayStateChanges() { if (widget.customVideoPlayerController.isPlayingNotifier.value) { _fadeOutControls(); } } void _toggleControlsVisibility(BuildContext context) { widget.customVideoPlayerController.areControlsVisible.value = !_controlsVisible; setState(() { _controlsVisible = !_controlsVisible; }); if (_controlsVisible) { _fadeOutControls(); } } Future _fadeOutControls() async { widget.customVideoPlayerController.areControlsVisible.value = true; _visibilityToggleCounter++; await Future.delayed( widget.customVideoPlayerController.customVideoPlayerSettings .durationAfterControlsFadeOut, () { _visibilityToggleCounter--; // only toggle visibility if the video is playing if (widget.customVideoPlayerController.customVideoPlayerSettings .autoFadeOutControls && widget.customVideoPlayerController.videoPlayerController.value .isPlaying) { if (_controlsVisible && _visibilityToggleCounter == 0) { widget.customVideoPlayerController.areControlsVisible.value = false; if (mounted) { setState(() { _controlsVisible = false; }); } } } }); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/control_bar.dart ================================================ import 'package:appinio_video_player/src/controls/mute_button.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/src/controls/fullscreen_button.dart'; import 'package:appinio_video_player/src/controls/play_button.dart'; import 'package:appinio_video_player/src/controls/progress_bar.dart'; import 'package:flutter/cupertino.dart'; class CustomVideoPlayerControlBar extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; final Function updateVideoState; final Function fadeOutOnPlay; const CustomVideoPlayerControlBar({ Key? key, required this.customVideoPlayerController, required this.updateVideoState, required this.fadeOutOnPlay, }) : super(key: key); @override Widget build(BuildContext context) { return Container( alignment: Alignment.bottomCenter, padding: customVideoPlayerController .customVideoPlayerSettings.controlBarPadding, decoration: customVideoPlayerController .customVideoPlayerSettings.controlBarDecoration, child: Row( children: [ if (customVideoPlayerController .customVideoPlayerSettings.showMuteButton) CustomVideoPlayerMuteButton( customVideoPlayerController: customVideoPlayerController, fadeOutOnPlay: fadeOutOnPlay, ), if (customVideoPlayerController .customVideoPlayerSettings.showPlayButton) CustomVideoPlayerPlayPauseButton( customVideoPlayerController: customVideoPlayerController, fadeOutOnPlay: fadeOutOnPlay, ), if (customVideoPlayerController .customVideoPlayerSettings.showDurationPlayed) Padding( padding: const EdgeInsets.only( left: 5.0, right: 5.0, ), child: ValueListenableBuilder( valueListenable: customVideoPlayerController.videoProgressNotifier, builder: ((context, progress, child) { return Text( getDurationAsString(progress), style: customVideoPlayerController .customVideoPlayerSettings.durationPlayedTextStyle, ); }), ), ), Expanded( child: CustomVideoPlayerProgressBar( customVideoPlayerController: customVideoPlayerController, ), ), if (customVideoPlayerController .customVideoPlayerSettings.showDurationRemaining) Padding( padding: const EdgeInsets.only( left: 5.0, right: 5.0, ), child: ValueListenableBuilder( valueListenable: customVideoPlayerController.videoProgressNotifier, builder: ((context, progress, child) { return Text( "-" + getDurationAsString(customVideoPlayerController .videoPlayerController.value.duration - progress), style: customVideoPlayerController .customVideoPlayerSettings.durationRemainingTextStyle, ); }), ), ), if (customVideoPlayerController .customVideoPlayerSettings.showFullscreenButton) CustomVideoPlayerFullscreenButton( customVideoPlayerController: customVideoPlayerController, ) ], ), ); } String getDurationAsString(Duration duration) { String twoDigits(int n) => n.toString().padLeft(2, "0"); String twoDigitMinutes = twoDigits(duration.inMinutes.remainder(60)); String twoDigitSeconds = twoDigits(duration.inSeconds.remainder(60)); String twoDigitHours = twoDigits(duration.inHours); if (int.parse(twoDigitMinutes) < 0) { twoDigitMinutes = "00"; } if (int.parse(twoDigitSeconds) < 0) { twoDigitSeconds = "00"; } if (int.parse(twoDigitHours) < 0) { twoDigitHours = "00"; } if (duration > const Duration(hours: 1)) { return "$twoDigitHours:$twoDigitMinutes:$twoDigitSeconds"; } else { return "$twoDigitMinutes:$twoDigitSeconds"; } } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/fullscreen_button.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/cupertino.dart'; class CustomVideoPlayerFullscreenButton extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; final bool? isFullscreen; const CustomVideoPlayerFullscreenButton({ Key? key, required this.customVideoPlayerController, this.isFullscreen, }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () async { if (customVideoPlayerController.isFullscreen) { await customVideoPlayerController.setFullscreen(false); } else { await customVideoPlayerController.setFullscreen(true); } }, child: customVideoPlayerController.isFullscreen ? customVideoPlayerController .customVideoPlayerSettings.exitFullscreenButton : customVideoPlayerController .customVideoPlayerSettings.enterFullscreenButton, ); } } class CustomVideoPlayerEnterFullscreenButton extends StatelessWidget { const CustomVideoPlayerEnterFullscreenButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(0, 5, 5, 5), child: Icon( CupertinoIcons.fullscreen, color: CupertinoColors.white, ), ); } } class CustomVideoPlayerExitFullscreenButton extends StatelessWidget { const CustomVideoPlayerExitFullscreenButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(0, 5, 5, 5), child: Icon( CupertinoIcons.fullscreen_exit, color: CupertinoColors.white, ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/mute_button.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/cupertino.dart'; class CustomVideoPlayerMuteButton extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; final Function fadeOutOnPlay; const CustomVideoPlayerMuteButton({ Key? key, required this.customVideoPlayerController, required this.fadeOutOnPlay, }) : super(key: key); @override State createState() => _CustomVideoPlayerMuteButtonState(); } class _CustomVideoPlayerMuteButtonState extends State { @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () => _muteUnMute(), child: isMute ? const CustomVideoUnMuteButton() : const CustomVideoMuteButton(), ); } bool get isMute => volume == 0; double get volume => widget.customVideoPlayerController.videoPlayerController.value.volume; Future _muteUnMute() async { if (isMute) { widget.customVideoPlayerController.unMute(); } else { widget.customVideoPlayerController.mute(); } setState(() {}); } } class CustomVideoMuteButton extends StatelessWidget { const CustomVideoMuteButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(5, 5, 0, 5), child: Icon( CupertinoIcons.volume_mute, color: CupertinoColors.white, ), ); } } class CustomVideoUnMuteButton extends StatelessWidget { const CustomVideoUnMuteButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(5, 5, 0, 5), child: Icon( CupertinoIcons.volume_off, color: CupertinoColors.white, ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/play_button.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/cupertino.dart'; class CustomVideoPlayerPlayPauseButton extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; final Function fadeOutOnPlay; const CustomVideoPlayerPlayPauseButton({ Key? key, required this.customVideoPlayerController, required this.fadeOutOnPlay, }) : super(key: key); @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: customVideoPlayerController.isPlayingNotifier, builder: (context, isPlaying, _) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () => _playPause(isPlaying), child: isPlaying ? customVideoPlayerController .customVideoPlayerSettings.pauseButton : customVideoPlayerController .customVideoPlayerSettings.playButton, ); }); } Future _playPause(bool isPlaying) async { if (isPlaying) { await customVideoPlayerController.videoPlayerController.pause(); } else { if (customVideoPlayerController.customVideoPlayerSettings.playOnlyOnce && customVideoPlayerController.playedOnceNotifier.value) { return; } else { await customVideoPlayerController.videoPlayerController.play(); fadeOutOnPlay(); } } } } class CustomVideoPlayerPlayButton extends StatelessWidget { const CustomVideoPlayerPlayButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(5, 5, 0, 5), child: Icon( CupertinoIcons.play, color: CupertinoColors.white, ), ); } } class CustomVideoPlayerPauseButton extends StatelessWidget { const CustomVideoPlayerPauseButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return const Padding( padding: EdgeInsets.fromLTRB(5, 5, 0, 5), child: Icon( CupertinoIcons.pause, color: CupertinoColors.white, ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/progress_bar.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/src/controls/progress_bar_indicator.dart'; import 'package:appinio_video_player/src/controls/seeker.dart'; import 'package:cached_video_player/cached_video_player.dart'; class CustomVideoPlayerProgressBar extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; const CustomVideoPlayerProgressBar({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override _VideoProgressIndicatorState createState() => _VideoProgressIndicatorState(); } class _VideoProgressIndicatorState extends State { @override void initState() { super.initState(); widget.customVideoPlayerController.videoPlayerController .addListener(updateWidgetListener); } @override void deactivate() { widget.customVideoPlayerController.videoPlayerController .removeListener(updateWidgetListener); super.deactivate(); } void updateWidgetListener() { if (mounted) { setState(() {}); } } @override Widget build(BuildContext context) { if (widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.showProgressBar) { Widget progressIndicator; if (widget.customVideoPlayerController.videoPlayerController.value .isInitialized) { final int duration = widget.customVideoPlayerController .videoPlayerController.value.duration.inMilliseconds; int maxBuffering = 0; for (DurationRange range in widget .customVideoPlayerController.videoPlayerController.value.buffered) { final int end = range.end.inMilliseconds; if (end > maxBuffering) { maxBuffering = end; } } progressIndicator = ClipRRect( borderRadius: BorderRadius.circular( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.progressBarBorderRadius, ), child: Stack( children: [ CustomVideoPlayerProgressIndicator( customVideoPlayerController: widget.customVideoPlayerController, progress: maxBuffering / duration, progressColor: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerProgressBarSettings .bufferedColor, backgroundColor: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerProgressBarSettings .backgroundColor, ), ValueListenableBuilder( valueListenable: widget.customVideoPlayerController.videoProgressNotifier, builder: (context, progress, child) { return CustomVideoPlayerProgressIndicator( customVideoPlayerController: widget.customVideoPlayerController, progress: progress.inMilliseconds / duration, progressColor: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerProgressBarSettings .progressColor, backgroundColor: Colors.transparent, ); }, ), ], ), ); } else { progressIndicator = LinearProgressIndicator( value: null, valueColor: AlwaysStoppedAnimation( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.progressColor, ), backgroundColor: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerProgressBarSettings .backgroundColor, ); } final Widget paddedProgressIndicator = Padding( padding: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.reachableProgressBarPadding, child: progressIndicator, ); if (widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.allowScrubbing) { return CustomVideoPlayerSeeker( child: paddedProgressIndicator, customvVideoPlayerController: widget.customVideoPlayerController, ); } else { return paddedProgressIndicator; } } else { return const SizedBox( width: double.infinity, ); } } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/progress_bar_indicator.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; class CustomVideoPlayerProgressIndicator extends StatefulWidget { final double progress; final CustomVideoPlayerController customVideoPlayerController; final Color progressColor; final Color backgroundColor; const CustomVideoPlayerProgressIndicator({ Key? key, required this.customVideoPlayerController, required this.progressColor, required this.backgroundColor, required this.progress, }) : super(key: key); @override _State createState() => _State(); } class _State extends State { Size mySize = Size.zero; @override Widget build(BuildContext context) { return WidgetSize( onChange: (size) { setState(() { mySize = size; }); }, child: _getProgressBar(), ); } Widget _getProgressBar() { return Container( width: double.infinity, height: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.progressBarHeight, decoration: BoxDecoration( color: widget.backgroundColor, borderRadius: BorderRadius.circular( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.progressBarBorderRadius, ), ), child: Align( alignment: Alignment.centerLeft, child: AnimatedContainer( width: _getProgressValue(mySize.width, widget.progress), decoration: BoxDecoration( color: widget.progressColor, borderRadius: BorderRadius.circular( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerProgressBarSettings.progressBarBorderRadius, ), ), duration: const Duration(milliseconds: 100), curve: Curves.linear, ), ), ); } double _getProgressValue(double maxValue, double? progress) { if (!(maxValue > 0) || progress == null || !(progress > 0)) { return 0; } return maxValue * progress; } } class WidgetSize extends StatefulWidget { final Widget child; final Function onChange; const WidgetSize({ Key? key, required this.onChange, required this.child, }) : super(key: key); @override _WidgetSizeState createState() => _WidgetSizeState(); } class _WidgetSizeState extends State { T? _ambiguate(T? value) => value; // to support older flutter versions @override Widget build(BuildContext context) { _ambiguate(SchedulerBinding.instance)! .addPostFrameCallback(postFrameCallback); return Container( key: widgetKey, child: widget.child, ); } GlobalKey widgetKey = GlobalKey(); Size? oldSize; void postFrameCallback(_) { BuildContext? context = widgetKey.currentContext; if (context == null || context.size == null) return; Size newSize = context.size!; if (oldSize == newSize) return; oldSize = newSize; widget.onChange(newSize); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/seeker.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; class CustomVideoPlayerSeeker extends StatefulWidget { final Widget child; final CustomVideoPlayerController customvVideoPlayerController; const CustomVideoPlayerSeeker({ Key? key, required this.child, required this.customvVideoPlayerController, }) : super(key: key); @override _CustomVideoPlayerSeekerState createState() => _CustomVideoPlayerSeekerState(); } class _CustomVideoPlayerSeekerState extends State { bool _videoPlaying = false; @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.opaque, child: widget.child, onHorizontalDragStart: (DragStartDetails details) { if (!widget.customvVideoPlayerController.videoPlayerController.value .isInitialized) { return; } _videoPlaying = widget .customvVideoPlayerController.videoPlayerController.value.isPlaying; if (_videoPlaying) { widget.customvVideoPlayerController.videoPlayerController.pause(); } }, onHorizontalDragUpdate: (DragUpdateDetails details) { if (!widget.customvVideoPlayerController.videoPlayerController.value .isInitialized) { return; } changeCurrentVideoPosition(details.globalPosition); }, onHorizontalDragEnd: (DragEndDetails details) { if (_videoPlaying) { widget.customvVideoPlayerController.videoPlayerController.play(); } }, onTapDown: (TapDownDetails details) { if (!widget.customvVideoPlayerController.videoPlayerController.value .isInitialized) { return; } changeCurrentVideoPosition(details.globalPosition); }, ); } void changeCurrentVideoPosition(Offset globalPosition) { final RenderBox box = context.findRenderObject() as RenderBox; final Offset tapPos = box.globalToLocal(globalPosition); final double relative = tapPos.dx / box.size.width; final Duration position = widget .customvVideoPlayerController.videoPlayerController.value.duration * relative; widget.customvVideoPlayerController.videoPlayerController.seekTo(position); widget.customvVideoPlayerController.videoProgressNotifier.value = position; } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/video_settings_button.dart ================================================ import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_dialog.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class VideoSettingsButton extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; final Function updateVideoState; const VideoSettingsButton({ Key? key, required this.customVideoPlayerController, required this.updateVideoState, }) : super(key: key); @override Widget build(BuildContext context) { return GestureDetector( onTap: () => _openVideoSettingsDialog(context), child: customVideoPlayerController.customVideoPlayerSettings.settingsButton, ); } Future _openVideoSettingsDialog(BuildContext context) async { await showGeneralDialog( context: context, barrierDismissible: true, barrierLabel: "custom_video_player_controls_barrier1", pageBuilder: (context, _, __) => VideoSettingsDialog( customVideoPlayerController: customVideoPlayerController, updateViewOnClose: updateVideoState, ), ); updateVideoState(); } } class CustomVideoPlayerSettingsButton extends StatelessWidget { const CustomVideoPlayerSettingsButton({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(8), decoration: const BoxDecoration( color: Color.fromRGBO(0, 0, 0, 0.5), borderRadius: BorderRadius.all( Radius.circular(10), ), ), child: const Icon( CupertinoIcons.settings, color: Colors.white, size: 18, ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/video_settings_popup/video_settings_dialog.dart ================================================ import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_dialog_item.dart'; import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_playback_speed_dialog.dart'; import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_quality_dialog.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/appinio_video_player.dart'; class VideoSettingsDialog extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; final Function updateViewOnClose; const VideoSettingsDialog({ Key? key, required this.customVideoPlayerController, required this.updateViewOnClose, }) : super(key: key); @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupDecoration.borderRadius ?? BorderRadius.zero, ), child: Container( padding: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupPadding, width: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupWidth, decoration: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupDecoration, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupTitle, style: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupTitleTextStyle, ), const SizedBox( height: 8, ), Column( children: [ if (customVideoPlayerController.additionalVideoSources != null) if (customVideoPlayerController .additionalVideoSources!.isNotEmpty) VideoSettingsDialogItem( title: customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings .popupQualityTitle, popupSettings: customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings, onPressed: () => _openSubSettingsDialog( context: context, isQuality: true, ), ), VideoSettingsDialogItem( title: customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupPlaybackSpeedTitle, popupSettings: customVideoPlayerController .customVideoPlayerSettings.customVideoPlayerPopupSettings, onPressed: () => _openSubSettingsDialog( context: context, isQuality: false, ), ), ], ) ], ), ), ); } _openSubSettingsDialog({ required BuildContext context, required bool isQuality, }) async { Navigator.of(context).pop(); //close old popup await showGeneralDialog( context: context, barrierDismissible: true, barrierLabel: "custom_video_player_controls_barrier2", pageBuilder: (context, _, __) { return isQuality ? VideoSettingsQualityDialog( customVideoPlayerController: customVideoPlayerController, updateView: updateViewOnClose, ) : VideoSettingsPlaybackSpeedDialog( customVideoPlayerController: customVideoPlayerController, ); }); updateViewOnClose(); } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/video_settings_popup/video_settings_dialog_item.dart ================================================ import 'package:appinio_video_player/src/models/custom_video_player_popup_settings.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class VideoSettingsDialogItem extends StatefulWidget { final String title; final Function onPressed; final bool? selected; final CustomVideoPlayerPopupSettings popupSettings; const VideoSettingsDialogItem({ Key? key, required this.title, required this.onPressed, required this.popupSettings, this.selected, }) : super(key: key); @override State createState() => _VideoSettingsDialogItemState(); } class _VideoSettingsDialogItemState extends State { bool _loading = false; @override Widget build(BuildContext context) { return GestureDetector( behavior: HitTestBehavior.translucent, onTap: () => _onPressed(), child: Container( padding: widget.popupSettings.popupItemsPadding, decoration: widget.popupSettings.popupItemsDecoration, child: Row( children: [ Text( widget.title, style: widget.popupSettings.popupItemsTextStyle, ), const Spacer(), widget.selected == null ? Icon( CupertinoIcons.chevron_right, color: widget.popupSettings.popupItemsTextStyle.color, size: widget.popupSettings.popupItemsTextStyle.fontSize, ) : _loading ? SizedBox( width: widget.popupSettings.popupItemsTextStyle.fontSize ?? 14, height: widget.popupSettings.popupItemsTextStyle.fontSize ?? 14, child: CircularProgressIndicator( color: widget.popupSettings.popupItemsTextStyle.color, strokeWidth: 1, ), ) : widget.selected! ? Icon( CupertinoIcons.check_mark, color: widget.popupSettings.popupItemsTextStyle.color, size: widget .popupSettings.popupItemsTextStyle.fontSize, ) : const SizedBox.shrink(), ], ), ), ); } _onPressed() async { setState(() { _loading = true; }); await widget.onPressed(); if (mounted) { setState(() { _loading = false; }); } } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/video_settings_popup/video_settings_playback_speed_dialog.dart ================================================ import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_dialog_item.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; class VideoSettingsPlaybackSpeedDialog extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; const VideoSettingsPlaybackSpeedDialog({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override State createState() => _VideoSettingsPlaybackSpeedDialogState(); } class _VideoSettingsPlaybackSpeedDialogState extends State { final List _playbackSpeeds = [ 0.25, 0.5, 0.75, 1.0, 1.25, 1.5, 1.75, 2.0, ]; @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings .popupDecoration .borderRadius ?? BorderRadius.zero, ), child: Container( padding: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupPadding, width: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupWidth, decoration: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupDecoration, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupPlaybackSpeedTitle, style: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings .popupTitleTextStyle, ), const SizedBox( height: 8, ), Flexible( child: ListView( shrinkWrap: true, padding: const EdgeInsets.all(0), controller: ScrollController(), children: [ for (double playbackSpeed in _playbackSpeeds) VideoSettingsDialogItem( title: playbackSpeed == 1.0 ? "${playbackSpeed}x (${widget.customVideoPlayerController.customVideoPlayerSettings.customVideoPlayerPopupSettings.defaultPlaybackspeedDescription})" : "${playbackSpeed}x", popupSettings: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings, onPressed: () => _changeVideoPlayBackSpeed(context, playbackSpeed), selected: widget.customVideoPlayerController .playbackSpeedNotifier.value == playbackSpeed, ), ], ), ) ], ), ), ); } void _changeVideoPlayBackSpeed( BuildContext context, double playbackSpeed, ) { widget.customVideoPlayerController.videoPlayerController .setPlaybackSpeed(playbackSpeed); if (mounted) { setState(() {}); } } } ================================================ FILE: packages/appinio_video_player/lib/src/controls/video_settings_popup/video_settings_quality_dialog.dart ================================================ import 'package:appinio_video_player/src/controls/video_settings_popup/video_settings_dialog_item.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/appinio_video_player.dart'; class VideoSettingsQualityDialog extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; final Function updateView; const VideoSettingsQualityDialog({ Key? key, required this.customVideoPlayerController, required this.updateView, }) : super(key: key); @override State createState() => _VideoSettingsQualityDialogState(); } class _VideoSettingsQualityDialogState extends State { @override Widget build(BuildContext context) { return Dialog( shape: RoundedRectangleBorder( borderRadius: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings .popupDecoration .borderRadius ?? BorderRadius.zero, ), child: Container( padding: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupPadding, width: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupWidth, decoration: widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupDecoration, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( widget.customVideoPlayerController.customVideoPlayerSettings .customVideoPlayerPopupSettings.popupQualityTitle, style: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings .popupTitleTextStyle, ), const SizedBox( height: 8, ), Flexible( child: ListView( controller: ScrollController(), padding: const EdgeInsets.all(0), shrinkWrap: true, children: [ for (MapEntry videoSource in widget.customVideoPlayerController .additionalVideoSources!.entries) VideoSettingsDialogItem( title: videoSource.key, popupSettings: widget .customVideoPlayerController .customVideoPlayerSettings .customVideoPlayerPopupSettings, onPressed: () => _changeVideoQuality( context: context, selectedSource: videoSource.key, ), selected: _getCurrentVideoPlayerSource() == videoSource.key, ), ], ), ), ], ), ), ); } String _getCurrentVideoPlayerSource() { return widget.customVideoPlayerController.additionalVideoSources!.entries .toList() .firstWhere((element) => element.value == widget.customVideoPlayerController.videoPlayerController) .key; } void _changeVideoQuality({ required BuildContext context, required String selectedSource, }) async { if (_getCurrentVideoPlayerSource() != selectedSource) { await widget.customVideoPlayerController .switchVideoSource(selectedSource); widget.updateView(); //maybe popup was dismissed on barrier tap before if (mounted) { setState(() {}); } } } } ================================================ FILE: packages/appinio_video_player/lib/src/custom_video_player.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:appinio_video_player/src/embedded_video_player.dart'; import 'package:flutter/material.dart'; class CustomVideoPlayer extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; const CustomVideoPlayer({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override Widget build(BuildContext context) { return EmbeddedVideoPlayer( isFullscreen: false, customVideoPlayerController: customVideoPlayerController, ); } } ================================================ FILE: packages/appinio_video_player/lib/src/custom_video_player_controller.dart ================================================ import 'dart:async'; import 'package:appinio_video_player/src/fullscreen_video_player.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:cached_video_player/cached_video_player.dart'; import 'package:appinio_video_player/src/models/custom_video_player_settings.dart'; /// The extension on the class is able to call private methods /// only the package can use these methods and not the public beacuse of the hide keyword in the package exports extension ProtectedCustomVideoPlayerController on CustomVideoPlayerController { Future Function(String) get switchVideoSource => _switchVideoSource; ValueNotifier get videoProgressNotifier => _videoProgressNotifier; ValueNotifier get playbackSpeedNotifier => _playbackSpeedNotifier; ValueNotifier get isPlayingNotifier => _isPlayingNotifier; bool get isFullscreen => _isFullscreen; set updateViewAfterFullscreen(Function updateViewAfterFullscreen) => _updateViewAfterFullscreen = updateViewAfterFullscreen; } class CustomVideoPlayerController { double _lastVolume = 0.5; Duration get getPosition => videoPlayerController.value.position; final BuildContext context; CachedVideoPlayerController videoPlayerController; final CustomVideoPlayerSettings customVideoPlayerSettings; final Map? additionalVideoSources; final ValueNotifier areControlsVisible = ValueNotifier(true); Future switchSource(String sourceKey) async { assert(additionalVideoSources != null && additionalVideoSources!.containsKey(sourceKey)); switchVideoSource(sourceKey); } CustomVideoPlayerController({ required this.context, required this.videoPlayerController, this.customVideoPlayerSettings = const CustomVideoPlayerSettings(), this.additionalVideoSources, }) { videoPlayerController.addListener(_videoListeners); } /// public accessable methods and values for the controller final ValueNotifier playedOnceNotifier = ValueNotifier(false); Future setFullscreen( bool fullscreen, ) async { if (kIsWeb) { debugPrint( "Web doesn't support fullscreen properly. When exiting fullscreen the video will be black. Audio still works."); } if (fullscreen) { await _enterFullscreen(); _updateViewAfterFullscreen?.call(); } else { await _exitFullscreen(); } } /// private fields Function? _updateViewAfterFullscreen; bool _isFullscreen = false; Timer? _timer; final ValueNotifier _videoProgressNotifier = ValueNotifier(Duration.zero); final ValueNotifier _playbackSpeedNotifier = ValueNotifier(1.0); final ValueNotifier _isPlayingNotifier = ValueNotifier(false); Future _enterFullscreen() async { final TransitionRoute route = PageRouteBuilder( pageBuilder: (context, animation, secondaryAnimation) { return AnimatedBuilder( animation: animation, builder: (BuildContext context, Widget? child) { return FullscreenVideoPlayer( customVideoPlayerController: this, ); }, ); }, ); _isFullscreen = true; _setOrientationForVideo(); SystemChrome.setEnabledSystemUIMode( customVideoPlayerSettings.systemUIModeInsideFullscreen); if(context.mounted){ await Navigator.of(context).push(route); } } Future _exitFullscreen() async { await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); await SystemChrome.setEnabledSystemUIMode( customVideoPlayerSettings.systemUIModeAfterFullscreen, overlays: customVideoPlayerSettings.systemUIOverlaysAfterFullscreen, ); await SystemChrome.setPreferredOrientations(customVideoPlayerSettings .deviceOrientationsAfterFullscreen); // reset device orientation values _isFullscreen = false; if (context.mounted) { Navigator.of(context).pop(); } } void _setOrientationForVideo() { final double videoWidth = videoPlayerController.value.size.width; final double videoHeight = videoPlayerController.value.size.height; final bool isLandscapeVideo = videoWidth > videoHeight; final bool isPortraitVideo = videoWidth < videoHeight; /// if video has more width than height set landscape orientation if (isLandscapeVideo) { SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); } /// otherwise set portrait orientation else if (isPortraitVideo) { SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); } /// if they are equal allow both else { SystemChrome.setPreferredOrientations(DeviceOrientation.values); } } Future _switchVideoSource(String selectedSource) async { CachedVideoPlayerController? newSource = additionalVideoSources![selectedSource]; if (newSource != null) { Duration _playedDuration = videoPlayerController.value.position; double _playbackSpeed = videoPlayerController.value.playbackSpeed; bool _wasPlaying = videoPlayerController.value.isPlaying; videoPlayerController.pause(); videoPlayerController.removeListener(_videoListeners); videoPlayerController = newSource; await videoPlayerController.initialize(); videoPlayerController.addListener( _videoListeners); // add listeners to new video controller if (isFullscreen) { _setOrientationForVideo(); // if video changed completely } await videoPlayerController.seekTo(_playedDuration); if (Theme.of(context).platform != TargetPlatform.iOS) { await videoPlayerController.setPlaybackSpeed(_playbackSpeed); } else { await videoPlayerController.setPlaybackSpeed( 1); // resetting to 1 because its not working on iOS. open issue on github } if (_wasPlaying) { await videoPlayerController.play(); } _updateViewAfterFullscreen?.call(); } } /// Listeners void _videoListeners() { _fluidVideoProgressListener(); _fullscreenFunctionalityListener(); _playPauseListener(); _playbackSpeedListener(); _onVideoEndListener(); } /// used to make progress more fluid Future _fluidVideoProgressListener() async { if (videoPlayerController.value.isPlaying) { _timer ??= Timer.periodic(const Duration(milliseconds: 100), (Timer timer) async { if (videoPlayerController.value.isInitialized) { _videoProgressNotifier.value = await videoPlayerController.position ?? _videoProgressNotifier.value; } }); } else { if (_timer != null) { _timer?.cancel(); _timer = null; if (videoPlayerController.value.isInitialized) { _videoProgressNotifier.value = (await videoPlayerController.position)!; } } } } /// save that the video is played once void _onVideoEndListener() { if (videoPlayerController.value.position > Duration.zero) { if (videoPlayerController.value.duration == videoPlayerController.value.position) { playedOnceNotifier.value = true; } } } void _fullscreenFunctionalityListener() { // exit fullscreen on end if (videoPlayerController.value.duration == videoPlayerController.value.position && !videoPlayerController.value.isPlaying && customVideoPlayerSettings.exitFullscreenOnEnd && _isFullscreen) { setFullscreen(false); } // enter fullscreen on start if (videoPlayerController.value.position == Duration.zero && videoPlayerController.value.isPlaying && customVideoPlayerSettings.enterFullscreenOnStart && !_isFullscreen) { setFullscreen(true); } } void _playPauseListener() { if (videoPlayerController.value.isPlaying) { _isPlayingNotifier.value = true; } else { _isPlayingNotifier.value = false; } } void _playbackSpeedListener() { _playbackSpeedNotifier.value = videoPlayerController.value.playbackSpeed; } /// call dispose on the dispose method in your parent widget to be sure that every values is disposed void dispose() { videoPlayerController.removeListener(_videoListeners); _timer?.cancel(); _timer = null; _isPlayingNotifier.dispose(); _videoProgressNotifier.dispose(); _playbackSpeedNotifier.dispose(); videoPlayerController.dispose(); if (additionalVideoSources != null) { if (additionalVideoSources!.isNotEmpty) { for (MapEntry videoSource in additionalVideoSources!.entries) { videoSource.value.dispose(); } } } } void mute() { _lastVolume = videoPlayerController.value.volume; videoPlayerController.setVolume(0); } void unMute() { videoPlayerController.setVolume(_lastVolume); } } ================================================ FILE: packages/appinio_video_player/lib/src/embedded_video_player.dart ================================================ import 'package:appinio_video_player/src/controls/all_controls_overlay.dart'; import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:appinio_video_player/src/seek_buttons.dart'; import 'package:appinio_video_player/src/thumbnail.dart'; import 'package:appinio_video_player/src/volume_control.dart'; import 'package:flutter/cupertino.dart'; import 'package:cached_video_player/cached_video_player.dart'; class EmbeddedVideoPlayer extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; final bool isFullscreen; const EmbeddedVideoPlayer({ Key? key, required this.customVideoPlayerController, this.isFullscreen = false, }) : super(key: key); @override State createState() => _EmbeddedVideoPlayerState(); } class _EmbeddedVideoPlayerState extends State { @override void initState() { super.initState(); if (!widget.isFullscreen) { widget.customVideoPlayerController.updateViewAfterFullscreen = _updateVideoState; } } @override Widget build(BuildContext context) { if (widget.customVideoPlayerController.videoPlayerController.value .isInitialized) { return AspectRatio( aspectRatio: widget.isFullscreen ? widget.customVideoPlayerController.videoPlayerController.value .aspectRatio : widget.customVideoPlayerController.customVideoPlayerSettings .customAspectRatio ?? widget.customVideoPlayerController.videoPlayerController.value .aspectRatio, child: Stack( children: [ Container( color: CupertinoColors.black, ), Center( child: AspectRatio( aspectRatio: widget.customVideoPlayerController .videoPlayerController.value.aspectRatio, child: IgnorePointer( child: CachedVideoPlayer( widget.customVideoPlayerController.videoPlayerController, ), ), ), ), Thumbnail( customVideoPlayerController: widget.customVideoPlayerController, ), AllControlsOverlay( customVideoPlayerController: widget.customVideoPlayerController, updateVideoState: _updateVideoState, ), if (widget.customVideoPlayerController.customVideoPlayerSettings .showSeekButtons) SeekButtons( customVideoPlayerController: widget.customVideoPlayerController, ), VolumeControls( customVideoPlayerController: widget.customVideoPlayerController, ), ], ), ); } else { return widget.customVideoPlayerController.customVideoPlayerSettings .placeholderWidget ?? const SizedBox.shrink(); } } void _updateVideoState() { if (mounted) { setState(() {}); } } } ================================================ FILE: packages/appinio_video_player/lib/src/fullscreen_video_player.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/material.dart'; import 'package:appinio_video_player/src/embedded_video_player.dart'; class FullscreenVideoPlayer extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; const FullscreenVideoPlayer({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override Widget build(BuildContext context) { return WillPopScope( onWillPop: () async { customVideoPlayerController.setFullscreen(false); return false; }, child: Scaffold( resizeToAvoidBottomInset: false, body: Container( alignment: Alignment.center, color: Colors.black, child: EmbeddedVideoPlayer( customVideoPlayerController: customVideoPlayerController, isFullscreen: true, ), ), ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/models/custom_video_player_popup_settings.dart ================================================ import 'package:flutter/material.dart'; class CustomVideoPlayerPopupSettings { final String popupTitle; final String popupQualityTitle; final String popupPlaybackSpeedTitle; final String defaultPlaybackspeedDescription; final TextStyle popupTitleTextStyle; final BoxDecoration popupDecoration; final double popupWidth; final EdgeInsets popupPadding; final TextStyle popupItemsTextStyle; final EdgeInsets popupItemsPadding; final BoxDecoration popupItemsDecoration; const CustomVideoPlayerPopupSettings({ this.popupTitle = 'Video Settings', this.popupQualityTitle = 'Video Quality', this.popupPlaybackSpeedTitle = 'Playback Speed', this.popupTitleTextStyle = const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w500, ), this.popupDecoration = const BoxDecoration( color: Color.fromARGB(255, 41, 40, 40), borderRadius: BorderRadius.all( Radius.circular(10), ), ), this.popupWidth = 300, this.popupPadding = const EdgeInsets.all(8), this.popupItemsTextStyle = const TextStyle( color: Colors.white, fontSize: 14, ), this.popupItemsPadding = const EdgeInsets.all(8), this.popupItemsDecoration = const BoxDecoration(), this.defaultPlaybackspeedDescription = 'Default', }); } ================================================ FILE: packages/appinio_video_player/lib/src/models/custom_video_player_progress_bar_settings.dart ================================================ import 'package:flutter/material.dart'; class CustomVideoPlayerProgressBarSettings { /// The [BorderRadius] of the progress bar. final double progressBarBorderRadius; /// If set to false the progress bar will not be displayed. final bool showProgressBar; /// If set to false the video cannot be skipped by sliding the finger over the progress bar. final bool allowScrubbing; /// The padding around the progress bar where it is also reachable. Can be useful to define a larger area where the users could tap the progress bar. final EdgeInsets reachableProgressBarPadding; /// The height of the progress bar. final double progressBarHeight; /// The color of the current progress of the video. final Color progressColor; /// The color of the buffered progress. final Color bufferedColor; /// The background color of the progress bar. final Color backgroundColor; const CustomVideoPlayerProgressBarSettings({ this.showProgressBar = true, this.allowScrubbing = true, this.reachableProgressBarPadding = const EdgeInsets.all(5), this.progressBarHeight = 10, this.progressBarBorderRadius = 10, this.progressColor = const Color.fromRGBO(255, 255, 255, 1), this.bufferedColor = const Color.fromRGBO(255, 255, 255, 0.3), this.backgroundColor = const Color.fromRGBO(156, 156, 156, 0.5), }); } ================================================ FILE: packages/appinio_video_player/lib/src/models/custom_video_player_settings.dart ================================================ import 'dart:ui'; import 'package:appinio_video_player/src/controls/fullscreen_button.dart'; import 'package:appinio_video_player/src/controls/play_button.dart'; import 'package:appinio_video_player/src/controls/video_settings_button.dart'; import 'package:appinio_video_player/src/models/custom_video_player_popup_settings.dart'; import 'package:appinio_video_player/src/models/custom_video_player_progress_bar_settings.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; class CustomVideoPlayerSettings { /// Define a custom aspect ratio for the video. final double? customAspectRatio; /// Show or hide mute button final bool showMuteButton; /// Allow volume change on sliding right part of screen final bool? allowVolumeOnSlide; /// Define a custom aspect ratio for the video. final Duration seekDuration; /// show seek buttons final bool showSeekButtons; /// The widget that should be shown as long the video is not initialized. final Widget? placeholderWidget; /// Set to false if no control bar should be available. final bool controlBarAvailable; /// Set to false if no playback speed adjustment button should be shown. final bool playbackSpeedButtonAvailable; /// The thumbnail widget of the video. Mostly that will be an image widget final Widget? thumbnailWidget; /// When this is true, the thumbnail will always be shown when the video is paused. /// If set to false, the thumbnail will only be shown when the video is at the beginning. final bool alwaysShowThumbnailOnVideoPaused; /// The padding between the controls and the edges of the video player final EdgeInsets controlsPadding; /// The padding of the control bar from the edges to its contents. final EdgeInsets controlBarPadding; /// Define the play button appearance. final Widget playButton; /// Define the pause button appearance. final Widget pauseButton; /// Define the enter-fullscreen button appearance. final Widget enterFullscreenButton; /// Define the exit-fullscreen button appearance. final Widget exitFullscreenButton; /// Define the settings button appearance. final Widget settingsButton; /// The [SystemUiMode] after leaving the fullscreen mode. Defaults to [SystemUiMode.edgeToEdge]. final SystemUiMode systemUIModeAfterFullscreen; /// The [SystemUiMode] when entering the fullscreen mode. Defaults to [SystemUiMode.leanBack]. final SystemUiMode systemUIModeInsideFullscreen; /// The system ui overlays after fullscreen mode. Especially useful if [systemUIModeAfterFullscreen] is set to [SystemUiMode.manual]. final List systemUIOverlaysAfterFullscreen; /// The possible device orientations after leaving fullscreen. For example if the app was a portrait only app before then set the orientations to DeviceOrientation.portraitUp here again. final List deviceOrientationsAfterFullscreen; /// The appearance of the control bar. final BoxDecoration controlBarDecoration; /// If set the video will enter the fullscreen mode on start. final bool enterFullscreenOnStart; /// If set the video will leave the fullscreen mode when its finished. Nothing happens if video wasn't in fullscreen before. final bool exitFullscreenOnEnd; /// If set the video can only be played once. final bool playOnlyOnce; /// If set the video controls will be faded out after the [durationAfterControlsFadeOut] has passed. final bool autoFadeOutControls; /// If set to false no play/pause button will not be displayed. final bool showPlayButton; /// If set to false no enter/exit fullscrenn button will not be displayed. Default it wont be displayed in web because there fullscreen doesnt work properly final bool showFullscreenButton; /// The duration after which the controls will fade out. Recommended duration is >= 2 seconds. final Duration durationAfterControlsFadeOut; /// The [TextStyle] of the played duration left from the progress bar. final TextStyle durationPlayedTextStyle; /// The [TextStyle] of the remaining duration right from the progress bar. final TextStyle durationRemainingTextStyle; /// If set to false the duration played will not be displayed. final bool showDurationPlayed; /// If set to false the duration remaining will not be displayed. final bool showDurationRemaining; /// If the settings button should be shown or not. final bool settingsButtonAvailable; /// TextStyle for the playback speed. final TextStyle playbackButtonTextStyle; /// The settings for the progress bar in the middle of the control bar. final CustomVideoPlayerProgressBarSettings customVideoPlayerProgressBarSettings; /// UI settings for the video settings popup. final CustomVideoPlayerPopupSettings customVideoPlayerPopupSettings; const CustomVideoPlayerSettings({ this.showMuteButton = true, this.allowVolumeOnSlide = true, this.customAspectRatio, this.placeholderWidget, this.thumbnailWidget, this.seekDuration = const Duration(seconds: 10), this.showSeekButtons = false, this.alwaysShowThumbnailOnVideoPaused = false, this.controlsPadding = const EdgeInsets.all(5), this.controlBarPadding = const EdgeInsets.all(5), this.playButton = const CustomVideoPlayerPlayButton(), this.pauseButton = const CustomVideoPlayerPauseButton(), this.settingsButton = const CustomVideoPlayerSettingsButton(), this.enterFullscreenButton = const CustomVideoPlayerEnterFullscreenButton(), this.exitFullscreenButton = const CustomVideoPlayerExitFullscreenButton(), this.controlBarDecoration = const BoxDecoration( color: Color.fromRGBO(0, 0, 0, 0.5), borderRadius: BorderRadius.all( Radius.circular(10), ), ), this.durationPlayedTextStyle = const TextStyle( color: Colors.white, fontSize: 14, fontFeatures: [FontFeature.tabularFigures()], ), this.durationRemainingTextStyle = const TextStyle( color: Colors.white, fontSize: 14, fontFeatures: [FontFeature.tabularFigures()], ), this.customVideoPlayerProgressBarSettings = const CustomVideoPlayerProgressBarSettings(), this.showDurationPlayed = true, this.showDurationRemaining = true, this.controlBarAvailable = true, this.enterFullscreenOnStart = false, this.exitFullscreenOnEnd = false, this.showPlayButton = true, this.playOnlyOnce = false, this.autoFadeOutControls = true, this.durationAfterControlsFadeOut = const Duration(seconds: 3), this.showFullscreenButton = !kIsWeb, this.systemUIModeAfterFullscreen = SystemUiMode.edgeToEdge, this.systemUIModeInsideFullscreen = SystemUiMode.leanBack, this.systemUIOverlaysAfterFullscreen = SystemUiOverlay.values, this.deviceOrientationsAfterFullscreen = DeviceOrientation.values, this.settingsButtonAvailable = true, this.playbackSpeedButtonAvailable = true, this.playbackButtonTextStyle = const TextStyle( color: Colors.white, fontSize: 14, fontFeatures: [FontFeature.tabularFigures()], ), this.customVideoPlayerPopupSettings = const CustomVideoPlayerPopupSettings(), }); } ================================================ FILE: packages/appinio_video_player/lib/src/seek_buttons.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/material.dart'; class SeekButtons extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; const SeekButtons({Key? key, required this.customVideoPlayerController}) : super(key: key); @override State createState() => _SeekButtonsState(); } class _SeekButtonsState extends State { bool _areControlsVisible = true; @override void initState() { super.initState(); _areControlsVisible = widget.customVideoPlayerController.areControlsVisible.value; widget.customVideoPlayerController.areControlsVisible.addListener(() { if (!mounted) return; setState(() { _areControlsVisible = widget.customVideoPlayerController.areControlsVisible.value; }); }); } @override Widget build(BuildContext context) { return AnimatedSwitcher( duration: const Duration(milliseconds: 300), reverseDuration: const Duration(milliseconds: 300), child: _areControlsVisible ? Center( child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Material( color: Colors.black12, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), child: InkWell( onTap: onSeekForward, child: const Icon( Icons.rotate_left_sharp, color: Colors.white, size: 30, ), ), ), Material( color: Colors.black12, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(5)), child: InkWell( onTap: onSeekBack, child: const Icon( Icons.rotate_right_sharp, color: Colors.white, size: 30, ), ), ), ], ), ) : null, ); } void onSeekBack() async { Duration? currentPosition = await widget.customVideoPlayerController.videoPlayerController.position; Duration seekDuration = widget .customVideoPlayerController.customVideoPlayerSettings.seekDuration; if (currentPosition != null) { Duration seekResult = Duration( microseconds: currentPosition.inMicroseconds + seekDuration.inMicroseconds); widget.customVideoPlayerController.videoPlayerController .seekTo(seekResult); } } void onSeekForward() async { Duration? currentPosition = await widget.customVideoPlayerController.videoPlayerController.position; Duration seekDuration = widget .customVideoPlayerController.customVideoPlayerSettings.seekDuration; if (currentPosition != null) { Duration seekResult = Duration( microseconds: currentPosition.inMicroseconds - seekDuration.inMicroseconds); widget.customVideoPlayerController.videoPlayerController .seekTo(seekResult); } } } ================================================ FILE: packages/appinio_video_player/lib/src/thumbnail.dart ================================================ import 'package:appinio_video_player/src/custom_video_player_controller.dart'; import 'package:flutter/cupertino.dart'; class Thumbnail extends StatelessWidget { final CustomVideoPlayerController customVideoPlayerController; const Thumbnail({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override Widget build(BuildContext context) { return ValueListenableBuilder( valueListenable: customVideoPlayerController.isPlayingNotifier, builder: ((context, isPlaying, child) { if (!isPlaying) { if (customVideoPlayerController .customVideoPlayerSettings.alwaysShowThumbnailOnVideoPaused) { return customVideoPlayerController .customVideoPlayerSettings.thumbnailWidget ?? const SizedBox.shrink(); } else { return ValueListenableBuilder( valueListenable: customVideoPlayerController.videoProgressNotifier, builder: ((context, progress, child) { if (progress == Duration.zero) { return customVideoPlayerController .customVideoPlayerSettings.thumbnailWidget ?? const SizedBox.shrink(); } else { return const SizedBox.shrink(); } }), ); } } else { return const SizedBox.shrink(); } }), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/volume_control.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/material.dart'; import 'dart:math'; class VolumeControls extends StatefulWidget { final CustomVideoPlayerController customVideoPlayerController; const VolumeControls({ Key? key, required this.customVideoPlayerController, }) : super(key: key); @override State createState() => _VolumeControlsState(); } class _VolumeControlsState extends State { final GlobalKey _globalKey = GlobalKey(); double _opacity = 0; double _progress = 0; @override Widget build(BuildContext context) { return Align( alignment: Alignment.centerRight, child: GestureDetector( onVerticalDragStart: (DragStartDetails details) { setState(() { _opacity = 1; }); }, onVerticalDragDown: (DragDownDetails details) { setState(() { _opacity = 1; }); }, onVerticalDragUpdate: onPanUpdate, onVerticalDragCancel: () { setState(() { _opacity = 0; }); }, onVerticalDragEnd: (DragEndDetails details) { setState(() { _opacity = 0; }); }, child: Container( margin: const EdgeInsets.only(bottom: 60), padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 40), child: AnimatedOpacity( duration: const Duration(milliseconds: 500), opacity: _opacity, child: SlideController( widgetKey: _globalKey, child: Container( height: _progress, decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(20), ), width: 15, ), ), ), ), ), ); } void onPanUpdate(DragUpdateDetails dragUpdateDetails) { double maxSpeedThreshold = 100.0; final RenderBox? _renderBoxRed = _globalKey.currentContext?.findRenderObject() as RenderBox; final double? height = _renderBoxRed?.size.height; final double volume = widget.customVideoPlayerController.videoPlayerController.value.volume; double factor = 0.03; double dx = dragUpdateDetails.primaryDelta!; // Change in x direction double dy = dragUpdateDetails.primaryDelta!; // Change in y direction double magnitude = dx * dx + dy * dy; double slideSpeed = sqrt(magnitude); double normalizedSpeed = slideSpeed / maxSpeedThreshold; normalizedSpeed = normalizedSpeed.clamp(0.0, 1.0); factor = normalizedSpeed; if (dragUpdateDetails.delta.dy > 0) { widget.customVideoPlayerController.videoPlayerController .setVolume(volume - factor); setState(() { _progress = ((volume - factor) < 0 ? 0 : (volume - factor)) * (height ?? 0); }); } else if (dragUpdateDetails.delta.dy < 0) { widget.customVideoPlayerController.videoPlayerController .setVolume(volume + factor); setState(() { _progress = ((volume + factor) > 1 ? 1 : (volume + factor)) * (height ?? 0); }); } } } class SlideController extends StatefulWidget { final Widget child; final GlobalKey widgetKey; const SlideController({ Key? key, required this.child, required this.widgetKey, }) : super(key: key); @override State createState() => _SlideControllerState(); } class _SlideControllerState extends State { @override Widget build(BuildContext context) { return Container( key: widget.widgetKey, decoration: BoxDecoration( color: Colors.white.withOpacity(0.3), borderRadius: BorderRadius.circular(20), ), width: 15, alignment: Alignment.bottomCenter, child: Column( mainAxisAlignment: MainAxisAlignment.end, mainAxisSize: MainAxisSize.max, children: [widget.child], ), ); } } ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/cupertino.dart'; import 'conditional_native_web_video_player_base.dart' if (dart.library.io) 'conditional_native_web_video_player_mobile.dart' if (dart.library.html) 'conditional_native_web_video_player_web.dart'; abstract class ConditionalNativeWebVideoPlayer { Widget getVideoWidget( CustomVideoPlayerWebController customVideoPlayerWebController) { return const SizedBox.shrink(); } factory ConditionalNativeWebVideoPlayer() => getSomething(); } ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player_base.dart ================================================ import 'conditional_native_web_video_player.dart'; ConditionalNativeWebVideoPlayer getSomething() => throw UnsupportedError("Cannot create NativeWebVideoPlayer"); ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player_mobile.dart ================================================ import 'package:appinio_video_player/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player.dart'; import 'package:appinio_video_player/src/web_video_player/custom_video_player_web_controller.dart'; import 'package:flutter/cupertino.dart'; class ConditionalNativeWebVideoPlayerMobile implements ConditionalNativeWebVideoPlayer { @override Widget getVideoWidget( CustomVideoPlayerWebController customVideoPlayerWebController) { debugPrint( 'Tried calling web video widget on mobile. Returning empty widget. Please use the mobile video player or run on web.'); return const SizedBox.shrink(); } } ConditionalNativeWebVideoPlayer getSomething() => ConditionalNativeWebVideoPlayerMobile(); ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player_web.dart ================================================ // ignore: avoid_web_libraries_in_flutter, unused_import import 'package:appinio_video_player/src/web_video_player/conditional_native_web_video_player/conditional_native_web_video_player.dart'; import 'package:appinio_video_player/src/web_video_player/custom_video_player_web_controller.dart'; import 'package:appinio_video_player/src/web_video_player/native_web_video_player.dart'; import 'package:flutter/cupertino.dart'; class ConditionalNativeWebVideoPlayerWeb implements ConditionalNativeWebVideoPlayer { @override Widget getVideoWidget( CustomVideoPlayerWebController customVideoPlayerWebController) { return NativeWebVideoPlayer( customVideoPlayerWebController: customVideoPlayerWebController, ); } } ConditionalNativeWebVideoPlayer getSomething() => ConditionalNativeWebVideoPlayerWeb(); ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/custom_video_player_web.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/material.dart'; class CustomVideoPlayerWeb extends StatelessWidget { final CustomVideoPlayerWebController customVideoPlayerWebController; const CustomVideoPlayerWeb({ Key? key, required this.customVideoPlayerWebController, }) : super(key: key); @override Widget build(BuildContext context) { return ConditionalNativeWebVideoPlayer() .getVideoWidget(customVideoPlayerWebController); } } ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/custom_video_player_web_controller.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/material.dart'; class CustomVideoPlayerWebController { final CustomVideoPlayerWebSettings webVideoPlayerSettings; CustomVideoPlayerWebController({ required this.webVideoPlayerSettings, }); /// play video late VoidCallback play; /// pause video late VoidCallback pause; /// enters/leaves fullscreen late Function(bool) setFullscreen; /// seek to a specific position late Function(double position) seekTo; /// mute video late VoidCallback mute; /// unmute video late VoidCallback unmute; /// sets playback speed. /// 1 is normal speed. /// 0.5 would be 50% speed. /// 2 would be 200% speed. late Function(double speed) setPlaybackSpeed; late ValueNotifier isPlaying = ValueNotifier(false); } ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/native_web_video_player.dart ================================================ import 'package:appinio_video_player/appinio_video_player.dart'; import 'package:flutter/cupertino.dart'; // ignore: avoid_web_libraries_in_flutter import 'dart:html' as html; import 'dart:ui' as ui; class NativeWebVideoPlayer extends StatefulWidget { final CustomVideoPlayerWebController customVideoPlayerWebController; NativeWebVideoPlayer({ required this.customVideoPlayerWebController, }) : super(key: customVideoPlayerWebController.webVideoPlayerSettings.key); @override _NativeWebVideoPlayerState createState() => _NativeWebVideoPlayerState(); } class _NativeWebVideoPlayerState extends State { final html.VideoElement _video = html.VideoElement(); late CustomVideoPlayerWebSettings _videoPlayerSettings; num _videoPosition = 0; @override void initState() { super.initState(); _videoPlayerSettings = widget.customVideoPlayerWebController.webVideoPlayerSettings; _initVideoElement(); } @override Widget build(BuildContext context) { return Directionality( textDirection: TextDirection.ltr, child: _videoPlayerSettings.aspectRatio != null ? AspectRatio( aspectRatio: _videoPlayerSettings.aspectRatio!, child: HtmlElementView( viewType: _videoPlayerSettings.src, ), ) : HtmlElementView( viewType: _videoPlayerSettings.src, ), ); } void _initVideoElement() { // ignore: undefined_prefixed_name ui.platformViewRegistry.registerViewFactory(_videoPlayerSettings.src, (int viewId) { _video.src = _videoPlayerSettings.src + '#t=${_videoPlayerSettings.startAt}'; _video.autoplay = _videoPlayerSettings.autoplay; _video.controls = _videoPlayerSettings.enableControls; if (_videoPlayerSettings.thumbnailPath != null) { _video.poster = _videoPlayerSettings.thumbnailPath!; } _video.setAttribute( 'disablePictureInPicture', widget.customVideoPlayerWebController.webVideoPlayerSettings .disablePictureInPicture, ); if (_videoPlayerSettings.hideDownloadButton) { _video.setAttribute('controlsList', 'nodownload'); } if (_videoPlayerSettings.backgroundColor != null) { _video.style.backgroundColor = _videoPlayerSettings.backgroundColor; } _video.style.width = '100%'; _video.style.height = '100%'; _video.style.border = 'none'; _video.setAttribute('playsInline', true); // listeners _video.onTimeUpdate.listen((event) { if (!_video.seeking) { _videoPosition = _video.currentTime; } }); _video.onEnded.listen((event) { if (_videoPlayerSettings.exitFullscreenOnEnd) { _video.exitFullscreen(); } }); _video.onPlay.listen((event) { widget.customVideoPlayerWebController.isPlaying.value = true; if (_videoPlayerSettings.enterFullscreenOnStart && _videoPosition == 0) { _video.requestFullscreen(); } }); _video.onPause.listen((event) { widget.customVideoPlayerWebController.isPlaying.value = false; }); _video.onSeeking.listen((event) { if (_videoPlayerSettings.preventSeeking) { num delta = _video.currentTime - _videoPosition; if (delta.abs() > 0.01) { _video.currentTime = _videoPosition; _video.pause(); } } }); //set controller methods widget.customVideoPlayerWebController.play = _play; widget.customVideoPlayerWebController.pause = _pause; widget.customVideoPlayerWebController.setFullscreen = _setFullscreen; widget.customVideoPlayerWebController.seekTo = _seekTo; widget.customVideoPlayerWebController.mute = _mute; widget.customVideoPlayerWebController.unmute = _unmute; widget.customVideoPlayerWebController.setPlaybackSpeed = _setPlaybackSpeed; return _video; }); } // controller methods void _play() { _video.play(); } void _pause() { _video.pause(); } void _setFullscreen(bool fullscreen) { if (fullscreen) { _video.enterFullscreen(); } else { _video.exitFullscreen(); } } void _seekTo(double position) { _video.currentTime = position; } void _mute() { _video.muted = true; } void _unmute() { _video.muted = false; } void _setPlaybackSpeed(double speed) { _video.playbackRate = speed; } } ================================================ FILE: packages/appinio_video_player/lib/src/web_video_player/web_video_player_settings.dart ================================================ import 'package:flutter/foundation.dart'; class CustomVideoPlayerWebSettings { /// Key final Key? key; /// optional aspect ratio for video. must be known or found out before final double? aspectRatio; /// video url final String src; /// video startig position in seconds final double startAt; /// set autoplay final bool autoplay; /// set controls available or not final bool enableControls; /// set background color of video element. seen if video doesnt fit in the defined width & height final String? backgroundColor; /// set if video should enter fullscreen on start final bool enterFullscreenOnStart; /// It will disable PIP Mode final bool disablePictureInPicture; /// set if video should exit fullscreen on end final bool exitFullscreenOnEnd; /// set if video should be prevented from seeking. use with caution (ui is jumpin but it works) final bool preventSeeking; /// on chrome browser the more menu contains a download button which can be hidden when this is set to true final bool hideDownloadButton; /// online url to the image that should be shown when the video is not playing final String? thumbnailPath; const CustomVideoPlayerWebSettings({ this.key, required this.src, this.aspectRatio, this.startAt = 0, this.autoplay = false, this.enableControls = true, this.backgroundColor, this.enterFullscreenOnStart = false, this.exitFullscreenOnEnd = false, this.preventSeeking = false, this.hideDownloadButton = false, this.disablePictureInPicture = false, this.thumbnailPath, }); } ================================================ FILE: packages/appinio_video_player/pubspec.yaml ================================================ name: appinio_video_player description: A custom video player that builds on top of the official video_player package by flutter and adds many functionalities. version: 1.3.0 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages environment: sdk: ">=2.12.0 <4.0.0" flutter: ">=1.17.0" dependencies: cached_video_player: ^2.0.4 flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^1.0.0 flutter: ================================================ FILE: packages/appinio_video_player/test/custom_video_player_test.dart ================================================ // import 'package:flutter_test/flutter_test.dart'; // import 'package:custom_video_player/custom_video_player.dart'; void main() { // test('adds one to input values', () { // final calculator = Calculator(); // expect(calculator.addOne(2), 3); // expect(calculator.addOne(-7), -6); // expect(calculator.addOne(0), 1); // }); } ================================================ FILE: packages/disable_screenshot/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. /pubspec.lock **/doc/api/ .dart_tool/ .packages build/ ================================================ FILE: packages/disable_screenshot/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled. version: revision: f1875d570e39de09040c8f79aa13cc56baab8db1 channel: stable project_type: plugin # Tracks metadata for the flutter migrate command migration: platforms: - platform: root create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: android create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 - platform: ios create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 # User provided section # List of Local paths (relative to this file) that should be # ignored by the migrate tool. # # Files that are not part of the templates will be ignored by default. unmanaged_files: - 'lib/main.dart' - 'ios/Runner.xcodeproj/project.pbxproj' ================================================ FILE: packages/disable_screenshot/CHANGELOG.md ================================================ ## 0.0.1 * TODO: Describe initial release. ================================================ FILE: packages/disable_screenshot/LICENSE ================================================ TODO: Add your license here. ================================================ FILE: packages/disable_screenshot/README.md ================================================ # disable_screenshot A new Flutter plugin project. ## Getting Started This project is a starting point for a Flutter [plug-in package](https://flutter.dev/developing-packages/), a specialized package that includes platform-specific implementation code for Android and/or iOS. For help getting started with Flutter development, view the [online documentation](https://flutter.dev/docs), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: packages/disable_screenshot/analysis_options.yaml ================================================ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/disable_screenshot/android/.gitignore ================================================ *.iml .gradle /local.properties /.idea/workspace.xml /.idea/libraries .DS_Store /build /captures .cxx ================================================ FILE: packages/disable_screenshot/android/build.gradle ================================================ group 'com.appinio.disable_screenshot' version '1.0-SNAPSHOT' buildscript { repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' } } rootProject.allprojects { repositories { google() mavenCentral() } } apply plugin: 'com.android.library' android { compileSdkVersion 31 compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } defaultConfig { minSdkVersion 16 } } dependencies { testImplementation 'junit:junit:4.12' androidTestImplementation 'com.android.support.test:runner:1.0.2' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' } ================================================ FILE: packages/disable_screenshot/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip ================================================ FILE: packages/disable_screenshot/android/settings.gradle ================================================ rootProject.name = 'disable_screenshot' ================================================ FILE: packages/disable_screenshot/android/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/disable_screenshot/android/src/main/java/com/appinio/disable_screenshot/DisableScreenshotPlugin.java ================================================ package com.appinio.disable_screenshot; import android.os.Build; import android.os.Environment; import android.os.FileObserver; import android.os.Handler; import android.os.Looper; import android.view.WindowManager; import android.webkit.MimeTypeMap; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Timer; import java.util.TimerTask; import io.flutter.embedding.engine.plugins.FlutterPlugin; import io.flutter.embedding.engine.plugins.activity.ActivityAware; import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding; import io.flutter.plugin.common.MethodCall; import io.flutter.plugin.common.MethodChannel; import io.flutter.plugin.common.MethodChannel.MethodCallHandler; import io.flutter.plugin.common.MethodChannel.Result; import io.flutter.plugin.common.EventChannel; /** DisableScreenshotPlugin */ public class DisableScreenshotPlugin implements FlutterPlugin, MethodCallHandler, EventChannel.StreamHandler, ActivityAware { private MethodChannel channel; private FileObserver fileObserver; private Timer timeout = new Timer(); private final Map watchModifier = new HashMap<>(); private ActivityPluginBinding activityPluginBinding; private Handler handler; private boolean screenRecording = false; private long tempSize = 0; private EventChannel.EventSink eventSink = null; @Override public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) { channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "com.appinio.screenshot/disableScreenshots"); EventChannel eventChannel = new EventChannel(flutterPluginBinding.getBinaryMessenger(), "com.appinio.screenshot/observer"); channel.setMethodCallHandler(this); eventChannel.setStreamHandler(this); } @Override public void onListen(Object arguments, EventChannel.EventSink events) { this.eventSink = events; handler = new Handler(Looper.getMainLooper()); updateScreenRecordStatus(); if(Build.VERSION.SDK_INT >=29){ final List files = new ArrayList<>(); final List paths = new ArrayList<>(); for (Path path : Path.values()) { files.add(new File(path.getPath())); paths.add(path.getPath()); } fileObserver = new FileObserver(files) { @Override public void onEvent(int event, final String filename) { if (event == FileObserver.CREATE) { handler.post(() -> { for(String fullPath : paths){ File file = new File(fullPath + filename); if(file.exists()){ if(getMimeType(file.getPath()).contains("image")){ eventSink.success("Got Screenshot"); } } } }); } } }; fileObserver.startWatching(); }else{ for (final Path path : Path.values()) { fileObserver = new FileObserver(path.getPath()) { @Override public void onEvent(int event, final String filename) { updateScreenRecordStatus(); File file = new File(path.getPath() + filename); if (event == FileObserver.CREATE) { handler.post(() -> { if(file.exists()){ if(getMimeType(file.getPath()).contains("image")){ eventSink.success("Got Screenshot"); } } }); } } }; fileObserver.startWatching(); } } } @Override public void onCancel(Object arguments) { if(fileObserver!=null) fileObserver.stopWatching(); for (Map.Entry stringObjectEntry : watchModifier.entrySet()) { stringObjectEntry.getValue().stopWatching(); } watchModifier.clear(); eventSink = null; } @Override public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) { switch(call.method){ case "disableScreenshots": if((boolean)call.arguments){ activityPluginBinding.getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_SECURE); }else{ activityPluginBinding.getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_SECURE); } break; default: } } private void updateScreenRecordStatus(){ List paths = new ArrayList<>(); for(Path path : Path.values()){ paths.add(path.getPath()); } for (int i = 0; i < Path.values().length;i++){ String fullPath = paths.get(i); File newFile = getLastModified(fullPath); if(newFile!=null && getMimeType(newFile.getPath()).toLowerCase().contains("video") && !watchModifier.containsKey(newFile.getPath())){ watchModifier.put(newFile.getPath(), new FileObserver(newFile) { @Override public void onEvent(int event, @Nullable String path) { long curSize = newFile.length(); if(curSize > tempSize){ if(timeout!=null){ try { timeout.cancel(); timeout = null; }catch (Exception ignored){} } setScreenRecordStatus(event == FileObserver.MODIFY); tempSize = newFile.length(); } if(timeout == null){ timeout = new Timer(); timeout.schedule(new TimerTask() { @Override public void run() { if(watchModifier.containsKey(newFile.getPath())){ setScreenRecordStatus(curSize != tempSize); } } }, 1500); } } }); FileObserver watch = watchModifier.get(newFile.getPath()); if(watch!=null) watch.startWatching(); } } } void setScreenRecordStatus(boolean value){ if(screenRecording != value){ new Handler(Looper.getMainLooper()).post(() -> { screenRecording = value; channel.invokeMethod("screenrecord",value); }); } } @Override public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { } public static String getMimeType(String url) { String type = null; String extension = MimeTypeMap.getFileExtensionFromUrl(url); if (extension != null) { type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); } return type; } public static File getLastModified(String directoryFilePath) { File directory = new File(directoryFilePath); if(directory.listFiles() == null) return null; File[] files = directory.listFiles(File::isFile); long lastModifiedTime = Long.MIN_VALUE; File chosenFile = null; if (files != null) { for (File file : files) { if (file.lastModified() > lastModifiedTime) { chosenFile = file; lastModifiedTime = file.lastModified(); } } } return chosenFile; } @Override public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) { activityPluginBinding = binding; } @Override public void onDetachedFromActivityForConfigChanges() { } @Override public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) { } @Override public void onDetachedFromActivity() { } public enum Path { DCIM(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) + File.separator + "Screenshots" + File.separator), PICTURES(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES ) + File.separator + "Screenshots" + File.separator); final private String path; public String getPath() { return path; } Path(String path) { this. path = path; } } } ================================================ FILE: packages/disable_screenshot/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/disable_screenshot/example/README.md ================================================ # disable_screenshot_example Demonstrates how to use the disable_screenshot plugin. ## 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://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) For help getting started with Flutter development, view the [online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: packages/disable_screenshot/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/disable_screenshot/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/disable_screenshot/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { 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.appinio.disable_screenshot_example" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/disable_screenshot/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/kotlin/com/appinio/disable_screenshot_example/MainActivity.kt ================================================ package com.appinio.disable_screenshot_example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/disable_screenshot/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' 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') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/disable_screenshot/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip ================================================ FILE: packages/disable_screenshot/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/disable_screenshot/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/disable_screenshot/example/ios/.gitignore ================================================ **/dgph *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/disable_screenshot/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/disable_screenshot/example/ios/Flutter/Debug.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/disable_screenshot/example/ios/Flutter/Release.xcconfig ================================================ #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" ================================================ FILE: packages/disable_screenshot/example/ios/Podfile ================================================ # Uncomment this line to define a global platform for your project # platform :ios, '9.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 ================================================ FILE: packages/disable_screenshot/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName Disable Screenshot CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier $(PRODUCT_BUNDLE_IDENTIFIER) CFBundleInfoDictionaryVersion 6.0 CFBundleName disable_screenshot_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 ================================================ FILE: packages/disable_screenshot/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 173A4DC85017C2708575114E /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 134011386083DF1A2B141EB6 /* Pods_Runner.framework */; }; 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 */ 134011386083DF1A2B141EB6 /* 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 = ""; }; 2FC3F324C212CE939ED89DE7 /* 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 = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 704A306330EBCF1471ADDF57 /* 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 = ""; }; 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 = ""; }; 933C7622552FF59BF29A1BC4 /* 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 = ""; }; 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( 173A4DC85017C2708575114E /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 5C81BC9BF149707B9B932B7C /* Pods */ = { isa = PBXGroup; children = ( 933C7622552FF59BF29A1BC4 /* Pods-Runner.debug.xcconfig */, 2FC3F324C212CE939ED89DE7 /* Pods-Runner.release.xcconfig */, 704A306330EBCF1471ADDF57 /* Pods-Runner.profile.xcconfig */, ); name = Pods; path = Pods; sourceTree = ""; }; 63F1A38829C08A1DFFB63B45 /* Frameworks */ = { isa = PBXGroup; children = ( 134011386083DF1A2B141EB6 /* Pods_Runner.framework */, ); name = Frameworks; 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 */, 5C81BC9BF149707B9B932B7C /* Pods */, 63F1A38829C08A1DFFB63B45 /* 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 = ( ACF369033080C9CA6A727007 /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 20E2A5286B0453268D58533F /* [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 */ 20E2A5286B0453268D58533F /* [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; }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; ACF369033080C9CA6A727007 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputFileListPaths = ( ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputFileListPaths = ( ); outputPaths = ( "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ 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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.appinio.disableScreenshotExample; 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 = 9.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 = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; SWIFT_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; 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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.appinio.disableScreenshotExample; 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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); PRODUCT_BUNDLE_IDENTIFIER = com.appinio.disableScreenshotExample; 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 */; } ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/disable_screenshot/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/disable_screenshot/example/lib/main.dart ================================================ import 'package:flutter/material.dart'; import 'dart:async'; import 'package:disable_screenshot/disable_screenshot.dart'; import 'package:share_plus/share_plus.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({Key? key}) : super(key: key); @override MyAppState createState() => MyAppState(); } class MyAppState extends State { @override Widget build(BuildContext context) { return const MaterialApp(home: RootApp()); } } class RootApp extends StatefulWidget { const RootApp({Key? key}) : super(key: key); @override RootAppState createState() => RootAppState(); } class RootAppState extends State { final DisableScreenshot _plugin = DisableScreenshot(); late StreamSubscription _screenshotsSubscription; int _screenshotsCount = 0; bool _disableScreenshots = false; @override void initState() { super.initState(); _screenshotsSubscription = _plugin.onScreenShots().listen((event) { setState(() { _screenshotsCount++; }); }); } Future _onCaptureScreenshotTap() async { final fileName = await _plugin.captureScreenShotFromWidget( Container( color: Colors.red, child: Container( margin: const EdgeInsets.all(30), color: Colors.green, ), ), context: context, ); Share.shareXFiles([XFile(fileName!)]); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Disable Screenshot'), ), body: Column( children: [ const SizedBox(height: 100), Center( child: Text("counts:$_screenshotsCount"), ), Center( child: Text(_disableScreenshots ? "disabled" : "allowed"), ), GestureDetector( onTap: () async { bool flag = !_disableScreenshots; await _plugin.disableScreenshots(flag); setState(() { _disableScreenshots = flag; }); }, child: Text(_disableScreenshots ? "allow screenshot" : "disable screenshot")), ], ), floatingActionButton: FloatingActionButton( onPressed: _onCaptureScreenshotTap, child: const Icon(Icons.image_outlined), ), ); } @override void dispose() { super.dispose(); _screenshotsSubscription.cancel(); } } ================================================ FILE: packages/disable_screenshot/example/pubspec.yaml ================================================ name: disable_screenshot_example description: Demonstrates how to use the disable_screenshot plugin. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: sdk: ">=2.17.6 <3.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter disable_screenshot: # When depending on this package from a real application you should use: # disable_screenshot: ^x.y.z # See https://dart.dev/tools/pub/dependencies#version-constraints # The example app is bundled with the plugin so we use a path dependency on # the parent directory to use the current plugin's version. path: ../ # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 share_plus: ^10.0.2 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 # 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: # 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 # 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 ================================================ FILE: packages/disable_screenshot/example/test/widget_test.dart ================================================ // // This is a basic Flutter widget test. // // // // To perform an interaction with a widget in your test, use the WidgetTester // // utility in the flutter_test package. For example, you can send tap and scroll // // gestures. You can also use WidgetTester to find child widgets in the widget // // tree, read text, and verify that the values of widget properties are correct. // import 'package:flutter/material.dart'; // import 'package:flutter_test/flutter_test.dart'; // import 'package:disable_screenshot_example/main.dart'; // void main() { // testWidgets('Verify Platform version', (WidgetTester tester) async { // // Build our app and trigger a frame. // await tester.pumpWidget(const MyApp()); // // Verify that platform version is retrieved. // expect( // find.byWidgetPredicate( // (Widget widget) => widget is Text && // widget.data!.startsWith('Running on:'), // ), // findsOneWidget, // ); // }); // } ================================================ FILE: packages/disable_screenshot/ios/.gitignore ================================================ .idea/ .vagrant/ .sconsign.dblite .svn/ .DS_Store *.swp profile DerivedData/ build/ GeneratedPluginRegistrant.h GeneratedPluginRegistrant.m .generated/ *.pbxuser *.mode1v3 *.mode2v3 *.perspectivev3 !default.pbxuser !default.mode1v3 !default.mode2v3 !default.perspectivev3 xcuserdata *.moved-aside *.pyc *sync/ Icon? .tags* /Flutter/Generated.xcconfig /Flutter/ephemeral/ /Flutter/flutter_export_environment.sh ================================================ FILE: packages/disable_screenshot/ios/Assets/.gitkeep ================================================ ================================================ FILE: packages/disable_screenshot/ios/Classes/DisableScreenshotPlugin.h ================================================ #import @interface DisableScreenshotPlugin : NSObject @end ================================================ FILE: packages/disable_screenshot/ios/Classes/DisableScreenshotPlugin.m ================================================ #import "DisableScreenshotPlugin.h" #if __has_include() #import #else // Support project import fallback if the generated compatibility header // is not copied when this plugin is created as a library. // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 #import "disable_screenshot-Swift.h" #endif @implementation DisableScreenshotPlugin + (void)registerWithRegistrar:(NSObject*)registrar { [SwiftDisableScreenshotPlugin registerWithRegistrar:registrar]; } @end ================================================ FILE: packages/disable_screenshot/ios/Classes/SwiftDisableScreenshotPlugin.swift ================================================ import Flutter import UIKit public class SwiftDisableScreenshotPlugin: NSObject, FlutterPlugin { var eventSink: FlutterEventSink? public static func register(with registrar: FlutterPluginRegistrar) { let instance = SwiftDisableScreenshotPlugin() let methodChannel = FlutterMethodChannel( name: "com.appinio.screenshot/disableScreenshots", binaryMessenger: registrar.messenger() ) registrar.addMethodCallDelegate(instance, channel: methodChannel) let channel = FlutterEventChannel( name: "com.appinio.screenshot/observer", binaryMessenger: registrar.messenger() ) channel.setStreamHandler(instance) } @objc func callScreenshots() { eventSink!("") } public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { /* if call.method == "disableScreenshots" { if let arg = call.arguments as? Dictionary, let disable = arg["disable"] as? Bool { if disable { //禁用截屏 } else { //允许截屏 } } else { print("【SwiftDisableScreenshotsPlugin】disableScreenshots 收到错误参数") } } else { result(FlutterMethodNotImplemented) } */ result(FlutterMethodNotImplemented) } } extension SwiftDisableScreenshotPlugin: FlutterStreamHandler { public func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? { eventSink = events NotificationCenter.default.addObserver( self, selector: #selector(callScreenshots), name: UIApplication.userDidTakeScreenshotNotification, object: nil) return nil } public func onCancel(withArguments arguments: Any?) -> FlutterError? { NotificationCenter.default.removeObserver(self) eventSink = nil return nil } } ================================================ FILE: packages/disable_screenshot/ios/disable_screenshot.podspec ================================================ # # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. # Run `pod lib lint disable_screenshot.podspec` to validate before publishing. # Pod::Spec.new do |s| s.name = 'disable_screenshot' s.version = '0.0.1' s.summary = 'A new Flutter plugin project.' s.description = <<-DESC A new Flutter plugin project. DESC s.homepage = 'http://example.com' s.license = { :file => '../LICENSE' } s.author = { 'Your Company' => 'email@example.com' } s.source = { :path => '.' } s.source_files = 'Classes/**/*' s.dependency 'Flutter' s.platform = :ios, '9.0' # Flutter.framework does not contain a i386 slice. s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } s.swift_version = '5.0' end ================================================ FILE: packages/disable_screenshot/lib/disable_screenshot.dart ================================================ import 'package:flutter/cupertino.dart'; import 'disable_screenshot_platform_interface.dart'; class DisableScreenshot { Future getPlatformVersion() { return DisableScreenshotPlatform.instance.getPlatformVersion(); } Stream onScreenShots() { return DisableScreenshotPlatform.instance.onScreenShots(); } Future disableScreenshots(bool disable) { return DisableScreenshotPlatform.instance.disableScreenshots(disable); } Future captureScreenShot({ required GlobalKey screenshotWidgetKey, String name = 'screenshot', }) async { return DisableScreenshotPlatform.instance.captureScreenShot( screenshotWidgetKey: screenshotWidgetKey, name: name); } Future captureScreenShotFromWidget(Widget widget, {Duration delay = const Duration(milliseconds: 50), double? pixelRatio, BuildContext? context, String? filename}) async { return DisableScreenshotPlatform.instance.captureScreenShotFromWidget( widget, delay: delay, pixelRatio: pixelRatio, context: context, filename: filename); } } ================================================ FILE: packages/disable_screenshot/lib/disable_screenshot_method_channel.dart ================================================ import 'dart:io'; import 'dart:ui' as ui; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter/services.dart'; import 'package:path_provider/path_provider.dart' if (dart.library.js) "package:flutter/material.dart"; import 'disable_screenshot_platform_interface.dart'; /// An implementation of [DisableScreenshotPlatform] that uses method channels. class MethodChannelDisableScreenshot extends DisableScreenshotPlatform { /// The method channel used to interact with the native platform. @visibleForTesting final methodChannel = const MethodChannel('disable_screenshot'); final MethodChannel _methodChannel = const MethodChannel("com.appinio.screenshot/disableScreenshots"); final EventChannel _eventChannel = const EventChannel('com.appinio.screenshot/observer'); @override Future getPlatformVersion() async { final version = await methodChannel.invokeMethod('getPlatformVersion'); return version; } Stream? _onScreenShots; @override Stream onScreenShots() { _onScreenShots ??= _eventChannel.receiveBroadcastStream(); return _onScreenShots!; } @override Future disableScreenshots(bool disable) async { if (Platform.isAndroid) { return await _methodChannel.invokeMethod("disableScreenshots", disable); } else { // print('Disabling screenshots is only supported on Android'); } } @override Future captureScreenShot({ required GlobalKey screenshotWidgetKey, String name = 'screenshot', }) async { try { RenderRepaintBoundary boundary = screenshotWidgetKey.currentContext! .findRenderObject() as RenderRepaintBoundary; ui.Image image = await boundary.toImage(pixelRatio: 3); String directory = !kIsWeb ? (await getApplicationDocumentsDirectory()).path : '/assets/db'; ByteData? byteData = await (image.toByteData(format: ui.ImageByteFormat.png)); if (byteData != null) { var pngBytes = byteData.buffer.asUint8List(); File imgFile = File('$directory/$name.png'); await imgFile.writeAsBytes(pngBytes); return '$directory/$name.png'; } else { return null; } } catch (e) { debugPrint(e.toString()); return null; } } @override Future captureScreenShotFromWidget(Widget widget, {Duration delay = const Duration(milliseconds: 50), double? pixelRatio, BuildContext? context, String? filename}) async { /// ///Retry counter /// int retryCounter = 3; bool isDirty = false; Widget child = widget; if (context != null) { /// ///Inherit Theme and MediaQuery of app /// /// child = InheritedTheme.captureAll( context, MediaQuery(data: MediaQuery.of(context), child: child), ); } final RenderRepaintBoundary repaintBoundary = RenderRepaintBoundary(); final contextViewConfiguration = ViewConfiguration.fromView(View.of(context!)); final RenderView renderView = RenderView( view: View.of(context), child: RenderPositionedBox( alignment: Alignment.center, child: repaintBoundary), configuration: ViewConfiguration( logicalConstraints: contextViewConfiguration.logicalConstraints, physicalConstraints: contextViewConfiguration.physicalConstraints, devicePixelRatio: pixelRatio ?? 1.0, ), ); final PipelineOwner pipelineOwner = PipelineOwner(); final BuildOwner buildOwner = BuildOwner( focusManager: FocusManager(), onBuildScheduled: () { /// ///current render is dirty, mark it. /// isDirty = true; }); pipelineOwner.rootNode = renderView; renderView.prepareInitialFrame(); final RenderObjectToWidgetElement rootElement = RenderObjectToWidgetAdapter( container: repaintBoundary, child: Directionality( textDirection: TextDirection.ltr, child: child, )).attachToRenderTree( buildOwner, ); //// ///Render Widget /// /// buildOwner.buildScope( rootElement, ); buildOwner.finalizeTree(); pipelineOwner.flushLayout(); pipelineOwner.flushCompositingBits(); pipelineOwner.flushPaint(); ui.Image? image; do { /// ///Reset the dirty flag /// /// isDirty = false; image = await repaintBoundary.toImage( pixelRatio: pixelRatio ?? contextViewConfiguration.devicePixelRatio, ); /// ///This delay shoud inceases with Widget tree Size /// await Future.delayed(delay); /// ///Check does this require rebuild /// /// if (isDirty) { /// ///Previous capture has been updated, re-render again. /// /// buildOwner.buildScope( rootElement, ); buildOwner.finalizeTree(); pipelineOwner.flushLayout(); pipelineOwner.flushCompositingBits(); pipelineOwner.flushPaint(); } retryCounter--; /// ///retry untill capture is successfull /// } while (isDirty && retryCounter >= 0); final ByteData? byteData = await image.toByteData(format: ui.ImageByteFormat.png); String directory = !kIsWeb ? (await getApplicationDocumentsDirectory()).path : '/assets/db'; await (image.toByteData(format: ui.ImageByteFormat.png)); if (byteData != null) { var pngBytes = byteData.buffer.asUint8List(); String path = '$directory/screenshot${filename ?? ""}.png'; File imgFile = File(path); await imgFile.writeAsBytes(pngBytes); return path; } else { return null; } } } extension Ex on double { double toPrecision(int n) => double.parse(toStringAsFixed(n)); } ================================================ FILE: packages/disable_screenshot/lib/disable_screenshot_platform_interface.dart ================================================ import 'package:flutter/material.dart'; import 'package:plugin_platform_interface/plugin_platform_interface.dart'; import 'disable_screenshot_method_channel.dart'; abstract class DisableScreenshotPlatform extends PlatformInterface { /// Constructs a DisableScreenshotPlatform. DisableScreenshotPlatform() : super(token: _token); static final Object _token = Object(); static DisableScreenshotPlatform _instance = MethodChannelDisableScreenshot(); /// The default instance of [DisableScreenshotPlatform] to use. /// /// Defaults to [MethodChannelDisableScreenshot]. static DisableScreenshotPlatform get instance => _instance; /// Platform-specific implementations should set this with their own /// platform-specific class that extends [DisableScreenshotPlatform] when /// they register themselves. static set instance(DisableScreenshotPlatform instance) { PlatformInterface.verifyToken(instance, _token); _instance = instance; } Future getPlatformVersion() { throw UnimplementedError('platformVersion() has not been implemented.'); } Stream onScreenShots() { throw UnimplementedError('platformVersion() has not been implemented.'); } Future disableScreenshots(bool disable) { throw UnimplementedError('platformVersion() has not been implemented.'); } Future captureScreenShot({ required GlobalKey screenshotWidgetKey, String name = 'screenshot', }) { throw UnimplementedError('captureScreenShot() has not been implemented.'); } Future captureScreenShotFromWidget(Widget widget, {Duration delay = const Duration(milliseconds: 50), double? pixelRatio, BuildContext? context, String? filename}) { throw UnimplementedError( 'captureScreenShotFromWidget() has not been implemented.'); } } ================================================ FILE: packages/disable_screenshot/pubspec.yaml ================================================ name: disable_screenshot description: A new Flutter plugin project. version: 0.0.1 publish_to: 'none' environment: sdk: ">=2.17.6 <3.0.0" flutter: ">=2.5.0" dependencies: path_provider: ^2.0.8 flutter: sdk: flutter plugin_platform_interface: ^2.0.2 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 # 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: # This section identifies this Flutter project as a plugin project. # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) # which should be registered in the plugin registry. This is required for # using method channels. # The Android 'package' specifies package in which the registered class is. # This is required for using method channels on Android. # The 'ffiPlugin' specifies that native code should be built and bundled. # This is required for using `dart:ffi`. # All these are used by the tooling to maintain consistency when # adding or updating assets for this project. plugin: platforms: android: package: com.appinio.disable_screenshot pluginClass: DisableScreenshotPlugin ios: pluginClass: DisableScreenshotPlugin web: # To add assets to your plugin 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.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/assets-and-images/#resolution-aware # To add custom fonts to your plugin 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.dev/custom-fonts/#from-packages ================================================ FILE: packages/disable_screenshot/test/disable_screenshot_method_channel_test.dart ================================================ import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:disable_screenshot/disable_screenshot_method_channel.dart'; void main() { MethodChannelDisableScreenshot platform = MethodChannelDisableScreenshot(); const MethodChannel channel = MethodChannel('disable_screenshot'); TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { channel.setMockMethodCallHandler((MethodCall methodCall) async { return '42'; }); }); tearDown(() { channel.setMockMethodCallHandler(null); }); test('getPlatformVersion', () async { expect(await platform.getPlatformVersion(), '42'); }); } ================================================ FILE: packages/disable_screenshot/test/disable_screenshot_test.dart ================================================ // import 'package:flutter_test/flutter_test.dart'; // import 'package:disable_screenshot/disable_screenshot.dart'; // import 'package:disable_screenshot/disable_screenshot_platform_interface.dart'; // import 'package:disable_screenshot/disable_screenshot_method_channel.dart'; // import 'package:plugin_platform_interface/plugin_platform_interface.dart'; // class MockDisableScreenshotPlatform // with MockPlatformInterfaceMixin // implements DisableScreenshotPlatform { // @override // Future getPlatformVersion() => Future.value('42'); // } // void main() { // final DisableScreenshotPlatform initialPlatform = DisableScreenshotPlatform.instance; // test('$MethodChannelDisableScreenshot is the default instance', () { // expect(initialPlatform, isInstanceOf()); // }); // test('getPlatformVersion', () async { // DisableScreenshot disableScreenshotPlugin = DisableScreenshot(); // MockDisableScreenshotPlatform fakePlatform = MockDisableScreenshotPlatform(); // DisableScreenshotPlatform.instance = fakePlatform; // expect(await disableScreenshotPlugin.getPlatformVersion(), '42'); // }); // } ================================================ FILE: packages/flutter_onboarding_slider/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/flutter_onboarding_slider/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: d79295af24c3ed621c33713ecda14ad196fd9c31 channel: stable project_type: package ================================================ FILE: packages/flutter_onboarding_slider/CHANGELOG.md ================================================ ## [1.0.11] - 2023.10.16 * Bug Fixes ## [1.0.10] - 2023.08.23 * Bug Fixes ## [1.0.9] - 2023.03.20 Features: * More UI customizing options. ## [1.0.8] - 2022.09.25 * Updating Readme. ## [1.0.7] - 2021.12.09 * Bug fix: resolving dependencies conflict. ## [1.0.6] - 2021.11.08 * Improvements. ## [1.0.5] - 2021.11.08 * Bug fixes & improvements. ## [1.0.4] - 2021.10.22 * Bug fixes. ## [1.0.3] - 2021.10.21 * Added parameters to allow further customization. * Fixed bugs on background widgets sizes. ## [1.0.2] - 2021.09.29 * Renamed parameters. * Added middle and leading widgets in navigation tab. ## [1.0.1] - 2021.09.28 * Updating dependencies. ## [1.0.0] - 2021.08.11 * Initial version. ================================================ FILE: packages/flutter_onboarding_slider/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2021 APPINIO GmbH 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. ================================================ FILE: packages/flutter_onboarding_slider/README.md ================================================ ```Flutter OnBoarding Slider``` is a Flutter package containing a page slider with parallex design that allows (Text) widgets or body to slide at a different speed with background. ✨ Supporting Android, iOS. ## Why? We build this package because we wanted to: - have parralex design of the background that allows background to slide at a different speed. - display with a bottom controller that indicates the current page. - trigger `skip` with a button on the top right with a final function. - NEW: you can use ```centerBackground``` property to center the background images. If you use this property ```imageHorizontalOffset``` property will get ignored. - NEW: You can use ```finishButtonStyle``` property to customize the finish button according to your design. ## Show Cases #### Swipe Touch swiping. #### Slide Swipe with the Floating Action Button. #### Skip Skip to last Slide. ## Installation Create a new project with the command ```yaml flutter create MyApp ``` Add ```yaml dependencies: ... flutter_onboarding_slider: ``` to your `pubspec.yaml` of your flutter project. **OR** run ```yaml flutter pub add flutter_onboarding_slider ``` in your project's root directory. In your library add the following import: ```dart import 'package:flutter_onboarding_slider/flutter_onboarding_slider.dart'; ``` For help getting started with Flutter, view the online [documentation](https://flutter.io/). ## Usage You can place your `OnBoardingSlider` inside of a `Scaffold` or `CupertinoApp` like we did here. Optional parameters can be defined to enable different features. See the following example.. ```dart class OnBoarding extends StatelessWidget { @override Widget build(BuildContext context) { return CupertinoApp( home: OnBoardingSlider( headerBackgroundColor: Colors.white, finishButtonText: 'Register', finishButtonStyle: FinishButtonStyle( backgroundColor: Colors.black, ), skipTextButton: Text('Skip'), trailing: Text('Login'), background: [ Image.asset('assets/slide_1.png'), Image.asset('assets/slide_2.png'), ], totalPage: 2, speed: 1.8, pageBodies: [ Container( padding: EdgeInsets.symmetric(horizontal: 40), child: Column( children: [ SizedBox( height: 480, ), Text('Description Text 1'), ], ), ), Container( padding: EdgeInsets.symmetric(horizontal: 40), child: Column( children: [ SizedBox( height: 480, ), Text('Description Text 2'), ], ), ), ], ), ); } } ``` ## Constructor #### Basic | Parameter | Default | Description | Required | |-----------------------|:--------|:--------------------------------------------------------------------------------------------------------|:--------:| | headerBackgroundColor | - | color of the background | false | | finishButtonText | - | Text inside last pages bottom button | false | | skipTextButton | - | NavigationBar trailing widget when not on last screen | false | | trailing | - | NavigationBar trailing widget when on last screen | false | | background | - | List of Widgets to be shown in the backgrounds of the pages. For example a picture or some illustration | true | | totalPage | - | Number of total pages | true | | speed | - | The speed of the animation for the [background] | true | | pageBodies | - | The main content ont the screen displayed above the [background] | true | | centerBackground | false | This flag is used to center the background. | false | | finishButtonStyle | - | This property is used to customize the finish button. | false |
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/flutter_onboarding_slider/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json ================================================ FILE: packages/flutter_onboarding_slider/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled. version: revision: 135454af32477f815a7525073027a3ff9eff1bfd channel: stable project_type: app # Tracks metadata for the flutter migrate command migration: platforms: - platform: root create_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: android create_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 135454af32477f815a7525073027a3ff9eff1bfd - platform: ios create_revision: 135454af32477f815a7525073027a3ff9eff1bfd base_revision: 135454af32477f815a7525073027a3ff9eff1bfd # User provided section # List of Local paths (relative to this file) that should be # ignored by the migrate tool. # # Files that are not part of the templates will be ignored by default. unmanaged_files: - 'lib/main.dart' - 'ios/Runner.xcodeproj/project.pbxproj' ================================================ FILE: packages/flutter_onboarding_slider/example/README.md ================================================ # example A new Flutter project. ## 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://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) For help getting started with Flutter development, view the [online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: packages/flutter_onboarding_slider/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/flutter_onboarding_slider/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion flutter.compileSdkVersion ndkVersion flutter.ndkVersion compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } 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-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 '../..' } ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/java/com/example/example/MainActivity.java ================================================ package com.example.example; import io.flutter.embedding.android.FlutterActivity; public class MainActivity extends FlutterActivity { } ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' 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') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/flutter_onboarding_slider/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip ================================================ FILE: packages/flutter_onboarding_slider/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/flutter_onboarding_slider/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/flutter_onboarding_slider/example/ios/.gitignore ================================================ *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 11.0 ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName Example 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 ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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)"; DEVELOPMENT_TEAM = 8YC2P2LVF5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; 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)"; DEVELOPMENT_TEAM = 8YC2P2LVF5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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)"; DEVELOPMENT_TEAM = 8YC2P2LVF5; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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 */; } ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/flutter_onboarding_slider/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/flutter_onboarding_slider/example/lib/main.dart ================================================ import 'package:example/screens/login_page.dart'; import 'package:example/screens/register_page.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_onboarding_slider/flutter_onboarding_slider.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const CupertinoApp( debugShowCheckedModeBanner: false, home: MyHome(), ); } } class MyHome extends StatelessWidget { final Color kDarkBlueColor = const Color(0xFF053149); const MyHome({super.key}); @override Widget build(BuildContext context) { return OnBoardingSlider( finishButtonText: 'Register', onFinish: () { Navigator.push( context, CupertinoPageRoute( builder: (context) => const RegisterPage(), ), ); }, finishButtonStyle: FinishButtonStyle( backgroundColor: kDarkBlueColor, ), skipTextButton: Text( 'Skip', style: TextStyle( fontSize: 16, color: kDarkBlueColor, fontWeight: FontWeight.w600, ), ), trailing: Text( 'Login', style: TextStyle( fontSize: 16, color: kDarkBlueColor, fontWeight: FontWeight.w600, ), ), trailingFunction: () { Navigator.push( context, CupertinoPageRoute( builder: (context) => const LoginPage(), ), ); }, controllerColor: kDarkBlueColor, totalPage: 3, headerBackgroundColor: Colors.white, pageBackgroundColor: Colors.white, background: [ Image.asset( 'assets/slide_1.png', height: 400, ), Image.asset( 'assets/slide_2.png', height: 400, ), Image.asset( 'assets/slide_3.png', height: 400, ), ], speed: 1.8, pageBodies: [ Container( alignment: Alignment.center, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.symmetric(horizontal: 40), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox( height: 480, ), Text( 'On your way...', textAlign: TextAlign.center, style: TextStyle( color: kDarkBlueColor, fontSize: 24.0, fontWeight: FontWeight.w600, ), ), const SizedBox( height: 20, ), const Text( 'to find the perfect looking Onboarding for your app?', textAlign: TextAlign.center, style: TextStyle( color: Colors.black26, fontSize: 18.0, fontWeight: FontWeight.w600, ), ), ], ), ), Container( alignment: Alignment.center, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.symmetric(horizontal: 40), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox( height: 480, ), Text( 'You’ve reached your destination.', textAlign: TextAlign.center, style: TextStyle( color: kDarkBlueColor, fontSize: 24.0, fontWeight: FontWeight.w600, ), ), const SizedBox( height: 20, ), const Text( 'Sliding with animation', textAlign: TextAlign.center, style: TextStyle( color: Colors.black26, fontSize: 18.0, fontWeight: FontWeight.w600, ), ), ], ), ), Container( alignment: Alignment.center, width: MediaQuery.of(context).size.width, padding: const EdgeInsets.symmetric(horizontal: 40), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.center, children: [ const SizedBox( height: 480, ), Text( 'Start now!', textAlign: TextAlign.center, style: TextStyle( color: kDarkBlueColor, fontSize: 24.0, fontWeight: FontWeight.w600, ), ), const SizedBox( height: 20, ), const Text( 'Where everything is possible and customize your onboarding.', textAlign: TextAlign.center, style: TextStyle( color: Colors.black26, fontSize: 18.0, fontWeight: FontWeight.w600, ), ), ], ), ), ], ); } } ================================================ FILE: packages/flutter_onboarding_slider/example/lib/screens/login_page.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class LoginPage extends StatelessWidget { const LoginPage({super.key}); @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Login Page'), backgroundColor: Colors.white, border: Border( bottom: BorderSide( color: Colors.transparent, ), ), ), child: Container(), ); } } ================================================ FILE: packages/flutter_onboarding_slider/example/lib/screens/register_page.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class RegisterPage extends StatelessWidget { const RegisterPage({super.key}); @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Register Page'), backgroundColor: Colors.white, border: Border( bottom: BorderSide( color: Colors.transparent, ), ), ), child: Container(), ); } } ================================================ FILE: packages/flutter_onboarding_slider/example/pubspec.yaml ================================================ name: example description: A new Flutter project. # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # 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 is used as CFBundleVersion. # Read more about iOS versioning at # 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.0.0+1 environment: sdk: '>=2.18.6 <3.0.0' # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.2 flutter_onboarding_slider: path: ../ dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^2.0.0 # 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: # 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 # To add assets to your application, add an assets section, like this: assets: - assets/ # - 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 ================================================ FILE: packages/flutter_onboarding_slider/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility in the flutter_test package. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/flutter_onboarding_slider/lib/background.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_onboarding_slider/background_image.dart'; class Background extends StatelessWidget { final Widget child; final int totalPage; final List background; final double speed; final double imageVerticalOffset; final double imageHorizontalOffset; final bool centerBackground; Background({ required this.imageVerticalOffset, required this.child, required this.centerBackground, required this.totalPage, required this.background, required this.speed, required this.imageHorizontalOffset, }); @override Widget build(BuildContext context) { assert(background.length == totalPage); return Stack( children: [ for (int i = 0; i < totalPage; i++) BackgroundImage( centerBackground: centerBackground, imageHorizontalOffset: imageHorizontalOffset, imageVerticalOffset: imageVerticalOffset, id: totalPage - i, speed: speed, background: background[totalPage - i - 1]), child, ], ); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/background_body.dart ================================================ import 'package:flutter/material.dart'; class BackgroundBody extends StatelessWidget { final PageController controller; final Function function; final int totalPage; final List bodies; BackgroundBody({ required this.controller, required this.function, required this.totalPage, required this.bodies, }); @override Widget build(BuildContext context) { assert(bodies.length == totalPage); return PageView( physics: ClampingScrollPhysics(), controller: controller, onPageChanged: (value) { function(value); }, children: bodies, ); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/background_controller.dart ================================================ import 'package:flutter/material.dart'; class BackgroundController extends StatelessWidget { final int currentPage; final int totalPage; final Color? controllerColor; final bool indicatorAbove; final double indicatorPosition; final bool hasFloatingButton; BackgroundController({ required this.currentPage, required this.totalPage, required this.controllerColor, required this.indicatorAbove, required this.hasFloatingButton, required this.indicatorPosition, }); @override Widget build(BuildContext context) { return indicatorAbove ? Container( padding: EdgeInsets.only(bottom: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: _buildPageIndicator(context), ), ) : (currentPage == totalPage - 1) && hasFloatingButton ? SizedBox.shrink() : Container( padding: EdgeInsets.only(bottom: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: _buildPageIndicator(context), ), ); } /// List of the slides Indicators. List _buildPageIndicator(BuildContext context) { List list = []; for (int i = 0; i < totalPage; i++) { list.add(i == currentPage ? _indicator(true, context) : _indicator(false, context)); } return list; } /// Slide Controller / Indicator. Widget _indicator(bool isActive, BuildContext context) { return AnimatedContainer( duration: Duration(milliseconds: 150), margin: EdgeInsets.only( left: 8.0, right: 8.0, bottom: indicatorAbove ? indicatorPosition : 28), height: 8.0, width: isActive ? 28.0 : 8.0, decoration: BoxDecoration( color: isActive ? controllerColor ?? Colors.white : (controllerColor ?? Colors.white).withOpacity(0.5), borderRadius: BorderRadius.all(Radius.circular(12)), ), ); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/background_final_button.dart ================================================ import 'package:flutter/material.dart'; class FinishButtonStyle { final ShapeBorder? shape; final double? elevation; final double? focusElevation; final double? hoverElevation; final double? highlightElevation; final double? disabledElevation; final Color? foregroundColor; final Color? backgroundColor; final Color? focusColor; final Color? hoverColor; final Color? splashColor; const FinishButtonStyle({ this.shape = const RoundedRectangleBorder( borderRadius: BorderRadius.all( Radius.circular(5.0), ), ), this.elevation = 0, this.focusElevation, this.hoverElevation, this.highlightElevation, this.disabledElevation, this.foregroundColor, this.backgroundColor, this.focusColor, this.hoverColor, this.splashColor, }); } class BackgroundFinalButton extends StatelessWidget { final int currentPage; final PageController pageController; final int totalPage; final bool addButton; final Function? onPageFinish; final TextStyle buttonTextStyle; final String? buttonText; final bool hasSkip; final Icon skipIcon; final FinishButtonStyle? finishButtonStyle; BackgroundFinalButton({ required this.currentPage, required this.pageController, required this.totalPage, this.onPageFinish, this.buttonText, required this.buttonTextStyle, required this.addButton, required this.hasSkip, required this.skipIcon, this.finishButtonStyle = const FinishButtonStyle(), }); @override Widget build(BuildContext context) { return addButton ? hasSkip ? AnimatedContainer( padding: currentPage == totalPage - 1 ? EdgeInsets.symmetric(horizontal: 30) : EdgeInsets.all(0), width: currentPage == totalPage - 1 ? MediaQuery.of(context).size.width - 30 : 60, duration: Duration(milliseconds: 100), child: currentPage == totalPage - 1 ? FloatingActionButton.extended( shape: finishButtonStyle?.shape, elevation: finishButtonStyle?.elevation, focusElevation: finishButtonStyle?.focusElevation, hoverElevation: finishButtonStyle?.hoverElevation, highlightElevation: finishButtonStyle?.highlightElevation, disabledElevation: finishButtonStyle?.disabledElevation, foregroundColor: finishButtonStyle?.foregroundColor, backgroundColor: finishButtonStyle?.backgroundColor, focusColor: finishButtonStyle?.focusColor, hoverColor: finishButtonStyle?.hoverColor, splashColor: finishButtonStyle?.splashColor, onPressed: () => onPageFinish?.call(), label: buttonText == null ? SizedBox.shrink() : Text( buttonText!, style: buttonTextStyle, ), ) : FloatingActionButton( shape: finishButtonStyle?.shape, elevation: finishButtonStyle?.elevation, focusElevation: finishButtonStyle?.focusElevation, hoverElevation: finishButtonStyle?.hoverElevation, highlightElevation: finishButtonStyle?.highlightElevation, disabledElevation: finishButtonStyle?.disabledElevation, foregroundColor: finishButtonStyle?.foregroundColor, backgroundColor: finishButtonStyle?.backgroundColor, focusColor: finishButtonStyle?.focusColor, hoverColor: finishButtonStyle?.hoverColor, splashColor: finishButtonStyle?.splashColor, onPressed: () => _goToNextPage(context), child: skipIcon, ), ) : Container( padding: EdgeInsets.symmetric(horizontal: 30), width: MediaQuery.of(context).size.width - 30, child: FloatingActionButton.extended( shape: finishButtonStyle?.shape, elevation: finishButtonStyle?.elevation, focusElevation: finishButtonStyle?.focusElevation, hoverElevation: finishButtonStyle?.hoverElevation, highlightElevation: finishButtonStyle?.highlightElevation, disabledElevation: finishButtonStyle?.disabledElevation, foregroundColor: finishButtonStyle?.foregroundColor, backgroundColor: finishButtonStyle?.backgroundColor, focusColor: finishButtonStyle?.focusColor, hoverColor: finishButtonStyle?.hoverColor, splashColor: finishButtonStyle?.splashColor, onPressed: () => onPageFinish?.call(), label: buttonText == null ? SizedBox.shrink() : Text( buttonText!, style: buttonTextStyle, ), )) : SizedBox.shrink(); } /// Switch to Next Slide using the Floating Action Button. void _goToNextPage(BuildContext context) { pageController.nextPage( duration: Duration(milliseconds: 500), curve: Curves.ease, ); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/background_image.dart ================================================ import 'package:flutter/material.dart'; import 'package:flutter_onboarding_slider/page_offset_provider.dart'; import 'package:provider/provider.dart'; class BackgroundImage extends StatelessWidget { final int id; final Widget background; final double imageVerticalOffset; final double speed; final double imageHorizontalOffset; final bool centerBackground; BackgroundImage({ required this.id, required this.speed, required this.background, required this.imageVerticalOffset, required this.centerBackground, required this.imageHorizontalOffset, }); @override Widget build(BuildContext context) { return Consumer( builder: (context, notifier, child) { return Stack(children: [ Positioned( top: imageVerticalOffset, left: MediaQuery.of(context).size.width * ((id - 1) * speed) - speed * notifier.offset + (centerBackground ? 0 : imageHorizontalOffset), child: centerBackground ? Container( width: MediaQuery.of(context).size.width, child: child!, ) : child!, ), ]); }, child: Container( child: background, ), ); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/flutter_onboarding_slider.dart ================================================ library flutter_onboarding_slider; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_onboarding_slider/background_controller.dart'; import 'package:flutter_onboarding_slider/background_final_button.dart'; import 'package:flutter_onboarding_slider/onboarding_navigation_bar.dart'; import 'package:flutter_onboarding_slider/page_offset_provider.dart'; import 'package:provider/provider.dart'; import 'background.dart'; import 'background_body.dart'; export 'background.dart'; export 'background_final_button.dart'; class OnBoardingSlider extends StatefulWidget { /// Number of total pages. final int totalPage; /// NavigationBars color. final Color headerBackgroundColor; /// List of Widgets to be shown in the backgrounds of the pages. For example a picture or some illustration. final List background; /// The speed of the animation for the [background]. final double speed; /// Background Color of whole screen apart from the NavigationBar. final Color? pageBackgroundColor; /// Background Gradient of whole screen apart from the NavigationBar. final Gradient? pageBackgroundGradient; /// Callback to be executed when clicked on the [finishButton]. final Function? onFinish; /// NavigationBar trailing widget when on last screen. final Widget? trailing; /// NavigationBar trailing widget when not on last screen. final Widget? skipTextButton; /// The main content ont the screen displayed above the [background]. final List pageBodies; /// Callback to be executed when clicked on the last pages bottom button. final Function? trailingFunction; /// Style of the bottom button on the last page. final FinishButtonStyle? finishButtonStyle; /// Text inside last pages bottom button. final String? finishButtonText; /// Text style for text inside last pages bottom button. final TextStyle finishButtonTextStyle; /// Color of the bottom page indicators. final Color? controllerColor; /// Toggle bottom button. final bool addButton; /// Center [background]. /// Do not pass [imageHorizontalOffset] when you turn this flag to true otherwise that will get ignored final bool centerBackground; /// Toggle bottom page controller visibilty. final bool addController; /// Defines the vertical offset of the [background]. final double imageVerticalOffset; /// Defines the horizontal offset of the [background]. /// Do not set [centerBackground] to true when you use this property otherwise this will get ignored final double imageHorizontalOffset; /// leading widget in the navigationBar. final Widget? leading; /// middle widget in the navigationBar. final Widget? middle; /// Whether has the floating action button to skip and the finish button final bool hasFloatingButton; /// Whether has the skip button in the bottom; final bool hasSkip; /// icon on the skip button final Icon skipIcon; /// is the indicator located on top of the screen final bool indicatorAbove; /// distance of indicator from bottom final double indicatorPosition; /// override the function for kip button in the navigator. final Function? skipFunctionOverride; OnBoardingSlider({ required this.totalPage, required this.headerBackgroundColor, required this.background, required this.speed, required this.pageBodies, this.onFinish, this.trailingFunction, this.trailing, this.skipTextButton, this.pageBackgroundColor, this.pageBackgroundGradient, this.finishButtonStyle, this.finishButtonText, this.controllerColor, this.addController = true, this.centerBackground = false, this.addButton = true, this.imageVerticalOffset = 0, this.imageHorizontalOffset = 0, this.leading, this.middle, this.hasFloatingButton = true, this.hasSkip = true, this.finishButtonTextStyle = const TextStyle( fontSize: 20, color: Colors.white, ), this.skipIcon = const Icon( Icons.arrow_forward, color: Colors.white, ), this.indicatorAbove = false, this.indicatorPosition = 90, this.skipFunctionOverride, }); @override _OnBoardingSliderState createState() => _OnBoardingSliderState(); } class _OnBoardingSliderState extends State { final PageController _pageController = PageController(initialPage: 0); int _currentPage = 0; @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (BuildContext context) => PageOffsetNotifier(_pageController), child: Scaffold( backgroundColor: widget.pageBackgroundColor ?? null, floatingActionButton: widget.hasFloatingButton ? BackgroundFinalButton( buttonTextStyle: widget.finishButtonTextStyle, skipIcon: widget.skipIcon, addButton: widget.addButton, currentPage: _currentPage, pageController: _pageController, totalPage: widget.totalPage, onPageFinish: widget.onFinish, finishButtonStyle: widget.finishButtonStyle, buttonText: widget.finishButtonText, hasSkip: widget.hasSkip, ) : SizedBox.shrink(), body: CupertinoPageScaffold( navigationBar: OnBoardingNavigationBar( skipFunctionOverride: widget.skipFunctionOverride, leading: widget.leading, middle: widget.middle, totalPage: widget.totalPage, currentPage: _currentPage, onSkip: _onSkip, headerBackgroundColor: widget.headerBackgroundColor, onFinish: widget.trailingFunction, finishButton: widget.trailing, skipTextButton: widget.skipTextButton, ), child: Container( height: MediaQuery.of(context).size.height, decoration: BoxDecoration( gradient: widget.pageBackgroundGradient ?? null, color: widget.pageBackgroundColor ?? null, ), child: SafeArea( child: Background( centerBackground: widget.centerBackground, imageHorizontalOffset: widget.imageHorizontalOffset, imageVerticalOffset: widget.imageVerticalOffset, background: widget.background, speed: widget.speed, totalPage: widget.totalPage, child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: BackgroundBody( controller: _pageController, function: slide, totalPage: widget.totalPage, bodies: widget.pageBodies, ), ), widget.addController ? BackgroundController( hasFloatingButton: widget.hasFloatingButton, indicatorPosition: widget.indicatorPosition, indicatorAbove: widget.indicatorAbove, currentPage: _currentPage, totalPage: widget.totalPage, controllerColor: widget.controllerColor, ) : SizedBox.shrink(), ]), ), ), ), ), ), ); } /// Slide to Next Page. void slide(int page) { setState(() { _currentPage = page; }); } /// Skip to last Slide. void _onSkip() { _pageController.jumpToPage(widget.totalPage - 1); setState(() { _currentPage = widget.totalPage - 1; }); } } ================================================ FILE: packages/flutter_onboarding_slider/lib/onboarding_navigation_bar.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class OnBoardingNavigationBar extends StatelessWidget implements ObstructingPreferredSizeWidget { final int currentPage; final Function onSkip; final int totalPage; final Function? onFinish; final Widget? finishButton; final Widget? skipTextButton; final Color headerBackgroundColor; final Widget? leading; final Widget? middle; final Function? skipFunctionOverride; OnBoardingNavigationBar({ required this.currentPage, required this.onSkip, required this.headerBackgroundColor, required this.totalPage, this.onFinish, this.finishButton, this.skipTextButton, this.leading, this.middle, this.skipFunctionOverride, }); @override Size get preferredSize => Size.fromHeight(40); @override bool shouldFullyObstruct(BuildContext context) { return true; } @override Widget build(BuildContext context) { if (hideNavigationBar) return SizedBox.shrink(); return CupertinoNavigationBar( automaticallyImplyLeading: false, leading: leading, middle: middle, trailing: currentPage == totalPage - 1 ? finishButton == null ? SizedBox.shrink() : Container( color: Colors.transparent, child: TextButton( onPressed: () => onFinish?.call(), child: finishButton!, ), ) : skipTextButton == null ? SizedBox.shrink() : Container( color: Colors.transparent, child: TextButton( onPressed: () { if (skipFunctionOverride == null) { onSkip(); } else { skipFunctionOverride!(); } }, child: skipTextButton!, ), ), border: Border( bottom: BorderSide(color: Colors.transparent), ), backgroundColor: headerBackgroundColor, ); } bool get hideNavigationBar { if (currentPage == totalPage - 1) { return finishButton == null; } return skipTextButton == null; } } ================================================ FILE: packages/flutter_onboarding_slider/lib/page_offset_provider.dart ================================================ import 'package:flutter/cupertino.dart'; class PageOffsetNotifier with ChangeNotifier { double _offset = 0; double _page = 0; PageOffsetNotifier(PageController pageController) { pageController.addListener(() { _offset = pageController.offset; _page = pageController.page ?? 0; notifyListeners(); }); } double get offset => _offset; double get page => _page; } ================================================ FILE: packages/flutter_onboarding_slider/pubspec.yaml ================================================ name: flutter_onboarding_slider description: A page slider with parallex design that allows (Text) widgets or body to slide at a different speed with background. version: 1.0.11 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/flutter_onboarding_slider environment: sdk: ">=2.12.0 <4.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter provider: ^6.0.0 dev_dependencies: flutter_test: sdk: flutter # The following section is specific to Flutter. flutter: ================================================ FILE: packages/flutter_onboarding_slider/test/page_slider_test.dart ================================================ ================================================ FILE: packages/flutter_timer_countdown/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/flutter_timer_countdown/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 02c026b03cd31dd3f867e5faeb7e104cce174c5f channel: stable project_type: package ================================================ FILE: packages/flutter_timer_countdown/CHANGELOG.md ================================================ ## [1.0.7] - 2023.11.06 * Removing flutter_lints dependency. ## [1.0.6] - 2023.10.16 * Get remaining time onTick. ## [1.0.5] - 2022.09.14 * Updating Readme file. ## [1.0.4] - 2022.09.11 * Updating dependencies & Readme file. ## [1.0.3] - 2021.12.09 * Bug fix: Fixing late initialization ## [1.0.2] - 2021.08.23 * Feature: Customizable space between number units and colons. * Bug fixes ## [1.0.1] - 2021.08.12 * Improvements ## [1.0.0] - 2021.08.11 * Initial version ================================================ FILE: packages/flutter_timer_countdown/LICENSE ================================================ MIT License Copyright (c) 2021 APPINIO GmbH 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. ================================================ FILE: packages/flutter_timer_countdown/README.md ================================================ ```flutter_timer_countdown``` is a Flutter package for a Timer. ✨ It is a simple customizable timer for counting down a given time with any Custom TextStyle. Supporting Android, iOS & WebApp. ## Why? We build this package because we wanted to: - have simple timer - customize timer textstyles - choose the timer description - be able to unable the timer description ## ❗NEW Features ❗ ### Customizable space between number units and colons With the parameter ```spacerWidth``` you can now define the size of the space between number units and colons. The default is set to ```10``` (double). ## Show Cases Show only the time units you want to... Show only days, hours, minutes, seconds... ## Installation Create a new project with the command ```yaml flutter create MyApp ``` Add ```yaml flutter_timer_countdown: ... ``` to your `pubspec.yaml` of your flutter project. **OR** run ```yaml flutter pub add flutter_timer_countdown ``` in your project's root directory. In your library add the following import: ```dart import 'package:flutter_timer_countdown/flutter_timer_countdown.dart'; ``` For help getting started with Flutter, view the online [documentation](https://flutter.io/). ## Usage You can place your `TimerCountdown` inside of a `Scaffold` or `CupertinoPageScaffold` like we did here. Optional parameters can be defined to enable different features. See the following example.. ```dart import 'package:flutter_timer_countdown/flutter_timer_countdown.dart'; import 'package:flutter/cupertino.dart'; class Example extends StatelessWidget { @override Widget build(BuildContext context) { return CupertinoPageScaffold( child: TimerCountdown( format: CountDownTimerFormat.daysHoursMinutesSeconds, endTime: DateTime.now().add( Duration( days: 5, hours: 14, minutes: 27, seconds: 34, ), ), onEnd: () { print("Timer finished"); }, ), ); } } ``` ## Constructor #### Basic | Parameter | Default | Description | Required | | ------------- |:-------------|:-----|:-----:| | endtime | - | Defines the time when the timer is over | true | format | DaysHoursMinutesSeconds | Format for the timer coundtown, choose between different ```CountDownTimerFormat```s | false | onEnd | - | Function to call when the timer is over | false | enableDescriptions | - | Toggle time units descriptions | false | timeTextStyle | - | ```TextStyle``` for the time numbers | false | colonsTextStyle | - | ```TextStyle``` for the colons betwenn the time numbers | false | descriptionTextStyle | - | ```TextStyle``` for the timer description | false | daysDescription | Days | Days unit description | false | hoursDescription | Hours | Hours unit description | false | minutesDescription | Minutes | Minutes unit description | false | secondsDescription | Seconds | Seconds unit description | false | spacerWidth | 10 | Defines the width between the colons and the units | false
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/flutter_timer_countdown/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/flutter_timer_countdown/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: 02c026b03cd31dd3f867e5faeb7e104cce174c5f channel: stable project_type: app ================================================ FILE: packages/flutter_timer_countdown/example/README.md ================================================ # example A new Flutter project. ## 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. ================================================ FILE: packages/flutter_timer_countdown/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties ================================================ FILE: packages/flutter_timer_countdown/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 30 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" minSdkVersion 16 targetSdkVersion 30 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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/flutter_timer_countdown/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip ================================================ FILE: packages/flutter_timer_countdown/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/flutter_timer_countdown/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/flutter_timer_countdown/example/ios/.gitignore ================================================ *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/flutter_timer_countdown/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 9.0 ================================================ FILE: packages/flutter_timer_countdown/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/flutter_timer_countdown/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Info.plist ================================================ 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 ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 = 1020; 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 = 9.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 = 9.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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 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 */; } ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/flutter_timer_countdown/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/flutter_timer_countdown/example/lib/main.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter_timer_countdown/flutter_timer_countdown.dart'; import 'package:example/timer_basic.dart'; import 'package:example/timer_frame.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return CupertinoApp( debugShowCheckedModeBanner: false, theme: CupertinoThemeData( brightness: Brightness.light, ), home: CupertinoPageScaffold( child: SafeArea( minimum: EdgeInsets.all(20), child: ListView( children: [ SizedBox( height: 20, ), TimerFrame( description: 'Customized Timer Countdown', timer: TimerBasic( format: CountDownTimerFormat.daysHoursMinutesSeconds, ), ), SizedBox( height: 20, ), TimerFrame( inverted: true, description: 'without seconds', timer: TimerBasic( format: CountDownTimerFormat.daysHoursMinutes, inverted: true, ), ), SizedBox( height: 20, ), TimerFrame( description: 'whitout minutes & seconds', timer: TimerBasic( format: CountDownTimerFormat.daysHours, ), ), SizedBox( height: 20, ), TimerFrame( inverted: true, description: 'only days', timer: TimerBasic( format: CountDownTimerFormat.daysOnly, inverted: true, ), ), SizedBox( height: 20, ), TimerFrame( description: 'only hours', timer: TimerBasic( format: CountDownTimerFormat.hoursOnly, ), ), SizedBox( height: 20, ), TimerFrame( inverted: true, description: 'only minutes', timer: TimerBasic( format: CountDownTimerFormat.minutesOnly, inverted: true, ), ), SizedBox( height: 20, ), TimerFrame( description: 'only seconds', timer: TimerBasic( format: CountDownTimerFormat.secondsOnly, ), ), ], ), ), ), ); } } ================================================ FILE: packages/flutter_timer_countdown/example/lib/timer_basic.dart ================================================ import 'dart:ui'; import 'package:flutter/cupertino.dart'; import 'package:example/timer_frame.dart'; import 'package:flutter_timer_countdown/flutter_timer_countdown.dart'; class TimerBasic extends StatelessWidget { final CountDownTimerFormat format; final bool inverted; TimerBasic({ required this.format, this.inverted = false, Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return TimerCountdown( format: format, endTime: DateTime.now().add( Duration( days: 15, hours: 20, minutes: 47, seconds: 45, ), ), onEnd: () { print("Timer finished"); }, timeTextStyle: TextStyle( color: (inverted) ? purple : CupertinoColors.white, fontWeight: FontWeight.w300, fontSize: 40, fontFeatures: [ FontFeature.tabularFigures(), ], ), colonsTextStyle: TextStyle( color: (inverted) ? purple : CupertinoColors.white, fontWeight: FontWeight.w300, fontSize: 40, fontFeatures: [ FontFeature.tabularFigures(), ], ), descriptionTextStyle: TextStyle( color: (inverted) ? purple : CupertinoColors.white, fontSize: 10, fontFeatures: [ FontFeature.tabularFigures(), ], ), spacerWidth: 0, daysDescription: "days", hoursDescription: "hours", minutesDescription: "minutes", secondsDescription: "seconds", ); } } ================================================ FILE: packages/flutter_timer_countdown/example/lib/timer_frame.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; const Color purple = Color.fromARGB(255, 63, 45, 149); class TimerFrame extends StatelessWidget { final String description; final Widget timer; final bool inverted; const TimerFrame({ required this.description, required this.timer, this.inverted = false, Key? key, }) : super(key: key); @override Widget build(BuildContext context) { return Container( width: MediaQuery.of(context).size.width, padding: EdgeInsets.symmetric( vertical: inverted ? 30 : 40, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(10), color: inverted ? CupertinoColors.white : purple, border: Border.all( width: 2, color: inverted ? purple : Colors.transparent, ), ), child: Column( children: [ Text( description, style: TextStyle( fontSize: 20, letterSpacing: 0, color: inverted ? purple : CupertinoColors.white, ), ), const SizedBox( height: 20, ), timer, ], ), ); } } ================================================ FILE: packages/flutter_timer_countdown/example/pubspec.yaml ================================================ name: example description: A new Flutter project. publish_to: 'none' version: 1.0.0+1 environment: sdk: ">=2.12.0 <3.0.0" dependencies: flutter_timer_countdown: path: ../ flutter: sdk: flutter cupertino_icons: ^1.0.2 dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true ================================================ FILE: packages/flutter_timer_countdown/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility that Flutter provides. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/flutter_timer_countdown/example/web/index.html ================================================ example ================================================ FILE: packages/flutter_timer_countdown/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/flutter_timer_countdown/lib/flutter_timer_countdown.dart ================================================ library flutter_timer_countdown; import 'dart:async'; import 'package:flutter/widgets.dart'; enum CountDownTimerFormat { daysHoursMinutesSeconds, daysHoursMinutes, daysHours, daysOnly, hoursMinutesSeconds, hoursMinutes, hoursOnly, minutesSeconds, minutesOnly, secondsOnly, } typedef OnTickCallBack = void Function(Duration remainingTime); class TimerCountdown extends StatefulWidget { /// Format for the timer coundtown, choose between different `CountDownTimerFormat`s final CountDownTimerFormat format; /// Defines the time when the timer is over. final DateTime endTime; /// Gives you remaining time after every tick. final OnTickCallBack? onTick; /// Function to call when the timer is over. final VoidCallback? onEnd; /// Toggle time units descriptions. final bool enableDescriptions; /// `TextStyle` for the time numbers. final TextStyle? timeTextStyle; /// `TextStyle` for the colons betwenn the time numbers. final TextStyle? colonsTextStyle; /// `TextStyle` for the description final TextStyle? descriptionTextStyle; /// Days unit description. final String daysDescription; /// Hours unit description. final String hoursDescription; /// Minutes unit description. final String minutesDescription; /// Seconds unit description. final String secondsDescription; /// Defines the width between the colons and the units. final double spacerWidth; TimerCountdown({ required this.endTime, this.format = CountDownTimerFormat.daysHoursMinutesSeconds, this.enableDescriptions = true, this.onEnd, this.timeTextStyle, this.onTick, this.colonsTextStyle, this.descriptionTextStyle, this.daysDescription = "Days", this.hoursDescription = "Hours", this.minutesDescription = "Minutes", this.secondsDescription = "Seconds", this.spacerWidth = 10, }); @override _TimerCountdownState createState() => _TimerCountdownState(); } class _TimerCountdownState extends State { Timer? timer; late String countdownDays; late String countdownHours; late String countdownMinutes; late String countdownSeconds; late Duration difference; @override void initState() { _startTimer(); super.initState(); } @override void dispose() { if (timer != null) { timer!.cancel(); } super.dispose(); } /// Calculate the time difference between now end the given [endTime] and initialize all UI timer values. /// /// Then create a periodic `Timer` which updates all fields every second depending on the time difference which is getting smaller. /// When this difference reached `Duration.zero` the `Timer` is stopped and the [onEnd] callback is invoked. void _startTimer() { if (widget.endTime.isBefore(DateTime.now())) { difference = Duration.zero; } else { difference = widget.endTime.difference(DateTime.now()); } countdownDays = _durationToStringDays(difference); countdownHours = _durationToStringHours(difference); countdownMinutes = _durationToStringMinutes(difference); countdownSeconds = _durationToStringSeconds(difference); if (difference == Duration.zero) { if (widget.onEnd != null) { widget.onEnd!(); } } else { timer = Timer.periodic(Duration(seconds: 1), (timer) { difference = widget.endTime.difference(DateTime.now()); widget.onTick?.call(difference); setState(() { countdownDays = _durationToStringDays(difference); countdownHours = _durationToStringHours(difference); countdownMinutes = _durationToStringMinutes(difference); countdownSeconds = _durationToStringSeconds(difference); }); if (difference <= Duration.zero) { timer.cancel(); if (widget.onEnd != null) { widget.onEnd!(); } } }); } } @override Widget build(BuildContext context) { return _countDownTimerFormat(); } /// Builds the UI colons between the time units. Widget _colon() { return Row( children: [ SizedBox( width: widget.spacerWidth, ), Column( mainAxisSize: MainAxisSize.min, mainAxisAlignment: MainAxisAlignment.center, children: [ Text( ":", style: widget.colonsTextStyle, ), if (widget.enableDescriptions) SizedBox( height: 5, ), if (widget.enableDescriptions) Text( "", style: widget.descriptionTextStyle, ), ], ), SizedBox( width: widget.spacerWidth, ), ], ); } /// Builds the timer days with its description. Widget _days(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( countdownDays, style: widget.timeTextStyle, ), if (widget.enableDescriptions) SizedBox( height: 5, ), if (widget.enableDescriptions) Text( widget.daysDescription, style: widget.descriptionTextStyle, ), ], ); } /// Builds the timer hours with its description. Widget _hours(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( countdownHours, style: widget.timeTextStyle, ), if (widget.enableDescriptions) SizedBox( height: 5, ), if (widget.enableDescriptions) Text( widget.hoursDescription, style: widget.descriptionTextStyle, ), ], ); } /// Builds the timer minutes with its description. Widget _minutes(BuildContext context) { return Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( countdownMinutes, style: widget.timeTextStyle, ), if (widget.enableDescriptions) SizedBox( height: 5, ), if (widget.enableDescriptions) Text( widget.minutesDescription, style: widget.descriptionTextStyle, ), ], ); } /// Builds the timer seconds with its description. Widget _seconds(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.min, children: [ Text( countdownSeconds, style: widget.timeTextStyle, ), if (widget.enableDescriptions) SizedBox( height: 5, ), if (widget.enableDescriptions) Text( widget.secondsDescription, style: widget.descriptionTextStyle, ), ], ); } /// When the selected [CountDownTimerFormat] is leaving out the last unit, this function puts the UI value of the unit before up by one. /// /// This is done to show the currently running time unit. String _twoDigits(int n, String unitType) { switch (unitType) { case "minutes": if (widget.format == CountDownTimerFormat.daysHoursMinutes || widget.format == CountDownTimerFormat.hoursMinutes || widget.format == CountDownTimerFormat.minutesOnly) { if (difference > Duration.zero) { n++; } } if (n >= 10) return "$n"; return "0$n"; case "hours": if (widget.format == CountDownTimerFormat.daysHours || widget.format == CountDownTimerFormat.hoursOnly) { if (difference > Duration.zero) { n++; } } if (n >= 10) return "$n"; return "0$n"; case "days": if (widget.format == CountDownTimerFormat.daysOnly) { if (difference > Duration.zero) { n++; } } if (n >= 10) return "$n"; return "0$n"; default: if (n >= 10) return "$n"; return "0$n"; } } /// Convert [Duration] in days to String for UI. String _durationToStringDays(Duration duration) { return _twoDigits(duration.inDays, "days").toString(); } /// Convert [Duration] in hours to String for UI. String _durationToStringHours(Duration duration) { if (widget.format == CountDownTimerFormat.hoursMinutesSeconds || widget.format == CountDownTimerFormat.hoursMinutes || widget.format == CountDownTimerFormat.hoursOnly) { return _twoDigits(duration.inHours, "hours"); } else return _twoDigits(duration.inHours.remainder(24), "hours").toString(); } /// Convert [Duration] in minutes to String for UI. String _durationToStringMinutes(Duration duration) { if (widget.format == CountDownTimerFormat.minutesSeconds || widget.format == CountDownTimerFormat.minutesOnly) { return _twoDigits(duration.inMinutes, "minutes"); } else return _twoDigits(duration.inMinutes.remainder(60), "minutes"); } /// Convert [Duration] in seconds to String for UI. String _durationToStringSeconds(Duration duration) { if (widget.format == CountDownTimerFormat.secondsOnly) { return _twoDigits(duration.inSeconds, "seconds"); } else return _twoDigits(duration.inSeconds.remainder(60), "seconds"); } /// Switches the UI to be displayed based on [CountDownTimerFormat]. Widget _countDownTimerFormat() { switch (widget.format) { case CountDownTimerFormat.daysHoursMinutesSeconds: return Row( mainAxisSize: MainAxisSize.min, children: [ _days(context), _colon(), _hours(context), _colon(), _minutes(context), _colon(), _seconds(context), ], ); case CountDownTimerFormat.daysHoursMinutes: return Row( mainAxisSize: MainAxisSize.min, children: [ _days(context), _colon(), _hours(context), _colon(), _minutes(context), ], ); case CountDownTimerFormat.daysHours: return Row( mainAxisSize: MainAxisSize.min, children: [ _days(context), _colon(), _hours(context), ], ); case CountDownTimerFormat.daysOnly: return Row( mainAxisSize: MainAxisSize.min, children: [ _days(context), ], ); case CountDownTimerFormat.hoursMinutesSeconds: return Row( mainAxisSize: MainAxisSize.min, children: [ _hours(context), _colon(), _minutes(context), _colon(), _seconds(context), ], ); case CountDownTimerFormat.hoursMinutes: return Row( mainAxisSize: MainAxisSize.min, children: [ _hours(context), _colon(), _minutes(context), ], ); case CountDownTimerFormat.hoursOnly: return Row( mainAxisSize: MainAxisSize.min, children: [ _hours(context), ], ); case CountDownTimerFormat.minutesSeconds: return Row( mainAxisSize: MainAxisSize.min, children: [ _minutes(context), _colon(), _seconds(context), ], ); case CountDownTimerFormat.minutesOnly: return Row( mainAxisSize: MainAxisSize.min, children: [ _minutes(context), ], ); case CountDownTimerFormat.secondsOnly: return Row( mainAxisSize: MainAxisSize.min, children: [ _seconds(context), ], ); default: return Row( mainAxisSize: MainAxisSize.min, children: [ _days(context), _colon(), _hours(context), _colon(), _minutes(context), _colon(), _seconds(context), ], ); } } } ================================================ FILE: packages/flutter_timer_countdown/pubspec.yaml ================================================ name: flutter_timer_countdown description: A simple timer for counting down a given time. Supports customizable appearance and different formats. version: 1.0.7 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/flutter_timer_countdown environment: sdk: ">=2.12.0 <4.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter: ================================================ FILE: packages/flutter_timer_countdown/test/flutter_timer_countdown_test.dart ================================================ void main() {} ================================================ FILE: packages/profile_sliver/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ build/ # Android related **/android/**/gradle-wrapper.jar **/android/.gradle **/android/captures/ **/android/gradlew **/android/gradlew.bat **/android/local.properties **/android/**/GeneratedPluginRegistrant.java # iOS/XCode related **/ios/**/*.mode1v3 **/ios/**/*.mode2v3 **/ios/**/*.moved-aside **/ios/**/*.pbxuser **/ios/**/*.perspectivev3 **/ios/**/*sync/ **/ios/**/.sconsign.dblite **/ios/**/.tags* **/ios/**/.vagrant/ **/ios/**/DerivedData/ **/ios/**/Icon? **/ios/**/Pods/ **/ios/**/.symlinks/ **/ios/**/profile **/ios/**/xcuserdata **/ios/.generated/ **/ios/Flutter/App.framework **/ios/Flutter/Flutter.framework **/ios/Flutter/Flutter.podspec **/ios/Flutter/Generated.xcconfig **/ios/Flutter/ephemeral **/ios/Flutter/app.flx **/ios/Flutter/app.zip **/ios/Flutter/flutter_assets/ **/ios/Flutter/flutter_export_environment.sh **/ios/ServiceDefinitions.json **/ios/Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !**/ios/**/default.mode1v3 !**/ios/**/default.mode2v3 !**/ios/**/default.pbxuser !**/ios/**/default.perspectivev3 ================================================ FILE: packages/profile_sliver/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: d79295af24c3ed621c33713ecda14ad196fd9c31 channel: stable project_type: package ================================================ FILE: packages/profile_sliver/CHANGELOG.md ================================================ ## 0.0.1 * The initial release of profile sliver. ================================================ FILE: packages/profile_sliver/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2021 Appinio 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. ================================================ FILE: packages/profile_sliver/README.md ================================================ # sliver_stretchy_header A sliver that contains a bottom-aligned box child and a stretchy box background. Improvement upon [flutter_stretchy_header](https://github.com/ShannonChenCHN/sliver_stretchy_header) that includes null safety. ================================================ FILE: packages/profile_sliver/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Web related lib/generated_plugin_registrant.dart # Symbolication related app.*.symbols # Obfuscation related app.*.map.json ================================================ FILE: packages/profile_sliver/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: f30b7f4db93ee747cd727df747941a28ead25ff5 channel: stable project_type: app ================================================ FILE: packages/profile_sliver/example/README.md ================================================ # example A new Flutter project. ## 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. ================================================ FILE: packages/profile_sliver/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties ================================================ FILE: packages/profile_sliver/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { compileSdkVersion 29 sourceSets { main.java.srcDirs += 'src/main/kotlin' } lintOptions { disable 'InvalidPackage' } defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.example.example" minSdkVersion 16 targetSdkVersion 29 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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/profile_sliver/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/profile_sliver/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/profile_sliver/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/profile_sliver/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/profile_sliver/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/profile_sliver/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/profile_sliver/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.3.50' repositories { google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.5.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } allprojects { repositories { google() jcenter() } } rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" } subprojects { project.evaluationDependsOn(':app') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/profile_sliver/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ #Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip ================================================ FILE: packages/profile_sliver/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/profile_sliver/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/profile_sliver/example/ios/.gitignore ================================================ *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/profile_sliver/example/ios/Flutter/AppFrameworkInfo.plist ================================================ 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 9.0 ================================================ FILE: packages/profile_sliver/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/profile_sliver/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/profile_sliver/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/profile_sliver/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/profile_sliver/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/profile_sliver/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/profile_sliver/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/profile_sliver/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/profile_sliver/example/ios/Runner/Info.plist ================================================ 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 ================================================ FILE: packages/profile_sliver/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 46; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 = 1020; 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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 = 9.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 = 9.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 = 9.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 */; } ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/profile_sliver/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/profile_sliver/example/lib/main.dart ================================================ import 'package:flutter/material.dart'; import 'package:profile_sliver/profile_sliver.dart'; void main() { runApp(MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, home: Scaffold( appBar: AppBar( title: Text( 'Profile Sliver Example', style: TextStyle( fontSize: 20, color: Colors.white, ), ), centerTitle: true, actions: [Icon(Icons.notifications)], ), body: CustomScrollView( slivers: [ ProfileSliver( headerHeight: 200, header: Container( height: 20, color: Color(0xFF053149), child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ SizedBox(height: 50), SizedBox(height: 20), Icon( Icons.arrow_downward, size: 40, color: Colors.white, ) ], ), ), body: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.only( topLeft: Radius.circular(15), topRight: Radius.circular(15), ), ), height: 60, child: Center(child: Text("Body")), ), ), SliverList( delegate: SliverChildBuilderDelegate((context, index) { return Container( height: 50, child: Center(child: Text("$index"))); }, childCount: 50)) ], ), )); } } ================================================ FILE: packages/profile_sliver/example/pubspec.yaml ================================================ name: example description: A new Flutter project. publish_to: 'none' version: 1.0.0+1 environment: sdk: ">=2.7.0 <3.0.0" dependencies: flutter: sdk: flutter profile_sliver: path: ../ dev_dependencies: flutter_test: sdk: flutter flutter: uses-material-design: true ================================================ FILE: packages/profile_sliver/lib/profile_sliver.dart ================================================ library profile_sliver; export 'src/profile_sliver.dart'; ================================================ FILE: packages/profile_sliver/lib/src/profile_sliver.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:profile_sliver/src/profile_sliver_element.dart'; import 'package:profile_sliver/src/profile_sliver_render_object.dart'; class ProfileSliver extends RenderObjectWidget { final Widget header; final Widget body; final double headerHeight; const ProfileSliver({ Key? key, required this.header, required this.body, required this.headerHeight, }) : super(key: key); @override ProfileSliverElement createElement() => ProfileSliverElement(this); /// create a render object instance of the profile sliver @override ProfileSliverRenderObject createRenderObject(BuildContext context) { return ProfileSliverRenderObject(headerHeight: headerHeight); } @override void updateRenderObject( BuildContext context, ProfileSliverRenderObject renderObject) { renderObject..headerHeight = headerHeight; } } ================================================ FILE: packages/profile_sliver/lib/src/profile_sliver_element.dart ================================================ import 'package:flutter/material.dart'; import 'package:profile_sliver/src/profile_sliver.dart'; import 'package:profile_sliver/src/profile_sliver_render_object.dart'; class ProfileSliverElement extends RenderObjectElement { Element? _header; Element? _body; ProfileSliverElement(ProfileSliver widget) : super(widget); @override ProfileSliver get widget => super.widget as ProfileSliver; @override void visitChildren(ElementVisitor visitor) { visitor(_body!); visitor(_header!); } /// remove the child @override void forgetChild(Element child) { if (child == _body) { _body = null; super.forgetChild(_body!); } if (child == _header) { _header = null; super.forgetChild(_header!); } } /// mount the child to the tree @override void mount(Element? parent, dynamic newSlot) { super.mount(parent, newSlot); _body = updateChild(_body, widget.body, 0); _header = updateChild(_header, widget.header, 1); } /// used when udpating a widget @override void update(ProfileSliver newWidget) { super.update(newWidget); assert(widget == newWidget); _body = updateChild(_body, widget.body, 0); _header = updateChild(_header, widget.header, 1); } /// insert a render object @override void insertRenderObjectChild(covariant RenderBox child, dynamic slot) { final ProfileSliverRenderObject renderObject = this.renderObject as ProfileSliverRenderObject; if (slot == 0) renderObject.body = child; if (slot == 1) renderObject.header = child; assert(renderObject == this.renderObject); } /// move a render object child @override void moveRenderObjectChild( covariant RenderObject child, dynamic oldSlot, dynamic newSlot) { assert(false); } /// remove render object child @override void removeRenderObjectChild(covariant RenderObject child, dynamic slot) { final ProfileSliverRenderObject renderObject = this.renderObject as ProfileSliverRenderObject; if (renderObject.body == child) renderObject.body = null; if (renderObject.header == child) renderObject.header = null; assert(renderObject == this.renderObject); } } ================================================ FILE: packages/profile_sliver/lib/src/profile_sliver_render_object.dart ================================================ import 'package:flutter/rendering.dart'; import 'dart:math' as math; class ProfileSliverRenderObject extends RenderSliver with RenderSliverHelpers { late double _headerHeight; RenderBox? _body; RenderBox? _header; ProfileSliverRenderObject({ RenderBox? body, RenderBox? header, required headerHeight, }) { _headerHeight = headerHeight; if (body != null) this.body = body; if (header != null) this.header = header; } /// return the height of the entire height of the header double get mainHeight => bodyExtent + headerHeight; /// return whether the header is being streched bool get isStretching => scrollOffset <= 0; /// get the scrolloffset that includes the overlapped area double get scrollOffset => constraints.scrollOffset + constraints.overlap; /// get the height of the header double get headerHeight => _headerHeight; set headerHeight(double value) { if (headerHeight == value) return; headerHeight = value; markNeedsLayout(); } /// get the height of the body double get bodyExtent { if (body == null) { return 0.0; } assert(body!.hasSize); assert(constraints.axis == Axis.vertical); return body!.size.height; } /// get the height of the background double get backgroundExtent { if (header == null) { return 0.0; } assert(header!.hasSize); assert(constraints.axis == Axis.vertical); return header!.size.height; } RenderBox? get body => _body; set body(RenderBox? value) { if (_body != null) dropChild(_body!); _body = value; if (_body != null) adoptChild(_body!); } RenderBox? get header => _header; set header(RenderBox? value) { if (_header != null) dropChild(_header!); _header = value; if (_header != null) adoptChild(_header!); } @override void attach(covariant PipelineOwner owner) { super.attach(owner); if (body != null) body!.attach(owner); if (header != null) header!.attach(owner); } @override void detach() { super.detach(); if (body != null) body!.detach(); if (header != null) header!.detach(); } @override void redepthChildren() { super.redepthChildren(); if (body != null) redepthChild(body!); if (header != null) redepthChild(header!); } @override void visitChildren(void Function(RenderObject child) visitor) { super.visitChildren(visitor); if (body != null) visitor(body!); if (header != null) visitor(header!); } @override List debugDescribeChildren() { List result = []; if (body != null) result.add(body!.toDiagnosticsNode(name: 'body')); if (body != null) result.add(header!.toDiagnosticsNode(name: 'background')); return result; } @override void performLayout() { if (body == null || header == null) { geometry = SliverGeometry.zero; return; } body!.layout(constraints.asBoxConstraints(), parentUsesSize: true); double stretchOffset = 0.0; if (constraints.overlap < 0) { stretchOffset = constraints.overlap.abs(); } final backgroundExtent = isStretching ? mainHeight + stretchOffset : mainHeight; header!.layout( constraints.asBoxConstraints( maxExtent: backgroundExtent, minExtent: backgroundExtent), parentUsesSize: true, ); if (isStretching) { final double effectiveRemainingPaintExtent = math.max(0, constraints.remainingPaintExtent - constraints.overlap); final double layoutExtent = (mainHeight - constraints.precedingScrollExtent) .clamp(0.0, effectiveRemainingPaintExtent); final double paintExtent = (backgroundExtent - constraints.precedingScrollExtent) .clamp(0.0, effectiveRemainingPaintExtent); geometry = SliverGeometry( scrollExtent: backgroundExtent, paintOrigin: math.min(constraints.overlap, 0.0), paintExtent: paintExtent, layoutExtent: layoutExtent, maxPaintExtent: paintExtent, cacheExtent: backgroundExtent, hitTestExtent: backgroundExtent, maxScrollObstructionExtent: 0.0, hasVisualOverflow: true, ); } else { final paintedBackgroundExtent = math.max(0.0, backgroundExtent - constraints.precedingScrollExtent); final double paintedBackgroundSize = calculatePaintOffset(constraints, from: 0.0, to: paintedBackgroundExtent); final double cacheExtent = calculateCacheOffset(constraints, from: 0.0, to: backgroundExtent); assert(paintedBackgroundSize.isFinite); assert(paintedBackgroundSize >= 0.0); geometry = SliverGeometry( scrollExtent: backgroundExtent, paintExtent: paintedBackgroundSize, cacheExtent: cacheExtent, layoutExtent: paintedBackgroundSize, maxPaintExtent: paintedBackgroundSize, hitTestExtent: backgroundExtent, hasVisualOverflow: backgroundExtent > constraints.remainingPaintExtent || scrollOffset > 0.0, ); } } /// change the position @override double childMainAxisPosition(covariant RenderObject child) { final double offset = isStretching ? 0 : -constraints.scrollOffset; final double originY = offset - constraints.precedingScrollExtent; if (child == this.header) { return originY; } if (child == this.body) { final double blankExtent = backgroundExtent - bodyExtent; return originY + blankExtent; } return 0.0; } /// hit text logic @override bool hitTest(SliverHitTestResult result, {required double mainAxisPosition, required double crossAxisPosition}) { assert(geometry!.hitTestExtent > constraints.precedingScrollExtent); if (mainAxisPosition >= -constraints.precedingScrollExtent && mainAxisPosition < geometry!.hitTestExtent - constraints.precedingScrollExtent && crossAxisPosition >= 0.0 && crossAxisPosition < constraints.crossAxisExtent) { if (hitTestChildren(result, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition) || hitTestSelf( mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition)) { result.add(SliverHitTestEntry( this, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition, )); return true; } } return false; } /// adapt hit test logic to children @override bool hitTestChildren(SliverHitTestResult result, {required double mainAxisPosition, required double crossAxisPosition}) { assert(geometry!.hitTestExtent > 0.0); if (body != null) { final bool isHit = hitTestBoxChild(BoxHitTestResult.wrap(result), body!, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition); if (isHit) return true; } if (header != null) { final bool isHitHere = hitTestBoxChild( BoxHitTestResult.wrap(result), header!, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition); if (isHitHere) return true; } return false; } /// get the child scroll offset @override double? childScrollOffset(covariant RenderObject child) { assert(child.parent == this); if (child == this.body) { return backgroundExtent - bodyExtent; } else { return super.childScrollOffset(child); } } @override void applyPaintTransform(RenderObject child, Matrix4 transform) { applyPaintTransformForBoxChild(child as RenderBox, transform); } /// paint @override void paint(PaintingContext context, Offset offset) { if (geometry!.visible) { assert(constraints.axisDirection == AxisDirection.down); if (header != null) context.paintChild( header!, offset + Offset(0.0, childMainAxisPosition(header!))); if (body != null) context.paintChild( body!, offset + Offset(0.0, childMainAxisPosition(body!))); } } /// debug fill properties @override void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties .add(DoubleProperty.lazy('minimum stretch extent', () => headerHeight)); properties.add(DoubleProperty.lazy( 'child position', () => childMainAxisPosition(body!))); } } ================================================ FILE: packages/profile_sliver/pubspec.yaml ================================================ name: profile_sliver description: A new Flutter package project. version: 0.0.1 homepage: environment: sdk: ">=2.12.0 <3.0.0" flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter # 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. 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.dev/assets-and-images/#from-packages # # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/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.dev/custom-fonts/#from-packages ================================================ FILE: packages/widget_zoom/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. /pubspec.lock **/doc/api/ .dart_tool/ .packages build/ ================================================ FILE: packages/widget_zoom/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled and should not be manually edited. version: revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 channel: stable project_type: package ================================================ FILE: packages/widget_zoom/CHANGELOG.md ================================================ ## [0.0.5] - 2024.12.16 - Added `closeIcon` option to `WidgetZoom`. ## [0.0.4] - 2024.03.07 - Added `closeFullScreenImageOnDispose` option to `WidgetZoom`. ## [0.0.3] - 2023.12.21 - Updated readme. ## [0.0.2] - 2023.10.16 - Updated readme. ## [0.0.1] - 2022.12.16 - Initial release. ================================================ FILE: packages/widget_zoom/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2022 APPINIO GmbH 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. ================================================ FILE: packages/widget_zoom/README.md ================================================ The `WidgetZoom` enables you to zoom on your images. Either zoom directly on the image with a pinch to zoom gesture or use a simple tap to open the image in fullscreen and zoom around there. You can either hit the close button or swipe down to dismiss the fullscreen again. Just as you know from other apps. ## Why? We build this package because we wanted to: - have a simple and easy way to use zoom on images for users - integrate a lightweight package - create an easy usage experience for developers ## Show Case ## Pinch to zoom ## Drag down to exit fullscreen ## Zoom flutter widgets ## Features - Directly use pinch to zoom gesture on the image - Open tapped image in fullscreen - Zoom and pan around in fullscreen view - Double tap to zoom in/out in fullscreen view - Swipe down to dismiss the fullscreen view - Coming soon: zoom on any widget you like ## Getting started Just wrap your image widget that should be zoomable with the `WidgetZoom` and pass an object for the `heroAnimationTag` parameter and you are good to go. (The Hero animation is there to provide you with a nice transition when entering and leaving the fullscreen by tapping your image) ## Usage It doesn't need more setup than this: ```dart WidgetZoom( heroAnimationTag: 'tag', zoomWidget: Image.network( 'https://i.picsum.photos/id/1076/1000/800.jpg?hmac=Dlz3UOB04NkIUuAcoyNPNP_uRbjWK9FSoHfy4i04yWI', ), ), ``` ## Constructor | Parameter | Default | Description | Required | | ---------------------------- | :------------------- | :--------------------------------------------------------------------------------- | :------: | | zoomWidget | - | The widget that should be zoomable | true | | heroAnimationTag | - | An object used for the Hero animation when navigating to and from fullscreen | true | | minScaleEmbeddedView | 1 | The smallest allowed scale when zooming the widget not in fullscreen | false | | maxScaleEmbeddedView | 4 | The highest allowed scale when zooming the widget not in fullscreen | false | | minScaleFullscreen | 1 | The smallest allowed scale when zooming the widget in fullscreen | false | | maxScaleFullscreen | 4 | The highest allowed scale when zooming the widget in fullscreen | false | | fullScreenDoubleTapZoomScale | maxScaleFullscreen | The zoom scale when double tapping the zoomable widget in fullscreen | false | | closeFullScreenImageOnDispose | false | Controls whether the full screen image will be closed once the widget is disposed. | false | | closeIcon | CupertinoIcons.xmark | Widget displayed at the top right corner of the full screen image that closes it. | false |
Made with ❤ by Flutter team at Appinio GmbH ================================================ FILE: packages/widget_zoom/analysis_options.yaml ================================================ include: package:flutter_lints/flutter.yaml # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/widget_zoom/example/.gitignore ================================================ # Miscellaneous *.class *.log *.pyc *.swp .DS_Store .atom/ .buildlog/ .history .svn/ migrate_working_dir/ # IntelliJ related *.iml *.ipr *.iws .idea/ # The .vscode folder contains launch configuration and tasks you configure in # VS Code which you may wish to be included in version control, so this line # is commented out by default. #.vscode/ # Flutter/Dart/Pub related **/doc/api/ **/ios/Flutter/.last_build_id .dart_tool/ .flutter-plugins .flutter-plugins-dependencies .packages .pub-cache/ .pub/ /build/ # Symbolication related app.*.symbols # Obfuscation related app.*.map.json # Android Studio will place build artifacts here /android/app/debug /android/app/profile /android/app/release ================================================ FILE: packages/widget_zoom/example/.metadata ================================================ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # # This file should be version controlled. version: revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 channel: stable project_type: app # Tracks metadata for the flutter migrate command migration: platforms: - platform: root create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 - platform: android create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 - platform: ios create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 - platform: linux create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 - platform: web create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 - platform: windows create_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 base_revision: b8f7f1f9869bb2d116aa6a70dbeac61000b52849 # User provided section # List of Local paths (relative to this file) that should be # ignored by the migrate tool. # # Files that are not part of the templates will be ignored by default. unmanaged_files: - 'lib/main.dart' - 'ios/Runner.xcodeproj/project.pbxproj' ================================================ FILE: packages/widget_zoom/example/README.md ================================================ # example A new Flutter project. ## 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://docs.flutter.dev/get-started/codelab) - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) For help getting started with Flutter development, view the [online documentation](https://docs.flutter.dev/), which offers tutorials, samples, guidance on mobile development, and a full API reference. ================================================ FILE: packages/widget_zoom/example/analysis_options.yaml ================================================ # This file configures the analyzer, which statically analyzes Dart code to # check for errors, warnings, and lints. # # The issues identified by the analyzer are surfaced in the UI of Dart-enabled # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be # invoked from the command line by running `flutter analyze`. # The following line activates a set of recommended lints for Flutter apps, # packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml linter: # The lint rules applied to this project can be customized in the # section below to disable rules from the `package:flutter_lints/flutter.yaml` # included above or to enable additional rules. A list of all available lints # and their documentation is published at # https://dart-lang.github.io/linter/lints/index.html. # # Instead of disabling a lint rule for the entire project in the # section below, it can also be suppressed for a single line of code # or a specific dart file by using the `// ignore: name_of_lint` and # `// ignore_for_file: name_of_lint` syntax on the line or in the file # producing the lint. rules: # avoid_print: false # Uncomment to disable the `avoid_print` rule # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options ================================================ FILE: packages/widget_zoom/example/android/.gitignore ================================================ gradle-wrapper.jar /.gradle /captures/ /gradlew /gradlew.bat /local.properties GeneratedPluginRegistrant.java # Remember to never publicly share your keystore. # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app key.properties **/*.keystore **/*.jks ================================================ FILE: packages/widget_zoom/example/android/app/build.gradle ================================================ def localProperties = new Properties() def localPropertiesFile = rootProject.file('local.properties') if (localPropertiesFile.exists()) { localPropertiesFile.withReader('UTF-8') { reader -> localProperties.load(reader) } } def flutterRoot = localProperties.getProperty('flutter.sdk') if (flutterRoot == null) { throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") } def flutterVersionCode = localProperties.getProperty('flutter.versionCode') if (flutterVersionCode == null) { flutterVersionCode = '1' } def flutterVersionName = localProperties.getProperty('flutter.versionName') if (flutterVersionName == null) { flutterVersionName = '1.0' } apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { 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-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 { implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" } ================================================ FILE: packages/widget_zoom/example/android/app/src/debug/AndroidManifest.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt ================================================ package com.example.example import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { } ================================================ FILE: packages/widget_zoom/example/android/app/src/main/res/drawable/launch_background.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/main/res/drawable-v21/launch_background.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/main/res/values/styles.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/main/res/values-night/styles.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/app/src/profile/AndroidManifest.xml ================================================ ================================================ FILE: packages/widget_zoom/example/android/build.gradle ================================================ buildscript { ext.kotlin_version = '1.6.10' repositories { google() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:7.1.2' 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') } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: packages/widget_zoom/example/android/gradle/wrapper/gradle-wrapper.properties ================================================ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip ================================================ FILE: packages/widget_zoom/example/android/gradle.properties ================================================ org.gradle.jvmargs=-Xmx1536M android.useAndroidX=true android.enableJetifier=true ================================================ FILE: packages/widget_zoom/example/android/settings.gradle ================================================ include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") def properties = new Properties() assert localPropertiesFile.exists() localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } def flutterSdkPath = properties.getProperty("flutter.sdk") assert flutterSdkPath != null, "flutter.sdk not set in local.properties" apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" ================================================ FILE: packages/widget_zoom/example/ios/.gitignore ================================================ **/dgph *.mode1v3 *.mode2v3 *.moved-aside *.pbxuser *.perspectivev3 **/*sync/ .sconsign.dblite .tags* **/.vagrant/ **/DerivedData/ Icon? **/Pods/ **/.symlinks/ profile xcuserdata **/.generated/ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ Flutter/flutter_export_environment.sh ServiceDefinitions.json Runner/GeneratedPluginRegistrant.* # Exceptions to above rules. !default.mode1v3 !default.mode2v3 !default.pbxuser !default.perspectivev3 ================================================ FILE: packages/widget_zoom/example/ios/Flutter/AppFrameworkInfo.plist ================================================ CFBundleDevelopmentRegion en CFBundleExecutable App CFBundleIdentifier io.flutter.flutter.app CFBundleInfoDictionaryVersion 6.0 CFBundleName App CFBundlePackageType FMWK CFBundleShortVersionString 1.0 CFBundleSignature ???? CFBundleVersion 1.0 MinimumOSVersion 11.0 ================================================ FILE: packages/widget_zoom/example/ios/Flutter/Debug.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/widget_zoom/example/ios/Flutter/Release.xcconfig ================================================ #include "Generated.xcconfig" ================================================ FILE: packages/widget_zoom/example/ios/Runner/AppDelegate.swift ================================================ 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) } } ================================================ FILE: packages/widget_zoom/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json ================================================ { "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" } } ================================================ FILE: packages/widget_zoom/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json ================================================ { "images" : [ { "idiom" : "universal", "filename" : "LaunchImage.png", "scale" : "1x" }, { "idiom" : "universal", "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { "idiom" : "universal", "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { "version" : 1, "author" : "xcode" } } ================================================ FILE: packages/widget_zoom/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md ================================================ # 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. ================================================ FILE: packages/widget_zoom/example/ios/Runner/Base.lproj/LaunchScreen.storyboard ================================================ ================================================ FILE: packages/widget_zoom/example/ios/Runner/Base.lproj/Main.storyboard ================================================ ================================================ FILE: packages/widget_zoom/example/ios/Runner/Info.plist ================================================ CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName Example 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 ================================================ FILE: packages/widget_zoom/example/ios/Runner/Runner-Bridging-Header.h ================================================ #import "GeneratedPluginRegistrant.h" ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcodeproj/project.pbxproj ================================================ // !$*UTF8*$! { archiveVersion = 1; classes = { }; objectVersion = 50; objects = { /* Begin PBXBuildFile section */ 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 */ 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 = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ 97C146EB1CF9000F007C117D /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ 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 */, ); 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 = ( 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, ); 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 */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); 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; 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"; }; /* 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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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_COMPILATION_MODE = wholemodule; SWIFT_OPTIMIZATION_LEVEL = "-O"; 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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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)"; DEVELOPMENT_TEAM = QY3ZXJ883Q; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); 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 */; } ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme ================================================ ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcworkspace/contents.xcworkspacedata ================================================ ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist ================================================ IDEDidComputeMac32BitWarning ================================================ FILE: packages/widget_zoom/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings ================================================ PreviewsEnabled ================================================ FILE: packages/widget_zoom/example/lib/main.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:widget_zoom/widget_zoom.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const CupertinoApp( debugShowCheckedModeBanner: false, home: MyHomePage(), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({ super.key, }); @override State createState() => _MyHomePageState(); } class _MyHomePageState extends State { @override Widget build(BuildContext context) { return CupertinoPageScaffold( navigationBar: const CupertinoNavigationBar( middle: Text('Appinio Zoom Widget'), ), child: Center( child: WidgetZoom( heroAnimationTag: 'tag', zoomWidget: Image.network( 'https://i.picsum.photos/id/161/1200/1200.jpg?hmac=Wah6VuM-bdIJPMP9gOppMBBFBr2FtYVRU7pCH_yONdM', width: 150, height: 150, ), ), ), ); } } ================================================ FILE: packages/widget_zoom/example/linux/.gitignore ================================================ flutter/ephemeral ================================================ FILE: packages/widget_zoom/example/linux/CMakeLists.txt ================================================ # Project-level configuration. cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "example") # The unique GTK application identifier for this application. See: # https://wiki.gnome.org/HowDoI/ChooseApplicationID set(APPLICATION_ID "com.example.example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(SET CMP0063 NEW) # Load bundled libraries from the lib/ directory relative to the binary. set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") # Root filesystem for cross-building. if(FLUTTER_TARGET_PLATFORM_SYSROOT) set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) endif() # Define build configuration options. if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Flutter build mode" FORCE) set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Profile" "Release") endif() # Compilation settings that should be applied to most targets. # # Be cautious about adding new options here, as plugins use this function by # default. In most cases, you should add new options to specific targets instead # of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_14) target_compile_options(${TARGET} PRIVATE -Wall -Werror) target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") endfunction() # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") # Define the application target. To change its name, change BINARY_NAME above, # not the value here, or `flutter run` will no longer work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} "main.cc" "my_application.cc" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add dependency libraries. Add any application-specific dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) # Only the install-generated bundle's copy of the executable will launch # correctly, since the resources must in the right relative locations. To avoid # people trying to run the unbundled copy, put it in a subdirectory instead of # the default top-level location. set_target_properties(${BINARY_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) # === Installation === # By default, "installing" just makes a relocatable bundle in the build # directory. set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) endif() # Start with a clean build bundle directory every time. install(CODE " file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") " COMPONENT Runtime) set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" COMPONENT Runtime) install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) install(FILES "${bundled_library}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endforeach(bundled_library) # Fully re-copy the assets directory on each build to avoid having stale files # from a previous install. set(FLUTTER_ASSET_DIR_NAME "flutter_assets") install(CODE " file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") " COMPONENT Runtime) install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) # Install the AOT library on non-Debug builds only. if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" COMPONENT Runtime) endif() ================================================ FILE: packages/widget_zoom/example/linux/flutter/CMakeLists.txt ================================================ # This file controls Flutter-level build steps. It should not be edited. cmake_minimum_required(VERSION 3.10) set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") # Configuration provided via flutter tool. include(${EPHEMERAL_DIR}/generated_config.cmake) # TODO: Move the rest of this into files in ephemeral. See # https://github.com/flutter/flutter/issues/57146. # Serves the same purpose as list(TRANSFORM ... PREPEND ...), # which isn't available in 3.10. function(list_prepend LIST_NAME PREFIX) set(NEW_LIST "") foreach(element ${${LIST_NAME}}) list(APPEND NEW_LIST "${PREFIX}${element}") endforeach(element) set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) endfunction() # === Flutter Library === # System-level dependencies. find_package(PkgConfig REQUIRED) pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") # Published to parent scope for install step. set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) list(APPEND FLUTTER_LIBRARY_HEADERS "fl_basic_message_channel.h" "fl_binary_codec.h" "fl_binary_messenger.h" "fl_dart_project.h" "fl_engine.h" "fl_json_message_codec.h" "fl_json_method_codec.h" "fl_message_codec.h" "fl_method_call.h" "fl_method_channel.h" "fl_method_codec.h" "fl_method_response.h" "fl_plugin_registrar.h" "fl_plugin_registry.h" "fl_standard_message_codec.h" "fl_standard_method_codec.h" "fl_string_codec.h" "fl_value.h" "fl_view.h" "flutter_linux.h" ) list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") add_library(flutter INTERFACE) target_include_directories(flutter INTERFACE "${EPHEMERAL_DIR}" ) target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") target_link_libraries(flutter INTERFACE PkgConfig::GTK PkgConfig::GLIB PkgConfig::GIO ) add_dependencies(flutter flutter_assemble) # === Flutter tool backend === # _phony_ is a non-existent file to force this command to run every time, # since currently there's no way to get a full input/output list from the # flutter tool. add_custom_command( OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/_phony_ COMMAND ${CMAKE_COMMAND} -E env ${FLUTTER_TOOL_ENVIRONMENT} "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} VERBATIM ) add_custom_target(flutter_assemble DEPENDS "${FLUTTER_LIBRARY}" ${FLUTTER_LIBRARY_HEADERS} ) ================================================ FILE: packages/widget_zoom/example/linux/flutter/generated_plugin_registrant.cc ================================================ // // Generated file. Do not edit. // // clang-format off #include "generated_plugin_registrant.h" void fl_register_plugins(FlPluginRegistry* registry) { } ================================================ FILE: packages/widget_zoom/example/linux/flutter/generated_plugin_registrant.h ================================================ // // Generated file. Do not edit. // // clang-format off #ifndef GENERATED_PLUGIN_REGISTRANT_ #define GENERATED_PLUGIN_REGISTRANT_ #include // Registers Flutter plugins. void fl_register_plugins(FlPluginRegistry* registry); #endif // GENERATED_PLUGIN_REGISTRANT_ ================================================ FILE: packages/widget_zoom/example/linux/flutter/generated_plugins.cmake ================================================ # # Generated file, do not edit. # list(APPEND FLUTTER_PLUGIN_LIST ) list(APPEND FLUTTER_FFI_PLUGIN_LIST ) set(PLUGIN_BUNDLED_LIBRARIES) foreach(plugin ${FLUTTER_PLUGIN_LIST}) add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) list(APPEND PLUGIN_BUNDLED_LIBRARIES $) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) endforeach(plugin) foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) endforeach(ffi_plugin) ================================================ FILE: packages/widget_zoom/example/linux/main.cc ================================================ #include "my_application.h" int main(int argc, char** argv) { g_autoptr(MyApplication) app = my_application_new(); return g_application_run(G_APPLICATION(app), argc, argv); } ================================================ FILE: packages/widget_zoom/example/linux/my_application.cc ================================================ #include "my_application.h" #include #ifdef GDK_WINDOWING_X11 #include #endif #include "flutter/generated_plugin_registrant.h" struct _MyApplication { GtkApplication parent_instance; char** dart_entrypoint_arguments; }; G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) // Implements GApplication::activate. static void my_application_activate(GApplication* application) { MyApplication* self = MY_APPLICATION(application); GtkWindow* window = GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); // Use a header bar when running in GNOME as this is the common style used // by applications and is the setup most users will be using (e.g. Ubuntu // desktop). // If running on X and not using GNOME then just use a traditional title bar // in case the window manager does more exotic layout, e.g. tiling. // If running on Wayland assume the header bar will work (may need changing // if future cases occur). gboolean use_header_bar = TRUE; #ifdef GDK_WINDOWING_X11 GdkScreen* screen = gtk_window_get_screen(window); if (GDK_IS_X11_SCREEN(screen)) { const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); if (g_strcmp0(wm_name, "GNOME Shell") != 0) { use_header_bar = FALSE; } } #endif if (use_header_bar) { GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); gtk_widget_show(GTK_WIDGET(header_bar)); gtk_header_bar_set_title(header_bar, "example"); gtk_header_bar_set_show_close_button(header_bar, TRUE); gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); } else { gtk_window_set_title(window, "example"); } gtk_window_set_default_size(window, 1280, 720); gtk_widget_show(GTK_WIDGET(window)); g_autoptr(FlDartProject) project = fl_dart_project_new(); fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); FlView* view = fl_view_new(project); gtk_widget_show(GTK_WIDGET(view)); gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); fl_register_plugins(FL_PLUGIN_REGISTRY(view)); gtk_widget_grab_focus(GTK_WIDGET(view)); } // Implements GApplication::local_command_line. static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { MyApplication* self = MY_APPLICATION(application); // Strip out the first argument as it is the binary name. self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); g_autoptr(GError) error = nullptr; if (!g_application_register(application, nullptr, &error)) { g_warning("Failed to register: %s", error->message); *exit_status = 1; return TRUE; } g_application_activate(application); *exit_status = 0; return TRUE; } // Implements GObject::dispose. static void my_application_dispose(GObject* object) { MyApplication* self = MY_APPLICATION(object); g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); G_OBJECT_CLASS(my_application_parent_class)->dispose(object); } static void my_application_class_init(MyApplicationClass* klass) { G_APPLICATION_CLASS(klass)->activate = my_application_activate; G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; G_OBJECT_CLASS(klass)->dispose = my_application_dispose; } static void my_application_init(MyApplication* self) {} MyApplication* my_application_new() { return MY_APPLICATION(g_object_new(my_application_get_type(), "application-id", APPLICATION_ID, "flags", G_APPLICATION_NON_UNIQUE, nullptr)); } ================================================ FILE: packages/widget_zoom/example/linux/my_application.h ================================================ #ifndef FLUTTER_MY_APPLICATION_H_ #define FLUTTER_MY_APPLICATION_H_ #include G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, GtkApplication) /** * my_application_new: * * Creates a new Flutter-based application. * * Returns: a new #MyApplication. */ MyApplication* my_application_new(); #endif // FLUTTER_MY_APPLICATION_H_ ================================================ FILE: packages/widget_zoom/example/pubspec.yaml ================================================ name: example description: A new Flutter project. publish_to: 'none' version: 1.0.0+1 environment: sdk: '>=2.18.4 <3.0.0' dependencies: flutter: sdk: flutter cupertino_icons: ^1.0.2 widget_zoom: path: ../ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 flutter: uses-material-design: true ================================================ FILE: packages/widget_zoom/example/test/widget_test.dart ================================================ // This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility in the flutter_test package. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:example/main.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); expect(find.text('1'), findsNothing); // Tap the '+' icon and trigger a frame. await tester.tap(find.byIcon(Icons.add)); await tester.pump(); // Verify that our counter has incremented. expect(find.text('0'), findsNothing); expect(find.text('1'), findsOneWidget); }); } ================================================ FILE: packages/widget_zoom/example/web/index.html ================================================ example ================================================ FILE: packages/widget_zoom/example/web/manifest.json ================================================ { "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" } ] } ================================================ FILE: packages/widget_zoom/example/windows/.gitignore ================================================ flutter/ephemeral/ # Visual Studio user-specific files. *.suo *.user *.userosscache *.sln.docstates # Visual Studio build-related files. x64/ x86/ # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ ================================================ FILE: packages/widget_zoom/example/windows/CMakeLists.txt ================================================ # Project-level configuration. cmake_minimum_required(VERSION 3.14) project(example LANGUAGES CXX) # The name of the executable created for the application. Change this to change # the on-disk name of your application. set(BINARY_NAME "example") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. cmake_policy(SET CMP0063 NEW) # Define build configuration option. 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() # Define settings for the Profile build mode. 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. # # Be cautious about adding new options here, as plugins use this function by # default. In most cases, you should add new options to specific targets instead # of modifying this function. function(APPLY_STANDARD_SETTINGS TARGET) target_compile_features(${TARGET} PUBLIC cxx_std_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() # Flutter library and tool build rules. set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build; see runner/CMakeLists.txt. 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) ================================================ FILE: packages/widget_zoom/example/windows/flutter/CMakeLists.txt ================================================ # This file controls Flutter-level build steps. It should not be edited. cmake_minimum_required(VERSION 3.14) 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" "flutter_texture_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} ) ================================================ FILE: packages/widget_zoom/example/windows/flutter/generated_plugin_registrant.cc ================================================ // // Generated file. Do not edit. // // clang-format off #include "generated_plugin_registrant.h" void RegisterPlugins(flutter::PluginRegistry* registry) { } ================================================ FILE: packages/widget_zoom/example/windows/flutter/generated_plugin_registrant.h ================================================ // // 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_ ================================================ FILE: packages/widget_zoom/example/windows/flutter/generated_plugins.cmake ================================================ # # Generated file, do not edit. # list(APPEND FLUTTER_PLUGIN_LIST ) 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) ================================================ FILE: packages/widget_zoom/example/windows/runner/CMakeLists.txt ================================================ cmake_minimum_required(VERSION 3.14) project(runner LANGUAGES CXX) # Define the application target. To change its name, change BINARY_NAME in the # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer # work. # # Any new source files that you add to the application should be added here. add_executable(${BINARY_NAME} WIN32 "flutter_window.cpp" "main.cpp" "utils.cpp" "win32_window.cpp" "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" "Runner.rc" "runner.exe.manifest" ) # Apply the standard set of build settings. This can be removed for applications # that need different build settings. apply_standard_settings(${BINARY_NAME}) # Add preprocessor definitions for the build version. target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") # Disable Windows macros that collide with C++ standard library functions. target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") # Add dependency libraries and include directories. Add any application-specific # dependencies here. target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") # Run the Flutter tool portions of the build. This must not be removed. add_dependencies(${BINARY_NAME} flutter_assemble) ================================================ FILE: packages/widget_zoom/example/windows/runner/Runner.rc ================================================ // 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 // #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD #else #define VERSION_AS_NUMBER 1,0,0,0 #endif #if defined(FLUTTER_VERSION) #define VERSION_AS_STRING FLUTTER_VERSION #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", "example" "\0" VALUE "FileVersion", VERSION_AS_STRING "\0" VALUE "InternalName", "example" "\0" VALUE "LegalCopyright", "Copyright (C) 2022 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 ================================================ FILE: packages/widget_zoom/example/windows/runner/flutter_window.cpp ================================================ #include "flutter_window.h" #include #include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow(const flutter::DartProject& project) : 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()); SetChildContent(flutter_controller_->view()->GetNativeWindow()); return true; } void FlutterWindow::OnDestroy() { if (flutter_controller_) { 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 opportunity 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); } ================================================ FILE: packages/widget_zoom/example/windows/runner/flutter_window.h ================================================ #ifndef RUNNER_FLUTTER_WINDOW_H_ #define RUNNER_FLUTTER_WINDOW_H_ #include #include #include #include "win32_window.h" // A window that does nothing but host a Flutter view. class FlutterWindow : public Win32Window { public: // Creates a new FlutterWindow hosting a Flutter view running |project|. explicit FlutterWindow(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 project to run. flutter::DartProject project_; // The Flutter instance hosted by this window. std::unique_ptr flutter_controller_; }; #endif // RUNNER_FLUTTER_WINDOW_H_ ================================================ FILE: packages/widget_zoom/example/windows/runner/main.cpp ================================================ #include #include #include #include "flutter_window.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); flutter::DartProject project(L"data"); std::vector command_line_arguments = GetCommandLineArguments(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); FlutterWindow window(project); Win32Window::Point origin(10, 10); Win32Window::Size size(1280, 720); if (!window.CreateAndShow(L"example", origin, size)) { return EXIT_FAILURE; } window.SetQuitOnClose(true); ::MSG msg; while (::GetMessage(&msg, nullptr, 0, 0)) { ::TranslateMessage(&msg); ::DispatchMessage(&msg); } ::CoUninitialize(); return EXIT_SUCCESS; } ================================================ FILE: packages/widget_zoom/example/windows/runner/resource.h ================================================ //{{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 ================================================ FILE: packages/widget_zoom/example/windows/runner/runner.exe.manifest ================================================ PerMonitorV2 ================================================ FILE: packages/widget_zoom/example/windows/runner/utils.cpp ================================================ #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(); } } std::vector GetCommandLineArguments() { // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. int argc; wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); if (argv == nullptr) { return std::vector(); } std::vector command_line_arguments; // Skip the first argument as it's the binary name. for (int i = 1; i < argc; i++) { command_line_arguments.push_back(Utf8FromUtf16(argv[i])); } ::LocalFree(argv); return command_line_arguments; } std::string Utf8FromUtf16(const wchar_t* utf16_string) { if (utf16_string == nullptr) { return std::string(); } int target_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, nullptr, 0, nullptr, nullptr); std::string utf8_string; if (target_length == 0 || target_length > utf8_string.max_size()) { return utf8_string; } utf8_string.resize(target_length); int converted_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, -1, utf8_string.data(), target_length, nullptr, nullptr); if (converted_length == 0) { return std::string(); } return utf8_string; } ================================================ FILE: packages/widget_zoom/example/windows/runner/utils.h ================================================ #ifndef RUNNER_UTILS_H_ #define RUNNER_UTILS_H_ #include #include // Creates a console for the process, and redirects stdout and stderr to // it for both the runner and the Flutter library. void CreateAndAttachConsole(); // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string // encoded in UTF-8. Returns an empty std::string on failure. std::string Utf8FromUtf16(const wchar_t* utf16_string); // Gets the command line arguments passed in as a std::vector, // encoded in UTF-8. Returns an empty std::vector on failure. std::vector GetCommandLineArguments(); #endif // RUNNER_UTILS_H_ ================================================ FILE: packages/widget_zoom/example/windows/runner/win32_window.cpp ================================================ #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. } ================================================ FILE: packages/widget_zoom/example/windows/runner/win32_window.h ================================================ #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_ ================================================ FILE: packages/widget_zoom/lib/src/widget_zoom.dart ================================================ import 'package:flutter/material.dart'; import 'package:widget_zoom/src/widget_zoom_full_screen.dart'; class WidgetZoom extends StatefulWidget { /// The widget that should be zoomed. final Widget zoomWidget; /// The minimal scale that is allowed for this widget to be zoomed to. final double minScaleEmbeddedView; /// The maximal scale that is allowed for this widget to be zoomed to. final double maxScaleEmbeddedView; /// min scale for the widget in fullscreen final double minScaleFullscreen; /// max scale for the widget in fullscreen final double maxScaleFullscreen; /// if not specified the [maxScaleFullscreen] is used final double? fullScreenDoubleTapZoomScale; /// provide custom hero animation tag and make sure every [WidgetZoom] in your subtree uses a different tag. otherwise the animation doesnt work final Object heroAnimationTag; /// Controls whether the full screen image will be closed once the widget is disposed. final bool closeFullScreenImageOnDispose; /// Widget displayed at the top right corner of the full screen image. Closes the overlay when tapped. /// If not specified, [CupertinoIcons.xmark] will be displayed in white color. final Widget? closeIcon; const WidgetZoom({ Key? key, this.minScaleEmbeddedView = 1, this.maxScaleEmbeddedView = 4, this.minScaleFullscreen = 1, this.maxScaleFullscreen = 4, this.fullScreenDoubleTapZoomScale, this.closeFullScreenImageOnDispose = false, required this.heroAnimationTag, required this.zoomWidget, this.closeIcon, }) : super(key: key); @override State createState() => _WidgetZoomState(); } class _WidgetZoomState extends State with SingleTickerProviderStateMixin { final TransformationController _transformationController = TransformationController(); late AnimationController _animationController; late double _scale = widget.minScaleEmbeddedView; Animation? _animation; OverlayEntry? _entry; Duration _opcaityBackgroundDuration = Duration.zero; bool _isFullScreenImageOpened = false; late NavigatorState _rootNavigator; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 300), ) ..addListener(() => _transformationController.value = _animation!.value) ..addStatusListener((status) { if (status == AnimationStatus.completed) { _removeOverlay(); } }); } @override void didChangeDependencies() { super.didChangeDependencies(); _rootNavigator = Navigator.of(context, rootNavigator: true); } @override void dispose() { _transformationController.dispose(); _animationController.dispose(); _removeOverlay(); _closeFullScreenImage(); super.dispose(); } @override Widget build(BuildContext context) { return GestureDetector( onTap: () => _openImageFullscreen(), child: _buildImage(), ); } Widget _buildImage() { return Builder( builder: (context) { return InteractiveViewer( transformationController: _transformationController, panEnabled: false, clipBehavior: Clip.none, minScale: widget.minScaleEmbeddedView, maxScale: widget.maxScaleEmbeddedView, onInteractionStart: _showOverlay, onInteractionUpdate: _onInteractionUpdate, onInteractionEnd: (details) => _resetAnimation(), child: Hero( tag: widget.heroAnimationTag, child: widget.zoomWidget, ), ); }, ); } void _onInteractionUpdate(ScaleUpdateDetails details) { if (_entry != null) { _scale = details.scale; _entry?.markNeedsBuild(); } } void _showOverlay(ScaleStartDetails details) { if (details.pointerCount > 1) { _removeOverlay(); final RenderBox imageBox = context.findRenderObject() as RenderBox; final Offset imageOffset = imageBox.localToGlobal(Offset.zero); _entry = OverlayEntry( builder: (context) => Stack( children: [ Positioned.fill( child: AnimatedOpacity( duration: _opcaityBackgroundDuration, opacity: ((_scale - 1) / (widget.maxScaleEmbeddedView - 1)) .clamp(0, 1) .toDouble(), child: Container( color: Colors.black, ), ), ), Positioned( left: imageOffset.dx, top: imageOffset.dy, width: imageBox.size.width, height: imageBox.size.height, child: _buildImage(), ), ], ), ); final OverlayState overlay = Overlay.of(context); overlay.insert(_entry!); } } void _removeOverlay() { _opcaityBackgroundDuration = Duration.zero; _entry?.remove(); _entry = null; } void _resetAnimation() { _opcaityBackgroundDuration = _animationController.duration ?? const Duration(milliseconds: 300); _animation = Matrix4Tween( begin: _transformationController.value, end: Matrix4.identity(), ).animate( CurvedAnimation( parent: _animationController, curve: Curves.easeInOut, ), ); _animationController.forward(from: 0); } Future _openImageFullscreen() async { _isFullScreenImageOpened = true; await _rootNavigator.push( PageRouteBuilder( opaque: false, pageBuilder: (context, animation1, animation2) => FadeTransition( opacity: animation1, child: WidgetZoomFullscreen( zoomWidget: widget.zoomWidget is Image ? Image( image: (widget.zoomWidget as Image).image, fit: BoxFit.contain, ) : widget.zoomWidget, minScale: widget.minScaleFullscreen, maxScale: widget.maxScaleFullscreen, heroAnimationTag: widget.heroAnimationTag, fullScreenDoubleTapZoomScale: widget.fullScreenDoubleTapZoomScale, closeIcon: widget.closeIcon, ), ), transitionDuration: const Duration(milliseconds: 300), reverseTransitionDuration: const Duration(milliseconds: 300), ), ); _isFullScreenImageOpened = false; } void _closeFullScreenImage() { if (_isFullScreenImageOpened && _rootNavigator.canPop()) { _rootNavigator.pop(); } } } ================================================ FILE: packages/widget_zoom/lib/src/widget_zoom_full_screen.dart ================================================ import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; class WidgetZoomFullscreen extends StatefulWidget { final Widget zoomWidget; final double minScale; final double maxScale; final Object heroAnimationTag; final double? fullScreenDoubleTapZoomScale; final Widget? closeIcon; const WidgetZoomFullscreen({ Key? key, required this.zoomWidget, required this.minScale, required this.maxScale, required this.heroAnimationTag, this.fullScreenDoubleTapZoomScale, this.closeIcon, }) : super(key: key); @override State createState() => _ImageZoomFullscreenState(); } class _ImageZoomFullscreenState extends State with SingleTickerProviderStateMixin { final TransformationController _transformationController = TransformationController(); late AnimationController _animationController; late double closingTreshold = MediaQuery.of(context).size.height / 5; //the higher you set the last value the earlier the full screen gets closed Animation? _animation; double _opacity = 1; double _imagePosition = 0; Duration _animationDuration = Duration.zero; Duration _opacityDuration = Duration.zero; late double _currentScale = widget.minScale; TapDownDetails? _doubleTapDownDetails; @override void initState() { super.initState(); _animationController = AnimationController( vsync: this, duration: const Duration(milliseconds: 200), )..addListener(() => _transformationController.value = _animation!.value); } @override void dispose() { _transformationController.dispose(); _animationController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final closeIcon = widget.closeIcon ?? const Icon( CupertinoIcons.xmark, color: Colors.white, size: 30, ); return Stack( children: [ Positioned.fill( child: AnimatedOpacity( duration: _opacityDuration, opacity: _opacity, child: Container( color: Colors.black, ), ), ), AnimatedPositioned( duration: _animationDuration, top: _imagePosition, bottom: -_imagePosition, child: SizedBox( width: MediaQuery.of(context).size.width, height: 200, child: InteractiveViewer( constrained: true, transformationController: _transformationController, minScale: widget.minScale, maxScale: widget.maxScale, onInteractionStart: _onInteractionStart, onInteractionUpdate: _onInteractionUpdate, onInteractionEnd: _onInteractionEnd, child: GestureDetector( // need to have both methods, otherwise the zoom will be triggered before the second tap releases the screen onDoubleTapDown: (details) => _doubleTapDownDetails = details, onDoubleTap: _zoomInOut, child: Hero( tag: widget.heroAnimationTag, child: widget.zoomWidget, ), ), ), ), ), SafeArea( child: Align( alignment: Alignment.topRight, child: GestureDetector( behavior: HitTestBehavior.translucent, onTap: () => Navigator.of(context).pop(), child: AnimatedOpacity( duration: _opacityDuration, opacity: _opacity, child: Padding( padding: const EdgeInsets.symmetric( horizontal: 10, vertical: 5, ), child: closeIcon, ), ), ), ), ), ], ); } void _zoomInOut() { final Offset tapPosition = _doubleTapDownDetails!.localPosition; final double zoomScale = widget.fullScreenDoubleTapZoomScale ?? widget.maxScale; final double x = -tapPosition.dx * (zoomScale - 1); final double y = -tapPosition.dy * (zoomScale - 1); final Matrix4 zoomedMatrix = Matrix4.identity() ..translate(x, y) ..scale(zoomScale); final Matrix4 widgetMatrix = _transformationController.value.isIdentity() ? zoomedMatrix : Matrix4.identity(); _animation = Matrix4Tween( begin: _transformationController.value, end: widgetMatrix, ).animate( CurveTween(curve: Curves.easeOut).animate(_animationController), ); _animationController.forward(from: 0); _currentScale = _transformationController.value.isIdentity() ? zoomScale : widget.minScale; } void _onInteractionStart(ScaleStartDetails details) { _animationDuration = Duration.zero; _opacityDuration = Duration.zero; } void _onInteractionEnd(ScaleEndDetails details) async { _currentScale = _transformationController.value.getMaxScaleOnAxis(); setState(() { _animationDuration = const Duration(milliseconds: 300); }); if (_imagePosition > closingTreshold) { setState(() { _imagePosition = MediaQuery.of(context).size.height; // move image down }); Navigator.of(context).pop(); } else { setState(() { _imagePosition = 0; _opacity = 1; _opacityDuration = const Duration(milliseconds: 300); }); } } void _onInteractionUpdate(ScaleUpdateDetails details) async { // chose 1.05 because maybe the image was not fully zoomed back but it almost looks like that if (details.pointerCount == 1 && _currentScale <= 1.05) { setState(() { _imagePosition += details.focalPointDelta.dy; _opacity = (1 - (_imagePosition / closingTreshold)).clamp(0, 1).toDouble(); }); } } } ================================================ FILE: packages/widget_zoom/lib/widget_zoom.dart ================================================ library widget_zoom; export 'src/widget_zoom.dart'; ================================================ FILE: packages/widget_zoom/pubspec.yaml ================================================ name: widget_zoom description: A widget to zoom another widget either directly in an overlay or in fullscreen. version: 0.0.5 homepage: https://github.com/appinioGmbH/flutter_packages repository: https://github.com/appinioGmbH/flutter_packages/tree/main/packages/widget_zoom environment: sdk: '>=2.18.4 <4.0.0' flutter: ">=1.17.0" dependencies: flutter: sdk: flutter dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 flutter: ================================================ FILE: packages/widget_zoom/test/widget_zoom_test.dart ================================================ void main() {}