├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── a-regression.md │ ├── b-bug-report.md │ ├── c-feature-request.md │ ├── d-enhancement-proposal.md │ └── e-question.md ├── PULL_REQUEST_TEMPLATE.md ├── dependabot.yaml ├── no-response.yml └── workflows │ ├── app_facing_package.yaml │ ├── platform_interface.yaml │ ├── platform_web.yaml │ └── web.yaml ├── .gitignore ├── README.md ├── cached_network_image ├── .gitignore ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.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-v21 │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── values-night │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values │ │ │ │ │ └── styles.xml │ │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ ├── build.gradle │ │ ├── gradle.properties │ │ ├── gradle │ │ │ └── wrapper │ │ │ │ └── gradle-wrapper.properties │ │ └── settings.gradle │ ├── ios │ │ ├── .gitignore │ │ ├── Flutter │ │ │ ├── AppFrameworkInfo.plist │ │ │ ├── Debug.xcconfig │ │ │ └── Release.xcconfig │ │ ├── Podfile │ │ ├── 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 │ │ ├── Runner │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ │ ├── AppIcon.appiconset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ │ │ └── LaunchImage.imageset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── LaunchImage.png │ │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ │ └── README.md │ │ │ ├── Base.lproj │ │ │ │ ├── LaunchScreen.storyboard │ │ │ │ └── Main.storyboard │ │ │ ├── Info.plist │ │ │ └── Runner-Bridging-Header.h │ │ └── RunnerTests │ │ │ └── RunnerTests.swift │ ├── 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.xcodeproj │ │ │ ├── project.pbxproj │ │ │ ├── project.xcworkspace │ │ │ │ └── xcshareddata │ │ │ │ │ └── IDEWorkspaceChecks.plist │ │ │ └── xcshareddata │ │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ ├── Runner.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── Runner │ │ │ ├── AppDelegate.swift │ │ │ ├── Assets.xcassets │ │ │ │ └── AppIcon.appiconset │ │ │ │ │ ├── Contents.json │ │ │ │ │ ├── app_icon_1024.png │ │ │ │ │ ├── app_icon_128.png │ │ │ │ │ ├── app_icon_16.png │ │ │ │ │ ├── app_icon_256.png │ │ │ │ │ ├── app_icon_32.png │ │ │ │ │ ├── app_icon_512.png │ │ │ │ │ └── app_icon_64.png │ │ │ ├── Base.lproj │ │ │ │ └── MainMenu.xib │ │ │ ├── Configs │ │ │ │ ├── AppInfo.xcconfig │ │ │ │ ├── Debug.xcconfig │ │ │ │ ├── Release.xcconfig │ │ │ │ └── Warnings.xcconfig │ │ │ ├── DebugProfile.entitlements │ │ │ ├── Info.plist │ │ │ ├── MainFlutterWindow.swift │ │ │ └── Release.entitlements │ │ └── RunnerTests │ │ │ └── RunnerTests.swift │ ├── pubspec.yaml │ ├── pubspec_overrides.yaml │ ├── web │ │ ├── favicon.png │ │ ├── icons │ │ │ ├── Icon-192.png │ │ │ ├── Icon-512.png │ │ │ ├── Icon-maskable-192.png │ │ │ └── Icon-maskable-512.png │ │ ├── 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 │ │ ├── resources │ │ └── app_icon.ico │ │ ├── runner.exe.manifest │ │ ├── utils.cpp │ │ ├── utils.h │ │ ├── win32_window.cpp │ │ └── win32_window.h ├── lib │ ├── cached_network_image.dart │ └── src │ │ ├── cached_image_widget.dart │ │ └── image_provider │ │ ├── _image_loader.dart │ │ ├── cached_network_image_provider.dart │ │ └── multi_image_stream_completer.dart ├── pubspec.yaml └── test │ ├── fake_cache_manager.dart │ ├── image_cache_manager_test.dart │ ├── image_data.dart │ ├── image_provider_test.dart │ ├── image_stream_completer_test.dart │ ├── image_widget_test.dart │ └── rendering_tester.dart ├── cached_network_image_platform_interface ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── lib │ └── cached_network_image_platform_interface.dart ├── pubspec.yaml └── test │ └── cached_network_image_platform_interface_test.dart ├── cached_network_image_web ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── lib │ └── cached_network_image_web.dart ├── pubspec.yaml └── test │ └── cached_network_image_web_test.dart └── icon.png /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [Baseflow, renefloor] 2 | custom: https://baseflow.com/contact 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/a-regression.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 🔙 Regression 4 | about: Report unexpected behavior that worked previously 5 | --- 6 | 7 | ## 🔙 Regression 8 | 9 | 10 | 11 | ### Old (and correct) behavior 12 | 13 | ### Current behavior 14 | 15 | ### Reproduction steps 16 | 17 | ### Configuration 18 | 19 | **Version:** 1.x 20 | 21 | **Platform:** 22 | - [ ] :iphone: iOS 23 | - [ ] :robot: Android -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/b-bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 🐛 Bug Report 4 | about: Create a report to help us fix bugs and make improvements 5 | --- 6 | 7 | ## 🐛 Bug Report 8 | 9 | 10 | 11 | ### Expected behavior 12 | 13 | ### Reproduction steps 14 | 15 | ### Configuration 16 | 17 | **Version:** 1.x 18 | 19 | **Platform:** 20 | - [ ] :iphone: iOS 21 | - [ ] :robot: Android -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/c-feature-request.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 🚀 Feature Request 4 | about: Want to see something new included in the Framework? Submit it! 5 | --- 6 | 7 | ## 🚀 Feature Requests 8 | 9 | 10 | 11 | ### Contextualize the feature 12 | 13 | 14 | ### Describe the feature 15 | 16 | 17 | ### Platforms affected (mark all that apply) 18 | - [ ] :iphone: iOS 19 | - [ ] :robot: Android -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/d-enhancement-proposal.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 🏗 Enhancement Proposal 4 | about: Proposals for code cleanup, refactor and improvements in general 5 | --- 6 | 7 | ## 🏗 Enhancement Proposal 8 | 9 | 10 | 11 | ### Pitch 12 | 13 | 14 | 15 | ### Platforms affected (mark all that apply) 16 | - [ ] :iphone: iOS 17 | - [ ] :robot: Android -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/e-question.md: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: 💬 Questions and Help 4 | about: If you have questions, please use this for support 5 | --- 6 | 7 | ## 💬 Questions and Help 8 | 9 | For questions or help we recommend checking: 10 | 11 | - The [Flutter tag in Stack Overflow](https://stackoverflow.com/questions/tagged/flutter) -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### :sparkles: What kind of change does this PR introduce? (Bug fix, feature, docs update...) 2 | 3 | 4 | ### :arrow_heading_down: What is the current behavior? 5 | 6 | 7 | ### :new: What is the new behavior (if this is a feature change)? 8 | 9 | 10 | ### :boom: Does this PR introduce a breaking change? 11 | 12 | 13 | ### :bug: Recommendations for testing 14 | 15 | 16 | ### :memo: Links to relevant issues/docs 17 | 18 | 19 | ### :thinking: Checklist before submitting 20 | 21 | - [ ] All projects build 22 | - [ ] Follows style guide lines ([code style guide](https://github.com/Baseflow/flutter_cached_network_image/blob/develop/CONTRIBUTING.md)) 23 | - [ ] Relevant documentation was updated 24 | - [ ] Rebased onto current develop -------------------------------------------------------------------------------- /.github/dependabot.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | enable-beta-ecosystems: true 3 | updates: 4 | - package-ecosystem: "github-actions" 5 | directory: "/" 6 | schedule: 7 | interval: "daily" 8 | - package-ecosystem: "pub" 9 | directory: "/cached_network_image/" 10 | schedule: 11 | interval: "daily" 12 | - package-ecosystem: "pub" 13 | directory: "/cached_network_image_platform_interface/" 14 | schedule: 15 | interval: "daily" 16 | - package-ecosystem: "pub" 17 | directory: "/cached_network_image_web/" 18 | schedule: 19 | interval: "daily" -------------------------------------------------------------------------------- /.github/no-response.yml: -------------------------------------------------------------------------------- 1 | # Configuration for probot-no-response - https://github.com/probot/no-response 2 | 3 | # Number of days of inactivity before an Issue is closed for lack of response 4 | daysUntilClose: 14 5 | 6 | # Label requiring a response 7 | responseRequiredLabel: "status: needs more info" 8 | 9 | # Comment to post when closing an Issue for lack of response. Set to `false` to disable 10 | closeComment: > 11 | This issue has been automatically closed because there has been no response 12 | to our request for more information from the original author. With only the 13 | information that is currently in the issue, we don't have enough information 14 | to take action. Please reach out if you have or find the answers we need so 15 | that we can investigate further. -------------------------------------------------------------------------------- /.github/workflows/platform_interface.yaml: -------------------------------------------------------------------------------- 1 | name: platform_interface 2 | 3 | # Controls when the action will run. Triggers the workflow on push or pull request 4 | # events but only for the develop branch 5 | on: 6 | workflow_dispatch: 7 | 8 | push: 9 | tags: 10 | - "interface-v[0-9]+.[0-9]+.[0-9]+*" 11 | branches: [develop, main] 12 | paths: 13 | - "cached_network_image_platform_interface/**" 14 | - ".github/workflows/platform_interface.yaml" 15 | pull_request: 16 | branches: [develop] 17 | paths: 18 | - "cached_network_image_platform_interface/**" 19 | - ".github/workflows/platform_interface.yaml" 20 | 21 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 22 | jobs: 23 | format: 24 | name: Format 25 | 26 | # The type of runner that the job will run on 27 | runs-on: ubuntu-latest 28 | 29 | env: 30 | source-directory: ./cached_network_image_platform_interface 31 | 32 | # Steps represent a sequence of tasks that will be executed as part of the job 33 | steps: 34 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 35 | - uses: actions/checkout@v4 36 | 37 | # Make sure the stable version of Flutter is available 38 | - name: Set up Flutter 39 | uses: subosito/flutter-action@v2 40 | with: 41 | channel: "stable" 42 | architecture: x64 43 | cache: true 44 | 45 | # Download all Flutter packages 46 | - name: Download dependencies 47 | run: flutter pub get 48 | working-directory: ${{env.source-directory}} 49 | 50 | # Run Flutter Format to ensure formatting is valid 51 | - name: Run Flutter Format 52 | run: dart format --set-exit-if-changed . 53 | working-directory: ${{env.source-directory}} 54 | 55 | analyze: 56 | name: Analyze 57 | 58 | # The type of runner that the job will run on 59 | runs-on: ubuntu-latest 60 | 61 | env: 62 | source-directory: ./cached_network_image_platform_interface 63 | 64 | # Steps represent a sequence of tasks that will be executed as part of the job 65 | steps: 66 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 67 | - uses: actions/checkout@v4 68 | 69 | # Make sure the stable version of Flutter is available 70 | - name: Set up Flutter 71 | uses: subosito/flutter-action@v2 72 | with: 73 | channel: "stable" 74 | architecture: x64 75 | cache: true 76 | 77 | # Download all Flutter packages 78 | - name: Download dependencies 79 | run: flutter pub get 80 | working-directory: ${{env.source-directory}} 81 | 82 | # Run Flutter Analyzer 83 | - name: Run Flutter Analyzer 84 | run: flutter analyze 85 | working-directory: ${{env.source-directory}} 86 | 87 | tests: 88 | name: Unit-tests 89 | # The type of runner that the job will run on 90 | runs-on: ubuntu-latest 91 | 92 | env: 93 | source-directory: ./cached_network_image_platform_interface 94 | 95 | # Steps represent a sequence of tasks that will be executed as part of the job 96 | steps: 97 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 98 | - uses: actions/checkout@v4 99 | 100 | # Make sure the stable version of Flutter is available 101 | - name: Set up Flutter 102 | uses: subosito/flutter-action@v2 103 | with: 104 | channel: "stable" 105 | architecture: x64 106 | cache: true 107 | 108 | # Download all Flutter packages 109 | - name: Download dependencies 110 | run: flutter pub get 111 | working-directory: ${{env.source-directory}} 112 | 113 | # Run all unit-tests with code coverage 114 | - name: Run unit tests 115 | run: flutter test --coverage 116 | working-directory: ${{env.source-directory}} 117 | 118 | # Upload code coverage information 119 | # - uses: codecov/codecov-action@v4 120 | # env: 121 | # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 122 | # with: 123 | # files: ${{env.source-directory}}/coverage/lcov.info 124 | # name: CachedNetworkImage (App Facing Package) 125 | # fail_ci_if_error: true 126 | 127 | publish: 128 | if: ${{ github.ref_type == 'tag' }} 129 | name: Publish package 130 | permissions: 131 | id-token: write 132 | needs: [format, analyze, tests] 133 | # The type of runner that the job will run on 134 | runs-on: ubuntu-latest 135 | 136 | env: 137 | source-directory: ./cached_network_image_platform_interface 138 | 139 | # Steps represent a sequence of tasks that will be executed as part of the job 140 | steps: 141 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 142 | - uses: actions/checkout@v4 143 | 144 | - name: Set up Dart 145 | uses: dart-lang/setup-dart@v1 146 | 147 | # Make sure the stable version of Flutter is available 148 | - name: Set up Flutter 149 | uses: subosito/flutter-action@v2 150 | with: 151 | channel: "stable" 152 | architecture: x64 153 | cache: true 154 | 155 | # Download all Flutter packages 156 | - name: Download dependencies 157 | run: flutter pub get 158 | working-directory: ${{env.source-directory}} 159 | 160 | # Publish the package 161 | - name: Publish package 162 | run: dart pub publish -v -f 163 | working-directory: ${{env.source-directory}} 164 | -------------------------------------------------------------------------------- /.github/workflows/platform_web.yaml: -------------------------------------------------------------------------------- 1 | name: platform_web 2 | 3 | # Controls when the action will run. Triggers the workflow on push or pull request 4 | # events but only for the develop branch 5 | on: 6 | workflow_dispatch: 7 | 8 | push: 9 | tags: 10 | - "web-v[0-9]+.[0-9]+.[0-9]+*" 11 | branches: [develop, main] 12 | paths: 13 | - "cached_network_image_web/**" 14 | - ".github/workflows/platform_web.yaml" 15 | pull_request: 16 | branches: [develop] 17 | paths: 18 | - "cached_network_image_web/**" 19 | - ".github/workflows/platform_web.yaml" 20 | 21 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 22 | jobs: 23 | format: 24 | name: Format 25 | 26 | # The type of runner that the job will run on 27 | runs-on: ubuntu-latest 28 | 29 | env: 30 | source-directory: ./cached_network_image_web 31 | 32 | # Steps represent a sequence of tasks that will be executed as part of the job 33 | steps: 34 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 35 | - uses: actions/checkout@v4 36 | 37 | # Make sure the stable version of Flutter is available 38 | - name: Set up Flutter 39 | uses: subosito/flutter-action@v2 40 | with: 41 | channel: "stable" 42 | architecture: x64 43 | cache: true 44 | 45 | # Download all Flutter packages 46 | - name: Download dependencies 47 | run: flutter pub get 48 | working-directory: ${{env.source-directory}} 49 | 50 | # Run Flutter Format to ensure formatting is valid 51 | - name: Run Flutter Format 52 | run: dart format --set-exit-if-changed . 53 | working-directory: ${{env.source-directory}} 54 | 55 | analyze: 56 | name: Analyze 57 | 58 | # The type of runner that the job will run on 59 | runs-on: ubuntu-latest 60 | 61 | env: 62 | source-directory: ./cached_network_image_web 63 | 64 | # Steps represent a sequence of tasks that will be executed as part of the job 65 | steps: 66 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 67 | - uses: actions/checkout@v4 68 | 69 | # Make sure the stable version of Flutter is available 70 | - name: Set up Flutter 71 | uses: subosito/flutter-action@v2 72 | with: 73 | channel: "stable" 74 | architecture: x64 75 | cache: true 76 | 77 | # Download all Flutter packages 78 | - name: Download dependencies 79 | run: flutter pub get 80 | working-directory: ${{env.source-directory}} 81 | 82 | # Run Flutter Analyzer 83 | - name: Run Flutter Analyzer 84 | run: flutter analyze 85 | working-directory: ${{env.source-directory}} 86 | 87 | # tests: 88 | # name: Unit-tests 89 | # # The type of runner that the job will run on 90 | # runs-on: ubuntu-latest 91 | 92 | # env: 93 | # source-directory: ./cached_network_image_web 94 | 95 | # # Steps represent a sequence of tasks that will be executed as part of the job 96 | # steps: 97 | # # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 98 | # - uses: actions/checkout@v4 99 | 100 | # # Make sure the stable version of Flutter is available 101 | # - name: Set up Flutter 102 | # uses: subosito/flutter-action@v2 103 | # with: 104 | # channel: "stable" 105 | # architecture: x64 106 | # cache: true 107 | 108 | # # Download all Flutter packages 109 | # - name: Download dependencies 110 | # run: flutter pub get 111 | # working-directory: ${{env.source-directory}} 112 | 113 | # # Run all unit-tests with code coverage 114 | # - name: Run unit tests 115 | # run: flutter test --coverage 116 | # working-directory: ${{env.source-directory}} 117 | 118 | # Upload code coverage information 119 | # - uses: codecov/codecov-action@v4 120 | # env: 121 | # CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} 122 | # with: 123 | # files: ${{env.source-directory}}/coverage/lcov.info 124 | # name: CachedNetworkImage (App Facing Package) 125 | # fail_ci_if_error: true 126 | 127 | publish: 128 | if: ${{ github.ref_type == 'tag' }} 129 | name: Publish package 130 | permissions: 131 | id-token: write 132 | needs: [format, analyze] 133 | # The type of runner that the job will run on 134 | runs-on: ubuntu-latest 135 | 136 | env: 137 | source-directory: ./cached_network_image_web 138 | 139 | # Steps represent a sequence of tasks that will be executed as part of the job 140 | steps: 141 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 142 | - uses: actions/checkout@v4 143 | 144 | - name: Set up Dart 145 | uses: dart-lang/setup-dart@v1 146 | 147 | # Make sure the stable version of Flutter is available 148 | - name: Set up Flutter 149 | uses: subosito/flutter-action@v2 150 | with: 151 | channel: "stable" 152 | architecture: x64 153 | cache: true 154 | 155 | # Download all Flutter packages 156 | - name: Download dependencies 157 | run: flutter pub get 158 | working-directory: ${{env.source-directory}} 159 | 160 | # Publish the package 161 | - name: Publish package 162 | run: dart pub publish -v -f 163 | working-directory: ${{env.source-directory}} 164 | -------------------------------------------------------------------------------- /.github/workflows/web.yaml: -------------------------------------------------------------------------------- 1 | name: web 2 | 3 | # Controls when the action will run. Triggers the workflow on push or pull request 4 | # events but only for the develop branch 5 | on: 6 | push: 7 | branches: [develop, main] 8 | paths: 9 | - "cached_network_image_web/**" 10 | - ".github/workflows/web.yaml" 11 | pull_request: 12 | branches: [develop] 13 | paths: 14 | - "cached_network_image_web/**" 15 | - ".github/workflows/web.yaml" 16 | 17 | # A workflow run is made up of one or more jobs that can run sequentially or in parallel 18 | jobs: 19 | format: 20 | name: Format 21 | 22 | # The type of runner that the job will run on 23 | runs-on: ubuntu-latest 24 | 25 | env: 26 | source-directory: ./cached_network_image_web 27 | 28 | # Steps represent a sequence of tasks that will be executed as part of the job 29 | steps: 30 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 31 | - uses: actions/checkout@v4 32 | 33 | # Make sure the stable version of Flutter is available 34 | - name: Set up Flutter 35 | uses: subosito/flutter-action@v2 36 | with: 37 | channel: "stable" 38 | architecture: x64 39 | cache: true 40 | 41 | # Download all Flutter packages 42 | - name: Download dependencies 43 | run: flutter pub get 44 | working-directory: ${{env.source-directory}} 45 | 46 | # Run Flutter Format to ensure formatting is valid 47 | - name: Run Flutter Format 48 | run: dart format --set-exit-if-changed . 49 | working-directory: ${{env.source-directory}} 50 | 51 | analyze: 52 | name: Analyze 53 | 54 | # The type of runner that the job will run on 55 | runs-on: ubuntu-latest 56 | 57 | env: 58 | source-directory: ./cached_network_image_web 59 | 60 | # Steps represent a sequence of tasks that will be executed as part of the job 61 | steps: 62 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 63 | - uses: actions/checkout@v4 64 | 65 | # Make sure the stable version of Flutter is available 66 | - name: Set up Flutter 67 | uses: subosito/flutter-action@v2 68 | with: 69 | channel: "stable" 70 | architecture: x64 71 | cache: true 72 | 73 | # Download all Flutter packages 74 | - name: Download dependencies 75 | run: flutter pub get 76 | working-directory: ${{env.source-directory}} 77 | 78 | # Run Flutter Analyzer 79 | - name: Run Flutter Analyzer 80 | run: flutter analyze 81 | working-directory: ${{env.source-directory}} 82 | 83 | tests: 84 | name: Unit-tests 85 | # The type of runner that the job will run on 86 | runs-on: macos-latest 87 | 88 | env: 89 | source-directory: ./cached_network_image_web 90 | 91 | # Steps represent a sequence of tasks that will be executed as part of the job 92 | steps: 93 | # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it 94 | - uses: actions/checkout@v4 95 | 96 | # Make sure the stable version of Flutter is available 97 | - name: Set up Flutter 98 | uses: subosito/flutter-action@v2 99 | with: 100 | channel: "stable" 101 | architecture: x64 102 | cache: true 103 | 104 | # Download all Flutter packages 105 | - name: Download dependencies 106 | run: flutter pub get 107 | working-directory: ${{env.source-directory}} 108 | 109 | # Run all unit-tests with code coverage 110 | - name: Run unit tests 111 | run: flutter test --platform chrome 112 | working-directory: ${{env.source-directory}} 113 | 114 | # # Upload code coverage information 115 | # - uses: codecov/codecov-action@v4 116 | # with: 117 | # files: ${{env.source-directory}}/coverage/lcov.info 118 | # name: CachedNetworkImage (Web) 119 | # fail_ci_if_error: true 120 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.lock 4 | *.log 5 | *.pyc 6 | *.swp 7 | .DS_Store 8 | .atom/ 9 | .buildlog/ 10 | .history 11 | .project 12 | .svn/ 13 | bin/ 14 | 15 | # IntelliJ related 16 | *.iml 17 | *.ipr 18 | *.iws 19 | .idea/ 20 | 21 | # Android Studio related 22 | android/.classpath 23 | android/.settings/ 24 | 25 | # Visual Studio Code related 26 | .vscode/ 27 | 28 | # Flutter repo-specific 29 | /bin/cache/ 30 | /bin/mingit/ 31 | /dev/benchmarks/mega_gallery/ 32 | /dev/bots/.recipe_deps 33 | /dev/bots/android_tools/ 34 | /dev/docs/doc/ 35 | /dev/docs/lib/ 36 | /dev/docs/pubspec.yaml 37 | /packages/flutter/coverage/ 38 | version 39 | 40 | # Flutter/Dart/Pub related 41 | **/doc/api/ 42 | .dart_tool/ 43 | .flutter-plugins 44 | .packages 45 | .pub-cache/ 46 | .pub/ 47 | build/ 48 | flutter_*.png 49 | linked_*.ds 50 | unlinked.ds 51 | unlinked_spec.ds 52 | flutter_export_environment.sh 53 | 54 | # Android related 55 | **/android/**/gradle-wrapper.jar 56 | **/android/.gradle 57 | **/android/captures/ 58 | **/android/gradlew 59 | **/android/gradlew.bat 60 | **/android/local.properties 61 | **/android/**/GeneratedPluginRegistrant.java 62 | 63 | # iOS/XCode related 64 | **/ios/**/*.mode1v3 65 | **/ios/**/*.mode2v3 66 | **/ios/**/*.moved-aside 67 | **/ios/**/*.pbxuser 68 | **/ios/**/*.perspectivev3 69 | **/ios/**/*sync/ 70 | **/ios/**/.sconsign.dblite 71 | **/ios/**/.tags* 72 | **/ios/**/.vagrant/ 73 | **/ios/**/DerivedData/ 74 | **/ios/**/Icon? 75 | **/ios/**/Pods/ 76 | **/ios/**/.symlinks/ 77 | **/ios/**/profile 78 | **/ios/**/xcuserdata 79 | **/ios/.generated/ 80 | **/ios/Flutter/App.framework 81 | **/ios/Flutter/Flutter.framework 82 | **/ios/Flutter/Generated.xcconfig 83 | **/ios/Flutter/app.flx 84 | **/ios/Flutter/app.zip 85 | **/ios/Flutter/flutter_assets/ 86 | **/ios/ServiceDefinitions.json 87 | **/ios/Runner/GeneratedPluginRegistrant.* 88 | 89 | # Exceptions to above rules. 90 | !**/ios/**/default.mode1v3 91 | !**/ios/**/default.mode2v3 92 | !**/ios/**/default.pbxuser 93 | !**/ios/**/default.perspectivev3 94 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 95 | example/.flutter-plugins-dependencies 96 | cached_network_image/example/.flutter-plugins-dependencies 97 | cached_network_image/example/lib/generated_plugin_registrant.dart 98 | cached_network_image/.flutter-plugins-dependencies 99 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Cached network image 2 | [](https://pub.dartlang.org/packages/cached_network_image) 3 | [](https://codecov.io/gh/Baseflow/flutter_cached_network_image) 4 | [](https://github.com/Baseflow/flutter_cached_network_image/actions/workflows/app_facing_package.yaml) 5 | 6 | A flutter library to show images from the internet and keep them in the cache directory. 7 | 8 | 9 | 10 | ## Sponsors 11 | Try the Flutter Chat Tutorial 💬 12 | 13 | 14 | 15 | ## How to use 16 | The CachedNetworkImage can be used directly or through the ImageProvider. 17 | Both the CachedNetworkImage as CachedNetworkImageProvider have minimal support for web. It currently doesn't include caching. 18 | 19 | With a placeholder: 20 | ```dart 21 | CachedNetworkImage( 22 | imageUrl: "http://via.placeholder.com/350x150", 23 | placeholder: (context, url) => CircularProgressIndicator(), 24 | errorWidget: (context, url, error) => Icon(Icons.error), 25 | ), 26 | ``` 27 | 28 | Or with a progress indicator: 29 | ```dart 30 | CachedNetworkImage( 31 | imageUrl: "http://via.placeholder.com/350x150", 32 | progressIndicatorBuilder: (context, url, downloadProgress) => 33 | CircularProgressIndicator(value: downloadProgress.progress), 34 | errorWidget: (context, url, error) => Icon(Icons.error), 35 | ), 36 | ``` 37 | 38 | 39 | ````dart 40 | Image(image: CachedNetworkImageProvider(url)) 41 | ```` 42 | 43 | When you want to have both the placeholder functionality and want to get the imageprovider to use in another widget you can provide an imageBuilder: 44 | ```dart 45 | CachedNetworkImage( 46 | imageUrl: "http://via.placeholder.com/200x150", 47 | imageBuilder: (context, imageProvider) => Container( 48 | decoration: BoxDecoration( 49 | image: DecorationImage( 50 | image: imageProvider, 51 | fit: BoxFit.cover, 52 | colorFilter: 53 | ColorFilter.mode(Colors.red, BlendMode.colorBurn)), 54 | ), 55 | ), 56 | placeholder: (context, url) => CircularProgressIndicator(), 57 | errorWidget: (context, url, error) => Icon(Icons.error), 58 | ), 59 | ``` 60 | 61 | ## How it works 62 | The cached network images stores and retrieves files using the [flutter_cache_manager](https://pub.dartlang.org/packages/flutter_cache_manager). 63 | 64 | ## FAQ 65 | ### My app crashes when the image loading failed. (I know, this is not really a question.) 66 | Does it really crash though? The debugger might pause, as the Dart VM doesn't recognize it as a caught exception; the console might print errors; even your crash reporting tool might report it (I know, that really sucks). However, does it really crash? Probably everything is just running fine. If you really get an app crashes you are fine to report an issue, but do that with a small example so we can reproduce that crash. 67 | 68 | See for example [this](https://github.com/Baseflow/flutter_cached_network_image/issues/336#issuecomment-760769361) or [this](https://github.com/Baseflow/flutter_cached_network_image/issues/536#issuecomment-760857495) answer on previous posted issues. 69 | -------------------------------------------------------------------------------- /cached_network_image/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /cached_network_image/CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at [hello@baseflow.com](mailto:hello@baseflow.com). All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /cached_network_image/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Contributing to CachedNetworkImage 2 | ============================================= 3 | 4 | What you will need 5 | ------------------ 6 | 7 | * A Linux, Mac OS X, or Windows machine (note: to run and compile iOS specific parts you'll need access to a Mac OS X machine); 8 | * git (used for source version control, installation instruction can be found [here](https://git-scm.com/)); 9 | * The Flutter SDK (installation instructions can be found [here](https://flutter.io/get-started/install/)); 10 | * A personal GitHub account (if you don't have one, you can sign-up for free [here](https://github.com/)) 11 | 12 | Setting up your development environment 13 | --------------------------------------- 14 | 15 | * Fork `https://github.com/baseflow/flutter_cached_network_image` into your own GitHub account. If you already have a fork and moving to a new computer, make sure you update you fork. 16 | * If you haven't configured your machine with an SSH key that's known to github, then 17 | follow [GitHub's directions](https://help.github.com/articles/generating-ssh-keys/) 18 | to generate an SSH key. 19 | * Clone your forked repo on your local development machine: `git clone git@github.com:/flutter_cached_network_image.git` 20 | * Change into the `flutter_cached_network_image` directory: `cd flutter_cached_network_image` 21 | * Add an upstream to the original repo, so that fetch from the main repository and not your clone: `git remote add upstream git@github.com:baseflow/flutter_cached_network_image.git` 22 | 23 | Running the example project 24 | --------------------------- 25 | 26 | * Change into the example directory: `cd example` 27 | * Run the App: `flutter run` 28 | 29 | Contribute 30 | ---------- 31 | 32 | We really appreciate contributions via GitHub pull requests. To contribute take the following steps: 33 | 34 | * Make sure you are up to date with the latest code on the main: 35 | * `git fetch upstream` 36 | * `git checkout upstream/develop -b ` 37 | * Apply your changes 38 | * Verify your changes and fix potential warnings/ errors: 39 | * Check formatting: `flutter format .` 40 | * Run static analyses: `flutter analyze` 41 | * Run unit-tests: `flutter test` 42 | * Commit your changes: `git commit -am ""` 43 | * Push changes to your fork: `git push origin ` 44 | 45 | Send us your pull request: 46 | 47 | * Go to `https://github.com/baseflow/flutter_cached_network_image` and click the "Compare & pull request" button. 48 | 49 | Please make sure you solved all warnings and errors reported by the static code analyses and that you fill in the full pull request template. Failing to do so will result in us asking you to fix it. 50 | -------------------------------------------------------------------------------- /cached_network_image/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 Rene Floor 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /cached_network_image/README.md: -------------------------------------------------------------------------------- 1 | # Cached network image 2 | [](https://pub.dartlang.org/packages/cached_network_image) 3 | [](https://codecov.io/gh/Baseflow/flutter_cached_network_image) 4 | [](https://github.com/Baseflow/flutter_cached_network_image/actions/workflows/app_facing_package.yaml) 5 | 6 | A flutter library to show images from the internet and keep them in the cache directory. 7 | 8 | 9 | 10 | ## Sponsors 11 | 12 | 13 | 14 | 15 | 16 | Try the Flutter Chat Tutorial 💬 17 | 18 | 19 | 20 | 21 | 22 | ## How to use 23 | The CachedNetworkImage can be used directly or through the ImageProvider. 24 | Both the CachedNetworkImage as CachedNetworkImageProvider have minimal support for web. It currently doesn't include caching. 25 | 26 | With a placeholder: 27 | ```dart 28 | CachedNetworkImage( 29 | imageUrl: "http://via.placeholder.com/350x150", 30 | placeholder: (context, url) => CircularProgressIndicator(), 31 | errorWidget: (context, url, error) => Icon(Icons.error), 32 | ), 33 | ``` 34 | 35 | Or with a progress indicator: 36 | ```dart 37 | CachedNetworkImage( 38 | imageUrl: "http://via.placeholder.com/350x150", 39 | progressIndicatorBuilder: (context, url, downloadProgress) => 40 | CircularProgressIndicator(value: downloadProgress.progress), 41 | errorWidget: (context, url, error) => Icon(Icons.error), 42 | ), 43 | ``` 44 | 45 | 46 | ````dart 47 | Image(image: CachedNetworkImageProvider(url)) 48 | ```` 49 | 50 | When you want to have both the placeholder functionality and want to get the imageprovider to use in another widget you can provide an imageBuilder: 51 | ```dart 52 | CachedNetworkImage( 53 | imageUrl: "http://via.placeholder.com/200x150", 54 | imageBuilder: (context, imageProvider) => Container( 55 | decoration: BoxDecoration( 56 | image: DecorationImage( 57 | image: imageProvider, 58 | fit: BoxFit.cover, 59 | colorFilter: 60 | ColorFilter.mode(Colors.red, BlendMode.colorBurn)), 61 | ), 62 | ), 63 | placeholder: (context, url) => CircularProgressIndicator(), 64 | errorWidget: (context, url, error) => Icon(Icons.error), 65 | ), 66 | ``` 67 | 68 | ## How it works 69 | The cached network images stores and retrieves files using the [flutter_cache_manager](https://pub.dartlang.org/packages/flutter_cache_manager). 70 | 71 | ## FAQ 72 | ### My app crashes when the image loading failed. (I know, this is not really a question.) 73 | Does it really crash though? The debugger might pause, as the Dart VM doesn't recognize it as a caught exception; the console might print errors; even your crash reporting tool might report it (I know, that really sucks). However, does it really crash? Probably everything is just running fine. If you really get an app crashes you are fine to report an issue, but do that with a small example so we can reproduce that crash. 74 | 75 | See for example [this](https://github.com/Baseflow/flutter_cached_network_image/issues/336#issuecomment-760769361) or [this](https://github.com/Baseflow/flutter_cached_network_image/issues/536#issuecomment-760857495) answer on previous posted issues. 76 | -------------------------------------------------------------------------------- /cached_network_image/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | -------------------------------------------------------------------------------- /cached_network_image/example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /cached_network_image/example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "b0850beeb25f6d5b10426284f506557f66181b36" 8 | channel: "stable" 9 | 10 | project_type: app 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: b0850beeb25f6d5b10426284f506557f66181b36 17 | base_revision: b0850beeb25f6d5b10426284f506557f66181b36 18 | 19 | # User provided section 20 | 21 | # List of Local paths (relative to this file) that should be 22 | # ignored by the migrate tool. 23 | # 24 | # Files that are not part of the templates will be ignored by default. 25 | unmanaged_files: 26 | - 'lib/main.dart' 27 | - 'ios/Runner.xcodeproj/project.pbxproj' 28 | -------------------------------------------------------------------------------- /cached_network_image/example/README.md: -------------------------------------------------------------------------------- 1 | # A project that showcases usage of cached_network_image 2 | -------------------------------------------------------------------------------- /cached_network_image/example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | -------------------------------------------------------------------------------- /cached_network_image/example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | **/*.keystore 13 | **/*.jks 14 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | def localProperties = new Properties() 9 | def localPropertiesFile = rootProject.file("local.properties") 10 | if (localPropertiesFile.exists()) { 11 | localPropertiesFile.withReader("UTF-8") { reader -> 12 | localProperties.load(reader) 13 | } 14 | } 15 | 16 | def flutterVersionCode = localProperties.getProperty("flutter.versionCode") 17 | if (flutterVersionCode == null) { 18 | flutterVersionCode = "1" 19 | } 20 | 21 | def flutterVersionName = localProperties.getProperty("flutter.versionName") 22 | if (flutterVersionName == null) { 23 | flutterVersionName = "1.0" 24 | } 25 | 26 | android { 27 | namespace = "com.example.example" 28 | compileSdk = flutter.compileSdkVersion 29 | ndkVersion = flutter.ndkVersion 30 | 31 | compileOptions { 32 | sourceCompatibility = JavaVersion.VERSION_1_8 33 | targetCompatibility = JavaVersion.VERSION_1_8 34 | } 35 | 36 | defaultConfig { 37 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 38 | applicationId = "com.example.example" 39 | // You can update the following values to match your application needs. 40 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. 41 | minSdk = flutter.minSdkVersion 42 | targetSdk = flutter.targetSdkVersion 43 | versionCode = flutterVersionCode.toInteger() 44 | versionName = flutterVersionName 45 | } 46 | 47 | buildTypes { 48 | release { 49 | // TODO: Add your own signing config for the release build. 50 | // Signing with the debug keys for now, so `flutter run --release` works. 51 | signingConfig = signingConfigs.debug 52 | } 53 | } 54 | } 55 | 56 | flutter { 57 | source = "../.." 58 | } 59 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/kotlin/com/example/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() 6 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /cached_network_image/example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cached_network_image/example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /cached_network_image/example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /cached_network_image/example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.3-all.zip 6 | -------------------------------------------------------------------------------- /cached_network_image/example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "7.3.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.7.10" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | target 'RunnerTests' do 36 | inherit! :search_paths 37 | end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | 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. -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Example 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | UIApplicationSupportsIndirectInputEvents 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /cached_network_image/example/ios/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral 2 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project-level configuration. 2 | cmake_minimum_required(VERSION 3.10) 3 | project(runner LANGUAGES CXX) 4 | 5 | # The name of the executable created for the application. Change this to change 6 | # the on-disk name of your application. 7 | set(BINARY_NAME "example") 8 | # The unique GTK application identifier for this application. See: 9 | # https://wiki.gnome.org/HowDoI/ChooseApplicationID 10 | set(APPLICATION_ID "com.baseflow.example") 11 | 12 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 13 | # versions of CMake. 14 | cmake_policy(SET CMP0063 NEW) 15 | 16 | # Load bundled libraries from the lib/ directory relative to the binary. 17 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") 18 | 19 | # Root filesystem for cross-building. 20 | if(FLUTTER_TARGET_PLATFORM_SYSROOT) 21 | set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) 22 | set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) 23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) 24 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) 25 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) 26 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) 27 | endif() 28 | 29 | # Define build configuration options. 30 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 31 | set(CMAKE_BUILD_TYPE "Debug" CACHE 32 | STRING "Flutter build mode" FORCE) 33 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 34 | "Debug" "Profile" "Release") 35 | endif() 36 | 37 | # Compilation settings that should be applied to most targets. 38 | # 39 | # Be cautious about adding new options here, as plugins use this function by 40 | # default. In most cases, you should add new options to specific targets instead 41 | # of modifying this function. 42 | function(APPLY_STANDARD_SETTINGS TARGET) 43 | target_compile_features(${TARGET} PUBLIC cxx_std_14) 44 | target_compile_options(${TARGET} PRIVATE -Wall -Werror) 45 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") 46 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") 47 | endfunction() 48 | 49 | # Flutter library and tool build rules. 50 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 51 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 52 | 53 | # System-level dependencies. 54 | find_package(PkgConfig REQUIRED) 55 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 56 | 57 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") 58 | 59 | # Define the application target. To change its name, change BINARY_NAME above, 60 | # not the value here, or `flutter run` will no longer work. 61 | # 62 | # Any new source files that you add to the application should be added here. 63 | add_executable(${BINARY_NAME} 64 | "main.cc" 65 | "my_application.cc" 66 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 67 | ) 68 | 69 | # Apply the standard set of build settings. This can be removed for applications 70 | # that need different build settings. 71 | apply_standard_settings(${BINARY_NAME}) 72 | 73 | # Add dependency libraries. Add any application-specific dependencies here. 74 | target_link_libraries(${BINARY_NAME} PRIVATE flutter) 75 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) 76 | 77 | # Run the Flutter tool portions of the build. This must not be removed. 78 | add_dependencies(${BINARY_NAME} flutter_assemble) 79 | 80 | # Only the install-generated bundle's copy of the executable will launch 81 | # correctly, since the resources must in the right relative locations. To avoid 82 | # people trying to run the unbundled copy, put it in a subdirectory instead of 83 | # the default top-level location. 84 | set_target_properties(${BINARY_NAME} 85 | PROPERTIES 86 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" 87 | ) 88 | 89 | 90 | # Generated plugin build rules, which manage building the plugins and adding 91 | # them to the application. 92 | include(flutter/generated_plugins.cmake) 93 | 94 | 95 | # === Installation === 96 | # By default, "installing" just makes a relocatable bundle in the build 97 | # directory. 98 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") 99 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 100 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 101 | endif() 102 | 103 | # Start with a clean build bundle directory every time. 104 | install(CODE " 105 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") 106 | " COMPONENT Runtime) 107 | 108 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 109 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") 110 | 111 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 112 | COMPONENT Runtime) 113 | 114 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 115 | COMPONENT Runtime) 116 | 117 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 118 | COMPONENT Runtime) 119 | 120 | foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES}) 121 | install(FILES "${bundled_library}" 122 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 123 | COMPONENT Runtime) 124 | endforeach(bundled_library) 125 | 126 | # Fully re-copy the assets directory on each build to avoid having stale files 127 | # from a previous install. 128 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 129 | install(CODE " 130 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 131 | " COMPONENT Runtime) 132 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 133 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 134 | 135 | # Install the AOT library on non-Debug builds only. 136 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") 137 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 138 | COMPONENT Runtime) 139 | endif() 140 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.10) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | 12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...), 13 | # which isn't available in 3.10. 14 | function(list_prepend LIST_NAME PREFIX) 15 | set(NEW_LIST "") 16 | foreach(element ${${LIST_NAME}}) 17 | list(APPEND NEW_LIST "${PREFIX}${element}") 18 | endforeach(element) 19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) 20 | endfunction() 21 | 22 | # === Flutter Library === 23 | # System-level dependencies. 24 | find_package(PkgConfig REQUIRED) 25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0) 26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0) 27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0) 28 | 29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so") 30 | 31 | # Published to parent scope for install step. 32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE) 36 | 37 | list(APPEND FLUTTER_LIBRARY_HEADERS 38 | "fl_basic_message_channel.h" 39 | "fl_binary_codec.h" 40 | "fl_binary_messenger.h" 41 | "fl_dart_project.h" 42 | "fl_engine.h" 43 | "fl_json_message_codec.h" 44 | "fl_json_method_codec.h" 45 | "fl_message_codec.h" 46 | "fl_method_call.h" 47 | "fl_method_channel.h" 48 | "fl_method_codec.h" 49 | "fl_method_response.h" 50 | "fl_plugin_registrar.h" 51 | "fl_plugin_registry.h" 52 | "fl_standard_message_codec.h" 53 | "fl_standard_method_codec.h" 54 | "fl_string_codec.h" 55 | "fl_value.h" 56 | "fl_view.h" 57 | "flutter_linux.h" 58 | ) 59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/") 60 | add_library(flutter INTERFACE) 61 | target_include_directories(flutter INTERFACE 62 | "${EPHEMERAL_DIR}" 63 | ) 64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") 65 | target_link_libraries(flutter INTERFACE 66 | PkgConfig::GTK 67 | PkgConfig::GLIB 68 | PkgConfig::GIO 69 | ) 70 | add_dependencies(flutter flutter_assemble) 71 | 72 | # === Flutter tool backend === 73 | # _phony_ is a non-existent file to force this command to run every time, 74 | # since currently there's no way to get a full input/output list from the 75 | # flutter tool. 76 | add_custom_command( 77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_ 79 | COMMAND ${CMAKE_COMMAND} -E env 80 | ${FLUTTER_TOOL_ENVIRONMENT} 81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh" 82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE} 83 | VERBATIM 84 | ) 85 | add_custom_target(flutter_assemble DEPENDS 86 | "${FLUTTER_LIBRARY}" 87 | ${FLUTTER_LIBRARY_HEADERS} 88 | ) 89 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void fl_register_plugins(FlPluginRegistry* registry) { 12 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar = 13 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin"); 14 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar); 15 | } 16 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void fl_register_plugins(FlPluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_linux 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/main.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | int main(int argc, char** argv) { 4 | g_autoptr(MyApplication) app = my_application_new(); 5 | return g_application_run(G_APPLICATION(app), argc, argv); 6 | } 7 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/my_application.cc: -------------------------------------------------------------------------------- 1 | #include "my_application.h" 2 | 3 | #include 4 | #ifdef GDK_WINDOWING_X11 5 | #include 6 | #endif 7 | 8 | #include "flutter/generated_plugin_registrant.h" 9 | 10 | struct _MyApplication { 11 | GtkApplication parent_instance; 12 | char** dart_entrypoint_arguments; 13 | }; 14 | 15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION) 16 | 17 | // Implements GApplication::activate. 18 | static void my_application_activate(GApplication* application) { 19 | MyApplication* self = MY_APPLICATION(application); 20 | GtkWindow* window = 21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application))); 22 | 23 | // Use a header bar when running in GNOME as this is the common style used 24 | // by applications and is the setup most users will be using (e.g. Ubuntu 25 | // desktop). 26 | // If running on X and not using GNOME then just use a traditional title bar 27 | // in case the window manager does more exotic layout, e.g. tiling. 28 | // If running on Wayland assume the header bar will work (may need changing 29 | // if future cases occur). 30 | gboolean use_header_bar = TRUE; 31 | #ifdef GDK_WINDOWING_X11 32 | GdkScreen* screen = gtk_window_get_screen(window); 33 | if (GDK_IS_X11_SCREEN(screen)) { 34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen); 35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) { 36 | use_header_bar = FALSE; 37 | } 38 | } 39 | #endif 40 | if (use_header_bar) { 41 | GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new()); 42 | gtk_widget_show(GTK_WIDGET(header_bar)); 43 | gtk_header_bar_set_title(header_bar, "example"); 44 | gtk_header_bar_set_show_close_button(header_bar, TRUE); 45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar)); 46 | } else { 47 | gtk_window_set_title(window, "example"); 48 | } 49 | 50 | gtk_window_set_default_size(window, 1280, 720); 51 | gtk_widget_show(GTK_WIDGET(window)); 52 | 53 | g_autoptr(FlDartProject) project = fl_dart_project_new(); 54 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments); 55 | 56 | FlView* view = fl_view_new(project); 57 | gtk_widget_show(GTK_WIDGET(view)); 58 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view)); 59 | 60 | fl_register_plugins(FL_PLUGIN_REGISTRY(view)); 61 | 62 | gtk_widget_grab_focus(GTK_WIDGET(view)); 63 | } 64 | 65 | // Implements GApplication::local_command_line. 66 | static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) { 67 | MyApplication* self = MY_APPLICATION(application); 68 | // Strip out the first argument as it is the binary name. 69 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1); 70 | 71 | g_autoptr(GError) error = nullptr; 72 | if (!g_application_register(application, nullptr, &error)) { 73 | g_warning("Failed to register: %s", error->message); 74 | *exit_status = 1; 75 | return TRUE; 76 | } 77 | 78 | g_application_activate(application); 79 | *exit_status = 0; 80 | 81 | return TRUE; 82 | } 83 | 84 | // Implements GObject::dispose. 85 | static void my_application_dispose(GObject* object) { 86 | MyApplication* self = MY_APPLICATION(object); 87 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev); 88 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object); 89 | } 90 | 91 | static void my_application_class_init(MyApplicationClass* klass) { 92 | G_APPLICATION_CLASS(klass)->activate = my_application_activate; 93 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line; 94 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose; 95 | } 96 | 97 | static void my_application_init(MyApplication* self) {} 98 | 99 | MyApplication* my_application_new() { 100 | return MY_APPLICATION(g_object_new(my_application_get_type(), 101 | "application-id", APPLICATION_ID, 102 | "flags", G_APPLICATION_NON_UNIQUE, 103 | nullptr)); 104 | } 105 | -------------------------------------------------------------------------------- /cached_network_image/example/linux/my_application.h: -------------------------------------------------------------------------------- 1 | #ifndef FLUTTER_MY_APPLICATION_H_ 2 | #define FLUTTER_MY_APPLICATION_H_ 3 | 4 | #include 5 | 6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION, 7 | GtkApplication) 8 | 9 | /** 10 | * my_application_new: 11 | * 12 | * Creates a new Flutter-based application. 13 | * 14 | * Returns: a new #MyApplication. 15 | */ 16 | MyApplication* my_application_new(); 17 | 18 | #endif // FLUTTER_MY_APPLICATION_H_ 19 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/.gitignore: -------------------------------------------------------------------------------- 1 | # Flutter-related 2 | **/Flutter/ephemeral/ 3 | **/Pods/ 4 | 5 | # Xcode-related 6 | **/dgph 7 | **/xcuserdata/ 8 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Flutter/Flutter-Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Flutter/Flutter-Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "ephemeral/Flutter-Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Flutter/GeneratedPluginRegistrant.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | import FlutterMacOS 6 | import Foundation 7 | 8 | import path_provider_foundation 9 | import sqflite 10 | import url_launcher_macos 11 | 12 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { 13 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) 14 | SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) 15 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) 16 | } 17 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, '10.14' 2 | 3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 5 | 6 | project 'Runner', { 7 | 'Debug' => :debug, 8 | 'Profile' => :release, 9 | 'Release' => :release, 10 | } 11 | 12 | def flutter_root 13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__) 14 | unless File.exist?(generated_xcode_build_settings_path) 15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first" 16 | end 17 | 18 | File.foreach(generated_xcode_build_settings_path) do |line| 19 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 20 | return matches[1].strip if matches 21 | end 22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\"" 23 | end 24 | 25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 26 | 27 | flutter_macos_podfile_setup 28 | 29 | target 'Runner' do 30 | use_frameworks! 31 | use_modular_headers! 32 | 33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__)) 34 | target 'RunnerTests' do 35 | inherit! :search_paths 36 | end 37 | end 38 | 39 | post_install do |installer| 40 | installer.pods_project.targets.each do |target| 41 | flutter_additional_macos_build_settings(target) 42 | end 43 | end 44 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 43 | 49 | 50 | 51 | 52 | 53 | 63 | 65 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | @NSApplicationMain 5 | class AppDelegate: FlutterAppDelegate { 6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool { 7 | return true 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "app_icon_16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "app_icon_32.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "app_icon_32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "app_icon_64.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "app_icon_128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "app_icon_256.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "app_icon_256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "app_icon_512.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "app_icon_512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "app_icon_1024.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Configs/AppInfo.xcconfig: -------------------------------------------------------------------------------- 1 | // Application-level settings for the Runner target. 2 | // 3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the 4 | // future. If not, the values below would default to using the project name when this becomes a 5 | // 'flutter create' template. 6 | 7 | // The application's name. By default this is also the title of the Flutter window. 8 | PRODUCT_NAME = example 9 | 10 | // The application's bundle identifier 11 | PRODUCT_BUNDLE_IDENTIFIER = com.example.example 12 | 13 | // The copyright displayed in application information 14 | PRODUCT_COPYRIGHT = Copyright © 2024 com.example. All rights reserved. 15 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Configs/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Debug.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Configs/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "../../Flutter/Flutter-Release.xcconfig" 2 | #include "Warnings.xcconfig" 3 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Configs/Warnings.xcconfig: -------------------------------------------------------------------------------- 1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings 2 | GCC_WARN_UNDECLARED_SELECTOR = YES 3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES 4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE 5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES 6 | CLANG_WARN_PRAGMA_PACK = YES 7 | CLANG_WARN_STRICT_PROTOTYPES = YES 8 | CLANG_WARN_COMMA = YES 9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES 10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES 11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES 12 | GCC_WARN_SHADOW = YES 13 | CLANG_WARN_UNREACHABLE_CODE = YES 14 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/DebugProfile.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.cs.allow-jit 8 | 9 | com.apple.security.network.server 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSMinimumSystemVersion 24 | $(MACOSX_DEPLOYMENT_TARGET) 25 | NSHumanReadableCopyright 26 | $(PRODUCT_COPYRIGHT) 27 | NSMainNibFile 28 | MainMenu 29 | NSPrincipalClass 30 | NSApplication 31 | 32 | 33 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/MainFlutterWindow.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | 4 | class MainFlutterWindow: NSWindow { 5 | override func awakeFromNib() { 6 | let flutterViewController = FlutterViewController() 7 | let windowFrame = self.frame 8 | self.contentViewController = flutterViewController 9 | self.setFrame(windowFrame, display: true) 10 | 11 | RegisterGeneratedPlugins(registry: flutterViewController) 12 | 13 | super.awakeFromNib() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/Runner/Release.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /cached_network_image/example/macos/RunnerTests/RunnerTests.swift: -------------------------------------------------------------------------------- 1 | import Cocoa 2 | import FlutterMacOS 3 | import XCTest 4 | 5 | class RunnerTests: XCTestCase { 6 | 7 | func testExample() { 8 | // If you add code to the Runner application, consider adding tests here. 9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest. 10 | } 11 | 12 | } 13 | -------------------------------------------------------------------------------- /cached_network_image/example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | description: A project that showcases usage of cached_network_image 3 | publish_to: none 4 | version: 1.0.0+1 5 | 6 | environment: 7 | sdk: ^3.0.0 8 | flutter: '>=3.10.0' 9 | 10 | dependencies: 11 | baseflow_plugin_template: ^2.2.0 12 | cached_network_image: 13 | path: ../ 14 | flutter: 15 | sdk: flutter 16 | flutter_blurhash: ^0.8.2 17 | 18 | dev_dependencies: 19 | flutter_test: 20 | sdk: flutter 21 | flutter_lints: ^4.0.0 22 | 23 | flutter: 24 | uses-material-design: true 25 | -------------------------------------------------------------------------------- /cached_network_image/example/pubspec_overrides.yaml: -------------------------------------------------------------------------------- 1 | dependency_overrides: 2 | cached_network_image_platform_interface: 3 | path: 4 | ../../cached_network_image_platform_interface 5 | cached_network_image_web: 6 | path: 7 | ../../cached_network_image_web 8 | -------------------------------------------------------------------------------- /cached_network_image/example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/web/favicon.png -------------------------------------------------------------------------------- /cached_network_image/example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /cached_network_image/example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /cached_network_image/example/web/icons/Icon-maskable-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/web/icons/Icon-maskable-192.png -------------------------------------------------------------------------------- /cached_network_image/example/web/icons/Icon-maskable-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/web/icons/Icon-maskable-512.png -------------------------------------------------------------------------------- /cached_network_image/example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | example 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /cached_network_image/example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | }, 22 | { 23 | "src": "icons/Icon-maskable-192.png", 24 | "sizes": "192x192", 25 | "type": "image/png", 26 | "purpose": "maskable" 27 | }, 28 | { 29 | "src": "icons/Icon-maskable-512.png", 30 | "sizes": "512x512", 31 | "type": "image/png", 32 | "purpose": "maskable" 33 | } 34 | ] 35 | } 36 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/.gitignore: -------------------------------------------------------------------------------- 1 | flutter/ephemeral/ 2 | 3 | # Visual Studio user-specific files. 4 | *.suo 5 | *.user 6 | *.userosscache 7 | *.sln.docstates 8 | 9 | # Visual Studio build-related files. 10 | x64/ 11 | x86/ 12 | 13 | # Visual Studio cache files 14 | # files ending in .cache can be ignored 15 | *.[Cc]ache 16 | # but keep track of directories ending in .cache 17 | !*.[Cc]ache/ 18 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Project-level configuration. 2 | cmake_minimum_required(VERSION 3.14) 3 | project(example LANGUAGES CXX) 4 | 5 | # The name of the executable created for the application. Change this to change 6 | # the on-disk name of your application. 7 | set(BINARY_NAME "example") 8 | 9 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent 10 | # versions of CMake. 11 | cmake_policy(VERSION 3.14...3.25) 12 | 13 | # Define build configuration option. 14 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) 15 | if(IS_MULTICONFIG) 16 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release" 17 | CACHE STRING "" FORCE) 18 | else() 19 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) 20 | set(CMAKE_BUILD_TYPE "Debug" CACHE 21 | STRING "Flutter build mode" FORCE) 22 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS 23 | "Debug" "Profile" "Release") 24 | endif() 25 | endif() 26 | # Define settings for the Profile build mode. 27 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}") 28 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}") 29 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}") 30 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}") 31 | 32 | # Use Unicode for all projects. 33 | add_definitions(-DUNICODE -D_UNICODE) 34 | 35 | # Compilation settings that should be applied to most targets. 36 | # 37 | # Be cautious about adding new options here, as plugins use this function by 38 | # default. In most cases, you should add new options to specific targets instead 39 | # of modifying this function. 40 | function(APPLY_STANDARD_SETTINGS TARGET) 41 | target_compile_features(${TARGET} PUBLIC cxx_std_17) 42 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100") 43 | target_compile_options(${TARGET} PRIVATE /EHsc) 44 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0") 45 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>") 46 | endfunction() 47 | 48 | # Flutter library and tool build rules. 49 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") 50 | add_subdirectory(${FLUTTER_MANAGED_DIR}) 51 | 52 | # Application build; see runner/CMakeLists.txt. 53 | add_subdirectory("runner") 54 | 55 | 56 | # Generated plugin build rules, which manage building the plugins and adding 57 | # them to the application. 58 | include(flutter/generated_plugins.cmake) 59 | 60 | 61 | # === Installation === 62 | # Support files are copied into place next to the executable, so that it can 63 | # run in place. This is done instead of making a separate bundle (as on Linux) 64 | # so that building and running from within Visual Studio will work. 65 | set(BUILD_BUNDLE_DIR "$") 66 | # Make the "install" step default, as it's required to run. 67 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1) 68 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 69 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) 70 | endif() 71 | 72 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") 73 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}") 74 | 75 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" 76 | COMPONENT Runtime) 77 | 78 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 79 | COMPONENT Runtime) 80 | 81 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 82 | COMPONENT Runtime) 83 | 84 | if(PLUGIN_BUNDLED_LIBRARIES) 85 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" 86 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 87 | COMPONENT Runtime) 88 | endif() 89 | 90 | # Copy the native assets provided by the build.dart from all packages. 91 | set(NATIVE_ASSETS_DIR "${PROJECT_BUILD_DIR}native_assets/windows/") 92 | install(DIRECTORY "${NATIVE_ASSETS_DIR}" 93 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" 94 | COMPONENT Runtime) 95 | 96 | # Fully re-copy the assets directory on each build to avoid having stale files 97 | # from a previous install. 98 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets") 99 | install(CODE " 100 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") 101 | " COMPONENT Runtime) 102 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" 103 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) 104 | 105 | # Install the AOT library on non-Debug builds only. 106 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" 107 | CONFIGURATIONS Profile;Release 108 | COMPONENT Runtime) 109 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/flutter/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # This file controls Flutter-level build steps. It should not be edited. 2 | cmake_minimum_required(VERSION 3.14) 3 | 4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") 5 | 6 | # Configuration provided via flutter tool. 7 | include(${EPHEMERAL_DIR}/generated_config.cmake) 8 | 9 | # TODO: Move the rest of this into files in ephemeral. See 10 | # https://github.com/flutter/flutter/issues/57146. 11 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") 12 | 13 | # Set fallback configurations for older versions of the flutter tool. 14 | if (NOT DEFINED FLUTTER_TARGET_PLATFORM) 15 | set(FLUTTER_TARGET_PLATFORM "windows-x64") 16 | endif() 17 | 18 | # === Flutter Library === 19 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll") 20 | 21 | # Published to parent scope for install step. 22 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) 23 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) 24 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE) 25 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE) 26 | 27 | list(APPEND FLUTTER_LIBRARY_HEADERS 28 | "flutter_export.h" 29 | "flutter_windows.h" 30 | "flutter_messenger.h" 31 | "flutter_plugin_registrar.h" 32 | "flutter_texture_registrar.h" 33 | ) 34 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/") 35 | add_library(flutter INTERFACE) 36 | target_include_directories(flutter INTERFACE 37 | "${EPHEMERAL_DIR}" 38 | ) 39 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib") 40 | add_dependencies(flutter flutter_assemble) 41 | 42 | # === Wrapper === 43 | list(APPEND CPP_WRAPPER_SOURCES_CORE 44 | "core_implementations.cc" 45 | "standard_codec.cc" 46 | ) 47 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") 48 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN 49 | "plugin_registrar.cc" 50 | ) 51 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") 52 | list(APPEND CPP_WRAPPER_SOURCES_APP 53 | "flutter_engine.cc" 54 | "flutter_view_controller.cc" 55 | ) 56 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") 57 | 58 | # Wrapper sources needed for a plugin. 59 | add_library(flutter_wrapper_plugin STATIC 60 | ${CPP_WRAPPER_SOURCES_CORE} 61 | ${CPP_WRAPPER_SOURCES_PLUGIN} 62 | ) 63 | apply_standard_settings(flutter_wrapper_plugin) 64 | set_target_properties(flutter_wrapper_plugin PROPERTIES 65 | POSITION_INDEPENDENT_CODE ON) 66 | set_target_properties(flutter_wrapper_plugin PROPERTIES 67 | CXX_VISIBILITY_PRESET hidden) 68 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) 69 | target_include_directories(flutter_wrapper_plugin PUBLIC 70 | "${WRAPPER_ROOT}/include" 71 | ) 72 | add_dependencies(flutter_wrapper_plugin flutter_assemble) 73 | 74 | # Wrapper sources needed for the runner. 75 | add_library(flutter_wrapper_app STATIC 76 | ${CPP_WRAPPER_SOURCES_CORE} 77 | ${CPP_WRAPPER_SOURCES_APP} 78 | ) 79 | apply_standard_settings(flutter_wrapper_app) 80 | target_link_libraries(flutter_wrapper_app PUBLIC flutter) 81 | target_include_directories(flutter_wrapper_app PUBLIC 82 | "${WRAPPER_ROOT}/include" 83 | ) 84 | add_dependencies(flutter_wrapper_app flutter_assemble) 85 | 86 | # === Flutter tool backend === 87 | # _phony_ is a non-existent file to force this command to run every time, 88 | # since currently there's no way to get a full input/output list from the 89 | # flutter tool. 90 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_") 91 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE) 92 | add_custom_command( 93 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS} 94 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN} 95 | ${CPP_WRAPPER_SOURCES_APP} 96 | ${PHONY_OUTPUT} 97 | COMMAND ${CMAKE_COMMAND} -E env 98 | ${FLUTTER_TOOL_ENVIRONMENT} 99 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat" 100 | ${FLUTTER_TARGET_PLATFORM} $ 101 | VERBATIM 102 | ) 103 | add_custom_target(flutter_assemble DEPENDS 104 | "${FLUTTER_LIBRARY}" 105 | ${FLUTTER_LIBRARY_HEADERS} 106 | ${CPP_WRAPPER_SOURCES_CORE} 107 | ${CPP_WRAPPER_SOURCES_PLUGIN} 108 | ${CPP_WRAPPER_SOURCES_APP} 109 | ) 110 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/flutter/generated_plugin_registrant.cc: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #include "generated_plugin_registrant.h" 8 | 9 | #include 10 | 11 | void RegisterPlugins(flutter::PluginRegistry* registry) { 12 | UrlLauncherWindowsRegisterWithRegistrar( 13 | registry->GetRegistrarForPlugin("UrlLauncherWindows")); 14 | } 15 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/flutter/generated_plugin_registrant.h: -------------------------------------------------------------------------------- 1 | // 2 | // Generated file. Do not edit. 3 | // 4 | 5 | // clang-format off 6 | 7 | #ifndef GENERATED_PLUGIN_REGISTRANT_ 8 | #define GENERATED_PLUGIN_REGISTRANT_ 9 | 10 | #include 11 | 12 | // Registers Flutter plugins. 13 | void RegisterPlugins(flutter::PluginRegistry* registry); 14 | 15 | #endif // GENERATED_PLUGIN_REGISTRANT_ 16 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/flutter/generated_plugins.cmake: -------------------------------------------------------------------------------- 1 | # 2 | # Generated file, do not edit. 3 | # 4 | 5 | list(APPEND FLUTTER_PLUGIN_LIST 6 | url_launcher_windows 7 | ) 8 | 9 | list(APPEND FLUTTER_FFI_PLUGIN_LIST 10 | ) 11 | 12 | set(PLUGIN_BUNDLED_LIBRARIES) 13 | 14 | foreach(plugin ${FLUTTER_PLUGIN_LIST}) 15 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin}) 16 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin) 17 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $) 18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries}) 19 | endforeach(plugin) 20 | 21 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST}) 22 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin}) 23 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries}) 24 | endforeach(ffi_plugin) 25 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.14) 2 | project(runner LANGUAGES CXX) 3 | 4 | # Define the application target. To change its name, change BINARY_NAME in the 5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer 6 | # work. 7 | # 8 | # Any new source files that you add to the application should be added here. 9 | add_executable(${BINARY_NAME} WIN32 10 | "flutter_window.cpp" 11 | "main.cpp" 12 | "utils.cpp" 13 | "win32_window.cpp" 14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" 15 | "Runner.rc" 16 | "runner.exe.manifest" 17 | ) 18 | 19 | # Apply the standard set of build settings. This can be removed for applications 20 | # that need different build settings. 21 | apply_standard_settings(${BINARY_NAME}) 22 | 23 | # Add preprocessor definitions for the build version. 24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"") 25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}") 26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}") 27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}") 28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}") 29 | 30 | # Disable Windows macros that collide with C++ standard library functions. 31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX") 32 | 33 | # Add dependency libraries and include directories. Add any application-specific 34 | # dependencies here. 35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) 36 | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib") 37 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") 38 | 39 | # Run the Flutter tool portions of the build. This must not be removed. 40 | add_dependencies(${BINARY_NAME} flutter_assemble) 41 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/Runner.rc: -------------------------------------------------------------------------------- 1 | // Microsoft Visual C++ generated resource script. 2 | // 3 | #pragma code_page(65001) 4 | #include "resource.h" 5 | 6 | #define APSTUDIO_READONLY_SYMBOLS 7 | ///////////////////////////////////////////////////////////////////////////// 8 | // 9 | // Generated from the TEXTINCLUDE 2 resource. 10 | // 11 | #include "winres.h" 12 | 13 | ///////////////////////////////////////////////////////////////////////////// 14 | #undef APSTUDIO_READONLY_SYMBOLS 15 | 16 | ///////////////////////////////////////////////////////////////////////////// 17 | // English (United States) resources 18 | 19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) 20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US 21 | 22 | #ifdef APSTUDIO_INVOKED 23 | ///////////////////////////////////////////////////////////////////////////// 24 | // 25 | // TEXTINCLUDE 26 | // 27 | 28 | 1 TEXTINCLUDE 29 | BEGIN 30 | "resource.h\0" 31 | END 32 | 33 | 2 TEXTINCLUDE 34 | BEGIN 35 | "#include ""winres.h""\r\n" 36 | "\0" 37 | END 38 | 39 | 3 TEXTINCLUDE 40 | BEGIN 41 | "\r\n" 42 | "\0" 43 | END 44 | 45 | #endif // APSTUDIO_INVOKED 46 | 47 | 48 | ///////////////////////////////////////////////////////////////////////////// 49 | // 50 | // Icon 51 | // 52 | 53 | // Icon with lowest ID value placed first to ensure application icon 54 | // remains consistent on all systems. 55 | IDI_APP_ICON ICON "resources\\app_icon.ico" 56 | 57 | 58 | ///////////////////////////////////////////////////////////////////////////// 59 | // 60 | // Version 61 | // 62 | 63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD) 64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD 65 | #else 66 | #define VERSION_AS_NUMBER 1,0,0,0 67 | #endif 68 | 69 | #if defined(FLUTTER_VERSION) 70 | #define VERSION_AS_STRING FLUTTER_VERSION 71 | #else 72 | #define VERSION_AS_STRING "1.0.0" 73 | #endif 74 | 75 | VS_VERSION_INFO VERSIONINFO 76 | FILEVERSION VERSION_AS_NUMBER 77 | PRODUCTVERSION VERSION_AS_NUMBER 78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK 79 | #ifdef _DEBUG 80 | FILEFLAGS VS_FF_DEBUG 81 | #else 82 | FILEFLAGS 0x0L 83 | #endif 84 | FILEOS VOS__WINDOWS32 85 | FILETYPE VFT_APP 86 | FILESUBTYPE 0x0L 87 | BEGIN 88 | BLOCK "StringFileInfo" 89 | BEGIN 90 | BLOCK "040904e4" 91 | BEGIN 92 | VALUE "CompanyName", "com.example" "\0" 93 | VALUE "FileDescription", "example" "\0" 94 | VALUE "FileVersion", VERSION_AS_STRING "\0" 95 | VALUE "InternalName", "example" "\0" 96 | VALUE "LegalCopyright", "Copyright (C) 2024 com.example. All rights reserved." "\0" 97 | VALUE "OriginalFilename", "example.exe" "\0" 98 | VALUE "ProductName", "example" "\0" 99 | VALUE "ProductVersion", VERSION_AS_STRING "\0" 100 | END 101 | END 102 | BLOCK "VarFileInfo" 103 | BEGIN 104 | VALUE "Translation", 0x409, 1252 105 | END 106 | END 107 | 108 | #endif // English (United States) resources 109 | ///////////////////////////////////////////////////////////////////////////// 110 | 111 | 112 | 113 | #ifndef APSTUDIO_INVOKED 114 | ///////////////////////////////////////////////////////////////////////////// 115 | // 116 | // Generated from the TEXTINCLUDE 3 resource. 117 | // 118 | 119 | 120 | ///////////////////////////////////////////////////////////////////////////// 121 | #endif // not APSTUDIO_INVOKED 122 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/flutter_window.cpp: -------------------------------------------------------------------------------- 1 | #include "flutter_window.h" 2 | 3 | #include 4 | 5 | #include "flutter/generated_plugin_registrant.h" 6 | 7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project) 8 | : project_(project) {} 9 | 10 | FlutterWindow::~FlutterWindow() {} 11 | 12 | bool FlutterWindow::OnCreate() { 13 | if (!Win32Window::OnCreate()) { 14 | return false; 15 | } 16 | 17 | RECT frame = GetClientArea(); 18 | 19 | // The size here must match the window dimensions to avoid unnecessary surface 20 | // creation / destruction in the startup path. 21 | flutter_controller_ = std::make_unique( 22 | frame.right - frame.left, frame.bottom - frame.top, project_); 23 | // Ensure that basic setup of the controller was successful. 24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) { 25 | return false; 26 | } 27 | RegisterPlugins(flutter_controller_->engine()); 28 | SetChildContent(flutter_controller_->view()->GetNativeWindow()); 29 | 30 | flutter_controller_->engine()->SetNextFrameCallback([&]() { 31 | this->Show(); 32 | }); 33 | 34 | // Flutter can complete the first frame before the "show window" callback is 35 | // registered. The following call ensures a frame is pending to ensure the 36 | // window is shown. It is a no-op if the first frame hasn't completed yet. 37 | flutter_controller_->ForceRedraw(); 38 | 39 | return true; 40 | } 41 | 42 | void FlutterWindow::OnDestroy() { 43 | if (flutter_controller_) { 44 | flutter_controller_ = nullptr; 45 | } 46 | 47 | Win32Window::OnDestroy(); 48 | } 49 | 50 | LRESULT 51 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message, 52 | WPARAM const wparam, 53 | LPARAM const lparam) noexcept { 54 | // Give Flutter, including plugins, an opportunity to handle window messages. 55 | if (flutter_controller_) { 56 | std::optional result = 57 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam, 58 | lparam); 59 | if (result) { 60 | return *result; 61 | } 62 | } 63 | 64 | switch (message) { 65 | case WM_FONTCHANGE: 66 | flutter_controller_->engine()->ReloadSystemFonts(); 67 | break; 68 | } 69 | 70 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam); 71 | } 72 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/flutter_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_FLUTTER_WINDOW_H_ 2 | #define RUNNER_FLUTTER_WINDOW_H_ 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | #include "win32_window.h" 10 | 11 | // A window that does nothing but host a Flutter view. 12 | class FlutterWindow : public Win32Window { 13 | public: 14 | // Creates a new FlutterWindow hosting a Flutter view running |project|. 15 | explicit FlutterWindow(const flutter::DartProject& project); 16 | virtual ~FlutterWindow(); 17 | 18 | protected: 19 | // Win32Window: 20 | bool OnCreate() override; 21 | void OnDestroy() override; 22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam, 23 | LPARAM const lparam) noexcept override; 24 | 25 | private: 26 | // The project to run. 27 | flutter::DartProject project_; 28 | 29 | // The Flutter instance hosted by this window. 30 | std::unique_ptr flutter_controller_; 31 | }; 32 | 33 | #endif // RUNNER_FLUTTER_WINDOW_H_ 34 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "flutter_window.h" 6 | #include "utils.h" 7 | 8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, 9 | _In_ wchar_t *command_line, _In_ int show_command) { 10 | // Attach to console when present (e.g., 'flutter run') or create a 11 | // new console when running with a debugger. 12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { 13 | CreateAndAttachConsole(); 14 | } 15 | 16 | // Initialize COM, so that it is available for use in the library and/or 17 | // plugins. 18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); 19 | 20 | flutter::DartProject project(L"data"); 21 | 22 | std::vector command_line_arguments = 23 | GetCommandLineArguments(); 24 | 25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); 26 | 27 | FlutterWindow window(project); 28 | Win32Window::Point origin(10, 10); 29 | Win32Window::Size size(1280, 720); 30 | if (!window.Create(L"example", origin, size)) { 31 | return EXIT_FAILURE; 32 | } 33 | window.SetQuitOnClose(true); 34 | 35 | ::MSG msg; 36 | while (::GetMessage(&msg, nullptr, 0, 0)) { 37 | ::TranslateMessage(&msg); 38 | ::DispatchMessage(&msg); 39 | } 40 | 41 | ::CoUninitialize(); 42 | return EXIT_SUCCESS; 43 | } 44 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by Runner.rc 4 | // 5 | #define IDI_APP_ICON 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1001 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/resources/app_icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/cached_network_image/example/windows/runner/resources/app_icon.ico -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/runner.exe.manifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PerMonitorV2 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/utils.cpp: -------------------------------------------------------------------------------- 1 | #include "utils.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | void CreateAndAttachConsole() { 11 | if (::AllocConsole()) { 12 | FILE *unused; 13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) { 14 | _dup2(_fileno(stdout), 1); 15 | } 16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) { 17 | _dup2(_fileno(stdout), 2); 18 | } 19 | std::ios::sync_with_stdio(); 20 | FlutterDesktopResyncOutputStreams(); 21 | } 22 | } 23 | 24 | std::vector GetCommandLineArguments() { 25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use. 26 | int argc; 27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc); 28 | if (argv == nullptr) { 29 | return std::vector(); 30 | } 31 | 32 | std::vector command_line_arguments; 33 | 34 | // Skip the first argument as it's the binary name. 35 | for (int i = 1; i < argc; i++) { 36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i])); 37 | } 38 | 39 | ::LocalFree(argv); 40 | 41 | return command_line_arguments; 42 | } 43 | 44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) { 45 | if (utf16_string == nullptr) { 46 | return std::string(); 47 | } 48 | unsigned int target_length = ::WideCharToMultiByte( 49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 50 | -1, nullptr, 0, nullptr, nullptr) 51 | -1; // remove the trailing null character 52 | int input_length = (int)wcslen(utf16_string); 53 | std::string utf8_string; 54 | if (target_length == 0 || target_length > utf8_string.max_size()) { 55 | return utf8_string; 56 | } 57 | utf8_string.resize(target_length); 58 | int converted_length = ::WideCharToMultiByte( 59 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, 60 | input_length, utf8_string.data(), target_length, nullptr, nullptr); 61 | if (converted_length == 0) { 62 | return std::string(); 63 | } 64 | return utf8_string; 65 | } 66 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_UTILS_H_ 2 | #define RUNNER_UTILS_H_ 3 | 4 | #include 5 | #include 6 | 7 | // Creates a console for the process, and redirects stdout and stderr to 8 | // it for both the runner and the Flutter library. 9 | void CreateAndAttachConsole(); 10 | 11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string 12 | // encoded in UTF-8. Returns an empty std::string on failure. 13 | std::string Utf8FromUtf16(const wchar_t* utf16_string); 14 | 15 | // Gets the command line arguments passed in as a std::vector, 16 | // encoded in UTF-8. Returns an empty std::vector on failure. 17 | std::vector GetCommandLineArguments(); 18 | 19 | #endif // RUNNER_UTILS_H_ 20 | -------------------------------------------------------------------------------- /cached_network_image/example/windows/runner/win32_window.h: -------------------------------------------------------------------------------- 1 | #ifndef RUNNER_WIN32_WINDOW_H_ 2 | #define RUNNER_WIN32_WINDOW_H_ 3 | 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be 11 | // inherited from by classes that wish to specialize with custom 12 | // rendering and input handling 13 | class Win32Window { 14 | public: 15 | struct Point { 16 | unsigned int x; 17 | unsigned int y; 18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {} 19 | }; 20 | 21 | struct Size { 22 | unsigned int width; 23 | unsigned int height; 24 | Size(unsigned int width, unsigned int height) 25 | : width(width), height(height) {} 26 | }; 27 | 28 | Win32Window(); 29 | virtual ~Win32Window(); 30 | 31 | // Creates a win32 window with |title| that is positioned and sized using 32 | // |origin| and |size|. New windows are created on the default monitor. Window 33 | // sizes are specified to the OS in physical pixels, hence to ensure a 34 | // consistent size this function will scale the inputted width and height as 35 | // as appropriate for the default monitor. The window is invisible until 36 | // |Show| is called. Returns true if the window was created successfully. 37 | bool Create(const std::wstring& title, const Point& origin, const Size& size); 38 | 39 | // Show the current window. Returns true if the window was successfully shown. 40 | bool Show(); 41 | 42 | // Release OS resources associated with window. 43 | void Destroy(); 44 | 45 | // Inserts |content| into the window tree. 46 | void SetChildContent(HWND content); 47 | 48 | // Returns the backing Window handle to enable clients to set icon and other 49 | // window properties. Returns nullptr if the window has been destroyed. 50 | HWND GetHandle(); 51 | 52 | // If true, closing this window will quit the application. 53 | void SetQuitOnClose(bool quit_on_close); 54 | 55 | // Return a RECT representing the bounds of the current client area. 56 | RECT GetClientArea(); 57 | 58 | protected: 59 | // Processes and route salient window messages for mouse handling, 60 | // size change and DPI. Delegates handling of these to member overloads that 61 | // inheriting classes can handle. 62 | virtual LRESULT MessageHandler(HWND window, 63 | UINT const message, 64 | WPARAM const wparam, 65 | LPARAM const lparam) noexcept; 66 | 67 | // Called when CreateAndShow is called, allowing subclass window-related 68 | // setup. Subclasses should return false if setup fails. 69 | virtual bool OnCreate(); 70 | 71 | // Called when Destroy is called. 72 | virtual void OnDestroy(); 73 | 74 | private: 75 | friend class WindowClassRegistrar; 76 | 77 | // OS callback called by message pump. Handles the WM_NCCREATE message which 78 | // is passed when the non-client area is being created and enables automatic 79 | // non-client DPI scaling so that the non-client area automatically 80 | // responds to changes in DPI. All other messages are handled by 81 | // MessageHandler. 82 | static LRESULT CALLBACK WndProc(HWND const window, 83 | UINT const message, 84 | WPARAM const wparam, 85 | LPARAM const lparam) noexcept; 86 | 87 | // Retrieves a class instance pointer for |window| 88 | static Win32Window* GetThisFromHandle(HWND const window) noexcept; 89 | 90 | // Update the window frame's theme to match the system theme. 91 | static void UpdateTheme(HWND const window); 92 | 93 | bool quit_on_close_ = false; 94 | 95 | // window handle for top level window. 96 | HWND window_handle_ = nullptr; 97 | 98 | // window handle for hosted content. 99 | HWND child_content_ = nullptr; 100 | }; 101 | 102 | #endif // RUNNER_WIN32_WINDOW_H_ 103 | -------------------------------------------------------------------------------- /cached_network_image/lib/cached_network_image.dart: -------------------------------------------------------------------------------- 1 | /// Flutter library to load and cache network images. 2 | /// Can also be used with placeholder and error widgets. 3 | library cached_network_image; 4 | 5 | export 'package:flutter_cache_manager/flutter_cache_manager.dart' 6 | show CacheManagerLogLevel, DownloadProgress; 7 | 8 | export 'src/cached_image_widget.dart'; 9 | export 'src/image_provider/cached_network_image_provider.dart'; 10 | export 'src/image_provider/multi_image_stream_completer.dart'; 11 | -------------------------------------------------------------------------------- /cached_network_image/lib/src/image_provider/_image_loader.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:typed_data'; 3 | import 'dart:ui' as ui; 4 | import 'dart:ui'; 5 | 6 | import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; 7 | import 'package:cached_network_image_platform_interface' 8 | '/cached_network_image_platform_interface.dart' as platform 9 | show ImageLoader; 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 12 | 13 | /// ImageLoader class to load images on IO platforms. 14 | class ImageLoader implements platform.ImageLoader { 15 | @Deprecated('Use loadImageAsync instead') 16 | @override 17 | Stream loadBufferAsync( 18 | String url, 19 | String? cacheKey, 20 | StreamController chunkEvents, 21 | DecoderBufferCallback decode, 22 | BaseCacheManager cacheManager, 23 | int? maxHeight, 24 | int? maxWidth, 25 | Map? headers, 26 | ImageRenderMethodForWeb imageRenderMethodForWeb, 27 | VoidCallback evictImage, 28 | ) { 29 | return _load( 30 | url, 31 | cacheKey, 32 | chunkEvents, 33 | (bytes) async { 34 | final buffer = await ImmutableBuffer.fromUint8List(bytes); 35 | return decode(buffer); 36 | }, 37 | cacheManager, 38 | maxHeight, 39 | maxWidth, 40 | headers, 41 | imageRenderMethodForWeb, 42 | evictImage, 43 | ); 44 | } 45 | 46 | @override 47 | Stream loadImageAsync( 48 | String url, 49 | String? cacheKey, 50 | StreamController chunkEvents, 51 | ImageDecoderCallback decode, 52 | BaseCacheManager cacheManager, 53 | int? maxHeight, 54 | int? maxWidth, 55 | Map? headers, 56 | ImageRenderMethodForWeb imageRenderMethodForWeb, 57 | VoidCallback evictImage, 58 | ) { 59 | return _load( 60 | url, 61 | cacheKey, 62 | chunkEvents, 63 | (bytes) async { 64 | final buffer = await ImmutableBuffer.fromUint8List(bytes); 65 | return decode(buffer); 66 | }, 67 | cacheManager, 68 | maxHeight, 69 | maxWidth, 70 | headers, 71 | imageRenderMethodForWeb, 72 | evictImage, 73 | ); 74 | } 75 | 76 | Stream _load( 77 | String url, 78 | String? cacheKey, 79 | StreamController chunkEvents, 80 | Future Function(Uint8List) decode, 81 | BaseCacheManager cacheManager, 82 | int? maxHeight, 83 | int? maxWidth, 84 | Map? headers, 85 | ImageRenderMethodForWeb imageRenderMethodForWeb, 86 | VoidCallback evictImage, 87 | ) async* { 88 | try { 89 | assert( 90 | cacheManager is ImageCacheManager || 91 | (maxWidth == null && maxHeight == null), 92 | 'To resize the image with a CacheManager the ' 93 | 'CacheManager needs to be an ImageCacheManager. maxWidth and ' 94 | 'maxHeight will be ignored when a normal CacheManager is used.'); 95 | 96 | final stream = cacheManager is ImageCacheManager 97 | ? cacheManager.getImageFile( 98 | url, 99 | maxHeight: maxHeight, 100 | maxWidth: maxWidth, 101 | withProgress: true, 102 | headers: headers, 103 | key: cacheKey, 104 | ) 105 | : cacheManager.getFileStream( 106 | url, 107 | withProgress: true, 108 | headers: headers, 109 | key: cacheKey, 110 | ); 111 | 112 | await for (final result in stream) { 113 | if (result is DownloadProgress) { 114 | chunkEvents.add( 115 | ImageChunkEvent( 116 | cumulativeBytesLoaded: result.downloaded, 117 | expectedTotalBytes: result.totalSize, 118 | ), 119 | ); 120 | } 121 | if (result is FileInfo) { 122 | final file = result.file; 123 | final bytes = await file.readAsBytes(); 124 | final decoded = await decode(bytes); 125 | yield decoded; 126 | } 127 | } 128 | } on Object catch (error, stackTrace) { 129 | // Depending on where the exception was thrown, the image cache may not 130 | // have had a chance to track the key in the cache at all. 131 | // Schedule a microtask to give the cache a chance to add the key. 132 | scheduleMicrotask(() { 133 | evictImage(); 134 | }); 135 | yield* Stream.error(error, stackTrace); 136 | } finally { 137 | await chunkEvents.close(); 138 | } 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /cached_network_image/lib/src/image_provider/cached_network_image_provider.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async' show Future, StreamController; 2 | import 'dart:ui' as ui show Codec; 3 | 4 | import 'package:cached_network_image/src/image_provider/multi_image_stream_completer.dart'; 5 | import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart' 6 | show ErrorListener, ImageRenderMethodForWeb; 7 | import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart' 8 | if (dart.library.io) '_image_loader.dart' 9 | if (dart.library.js_interop) 'package:cached_network_image_web/cached_network_image_web.dart' 10 | show ImageLoader; 11 | import 'package:flutter/foundation.dart'; 12 | import 'package:flutter/material.dart'; 13 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 14 | 15 | /// IO implementation of the CachedNetworkImageProvider; the ImageProvider to 16 | /// load network images using a cache. 17 | @immutable 18 | class CachedNetworkImageProvider 19 | extends ImageProvider { 20 | /// Creates an ImageProvider which loads an image from the [url], using the [scale]. 21 | /// When the image fails to load [errorListener] is called. 22 | const CachedNetworkImageProvider( 23 | this.url, { 24 | this.maxHeight, 25 | this.maxWidth, 26 | this.scale = 1.0, 27 | this.errorListener, 28 | this.headers, 29 | this.cacheManager, 30 | this.cacheKey, 31 | this.imageRenderMethodForWeb = ImageRenderMethodForWeb.HtmlImage, 32 | }); 33 | 34 | /// CacheManager from which the image files are loaded. 35 | final BaseCacheManager? cacheManager; 36 | 37 | /// The default cache manager used for image caching. 38 | static BaseCacheManager defaultCacheManager = DefaultCacheManager(); 39 | 40 | /// Web url of the image to load 41 | final String url; 42 | 43 | /// Cache key of the image to cache 44 | final String? cacheKey; 45 | 46 | /// Scale of the image 47 | final double scale; 48 | 49 | /// Listener to be called when images fails to load. 50 | final ErrorListener? errorListener; 51 | 52 | /// Set headers for the image provider, for example for authentication 53 | final Map? headers; 54 | 55 | /// Maximum height of the loaded image. If not null and using an 56 | /// [ImageCacheManager] the image is resized on disk to fit the height. 57 | final int? maxHeight; 58 | 59 | /// Maximum width of the loaded image. If not null and using an 60 | /// [ImageCacheManager] the image is resized on disk to fit the width. 61 | final int? maxWidth; 62 | 63 | /// Render option for images on the web platform. 64 | final ImageRenderMethodForWeb imageRenderMethodForWeb; 65 | 66 | @override 67 | Future obtainKey( 68 | ImageConfiguration configuration, 69 | ) { 70 | return SynchronousFuture(this); 71 | } 72 | 73 | @Deprecated('loadBuffer is deprecated, use loadImage instead') 74 | @override 75 | ImageStreamCompleter loadBuffer( 76 | CachedNetworkImageProvider key, 77 | DecoderBufferCallback decode, 78 | ) { 79 | final chunkEvents = StreamController(); 80 | final imageStreamCompleter = MultiImageStreamCompleter( 81 | codec: _loadBufferAsync(key, chunkEvents, decode), 82 | chunkEvents: chunkEvents.stream, 83 | scale: key.scale, 84 | informationCollector: () => [ 85 | DiagnosticsProperty('Image provider', this), 86 | DiagnosticsProperty('Image key', key), 87 | ], 88 | ); 89 | 90 | if (errorListener != null) { 91 | imageStreamCompleter.addListener( 92 | ImageStreamListener( 93 | (image, synchronousCall) {}, 94 | onError: (Object error, StackTrace? trace) { 95 | errorListener?.call(error); 96 | }, 97 | ), 98 | ); 99 | } 100 | 101 | return imageStreamCompleter; 102 | } 103 | 104 | @Deprecated('_loadBufferAsync is deprecated, use _loadImageAsync instead') 105 | Stream _loadBufferAsync( 106 | CachedNetworkImageProvider key, 107 | StreamController chunkEvents, 108 | DecoderBufferCallback decode, 109 | ) { 110 | assert(key == this); 111 | return ImageLoader().loadBufferAsync( 112 | url, 113 | cacheKey, 114 | chunkEvents, 115 | decode, 116 | cacheManager ?? defaultCacheManager, 117 | maxHeight, 118 | maxWidth, 119 | headers, 120 | imageRenderMethodForWeb, 121 | () => PaintingBinding.instance.imageCache.evict(key), 122 | ); 123 | } 124 | 125 | @override 126 | ImageStreamCompleter loadImage( 127 | CachedNetworkImageProvider key, 128 | ImageDecoderCallback decode, 129 | ) { 130 | final chunkEvents = StreamController(); 131 | final imageStreamCompleter = MultiImageStreamCompleter( 132 | codec: _loadImageAsync(key, chunkEvents, decode), 133 | chunkEvents: chunkEvents.stream, 134 | scale: key.scale, 135 | informationCollector: () => [ 136 | DiagnosticsProperty('Image provider', this), 137 | DiagnosticsProperty('Image key', key), 138 | ], 139 | ); 140 | 141 | if (errorListener != null) { 142 | imageStreamCompleter.addListener( 143 | ImageStreamListener( 144 | (image, synchronousCall) {}, 145 | onError: (Object error, StackTrace? trace) { 146 | errorListener?.call(error); 147 | }, 148 | ), 149 | ); 150 | } 151 | 152 | return imageStreamCompleter; 153 | } 154 | 155 | Stream _loadImageAsync( 156 | CachedNetworkImageProvider key, 157 | StreamController chunkEvents, 158 | ImageDecoderCallback decode, 159 | ) { 160 | assert(key == this); 161 | return ImageLoader().loadImageAsync( 162 | url, 163 | cacheKey, 164 | chunkEvents, 165 | decode, 166 | cacheManager ?? defaultCacheManager, 167 | maxHeight, 168 | maxWidth, 169 | headers, 170 | imageRenderMethodForWeb, 171 | () => PaintingBinding.instance.imageCache.evict(key), 172 | ); 173 | } 174 | 175 | @override 176 | bool operator ==(Object other) { 177 | if (other is CachedNetworkImageProvider) { 178 | return ((cacheKey ?? url) == (other.cacheKey ?? other.url)) && 179 | scale == other.scale && 180 | maxHeight == other.maxHeight && 181 | maxWidth == other.maxWidth; 182 | } 183 | return false; 184 | } 185 | 186 | @override 187 | int get hashCode => Object.hash(cacheKey ?? url, scale, maxHeight, maxWidth); 188 | 189 | @override 190 | String toString() => 'CachedNetworkImageProvider("$url", scale: $scale)'; 191 | } 192 | -------------------------------------------------------------------------------- /cached_network_image/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cached_network_image 2 | description: Flutter library to load and cache network images. 3 | Can also be used with placeholder and error widgets. 4 | homepage: https://github.com/Baseflow/flutter_cached_network_image 5 | topics: 6 | - cache 7 | - image 8 | - network-image 9 | version: 3.4.1 10 | 11 | environment: 12 | sdk: ^3.0.0 13 | flutter: '>=3.10.0' 14 | 15 | dependencies: 16 | cached_network_image_platform_interface: ^4.1.1 17 | cached_network_image_web: ^1.3.1 18 | flutter: 19 | sdk: flutter 20 | flutter_cache_manager: ^3.4.1 21 | octo_image: ^2.1.0 22 | 23 | dev_dependencies: 24 | file: '>=7.0.0 <8.0.0' 25 | flutter_lints: ^4.0.0 26 | flutter_test: 27 | sdk: flutter 28 | mocktail: ^1.0.4 29 | -------------------------------------------------------------------------------- /cached_network_image/test/fake_cache_manager.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Rene Floor. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:async'; 6 | import 'dart:typed_data'; 7 | 8 | import 'package:file/memory.dart'; 9 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 10 | import 'package:mocktail/mocktail.dart'; 11 | 12 | class FakeCacheManager extends Mock implements CacheManager { 13 | void throwsNotFound(String url) { 14 | when( 15 | () => getFileStream( 16 | url, 17 | key: any(named: 'key'), 18 | headers: any(named: 'headers'), 19 | withProgress: any(named: 'withProgress'), 20 | ), 21 | ).thenThrow( 22 | HttpExceptionWithStatus( 23 | 404, 24 | 'Invalid statusCode: 404', 25 | uri: Uri.parse(url), 26 | ), 27 | ); 28 | } 29 | 30 | ExpectedData returns( 31 | String url, 32 | List imageData, { 33 | Duration? delayBetweenChunks, 34 | }) { 35 | const chunkSize = 8; 36 | final chunks = [ 37 | for (int offset = 0; offset < imageData.length; offset += chunkSize) 38 | Uint8List.fromList(imageData.skip(offset).take(chunkSize).toList()), 39 | ]; 40 | 41 | when( 42 | () => getFileStream( 43 | url, 44 | key: any(named: 'key'), 45 | headers: any(named: 'headers'), 46 | withProgress: any(named: 'withProgress'), 47 | ), 48 | ).thenAnswer( 49 | (_) => _createResultStream( 50 | url, 51 | chunks, 52 | imageData, 53 | delayBetweenChunks, 54 | ), 55 | ); 56 | 57 | return ExpectedData( 58 | chunks: chunks.length, 59 | totalSize: imageData.length, 60 | chunkSize: chunkSize, 61 | ); 62 | } 63 | 64 | Stream _createResultStream( 65 | String url, 66 | List chunks, 67 | List imageData, 68 | Duration? delayBetweenChunks, 69 | ) async* { 70 | final totalSize = imageData.length; 71 | var downloaded = 0; 72 | for (final chunk in chunks) { 73 | downloaded += chunk.length; 74 | if (delayBetweenChunks != null) { 75 | await Future.delayed(delayBetweenChunks); 76 | } 77 | yield DownloadProgress(url, totalSize, downloaded); 78 | } 79 | final file = MemoryFileSystem().systemTempDirectory.childFile('test.jpg'); 80 | await file.writeAsBytes(imageData); 81 | yield FileInfo( 82 | file, 83 | FileSource.Online, 84 | DateTime.now().add(const Duration(days: 1)), 85 | url, 86 | ); 87 | } 88 | } 89 | 90 | class FakeImageCacheManager extends Mock implements ImageCacheManager { 91 | ExpectedData returns( 92 | String url, 93 | List imageData, { 94 | Duration? delayBetweenChunks, 95 | }) { 96 | const chunkSize = 8; 97 | final chunks = [ 98 | for (int offset = 0; offset < imageData.length; offset += chunkSize) 99 | Uint8List.fromList(imageData.skip(offset).take(chunkSize).toList()), 100 | ]; 101 | 102 | when( 103 | () => getImageFile( 104 | url, 105 | key: any(named: 'key'), 106 | headers: any(named: 'headers'), 107 | withProgress: any(named: 'withProgress'), 108 | maxHeight: any(named: 'maxHeight'), 109 | maxWidth: any(named: 'maxWidth'), 110 | ), 111 | ).thenAnswer( 112 | (_) => _createResultStream( 113 | url, 114 | chunks, 115 | imageData, 116 | delayBetweenChunks, 117 | ), 118 | ); 119 | 120 | return ExpectedData( 121 | chunks: chunks.length, 122 | totalSize: imageData.length, 123 | chunkSize: chunkSize, 124 | ); 125 | } 126 | 127 | Stream _createResultStream( 128 | String url, 129 | List chunks, 130 | List imageData, 131 | Duration? delayBetweenChunks, 132 | ) async* { 133 | final totalSize = imageData.length; 134 | var downloaded = 0; 135 | for (final chunk in chunks) { 136 | downloaded += chunk.length; 137 | if (delayBetweenChunks != null) { 138 | await Future.delayed(delayBetweenChunks); 139 | } 140 | yield DownloadProgress(url, totalSize, downloaded); 141 | } 142 | final file = MemoryFileSystem().systemTempDirectory.childFile('test.jpg'); 143 | await file.writeAsBytes(imageData); 144 | yield FileInfo( 145 | file, 146 | FileSource.Online, 147 | DateTime.now().add(const Duration(days: 1)), 148 | url, 149 | ); 150 | } 151 | } 152 | 153 | class ExpectedData { 154 | final int chunks; 155 | final int totalSize; 156 | final int chunkSize; 157 | 158 | const ExpectedData({ 159 | required this.chunks, 160 | required this.totalSize, 161 | required this.chunkSize, 162 | }); 163 | } 164 | -------------------------------------------------------------------------------- /cached_network_image/test/image_cache_manager_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:cached_network_image/cached_network_image.dart'; 4 | import 'package:flutter/painting.dart'; 5 | import 'package:flutter_test/flutter_test.dart'; 6 | import 'package:mocktail/mocktail.dart'; 7 | 8 | import 'fake_cache_manager.dart'; 9 | import 'image_data.dart'; 10 | import 'rendering_tester.dart'; 11 | 12 | void main() { 13 | TestRenderingFlutterBinding(); 14 | 15 | setUp(() {}); 16 | 17 | tearDown(() { 18 | PaintingBinding.instance.imageCache.clear(); 19 | PaintingBinding.instance.imageCache.clearLiveImages(); 20 | }); 21 | 22 | test( 23 | 'Supplying an ImageCacheManager should call getImageFile', 24 | () async { 25 | var url = 'foo.nl'; 26 | 27 | var cacheManager = FakeImageCacheManager(); 28 | cacheManager.returns(url, kTransparentImage); 29 | final imageAvailable = Completer(); 30 | 31 | final ImageProvider imageProvider = 32 | CachedNetworkImageProvider(url, cacheManager: cacheManager); 33 | final result = imageProvider.resolve(ImageConfiguration.empty); 34 | 35 | result.addListener( 36 | ImageStreamListener( 37 | (ImageInfo image, bool synchronousCall) { 38 | imageAvailable.complete(); 39 | }, 40 | ), 41 | ); 42 | await imageAvailable.future; 43 | 44 | verify( 45 | () => cacheManager.getImageFile( 46 | url, 47 | key: any(named: 'key'), 48 | headers: any(named: 'headers'), 49 | withProgress: any(named: 'withProgress'), 50 | maxHeight: any(named: 'maxHeight'), 51 | maxWidth: any(named: 'maxWidth'), 52 | ), 53 | ).called(1); 54 | 55 | verifyNever( 56 | () => cacheManager.getFileStream( 57 | url, 58 | key: any(named: 'key'), 59 | headers: any(named: 'headers'), 60 | withProgress: any(named: 'withProgress'), 61 | ), 62 | ); 63 | }, 64 | skip: isBrowser, 65 | ); 66 | 67 | test( 68 | 'Supplying an CacheManager should call getFileStream', 69 | () async { 70 | var url = 'foo.nl'; 71 | 72 | var cacheManager = FakeCacheManager(); 73 | cacheManager.returns(url, kTransparentImage); 74 | final imageAvailable = Completer(); 75 | 76 | final ImageProvider imageProvider = 77 | CachedNetworkImageProvider(url, cacheManager: cacheManager); 78 | final result = imageProvider.resolve(ImageConfiguration.empty); 79 | 80 | result.addListener( 81 | ImageStreamListener( 82 | (ImageInfo image, bool synchronousCall) { 83 | imageAvailable.complete(); 84 | }, 85 | ), 86 | ); 87 | await imageAvailable.future; 88 | 89 | verify( 90 | () => cacheManager.getFileStream( 91 | url, 92 | key: any(named: 'key'), 93 | headers: any(named: 'headers'), 94 | withProgress: any(named: 'withProgress'), 95 | ), 96 | ).called(1); 97 | }, 98 | skip: isBrowser, 99 | ); 100 | 101 | test( 102 | 'Supplying an CacheManager with maxHeight throws assertion', 103 | () async { 104 | var url = 'foo.nl'; 105 | final caughtError = Completer(); 106 | 107 | var cacheManager = FakeCacheManager(); 108 | cacheManager.returns(url, kTransparentImage); 109 | final imageAvailable = Completer(); 110 | 111 | final ImageProvider imageProvider = CachedNetworkImageProvider( 112 | url, 113 | cacheManager: cacheManager, 114 | maxHeight: 20, 115 | ); 116 | final result = imageProvider.resolve(ImageConfiguration.empty); 117 | 118 | result.addListener( 119 | ImageStreamListener( 120 | (ImageInfo image, bool synchronousCall) { 121 | imageAvailable.complete(); 122 | }, 123 | onError: (Object error, StackTrace? stackTrace) { 124 | caughtError.complete(error); 125 | }, 126 | ), 127 | ); 128 | final dynamic err = await caughtError.future; 129 | 130 | expect(err, isA()); 131 | }, 132 | skip: isBrowser, 133 | ); 134 | 135 | test( 136 | 'Supplying an CacheManager with maxWidth throws assertion', 137 | () async { 138 | var url = 'foo.nl'; 139 | final caughtError = Completer(); 140 | 141 | var cacheManager = FakeCacheManager(); 142 | cacheManager.returns(url, kTransparentImage); 143 | final imageAvailable = Completer(); 144 | 145 | final ImageProvider imageProvider = CachedNetworkImageProvider( 146 | url, 147 | cacheManager: cacheManager, 148 | maxWidth: 20, 149 | ); 150 | final result = imageProvider.resolve(ImageConfiguration.empty); 151 | 152 | result.addListener( 153 | ImageStreamListener( 154 | (ImageInfo image, bool synchronousCall) { 155 | imageAvailable.complete(); 156 | }, 157 | onError: (dynamic error, StackTrace? stackTrace) { 158 | caughtError.complete(error); 159 | }, 160 | ), 161 | ); 162 | final dynamic err = await caughtError.future; 163 | 164 | expect(err, isA()); 165 | }, 166 | skip: isBrowser, 167 | ); 168 | } 169 | -------------------------------------------------------------------------------- /cached_network_image/test/image_data.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2016 The Chromium Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style license that can be 3 | // found in the LICENSE file. 4 | 5 | const List kTransparentImage = [ 6 | 0x89, 7 | 0x50, 8 | 0x4E, 9 | 0x47, 10 | 0x0D, 11 | 0x0A, 12 | 0x1A, 13 | 0x0A, 14 | 0x00, 15 | 0x00, 16 | 0x00, 17 | 0x0D, 18 | 0x49, 19 | 0x48, 20 | 0x44, 21 | 0x52, 22 | 0x00, 23 | 0x00, 24 | 0x00, 25 | 0x01, 26 | 0x00, 27 | 0x00, 28 | 0x00, 29 | 0x01, 30 | 0x08, 31 | 0x06, 32 | 0x00, 33 | 0x00, 34 | 0x00, 35 | 0x1F, 36 | 0x15, 37 | 0xC4, 38 | 0x89, 39 | 0x00, 40 | 0x00, 41 | 0x00, 42 | 0x0A, 43 | 0x49, 44 | 0x44, 45 | 0x41, 46 | 0x54, 47 | 0x78, 48 | 0x9C, 49 | 0x63, 50 | 0x00, 51 | 0x01, 52 | 0x00, 53 | 0x00, 54 | 0x05, 55 | 0x00, 56 | 0x01, 57 | 0x0D, 58 | 0x0A, 59 | 0x2D, 60 | 0xB4, 61 | 0x00, 62 | 0x00, 63 | 0x00, 64 | 0x00, 65 | 0x49, 66 | 0x45, 67 | 0x4E, 68 | 0x44, 69 | 0xAE, 70 | ]; 71 | -------------------------------------------------------------------------------- /cached_network_image/test/image_provider_test.dart: -------------------------------------------------------------------------------- 1 | // Copyright 2020 Rene Floor. All rights reserved. 2 | // Use of this source code is governed by a MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | import 'dart:async'; 6 | import 'dart:math' as math; 7 | import 'dart:ui' show Codec, FrameInfo; 8 | 9 | import 'package:cached_network_image/cached_network_image.dart'; 10 | import 'package:flutter/painting.dart'; 11 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 12 | import 'package:flutter_test/flutter_test.dart'; 13 | 14 | import 'fake_cache_manager.dart'; 15 | import 'image_data.dart'; 16 | import 'rendering_tester.dart'; 17 | 18 | void main() { 19 | TestRenderingFlutterBinding(); 20 | 21 | late FakeCacheManager cacheManager; 22 | 23 | setUp(() { 24 | cacheManager = FakeCacheManager(); 25 | }); 26 | 27 | tearDown(() { 28 | PaintingBinding.instance.imageCache.clear(); 29 | PaintingBinding.instance.imageCache.clearLiveImages(); 30 | }); 31 | 32 | test( 33 | 'Expect thrown exception with statusCode - evicts from cache', 34 | () async { 35 | const requestUrl = 'foo-url'; 36 | cacheManager.throwsNotFound(requestUrl); 37 | 38 | final caughtError = Completer(); 39 | 40 | final ImageProvider imageProvider = CachedNetworkImageProvider( 41 | nonconst(requestUrl), 42 | cacheManager: cacheManager, 43 | ); 44 | expect(imageCache.pendingImageCount, 0); 45 | expect(imageCache.statusForKey(imageProvider).untracked, true); 46 | 47 | final result = imageProvider.resolve(ImageConfiguration.empty); 48 | 49 | expect(imageCache.pendingImageCount, 1); 50 | expect(imageCache.statusForKey(imageProvider).pending, true); 51 | 52 | result.addListener( 53 | ImageStreamListener( 54 | (ImageInfo info, bool syncCall) {}, 55 | onError: (Object error, StackTrace? stackTrace) { 56 | caughtError.complete(error); 57 | }, 58 | ), 59 | ); 60 | 61 | final dynamic err = await caughtError.future; 62 | 63 | expect(imageCache.pendingImageCount, 0); 64 | expect(imageCache.statusForKey(imageProvider).untracked, true); 65 | 66 | expect( 67 | err, 68 | isA() 69 | .having( 70 | (HttpExceptionWithStatus e) => e.statusCode, 71 | 'statusCode', 72 | 404, 73 | ) 74 | .having( 75 | (HttpExceptionWithStatus e) => e.uri, 76 | 'uri', 77 | Uri.parse(requestUrl), 78 | ), 79 | ); 80 | }, 81 | skip: isBrowser, 82 | ); // Browser implementation does not use HTTP client but an tag. 83 | 84 | test('Propagates http client errors during resolve()', () async { 85 | var uncaught = false; 86 | var url = 'asdasdasdas'; 87 | cacheManager.throwsNotFound(url); 88 | 89 | await runZoned( 90 | () async { 91 | final ImageProvider imageProvider = 92 | CachedNetworkImageProvider(url, cacheManager: cacheManager); 93 | final caughtError = Completer(); 94 | FlutterError.onError = (FlutterErrorDetails details) { 95 | throw Error(); 96 | }; 97 | final result = imageProvider.resolve(ImageConfiguration.empty); 98 | result.addListener( 99 | ImageStreamListener( 100 | (ImageInfo info, bool syncCall) {}, 101 | onError: (Object error, StackTrace? stackTrace) { 102 | caughtError.complete(true); 103 | }, 104 | ), 105 | ); 106 | expect(await caughtError.future, true); 107 | }, 108 | zoneSpecification: ZoneSpecification( 109 | handleUncaughtError: ( 110 | Zone zone, 111 | ZoneDelegate zoneDelegate, 112 | Zone parent, 113 | Object error, 114 | StackTrace stackTrace, 115 | ) { 116 | uncaught = true; 117 | }, 118 | ), 119 | ); 120 | expect(uncaught, false); 121 | }); 122 | 123 | test( 124 | 'Notifies listeners of chunk events', 125 | () async { 126 | final imageAvailable = Completer(); 127 | var url = 'foo'; 128 | var expectedResult = cacheManager.returns(url, kTransparentImage); 129 | 130 | final ImageProvider imageProvider = CachedNetworkImageProvider( 131 | nonconst('foo'), 132 | cacheManager: cacheManager, 133 | ); 134 | final result = imageProvider.resolve(ImageConfiguration.empty); 135 | final events = []; 136 | result.addListener( 137 | ImageStreamListener( 138 | (ImageInfo image, bool synchronousCall) { 139 | imageAvailable.complete(); 140 | }, 141 | onChunk: (ImageChunkEvent event) { 142 | events.add(event); 143 | }, 144 | onError: (Object error, StackTrace? stackTrace) { 145 | imageAvailable.completeError(error, stackTrace); 146 | }, 147 | ), 148 | ); 149 | await imageAvailable.future; 150 | expect(events.length, expectedResult.chunks); 151 | for (var i = 0; i < events.length; i++) { 152 | expect( 153 | events[i].cumulativeBytesLoaded, 154 | math.min( 155 | (i + 1) * expectedResult.chunkSize, 156 | kTransparentImage.length, 157 | ), 158 | ); 159 | expect(events[i].expectedTotalBytes, kTransparentImage.length); 160 | } 161 | }, 162 | skip: isBrowser, 163 | ); // Browser loads images through not Http. 164 | } 165 | 166 | class FakeCodec implements Codec { 167 | @override 168 | void dispose() {} 169 | 170 | @override 171 | int get frameCount => throw UnimplementedError(); 172 | 173 | @override 174 | Future getNextFrame() { 175 | throw UnimplementedError(); 176 | } 177 | 178 | @override 179 | int get repetitionCount => throw UnimplementedError(); 180 | } 181 | -------------------------------------------------------------------------------- /cached_network_image/test/image_widget_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:cached_network_image/cached_network_image.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'fake_cache_manager.dart'; 6 | import 'image_data.dart'; 7 | 8 | void main() { 9 | late FakeCacheManager cacheManager; 10 | 11 | setUp(() { 12 | cacheManager = FakeCacheManager(); 13 | }); 14 | 15 | tearDown(() { 16 | PaintingBinding.instance.imageCache.clear(); 17 | PaintingBinding.instance.imageCache.clearLiveImages(); 18 | }); 19 | 20 | group('test logger', () { 21 | test('set log level', () { 22 | CachedNetworkImage.logLevel = CacheManagerLogLevel.verbose; 23 | expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.verbose); 24 | 25 | CachedNetworkImage.logLevel = CacheManagerLogLevel.debug; 26 | expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.debug); 27 | 28 | CachedNetworkImage.logLevel = CacheManagerLogLevel.warning; 29 | expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.warning); 30 | 31 | CachedNetworkImage.logLevel = CacheManagerLogLevel.none; 32 | expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.none); 33 | }); 34 | }); 35 | 36 | group('widget tests', () { 37 | testWidgets('progress indicator called when success', (tester) async { 38 | var imageUrl = '123'; 39 | // Create the widget by telling the tester to build it. 40 | cacheManager.returns(imageUrl, kTransparentImage); 41 | var progressShown = false; 42 | var thrown = false; 43 | await tester.pumpWidget( 44 | MyImageWidget( 45 | imageUrl: imageUrl, 46 | cacheManager: cacheManager, 47 | onProgress: () => progressShown = true, 48 | onError: () => thrown = true, 49 | ), 50 | ); 51 | await tester.pump(); 52 | expect(thrown, isFalse); 53 | expect(progressShown, isTrue); 54 | }); 55 | 56 | testWidgets('placeholder called when fail', (tester) async { 57 | var imageUrl = '1234'; 58 | // Create the widget by telling the tester to build it. 59 | cacheManager.throwsNotFound(imageUrl); 60 | var placeholderShown = false; 61 | var thrown = false; 62 | await tester.pumpWidget( 63 | MyImageWidget( 64 | imageUrl: imageUrl, 65 | cacheManager: cacheManager, 66 | onPlaceHolder: () => placeholderShown = true, 67 | onError: () => thrown = true, 68 | ), 69 | ); 70 | await tester.pumpAndSettle(); 71 | expect(thrown, isTrue); 72 | expect(placeholderShown, isTrue); 73 | }); 74 | 75 | testWidgets('errorBuilder called when image fails', (tester) async { 76 | var imageUrl = '12345'; 77 | cacheManager.throwsNotFound(imageUrl); 78 | var thrown = false; 79 | await tester.pumpWidget( 80 | MyImageWidget( 81 | imageUrl: imageUrl, 82 | cacheManager: cacheManager, 83 | onError: () => thrown = true, 84 | ), 85 | ); 86 | await tester.pumpAndSettle(); 87 | expect(thrown, isTrue); 88 | }); 89 | 90 | testWidgets("errorBuilder doesn't call when image doesn't fail", 91 | (tester) async { 92 | var imageUrl = '123456'; 93 | // Create the widget by telling the tester to build it. 94 | cacheManager.returns(imageUrl, kTransparentImage); 95 | var thrown = false; 96 | await tester.pumpWidget( 97 | MyImageWidget( 98 | imageUrl: imageUrl, 99 | cacheManager: cacheManager, 100 | onError: () => thrown = true, 101 | ), 102 | ); 103 | await tester.pumpAndSettle(); 104 | expect(thrown, isFalse); 105 | }); 106 | 107 | testWidgets('placeholder called when success', (tester) async { 108 | var imageUrl = '789'; 109 | // Create the widget by telling the tester to build it. 110 | cacheManager.returns(imageUrl, kTransparentImage); 111 | var placeholderShown = false; 112 | var thrown = false; 113 | await tester.pumpWidget( 114 | MyImageWidget( 115 | imageUrl: imageUrl, 116 | cacheManager: cacheManager, 117 | onPlaceHolder: () => placeholderShown = true, 118 | onError: () => thrown = true, 119 | ), 120 | ); 121 | await tester.pumpAndSettle(); 122 | expect(thrown, isFalse); 123 | expect(placeholderShown, isTrue); 124 | }); 125 | 126 | testWidgets('progressIndicator called several times', (tester) async { 127 | var imageUrl = '7891'; 128 | // Create the widget by telling the tester to build it. 129 | var delay = const Duration(milliseconds: 1); 130 | var expectedResult = cacheManager.returns( 131 | imageUrl, 132 | kTransparentImage, 133 | delayBetweenChunks: delay, 134 | ); 135 | var progressIndicatorCalled = 0; 136 | var thrown = false; 137 | await tester.pumpWidget( 138 | MyImageWidget( 139 | imageUrl: imageUrl, 140 | cacheManager: cacheManager, 141 | onProgress: () => progressIndicatorCalled++, 142 | onError: () => thrown = true, 143 | ), 144 | ); 145 | for (var i = 0; i < expectedResult.chunks; i++) { 146 | await tester.pump(delay); 147 | await tester.idle(); 148 | } 149 | expect(thrown, isFalse); 150 | expect(progressIndicatorCalled, expectedResult.chunks + 1); 151 | }); 152 | }); 153 | } 154 | 155 | class MyImageWidget extends StatelessWidget { 156 | final FakeCacheManager cacheManager; 157 | final ProgressIndicatorBuilder? progressBuilder; 158 | final PlaceholderWidgetBuilder? placeholderBuilder; 159 | final LoadingErrorWidgetBuilder? errorBuilder; 160 | final String imageUrl; 161 | 162 | MyImageWidget({ 163 | super.key, 164 | required this.imageUrl, 165 | required this.cacheManager, 166 | VoidCallback? onProgress, 167 | VoidCallback? onPlaceHolder, 168 | VoidCallback? onError, 169 | }) : progressBuilder = getProgress(onProgress), 170 | placeholderBuilder = getPlaceholder(onPlaceHolder), 171 | errorBuilder = getErrorBuilder(onError); 172 | 173 | static ProgressIndicatorBuilder? getProgress(VoidCallback? onProgress) { 174 | if (onProgress == null) return null; 175 | return (context, url, progress) { 176 | onProgress(); 177 | return const CircularProgressIndicator(); 178 | }; 179 | } 180 | 181 | static PlaceholderWidgetBuilder? getPlaceholder(VoidCallback? onPlaceHolder) { 182 | if (onPlaceHolder == null) return null; 183 | return (context, url) { 184 | onPlaceHolder(); 185 | return const Placeholder(); 186 | }; 187 | } 188 | 189 | static LoadingErrorWidgetBuilder? getErrorBuilder(VoidCallback? onError) { 190 | if (onError == null) return null; 191 | return (context, error, stacktrace) { 192 | onError(); 193 | return const Icon(Icons.error); 194 | }; 195 | } 196 | 197 | @override 198 | Widget build(BuildContext context) { 199 | return MaterialApp( 200 | title: 'Flutter Demo', 201 | home: Scaffold( 202 | body: Center( 203 | child: CachedNetworkImage( 204 | imageUrl: imageUrl, 205 | cacheManager: cacheManager, 206 | progressIndicatorBuilder: progressBuilder, 207 | placeholder: placeholderBuilder, 208 | errorWidget: errorBuilder, 209 | ), 210 | ), 211 | ), 212 | ); 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Symbolication related 36 | app.*.symbols 37 | 38 | # Obfuscation related 39 | app.*.map.json 40 | 41 | # Android Studio will place build artifacts here 42 | /android/app/debug 43 | /android/app/profile 44 | /android/app/release 45 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [4.1.1] - 2024-08-13 2 | 3 | * Target js_interop for Wasm support 4 | 5 | ## [4.1.0] - 2024-08-01 6 | 7 | * Update dependencies 8 | * Update SDK version to 3.0.0 9 | 10 | ## [4.0.0] - 2023-12-31 11 | 12 | * Removed errorListener from ImageLoader interface 13 | 14 | ## [3.0.0] - 2023-09-25 15 | 16 | * Add error to ErrorListener 17 | * Specify types 18 | * Remove [`load`](https://github.com/flutter/flutter/pull/132679), use `loadImage` instead `loadBuffer` 19 | 20 | ## [2.0.0] - 2022-08-31 21 | 22 | * Added loadBufferAsync for Flutter 3.3 23 | 24 | ## [1.0.0] - 2021-07-16 25 | 26 | * Initial release 27 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 Rene Floor 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/README.md: -------------------------------------------------------------------------------- 1 | # cached_network_image_platform_interface 2 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/lib/cached_network_image_platform_interface.dart: -------------------------------------------------------------------------------- 1 | /// Platform interface for CachedNetworkImage 2 | library cached_network_image_platform_interface; 3 | 4 | import 'dart:async'; 5 | import 'dart:ui' as ui; 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 9 | 10 | /// Listener for errors 11 | typedef ErrorListener = void Function(Object); 12 | 13 | /// Render options for images on the web platform. 14 | enum ImageRenderMethodForWeb { 15 | /// HtmlImage uses a default web image including default browser caching. 16 | /// This is the recommended and default choice. 17 | HtmlImage, // ignore: constant_identifier_names 18 | 19 | /// HttpGet uses an http client to fetch an image. It enables the use of 20 | /// headers, but loses some default web functionality. 21 | HttpGet, // ignore: constant_identifier_names 22 | } 23 | 24 | /// ImageLoader class to load images differently on various platforms. 25 | class ImageLoader { 26 | /// loads the images async and gives the resulted codecs on a Stream. The 27 | /// Stream gives the option to show multiple images after each other. 28 | @Deprecated('Use loadImageAsync instead') 29 | Stream loadBufferAsync( 30 | String url, 31 | String? cacheKey, 32 | StreamController chunkEvents, 33 | DecoderBufferCallback decode, 34 | BaseCacheManager cacheManager, 35 | int? maxHeight, 36 | int? maxWidth, 37 | Map? headers, 38 | ImageRenderMethodForWeb imageRenderMethodForWeb, 39 | VoidCallback evictImage, 40 | ) { 41 | throw UnimplementedError(); 42 | } 43 | 44 | /// loads the images async and gives the resulted codecs on a Stream. The 45 | /// Stream gives the option to show multiple images after each other. 46 | Stream loadImageAsync( 47 | String url, 48 | String? cacheKey, 49 | StreamController chunkEvents, 50 | ImageDecoderCallback decode, 51 | BaseCacheManager cacheManager, 52 | int? maxHeight, 53 | int? maxWidth, 54 | Map? headers, 55 | ImageRenderMethodForWeb imageRenderMethodForWeb, 56 | VoidCallback evictImage, 57 | ) { 58 | throw UnimplementedError(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cached_network_image_platform_interface 2 | description: Platform interface for CachedNetworkImage 3 | version: 4.1.1 4 | homepage: https://github.com/Baseflow/flutter_cached_network_image 5 | 6 | environment: 7 | sdk: ^3.0.0 8 | flutter: '>=3.10.0' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | flutter_cache_manager: ^3.4.1 14 | 15 | dev_dependencies: 16 | file: '>=7.0.0 <8.0.0' 17 | flutter_lints: ^4.0.0 18 | flutter_test: 19 | sdk: flutter 20 | -------------------------------------------------------------------------------- /cached_network_image_platform_interface/test/cached_network_image_platform_interface_test.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: deprecated_member_use_from_same_package 2 | 3 | import 'dart:async'; 4 | import 'dart:typed_data'; 5 | import 'dart:ui' as ui; 6 | 7 | import 'package:cached_network_image_platform_interface/cached_network_image_platform_interface.dart'; 8 | import 'package:file/file.dart'; 9 | import 'package:file/src/interface/file.dart'; 10 | import 'package:flutter/widgets.dart'; 11 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 12 | import 'package:flutter_test/flutter_test.dart'; 13 | 14 | void main() { 15 | group('ImageLoader', () { 16 | test('Default loadImageAsync throws UnimplementedError', () { 17 | final imageLoader = ImageLoader(); 18 | expect( 19 | () => imageLoader.loadImageAsync( 20 | 'test.com/image', 21 | null, 22 | StreamController(), 23 | decoder, 24 | MockCacheManager(), 25 | null, 26 | null, 27 | null, 28 | ImageRenderMethodForWeb.HttpGet, 29 | () => {}, 30 | ), 31 | throwsA(const TypeMatcher()), 32 | ); 33 | }); 34 | }); 35 | } 36 | 37 | Future decoder( 38 | ui.ImmutableBuffer buffer, { 39 | ui.TargetImageSizeCallback? getTargetSize, 40 | }) { 41 | throw UnimplementedError(); 42 | } 43 | 44 | class MockCacheManager implements BaseCacheManager { 45 | @override 46 | Future dispose() { 47 | throw UnimplementedError(); 48 | } 49 | 50 | @override 51 | Future downloadFile( 52 | String url, { 53 | String? key, 54 | Map? authHeaders, 55 | bool force = false, 56 | }) { 57 | throw UnimplementedError(); 58 | } 59 | 60 | @override 61 | Future emptyCache() { 62 | throw UnimplementedError(); 63 | } 64 | 65 | @override 66 | Stream getFile( 67 | String url, { 68 | String? key, 69 | Map? headers, 70 | }) { 71 | throw UnimplementedError(); 72 | } 73 | 74 | @override 75 | Future getFileFromCache( 76 | String key, { 77 | bool ignoreMemCache = false, 78 | }) { 79 | throw UnimplementedError(); 80 | } 81 | 82 | @override 83 | Future getFileFromMemory(String key) { 84 | throw UnimplementedError(); 85 | } 86 | 87 | @override 88 | Stream getFileStream( 89 | String url, { 90 | String? key, 91 | Map? headers, 92 | bool withProgress = false, 93 | }) { 94 | throw UnimplementedError(); 95 | } 96 | 97 | @override 98 | Future getSingleFile( 99 | String url, { 100 | String? key, 101 | Map? headers, 102 | }) { 103 | throw UnimplementedError(); 104 | } 105 | 106 | @override 107 | Future putFile( 108 | String url, 109 | Uint8List fileBytes, { 110 | String? key, 111 | String? eTag, 112 | Duration maxAge = const Duration(days: 30), 113 | String fileExtension = 'file', 114 | }) { 115 | throw UnimplementedError(); 116 | } 117 | 118 | @override 119 | Future putFileStream( 120 | String url, 121 | Stream> source, { 122 | String? key, 123 | String? eTag, 124 | Duration maxAge = const Duration(days: 30), 125 | String fileExtension = 'file', 126 | }) { 127 | throw UnimplementedError(); 128 | } 129 | 130 | @override 131 | Future removeFile(String key) { 132 | throw UnimplementedError(); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /cached_network_image_web/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | **/pubspec_overrides.yaml 35 | 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Android Studio will place build artifacts here 44 | /android/app/debug 45 | /android/app/profile 46 | /android/app/release 47 | -------------------------------------------------------------------------------- /cached_network_image_web/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## [1.3.1] - 2024-08-13 2 | 3 | * Target js_interop for Wasm support 4 | 5 | ## [1.3.0] - 2024-08-01 6 | 7 | * Update dependencies 8 | * Update SDK version to 3.0.0 9 | 10 | ## [1.2.0] - 2024-04-29 11 | 12 | * Replace deprecated `webOnlyInstantiateImageCodecFromUrl` to `createImageCodecFromUrl` from `dart:ui_web` 13 | 14 | ## [1.1.1] - 2023-12-31 15 | 16 | * Removed errorListener from ImageLoader interface 17 | 18 | ## [1.1.0] - 2023-09-25 19 | 20 | * Add error to ErrorListener 21 | * Specify types 22 | * Update example 23 | * Remove [`load`](https://github.com/flutter/flutter/pull/132679), use `loadImage` instead `loadBuffer` 24 | 25 | ## [1.0.2] - 2022-08-31 26 | 27 | * Added loadBufferAsync and deprecated loadAsync 28 | 29 | ## [1.0.1] - 2021-08-02 30 | 31 | * Bug: fixed CORS issues in HTML image version. 32 | 33 | ## [1.0.0] - 2021-07-16 34 | 35 | * Initial release 36 | -------------------------------------------------------------------------------- /cached_network_image_web/LICENSE: -------------------------------------------------------------------------------- 1 | 2 | The MIT License (MIT) 3 | 4 | Copyright (c) 2018 Rene Floor 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /cached_network_image_web/README.md: -------------------------------------------------------------------------------- 1 | # cached_network_image_web 2 | -------------------------------------------------------------------------------- /cached_network_image_web/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | -------------------------------------------------------------------------------- /cached_network_image_web/lib/cached_network_image_web.dart: -------------------------------------------------------------------------------- 1 | /// Web implementation of CachedNetworkImage 2 | library cached_network_image_web; 3 | 4 | import 'dart:async'; 5 | import 'dart:typed_data'; 6 | import 'dart:ui' as ui; 7 | import 'dart:ui_web'; 8 | 9 | import 'package:cached_network_image_platform_interface' 10 | '/cached_network_image_platform_interface.dart' as platform 11 | show ImageLoader, ImageRenderMethodForWeb; 12 | import 'package:flutter/material.dart'; 13 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 14 | 15 | enum _State { open, waitingForData, closing } 16 | 17 | /// ImageLoader class to load images on the web platform. 18 | class ImageLoader implements platform.ImageLoader { 19 | @Deprecated('Use loadImageAsync instead') 20 | @override 21 | Stream loadBufferAsync( 22 | String url, 23 | String? cacheKey, 24 | StreamController chunkEvents, 25 | DecoderBufferCallback decode, 26 | BaseCacheManager cacheManager, 27 | int? maxHeight, 28 | int? maxWidth, 29 | Map? headers, 30 | platform.ImageRenderMethodForWeb imageRenderMethodForWeb, 31 | VoidCallback evictImage, 32 | ) { 33 | return _load( 34 | url, 35 | cacheKey, 36 | chunkEvents, 37 | (bytes) async { 38 | final buffer = await ui.ImmutableBuffer.fromUint8List(bytes); 39 | return decode(buffer); 40 | }, 41 | cacheManager, 42 | maxHeight, 43 | maxWidth, 44 | headers, 45 | imageRenderMethodForWeb, 46 | evictImage, 47 | ); 48 | } 49 | 50 | @override 51 | Stream loadImageAsync( 52 | String url, 53 | String? cacheKey, 54 | StreamController chunkEvents, 55 | ImageDecoderCallback decode, 56 | BaseCacheManager cacheManager, 57 | int? maxHeight, 58 | int? maxWidth, 59 | Map? headers, 60 | platform.ImageRenderMethodForWeb imageRenderMethodForWeb, 61 | VoidCallback evictImage, 62 | ) { 63 | return _load( 64 | url, 65 | cacheKey, 66 | chunkEvents, 67 | (bytes) async { 68 | final buffer = await ui.ImmutableBuffer.fromUint8List(bytes); 69 | return decode(buffer); 70 | }, 71 | cacheManager, 72 | maxHeight, 73 | maxWidth, 74 | headers, 75 | imageRenderMethodForWeb, 76 | evictImage, 77 | ); 78 | } 79 | 80 | Stream _load( 81 | String url, 82 | String? cacheKey, 83 | StreamController chunkEvents, 84 | _FileDecoderCallback decode, 85 | BaseCacheManager cacheManager, 86 | int? maxHeight, 87 | int? maxWidth, 88 | Map? headers, 89 | platform.ImageRenderMethodForWeb imageRenderMethodForWeb, 90 | VoidCallback evictImage, 91 | ) { 92 | switch (imageRenderMethodForWeb) { 93 | case platform.ImageRenderMethodForWeb.HttpGet: 94 | return _loadAsyncHttpGet( 95 | url, 96 | cacheKey, 97 | chunkEvents, 98 | decode, 99 | cacheManager, 100 | maxHeight, 101 | maxWidth, 102 | headers, 103 | evictImage, 104 | ); 105 | case platform.ImageRenderMethodForWeb.HtmlImage: 106 | return _loadAsyncHtmlImage(url, chunkEvents).asStream(); 107 | } 108 | } 109 | 110 | Stream _loadAsyncHttpGet( 111 | String url, 112 | String? cacheKey, 113 | StreamController chunkEvents, 114 | _FileDecoderCallback decode, 115 | BaseCacheManager cacheManager, 116 | int? maxHeight, 117 | int? maxWidth, 118 | Map? headers, 119 | VoidCallback evictImage, 120 | ) { 121 | var streamController = StreamController(); 122 | 123 | try { 124 | final stream = cacheManager.getFileStream( 125 | url, 126 | withProgress: true, 127 | headers: headers, 128 | key: cacheKey, 129 | ); 130 | 131 | var state = _State.open; 132 | 133 | stream.listen( 134 | (event) { 135 | if (event is DownloadProgress) { 136 | chunkEvents.add( 137 | ImageChunkEvent( 138 | cumulativeBytesLoaded: event.downloaded, 139 | expectedTotalBytes: event.totalSize, 140 | ), 141 | ); 142 | } 143 | if (event is FileInfo) { 144 | if (state == _State.open) { 145 | state = _State.waitingForData; 146 | } 147 | 148 | event.file 149 | .readAsBytes() 150 | .then((value) => decode(value)) 151 | .then((data) { 152 | streamController.add(data); 153 | if (state == _State.closing) { 154 | streamController.close(); 155 | chunkEvents.close(); 156 | } 157 | }); 158 | } 159 | }, 160 | onError: (e, st) { 161 | scheduleMicrotask(() { 162 | evictImage(); 163 | }); 164 | streamController.addError(e, st); 165 | }, 166 | onDone: () async { 167 | if (state == _State.open) { 168 | streamController.close(); 169 | chunkEvents.close(); 170 | } else if (state == _State.waitingForData) { 171 | state = _State.closing; 172 | } 173 | }, 174 | cancelOnError: true, 175 | ); 176 | } on Object catch (e, st) { 177 | scheduleMicrotask(() { 178 | evictImage(); 179 | }); 180 | streamController.addError(e, st); 181 | } 182 | 183 | return streamController.stream; 184 | } 185 | 186 | Future _loadAsyncHtmlImage( 187 | String url, 188 | StreamController chunkEvents, 189 | ) { 190 | final resolved = Uri.base.resolve(url); 191 | // ignore: undefined_function 192 | return createImageCodecFromUrl( 193 | resolved, 194 | chunkCallback: (int bytes, int total) { 195 | chunkEvents.add( 196 | ImageChunkEvent( 197 | cumulativeBytesLoaded: bytes, 198 | expectedTotalBytes: total, 199 | ), 200 | ); 201 | }, 202 | ); 203 | } 204 | } 205 | 206 | typedef _FileDecoderCallback = Future Function(Uint8List); 207 | -------------------------------------------------------------------------------- /cached_network_image_web/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: cached_network_image_web 2 | description: Web implementation of CachedNetworkImage 3 | version: 1.3.1 4 | homepage: https://github.com/Baseflow/flutter_cached_network_image 5 | 6 | environment: 7 | sdk: ^3.0.0 8 | flutter: '>=3.10.0' 9 | 10 | dependencies: 11 | cached_network_image_platform_interface: ^4.1.1 12 | flutter: 13 | sdk: flutter 14 | flutter_cache_manager: ^3.4.1 15 | web: ^1.0.0 16 | 17 | dev_dependencies: 18 | file: '>=7.0.0 <8.0.0' 19 | flutter_lints: ^4.0.0 20 | flutter_test: 21 | sdk: flutter 22 | -------------------------------------------------------------------------------- /cached_network_image_web/test/cached_network_image_web_test.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: deprecated_member_use_from_same_package 2 | 3 | import 'dart:async'; 4 | import 'dart:typed_data'; 5 | import 'dart:ui' as ui; 6 | 7 | import 'package:cached_network_image_platform_interface' 8 | '/cached_network_image_platform_interface.dart' hide ImageLoader; 9 | import 'package:cached_network_image_web/cached_network_image_web.dart'; 10 | import 'package:file/file.dart'; 11 | import 'package:flutter/widgets.dart'; 12 | import 'package:flutter_cache_manager/flutter_cache_manager.dart'; 13 | import 'package:flutter_test/flutter_test.dart'; 14 | 15 | void main() { 16 | test('loadImageAsync returns a stream', () { 17 | final imageLoader = ImageLoader(); 18 | final stream = imageLoader.loadImageAsync( 19 | 'test.com/image', 20 | null, 21 | StreamController(), 22 | decoder, 23 | MockCacheManager(), 24 | null, 25 | null, 26 | null, 27 | ImageRenderMethodForWeb.HttpGet, 28 | () => {}, 29 | ); 30 | expect(stream, isNotNull); 31 | }); 32 | } 33 | 34 | Future decoder( 35 | ui.ImmutableBuffer buffer, { 36 | ui.TargetImageSizeCallback? getTargetSize, 37 | }) { 38 | throw UnimplementedError(); 39 | } 40 | 41 | class MockCacheManager implements BaseCacheManager { 42 | @override 43 | Future dispose() { 44 | throw UnimplementedError(); 45 | } 46 | 47 | @override 48 | Future downloadFile( 49 | String url, { 50 | String? key, 51 | Map? authHeaders, 52 | bool force = false, 53 | }) { 54 | throw UnimplementedError(); 55 | } 56 | 57 | @override 58 | Future emptyCache() { 59 | throw UnimplementedError(); 60 | } 61 | 62 | @override 63 | Stream getFile( 64 | String url, { 65 | String? key, 66 | Map? headers, 67 | }) { 68 | throw UnimplementedError(); 69 | } 70 | 71 | @override 72 | Future getFileFromCache( 73 | String key, { 74 | bool ignoreMemCache = false, 75 | }) { 76 | throw UnimplementedError(); 77 | } 78 | 79 | @override 80 | Future getFileFromMemory(String key) { 81 | throw UnimplementedError(); 82 | } 83 | 84 | @override 85 | Stream getFileStream( 86 | String url, { 87 | String? key, 88 | Map? headers, 89 | bool withProgress = false, 90 | }) { 91 | throw UnimplementedError(); 92 | } 93 | 94 | @override 95 | Future getSingleFile( 96 | String url, { 97 | String? key, 98 | Map? headers, 99 | }) { 100 | throw UnimplementedError(); 101 | } 102 | 103 | @override 104 | Future putFile( 105 | String url, 106 | Uint8List fileBytes, { 107 | String? key, 108 | String? eTag, 109 | Duration maxAge = const Duration(days: 30), 110 | String fileExtension = 'file', 111 | }) { 112 | throw UnimplementedError(); 113 | } 114 | 115 | @override 116 | Future putFileStream( 117 | String url, 118 | Stream> source, { 119 | String? key, 120 | String? eTag, 121 | Duration maxAge = const Duration(days: 30), 122 | String fileExtension = 'file', 123 | }) { 124 | throw UnimplementedError(); 125 | } 126 | 127 | @override 128 | Future removeFile(String key) { 129 | throw UnimplementedError(); 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Baseflow/flutter_cached_network_image/0775e1f41dd6c3d1e1d0744365683390bc11a7d5/icon.png --------------------------------------------------------------------------------