├── .gitignore ├── .metadata ├── README.md ├── amplify ├── .config │ └── project-config.json ├── README.md ├── backend │ ├── auth │ │ └── amplifystorageappca606e91 │ │ │ ├── build │ │ │ ├── amplifystorageappca606e91-cloudformation-template.json │ │ │ └── parameters.json │ │ │ └── cli-inputs.json │ ├── backend-config.json │ ├── storage │ │ └── s3c9f7838f │ │ │ └── cli-inputs.json │ ├── tags.json │ └── types │ │ └── amplify-dependent-resources-ref.d.ts ├── cli.json └── hooks │ └── README.md ├── analysis_options.yaml ├── android ├── .gitignore ├── app │ ├── build.gradle │ └── src │ │ ├── debug │ │ └── AndroidManifest.xml │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── kotlin │ │ │ └── com │ │ │ │ └── example │ │ │ │ └── amplify_storage_app │ │ │ │ └── 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 ├── coverage └── lcov.info ├── ios ├── .gitignore ├── Flutter │ ├── AppFrameworkInfo.plist │ ├── Debug.xcconfig │ └── Release.xcconfig ├── Podfile ├── Podfile.lock ├── 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 ├── lib ├── features │ └── storage_file │ │ ├── controller │ │ └── storage_files_controller.dart │ │ ├── models │ │ ├── storage_file.dart │ │ ├── storage_file.freezed.dart │ │ └── storage_file.g.dart │ │ ├── services │ │ └── storage_service.dart │ │ └── ui │ │ └── storage_files_list │ │ ├── delete_storage_file_dialog.dart │ │ ├── storage_file_tile.dart │ │ ├── storage_files_list_page.dart │ │ └── upload_progress_dialog.dart ├── main.dart ├── storage_gallery_app.dart └── utils.dart ├── pubspec.lock ├── pubspec.yaml └── test └── items_list_page_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 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 | 48 | 49 | amplify/team-provider-info.json 50 | 51 | #amplify-do-not-edit-begin 52 | amplify/\#current-cloud-backend 53 | amplify/.config/local-* 54 | amplify/logs 55 | amplify/mock-data 56 | amplify/backend/amplify-meta.json 57 | amplify/backend/.temp 58 | build/ 59 | dist/ 60 | node_modules/ 61 | aws-exports.js 62 | awsconfiguration.json 63 | amplifyconfiguration.json 64 | amplifyconfiguration.dart 65 | amplify-build-config.json 66 | amplify-gradle-config.json 67 | amplifytools.xcconfig 68 | .secret-* 69 | **.sample 70 | !amplify/backend/auth/*/build 71 | #amplify-do-not-edit-end 72 | -------------------------------------------------------------------------------- /.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. 5 | 6 | version: 7 | revision: f1875d570e39de09040c8f79aa13cc56baab8db1 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: f1875d570e39de09040c8f79aa13cc56baab8db1 17 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 18 | - platform: android 19 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 20 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 21 | - platform: ios 22 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 23 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 24 | - platform: linux 25 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 26 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 27 | - platform: macos 28 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 29 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 30 | - platform: windows 31 | create_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 32 | base_revision: f1875d570e39de09040c8f79aa13cc56baab8db1 33 | 34 | # User provided section 35 | 36 | # List of Local paths (relative to this file) that should be 37 | # ignored by the migrate tool. 38 | # 39 | # Files that are not part of the templates will be ignored by default. 40 | unmanaged_files: 41 | - 'lib/main.dart' 42 | - 'ios/Runner.xcodeproj/project.pbxproj' 43 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Amplify Flutter Storage Gallery App 2 | 3 | [![HitCount](https://hits.dwyl.com/offlineprogrammer/amplify_storage_app.svg?style=flat-square&show=unique)](http://hits.dwyl.com/offlineprogrammer/amplify_storage_app) 4 | 5 | This is a sample app that uses [`Amplify Storage`](https://docs.amplify.aws/lib/storage/getting-started/q/platform/flutter/) to upload images to AWS S3 6 | 7 | 8 | ## Previews 9 | 10 |

11 | 12 |

13 | 14 | 15 | ## Getting Started 16 | * [`Install`](https://docs.amplify.aws/cli/start/install/) and configure Amplify CLI 17 | * A Flutter application targeting Flutter SDK >= 2.10.0 (stable version). 18 | * An iOS configuration targeting at least iOS 11.0 19 | * An Android configuration targeting at least Android API level 21 (Android 5.0) or above 20 | 21 | 22 | ## Running the App 23 | - Clone the application. 24 | 25 | ```bash 26 | git clone https://github.com/offlineprogrammer/amplify_storage_app 27 | ``` 28 | 29 | - Create your amplify environment for this app 30 | 31 | ```bash 32 | amplify init 33 | ``` 34 | 35 | - Install dependencies 36 | 37 | ```bash 38 | flutter pub get 39 | ``` 40 | 41 | - Build all your local backend resources and provision it in the cloud. 42 | 43 | ```bash 44 | amplify push 45 | ``` 46 | 47 | - Run the app and try uploading images. 48 | 49 | 50 | ## App Architecture and Folder Structure 51 | 52 | The code of the app implements clean architecture to separate the app layers with a feature-first approach for folder structure. I used [`Riverpod`](https://riverpod.dev/) for state management and [`Freezed`](https://pub.dev/packages/freezed) for the storage file model 53 | 54 | 55 | #### Folder Structure 56 | 57 | ``` 58 | lib 59 | ├── features 60 | │ ├── storage_file 61 | │ │ ├── controller 62 | │ │ ├── models 63 | │ │ ├── services 64 | │ │ └── ui 65 | │ │ └── storage_file_list 66 | ├── main.dart 67 | ├── storage_gallery_app.dart 68 | └── utils.dart 69 | ``` 70 | 71 | * `main.dart` file has Amplify initialization & configuration code and wraps the root `StorageGalleryApp` with a `ProviderScope` 72 | * `storage_gallery_app.dart` has the root `MaterialApp` wrapped in the Amplify Authenticator to add complete authentication flows to the App. 73 | * The `features/storage_file` folder contains code for displaying/uploading storage file 74 | * `ui/storage_file_list` contain the implementation to display the storage files gallery & the storage upload indicator 75 | * `services` is the app services layer 76 | * `storage_service.dart` is the service & provider to use Amplify Storage for files listing & uploading 77 | * `models` is the storage_file model generated using Freezed 78 | * `controller` is an abstract layer that used by the ui for the buisness logic 79 | -------------------------------------------------------------------------------- /amplify/.config/project-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "projectName": "amplifystorageapp", 3 | "version": "3.1", 4 | "frontend": "flutter", 5 | "flutter": { 6 | "config": { 7 | "ResDir": "./lib/" 8 | } 9 | }, 10 | "providers": [ 11 | "awscloudformation" 12 | ] 13 | } -------------------------------------------------------------------------------- /amplify/README.md: -------------------------------------------------------------------------------- 1 | # Getting Started with Amplify CLI 2 | This directory was generated by [Amplify CLI](https://docs.amplify.aws/cli). 3 | 4 | Helpful resources: 5 | - Amplify documentation: https://docs.amplify.aws 6 | - Amplify CLI documentation: https://docs.amplify.aws/cli 7 | - More details on this folder & generated files: https://docs.amplify.aws/cli/reference/files 8 | - Join Amplify's community: https://amplify.aws/community/ 9 | -------------------------------------------------------------------------------- /amplify/backend/auth/amplifystorageappca606e91/build/amplifystorageappca606e91-cloudformation-template.json: -------------------------------------------------------------------------------- 1 | { 2 | "Description": "{\"createdOn\":\"Mac\",\"createdBy\":\"Amplify\",\"createdWith\":\"8.2.0\",\"stackType\":\"auth-Cognito\",\"metadata\":{}}", 3 | "AWSTemplateFormatVersion": "2010-09-09", 4 | "Parameters": { 5 | "env": { 6 | "Type": "String" 7 | }, 8 | "identityPoolName": { 9 | "Type": "String" 10 | }, 11 | "allowUnauthenticatedIdentities": { 12 | "Type": "String" 13 | }, 14 | "resourceNameTruncated": { 15 | "Type": "String" 16 | }, 17 | "userPoolName": { 18 | "Type": "String" 19 | }, 20 | "autoVerifiedAttributes": { 21 | "Type": "CommaDelimitedList" 22 | }, 23 | "mfaConfiguration": { 24 | "Type": "String" 25 | }, 26 | "mfaTypes": { 27 | "Type": "CommaDelimitedList" 28 | }, 29 | "smsAuthenticationMessage": { 30 | "Type": "String" 31 | }, 32 | "smsVerificationMessage": { 33 | "Type": "String" 34 | }, 35 | "emailVerificationSubject": { 36 | "Type": "String" 37 | }, 38 | "emailVerificationMessage": { 39 | "Type": "String" 40 | }, 41 | "defaultPasswordPolicy": { 42 | "Type": "String" 43 | }, 44 | "passwordPolicyMinLength": { 45 | "Type": "String" 46 | }, 47 | "passwordPolicyCharacters": { 48 | "Type": "CommaDelimitedList" 49 | }, 50 | "requiredAttributes": { 51 | "Type": "CommaDelimitedList" 52 | }, 53 | "aliasAttributes": { 54 | "Type": "CommaDelimitedList" 55 | }, 56 | "userpoolClientGenerateSecret": { 57 | "Type": "String" 58 | }, 59 | "userpoolClientRefreshTokenValidity": { 60 | "Type": "String" 61 | }, 62 | "userpoolClientWriteAttributes": { 63 | "Type": "CommaDelimitedList" 64 | }, 65 | "userpoolClientReadAttributes": { 66 | "Type": "CommaDelimitedList" 67 | }, 68 | "userpoolClientLambdaRole": { 69 | "Type": "String" 70 | }, 71 | "userpoolClientSetAttributes": { 72 | "Type": "String" 73 | }, 74 | "sharedId": { 75 | "Type": "String" 76 | }, 77 | "resourceName": { 78 | "Type": "String" 79 | }, 80 | "authSelections": { 81 | "Type": "String" 82 | }, 83 | "useDefault": { 84 | "Type": "String" 85 | }, 86 | "usernameAttributes": { 87 | "Type": "CommaDelimitedList" 88 | }, 89 | "userPoolGroupList": { 90 | "Type": "CommaDelimitedList" 91 | }, 92 | "serviceName": { 93 | "Type": "String" 94 | }, 95 | "useEnabledMfas": { 96 | "Type": "String" 97 | }, 98 | "authRoleArn": { 99 | "Type": "String" 100 | }, 101 | "unauthRoleArn": { 102 | "Type": "String" 103 | }, 104 | "breakCircularDependency": { 105 | "Type": "String" 106 | }, 107 | "dependsOn": { 108 | "Type": "CommaDelimitedList" 109 | } 110 | }, 111 | "Conditions": { 112 | "ShouldNotCreateEnvResources": { 113 | "Fn::Equals": [ 114 | { 115 | "Ref": "env" 116 | }, 117 | "NONE" 118 | ] 119 | }, 120 | "ShouldOutputAppClientSecrets": { 121 | "Fn::Equals": [ 122 | { 123 | "Ref": "userpoolClientGenerateSecret" 124 | }, 125 | true 126 | ] 127 | } 128 | }, 129 | "Resources": { 130 | "SNSRole": { 131 | "Type": "AWS::IAM::Role", 132 | "Properties": { 133 | "AssumeRolePolicyDocument": { 134 | "Version": "2012-10-17", 135 | "Statement": [ 136 | { 137 | "Sid": "", 138 | "Effect": "Allow", 139 | "Principal": { 140 | "Service": "cognito-idp.amazonaws.com" 141 | }, 142 | "Action": [ 143 | "sts:AssumeRole" 144 | ], 145 | "Condition": { 146 | "StringEquals": { 147 | "sts:ExternalId": "amplifca606e91_role_external_id" 148 | } 149 | } 150 | } 151 | ] 152 | }, 153 | "Policies": [ 154 | { 155 | "PolicyDocument": { 156 | "Version": "2012-10-17", 157 | "Statement": [ 158 | { 159 | "Effect": "Allow", 160 | "Action": [ 161 | "sns:Publish" 162 | ], 163 | "Resource": "*" 164 | } 165 | ] 166 | }, 167 | "PolicyName": "amplifca606e91-sns-policy" 168 | } 169 | ], 170 | "RoleName": { 171 | "Fn::If": [ 172 | "ShouldNotCreateEnvResources", 173 | "amplifca606e91_sns-role", 174 | { 175 | "Fn::Join": [ 176 | "", 177 | [ 178 | "snsca606e91", 179 | { 180 | "Fn::Select": [ 181 | 3, 182 | { 183 | "Fn::Split": [ 184 | "-", 185 | { 186 | "Ref": "AWS::StackName" 187 | } 188 | ] 189 | } 190 | ] 191 | }, 192 | "-", 193 | { 194 | "Ref": "env" 195 | } 196 | ] 197 | ] 198 | } 199 | ] 200 | } 201 | } 202 | }, 203 | "UserPool": { 204 | "Type": "AWS::Cognito::UserPool", 205 | "Properties": { 206 | "AutoVerifiedAttributes": [ 207 | "email" 208 | ], 209 | "EmailVerificationMessage": { 210 | "Ref": "emailVerificationMessage" 211 | }, 212 | "EmailVerificationSubject": { 213 | "Ref": "emailVerificationSubject" 214 | }, 215 | "MfaConfiguration": { 216 | "Ref": "mfaConfiguration" 217 | }, 218 | "Policies": { 219 | "PasswordPolicy": { 220 | "MinimumLength": { 221 | "Ref": "passwordPolicyMinLength" 222 | }, 223 | "RequireLowercase": false, 224 | "RequireNumbers": false, 225 | "RequireSymbols": false, 226 | "RequireUppercase": false 227 | } 228 | }, 229 | "Schema": [ 230 | { 231 | "Mutable": true, 232 | "Name": "email", 233 | "Required": true 234 | } 235 | ], 236 | "SmsAuthenticationMessage": { 237 | "Ref": "smsAuthenticationMessage" 238 | }, 239 | "SmsConfiguration": { 240 | "ExternalId": "amplifca606e91_role_external_id", 241 | "SnsCallerArn": { 242 | "Fn::GetAtt": [ 243 | "SNSRole", 244 | "Arn" 245 | ] 246 | } 247 | }, 248 | "SmsVerificationMessage": { 249 | "Ref": "smsVerificationMessage" 250 | }, 251 | "UsernameAttributes": { 252 | "Ref": "usernameAttributes" 253 | }, 254 | "UserPoolName": { 255 | "Fn::If": [ 256 | "ShouldNotCreateEnvResources", 257 | { 258 | "Ref": "userPoolName" 259 | }, 260 | { 261 | "Fn::Join": [ 262 | "", 263 | [ 264 | { 265 | "Ref": "userPoolName" 266 | }, 267 | "-", 268 | { 269 | "Ref": "env" 270 | } 271 | ] 272 | ] 273 | } 274 | ] 275 | } 276 | } 277 | }, 278 | "UserPoolClientWeb": { 279 | "Type": "AWS::Cognito::UserPoolClient", 280 | "Properties": { 281 | "UserPoolId": { 282 | "Ref": "UserPool" 283 | }, 284 | "ClientName": "amplifca606e91_app_clientWeb", 285 | "RefreshTokenValidity": { 286 | "Ref": "userpoolClientRefreshTokenValidity" 287 | } 288 | }, 289 | "DependsOn": [ 290 | "UserPool" 291 | ] 292 | }, 293 | "UserPoolClient": { 294 | "Type": "AWS::Cognito::UserPoolClient", 295 | "Properties": { 296 | "UserPoolId": { 297 | "Ref": "UserPool" 298 | }, 299 | "ClientName": "amplifca606e91_app_client", 300 | "GenerateSecret": { 301 | "Ref": "userpoolClientGenerateSecret" 302 | }, 303 | "RefreshTokenValidity": { 304 | "Ref": "userpoolClientRefreshTokenValidity" 305 | } 306 | }, 307 | "DependsOn": [ 308 | "UserPool" 309 | ] 310 | }, 311 | "UserPoolClientRole": { 312 | "Type": "AWS::IAM::Role", 313 | "Properties": { 314 | "AssumeRolePolicyDocument": { 315 | "Version": "2012-10-17", 316 | "Statement": [ 317 | { 318 | "Effect": "Allow", 319 | "Principal": { 320 | "Service": "lambda.amazonaws.com" 321 | }, 322 | "Action": "sts:AssumeRole" 323 | } 324 | ] 325 | }, 326 | "RoleName": { 327 | "Fn::If": [ 328 | "ShouldNotCreateEnvResources", 329 | { 330 | "Ref": "userpoolClientLambdaRole" 331 | }, 332 | { 333 | "Fn::Join": [ 334 | "", 335 | [ 336 | "upClientLambdaRoleca606e91", 337 | { 338 | "Fn::Select": [ 339 | 3, 340 | { 341 | "Fn::Split": [ 342 | "-", 343 | { 344 | "Ref": "AWS::StackName" 345 | } 346 | ] 347 | } 348 | ] 349 | }, 350 | "-", 351 | { 352 | "Ref": "env" 353 | } 354 | ] 355 | ] 356 | } 357 | ] 358 | } 359 | }, 360 | "DependsOn": [ 361 | "UserPoolClient" 362 | ] 363 | }, 364 | "UserPoolClientLambda": { 365 | "Type": "AWS::Lambda::Function", 366 | "Properties": { 367 | "Code": { 368 | "ZipFile": "const response = require('cfn-response');\nconst aws = require('aws-sdk');\nconst identity = new aws.CognitoIdentityServiceProvider();\nexports.handler = (event, context, callback) => {\n if (event.RequestType == 'Delete') {\n response.send(event, context, response.SUCCESS, {});\n }\n if (event.RequestType == 'Update' || event.RequestType == 'Create') {\n const params = {\n ClientId: event.ResourceProperties.clientId,\n UserPoolId: event.ResourceProperties.userpoolId,\n };\n identity\n .describeUserPoolClient(params)\n .promise()\n .then(res => {\n response.send(event, context, response.SUCCESS, { appSecret: res.UserPoolClient.ClientSecret });\n })\n .catch(err => {\n response.send(event, context, response.FAILED, { err });\n });\n }\n};\n" 369 | }, 370 | "Role": { 371 | "Fn::GetAtt": [ 372 | "UserPoolClientRole", 373 | "Arn" 374 | ] 375 | }, 376 | "Handler": "index.handler", 377 | "Runtime": "nodejs14.x", 378 | "Timeout": 300 379 | }, 380 | "DependsOn": [ 381 | "UserPoolClientRole" 382 | ] 383 | }, 384 | "UserPoolClientLambdaPolicy": { 385 | "Type": "AWS::IAM::Policy", 386 | "Properties": { 387 | "PolicyDocument": { 388 | "Version": "2012-10-17", 389 | "Statement": [ 390 | { 391 | "Effect": "Allow", 392 | "Action": [ 393 | "cognito-idp:DescribeUserPoolClient" 394 | ], 395 | "Resource": { 396 | "Fn::GetAtt": [ 397 | "UserPool", 398 | "Arn" 399 | ] 400 | } 401 | } 402 | ] 403 | }, 404 | "PolicyName": "amplifca606e91_userpoolclient_lambda_iam_policy", 405 | "Roles": [ 406 | { 407 | "Ref": "UserPoolClientRole" 408 | } 409 | ] 410 | }, 411 | "DependsOn": [ 412 | "UserPoolClientLambda" 413 | ] 414 | }, 415 | "UserPoolClientLogPolicy": { 416 | "Type": "AWS::IAM::Policy", 417 | "Properties": { 418 | "PolicyDocument": { 419 | "Version": "2012-10-17", 420 | "Statement": [ 421 | { 422 | "Effect": "Allow", 423 | "Action": [ 424 | "logs:CreateLogGroup", 425 | "logs:CreateLogStream", 426 | "logs:PutLogEvents" 427 | ], 428 | "Resource": { 429 | "Fn::Sub": [ 430 | "arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*", 431 | { 432 | "region": { 433 | "Ref": "AWS::Region" 434 | }, 435 | "account": { 436 | "Ref": "AWS::AccountId" 437 | }, 438 | "lambda": { 439 | "Ref": "UserPoolClientLambda" 440 | } 441 | } 442 | ] 443 | } 444 | } 445 | ] 446 | }, 447 | "PolicyName": "amplifca606e91_userpoolclient_lambda_log_policy", 448 | "Roles": [ 449 | { 450 | "Ref": "UserPoolClientRole" 451 | } 452 | ] 453 | }, 454 | "DependsOn": [ 455 | "UserPoolClientLambdaPolicy" 456 | ] 457 | }, 458 | "UserPoolClientInputs": { 459 | "Type": "Custom::LambdaCallout", 460 | "Properties": { 461 | "ServiceToken": { 462 | "Fn::GetAtt": [ 463 | "UserPoolClientLambda", 464 | "Arn" 465 | ] 466 | }, 467 | "clientId": { 468 | "Ref": "UserPoolClient" 469 | }, 470 | "userpoolId": { 471 | "Ref": "UserPool" 472 | } 473 | }, 474 | "DependsOn": [ 475 | "UserPoolClientLogPolicy" 476 | ], 477 | "UpdateReplacePolicy": "Delete", 478 | "DeletionPolicy": "Delete" 479 | }, 480 | "IdentityPool": { 481 | "Type": "AWS::Cognito::IdentityPool", 482 | "Properties": { 483 | "AllowUnauthenticatedIdentities": { 484 | "Ref": "allowUnauthenticatedIdentities" 485 | }, 486 | "CognitoIdentityProviders": [ 487 | { 488 | "ClientId": { 489 | "Ref": "UserPoolClient" 490 | }, 491 | "ProviderName": { 492 | "Fn::Sub": [ 493 | "cognito-idp.${region}.amazonaws.com/${client}", 494 | { 495 | "region": { 496 | "Ref": "AWS::Region" 497 | }, 498 | "client": { 499 | "Ref": "UserPool" 500 | } 501 | } 502 | ] 503 | } 504 | }, 505 | { 506 | "ClientId": { 507 | "Ref": "UserPoolClientWeb" 508 | }, 509 | "ProviderName": { 510 | "Fn::Sub": [ 511 | "cognito-idp.${region}.amazonaws.com/${client}", 512 | { 513 | "region": { 514 | "Ref": "AWS::Region" 515 | }, 516 | "client": { 517 | "Ref": "UserPool" 518 | } 519 | } 520 | ] 521 | } 522 | } 523 | ], 524 | "IdentityPoolName": { 525 | "Fn::If": [ 526 | "ShouldNotCreateEnvResources", 527 | "amplifystorageappca606e91_identitypool_ca606e91", 528 | { 529 | "Fn::Join": [ 530 | "", 531 | [ 532 | "amplifystorageappca606e91_identitypool_ca606e91__", 533 | { 534 | "Ref": "env" 535 | } 536 | ] 537 | ] 538 | } 539 | ] 540 | } 541 | }, 542 | "DependsOn": [ 543 | "UserPoolClientInputs" 544 | ] 545 | }, 546 | "IdentityPoolRoleMap": { 547 | "Type": "AWS::Cognito::IdentityPoolRoleAttachment", 548 | "Properties": { 549 | "IdentityPoolId": { 550 | "Ref": "IdentityPool" 551 | }, 552 | "Roles": { 553 | "unauthenticated": { 554 | "Ref": "unauthRoleArn" 555 | }, 556 | "authenticated": { 557 | "Ref": "authRoleArn" 558 | } 559 | } 560 | }, 561 | "DependsOn": [ 562 | "IdentityPool" 563 | ] 564 | } 565 | }, 566 | "Outputs": { 567 | "IdentityPoolId": { 568 | "Description": "Id for the identity pool", 569 | "Value": { 570 | "Ref": "IdentityPool" 571 | } 572 | }, 573 | "IdentityPoolName": { 574 | "Value": { 575 | "Fn::GetAtt": [ 576 | "IdentityPool", 577 | "Name" 578 | ] 579 | } 580 | }, 581 | "UserPoolId": { 582 | "Description": "Id for the user pool", 583 | "Value": { 584 | "Ref": "UserPool" 585 | } 586 | }, 587 | "UserPoolArn": { 588 | "Description": "Arn for the user pool", 589 | "Value": { 590 | "Fn::GetAtt": [ 591 | "UserPool", 592 | "Arn" 593 | ] 594 | } 595 | }, 596 | "UserPoolName": { 597 | "Value": { 598 | "Ref": "userPoolName" 599 | } 600 | }, 601 | "AppClientIDWeb": { 602 | "Description": "The user pool app client id for web", 603 | "Value": { 604 | "Ref": "UserPoolClientWeb" 605 | } 606 | }, 607 | "AppClientID": { 608 | "Description": "The user pool app client id", 609 | "Value": { 610 | "Ref": "UserPoolClient" 611 | } 612 | }, 613 | "AppClientSecret": { 614 | "Value": { 615 | "Fn::GetAtt": [ 616 | "UserPoolClientInputs", 617 | "appSecret" 618 | ] 619 | }, 620 | "Condition": "ShouldOutputAppClientSecrets" 621 | }, 622 | "CreatedSNSRole": { 623 | "Description": "role arn", 624 | "Value": { 625 | "Fn::GetAtt": [ 626 | "SNSRole", 627 | "Arn" 628 | ] 629 | } 630 | } 631 | } 632 | } -------------------------------------------------------------------------------- /amplify/backend/auth/amplifystorageappca606e91/build/parameters.json: -------------------------------------------------------------------------------- 1 | { 2 | "identityPoolName": "amplifystorageappca606e91_identitypool_ca606e91", 3 | "allowUnauthenticatedIdentities": true, 4 | "resourceNameTruncated": "amplifca606e91", 5 | "userPoolName": "amplifystorageappca606e91_userpool_ca606e91", 6 | "autoVerifiedAttributes": [ 7 | "email" 8 | ], 9 | "mfaConfiguration": "OFF", 10 | "mfaTypes": [ 11 | "SMS Text Message" 12 | ], 13 | "smsAuthenticationMessage": "Your authentication code is {####}", 14 | "smsVerificationMessage": "Your verification code is {####}", 15 | "emailVerificationSubject": "Your verification code", 16 | "emailVerificationMessage": "Your verification code is {####}", 17 | "defaultPasswordPolicy": false, 18 | "passwordPolicyMinLength": 8, 19 | "passwordPolicyCharacters": [], 20 | "requiredAttributes": [ 21 | "email" 22 | ], 23 | "aliasAttributes": [], 24 | "userpoolClientGenerateSecret": false, 25 | "userpoolClientRefreshTokenValidity": 30, 26 | "userpoolClientWriteAttributes": [ 27 | "email" 28 | ], 29 | "userpoolClientReadAttributes": [ 30 | "email" 31 | ], 32 | "userpoolClientLambdaRole": "amplifca606e91_userpoolclient_lambda_role", 33 | "userpoolClientSetAttributes": false, 34 | "sharedId": "ca606e91", 35 | "resourceName": "amplifystorageappca606e91", 36 | "authSelections": "identityPoolAndUserPool", 37 | "useDefault": "default", 38 | "usernameAttributes": [ 39 | "email" 40 | ], 41 | "userPoolGroupList": [], 42 | "serviceName": "Cognito", 43 | "useEnabledMfas": false, 44 | "authRoleArn": { 45 | "Fn::GetAtt": [ 46 | "AuthRole", 47 | "Arn" 48 | ] 49 | }, 50 | "unauthRoleArn": { 51 | "Fn::GetAtt": [ 52 | "UnauthRole", 53 | "Arn" 54 | ] 55 | }, 56 | "breakCircularDependency": false, 57 | "dependsOn": [] 58 | } -------------------------------------------------------------------------------- /amplify/backend/auth/amplifystorageappca606e91/cli-inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "1", 3 | "cognitoConfig": { 4 | "identityPoolName": "amplifystorageappca606e91_identitypool_ca606e91", 5 | "allowUnauthenticatedIdentities": true, 6 | "resourceNameTruncated": "amplifca606e91", 7 | "userPoolName": "amplifystorageappca606e91_userpool_ca606e91", 8 | "autoVerifiedAttributes": [ 9 | "email" 10 | ], 11 | "mfaConfiguration": "OFF", 12 | "mfaTypes": [ 13 | "SMS Text Message" 14 | ], 15 | "smsAuthenticationMessage": "Your authentication code is {####}", 16 | "smsVerificationMessage": "Your verification code is {####}", 17 | "emailVerificationSubject": "Your verification code", 18 | "emailVerificationMessage": "Your verification code is {####}", 19 | "defaultPasswordPolicy": false, 20 | "passwordPolicyMinLength": 8, 21 | "passwordPolicyCharacters": [], 22 | "requiredAttributes": [ 23 | "email" 24 | ], 25 | "aliasAttributes": [], 26 | "userpoolClientGenerateSecret": false, 27 | "userpoolClientRefreshTokenValidity": 30, 28 | "userpoolClientWriteAttributes": [ 29 | "email" 30 | ], 31 | "userpoolClientReadAttributes": [ 32 | "email" 33 | ], 34 | "userpoolClientLambdaRole": "amplifca606e91_userpoolclient_lambda_role", 35 | "userpoolClientSetAttributes": false, 36 | "sharedId": "ca606e91", 37 | "resourceName": "amplifystorageappca606e91", 38 | "authSelections": "identityPoolAndUserPool", 39 | "useDefault": "default", 40 | "usernameAttributes": [ 41 | "email" 42 | ], 43 | "userPoolGroupList": [], 44 | "serviceName": "Cognito", 45 | "useEnabledMfas": false, 46 | "authRoleArn": { 47 | "Fn::GetAtt": [ 48 | "AuthRole", 49 | "Arn" 50 | ] 51 | }, 52 | "unauthRoleArn": { 53 | "Fn::GetAtt": [ 54 | "UnauthRole", 55 | "Arn" 56 | ] 57 | }, 58 | "breakCircularDependency": false, 59 | "dependsOn": [] 60 | } 61 | } -------------------------------------------------------------------------------- /amplify/backend/backend-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth": { 3 | "amplifystorageappca606e91": { 4 | "service": "Cognito", 5 | "providerPlugin": "awscloudformation", 6 | "dependsOn": [], 7 | "customAuth": false, 8 | "frontendAuthConfig": { 9 | "socialProviders": [], 10 | "usernameAttributes": [ 11 | "EMAIL" 12 | ], 13 | "signupAttributes": [ 14 | "EMAIL" 15 | ], 16 | "passwordProtectionSettings": { 17 | "passwordPolicyMinLength": 8, 18 | "passwordPolicyCharacters": [] 19 | }, 20 | "mfaConfiguration": "OFF", 21 | "mfaTypes": [ 22 | "SMS" 23 | ], 24 | "verificationMechanisms": [ 25 | "EMAIL" 26 | ] 27 | } 28 | } 29 | }, 30 | "storage": { 31 | "s3c9f7838f": { 32 | "service": "S3", 33 | "providerPlugin": "awscloudformation", 34 | "dependsOn": [] 35 | } 36 | } 37 | } -------------------------------------------------------------------------------- /amplify/backend/storage/s3c9f7838f/cli-inputs.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceName": "s3c9f7838f", 3 | "policyUUID": "c9f7838f", 4 | "bucketName": "amplifystorageapp", 5 | "storageAccess": "authAndGuest", 6 | "guestAccess": [ 7 | "READ" 8 | ], 9 | "authAccess": [ 10 | "CREATE_AND_UPDATE", 11 | "READ", 12 | "DELETE" 13 | ], 14 | "triggerFunction": "NONE", 15 | "groupAccess": {} 16 | } -------------------------------------------------------------------------------- /amplify/backend/tags.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "Key": "user:Stack", 4 | "Value": "{project-env}" 5 | }, 6 | { 7 | "Key": "user:Application", 8 | "Value": "{project-name}" 9 | } 10 | ] -------------------------------------------------------------------------------- /amplify/backend/types/amplify-dependent-resources-ref.d.ts: -------------------------------------------------------------------------------- 1 | export type AmplifyDependentResourcesAttributes = { 2 | "auth": { 3 | "amplifystorageappca606e91": { 4 | "IdentityPoolId": "string", 5 | "IdentityPoolName": "string", 6 | "UserPoolId": "string", 7 | "UserPoolArn": "string", 8 | "UserPoolName": "string", 9 | "AppClientIDWeb": "string", 10 | "AppClientID": "string", 11 | "CreatedSNSRole": "string" 12 | } 13 | }, 14 | "storage": { 15 | "s3c9f7838f": { 16 | "BucketName": "string", 17 | "Region": "string" 18 | } 19 | } 20 | } -------------------------------------------------------------------------------- /amplify/cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "features": { 3 | "graphqltransformer": { 4 | "addmissingownerfields": false, 5 | "improvepluralization": false, 6 | "validatetypenamereservedwords": true, 7 | "useexperimentalpipelinedtransformer": false, 8 | "enableiterativegsiupdates": false, 9 | "secondarykeyasgsi": false, 10 | "skipoverridemutationinputtypes": false, 11 | "transformerversion": 1, 12 | "suppressschemamigrationprompt": true, 13 | "securityenhancementnotification": true, 14 | "showfieldauthnotification": false, 15 | "usesubusernamefordefaultidentityclaim": false, 16 | "securityEnhancementNotification": false 17 | }, 18 | "frontend-ios": { 19 | "enablexcodeintegration": false 20 | }, 21 | "auth": { 22 | "enablecaseinsensitivity": false, 23 | "useinclusiveterminology": false, 24 | "breakcirculardependency": false, 25 | "forcealiasattributes": false, 26 | "useenabledmfas": false 27 | }, 28 | "codegen": { 29 | "useappsyncmodelgenplugin": false, 30 | "usedocsgeneratorplugin": false, 31 | "usetypesgeneratorplugin": false, 32 | "cleangeneratedmodelsdirectory": false, 33 | "retaincasestyle": false, 34 | "addtimestampfields": false, 35 | "handlelistnullabilitytransparently": false, 36 | "emitauthprovider": false, 37 | "generateindexrules": false, 38 | "enabledartnullsafety": false 39 | }, 40 | "appsync": { 41 | "generategraphqlpermissions": false 42 | }, 43 | "latestregionsupport": { 44 | "pinpoint": 0, 45 | "translate": 0, 46 | "transcribe": 0, 47 | "rekognition": 0, 48 | "textract": 0, 49 | "comprehend": 0 50 | }, 51 | "project": { 52 | "overrides": true 53 | } 54 | } 55 | } -------------------------------------------------------------------------------- /amplify/hooks/README.md: -------------------------------------------------------------------------------- 1 | # Command Hooks 2 | 3 | Command hooks can be used to run custom scripts upon Amplify CLI lifecycle events like pre-push, post-add-function, etc. 4 | 5 | To get started, add your script files based on the expected naming convention in this directory. 6 | 7 | Learn more about the script file naming convention, hook parameters, third party dependencies, and advanced configurations at https://docs.amplify.aws/cli/usage/command-hooks 8 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the analyzer, which statically analyzes Dart code to 2 | # check for errors, warnings, and lints. 3 | # 4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled 5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be 6 | # invoked from the command line by running `flutter analyze`. 7 | 8 | # The following line activates a set of recommended lints for Flutter apps, 9 | # packages, and plugins designed to encourage good coding practices. 10 | include: package:flutter_lints/flutter.yaml 11 | 12 | analyzer: 13 | # strong-mode: 14 | # implicit-dynamic: false 15 | exclude: 16 | - lib/models/** 17 | - '**/*.g.dart' 18 | - '**/*.freezed.dart' -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | ndkVersion flutter.ndkVersion 31 | 32 | compileOptions { 33 | sourceCompatibility JavaVersion.VERSION_1_8 34 | targetCompatibility JavaVersion.VERSION_1_8 35 | } 36 | 37 | kotlinOptions { 38 | jvmTarget = '1.8' 39 | } 40 | 41 | sourceSets { 42 | main.java.srcDirs += 'src/main/kotlin' 43 | } 44 | 45 | defaultConfig { 46 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 47 | applicationId "com.example.amplify_storage_app" 48 | // You can update the following values to match your application needs. 49 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 50 | minSdkVersion flutter.minSdkVersion 51 | targetSdkVersion flutter.targetSdkVersion 52 | versionCode flutterVersionCode.toInteger() 53 | versionName flutterVersionName 54 | } 55 | 56 | buildTypes { 57 | release { 58 | // TODO: Add your own signing config for the release build. 59 | // Signing with the debug keys for now, so `flutter run --release` works. 60 | signingConfig signingConfigs.debug 61 | } 62 | } 63 | } 64 | 65 | flutter { 66 | source '../..' 67 | } 68 | 69 | dependencies { 70 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 71 | } 72 | -------------------------------------------------------------------------------- /android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 30 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /android/app/src/main/kotlin/com/example/amplify_storage_app/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.example.amplify_storage_app 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.6.10' 3 | repositories { 4 | google() 5 | mavenCentral() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.1.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | mavenCentral() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 7 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /coverage/lcov.info: -------------------------------------------------------------------------------- 1 | SF:lib/features/storage_item/controller/storage_items_controller.dart 2 | DA:7,0 3 | DA:8,0 4 | DA:11,2 5 | DA:12,1 6 | DA:13,0 7 | DA:14,0 8 | DA:20,0 9 | DA:22,0 10 | DA:23,0 11 | DA:25,0 12 | DA:29,0 13 | DA:30,0 14 | DA:33,0 15 | DA:34,0 16 | DA:36,0 17 | LF:15 18 | LH:2 19 | end_of_record 20 | SF:lib/features/storage_item/ui/items_list/items_list_page.dart 21 | DA:12,1 22 | DA:16,0 23 | DA:20,0 24 | DA:21,0 25 | DA:26,0 26 | DA:27,0 27 | DA:30,0 28 | DA:33,0 29 | DA:36,1 30 | DA:38,2 31 | DA:40,1 32 | DA:41,1 33 | DA:44,1 34 | DA:45,0 35 | DA:46,0 36 | DA:49,0 37 | DA:50,0 38 | DA:52,0 39 | DA:58,1 40 | DA:59,2 41 | DA:63,1 42 | DA:64,1 43 | DA:65,1 44 | DA:66,1 45 | DA:74,1 46 | DA:75,2 47 | DA:76,1 48 | DA:82,1 49 | DA:85,0 50 | LF:29 51 | LH:16 52 | end_of_record 53 | SF:lib/features/storage_item/services/storage_service.dart 54 | DA:13,0 55 | DA:14,0 56 | DA:17,0 57 | DA:18,0 58 | DA:19,0 59 | DA:20,0 60 | DA:22,0 61 | DA:23,0 62 | DA:28,0 63 | DA:29,0 64 | DA:34,0 65 | DA:35,0 66 | DA:37,0 67 | DA:39,0 68 | DA:42,0 69 | DA:43,0 70 | DA:46,0 71 | DA:48,0 72 | DA:49,0 73 | DA:50,0 74 | DA:53,0 75 | DA:54,0 76 | DA:60,0 77 | DA:61,0 78 | DA:66,0 79 | DA:67,0 80 | DA:71,0 81 | DA:72,0 82 | LF:28 83 | LH:0 84 | end_of_record 85 | SF:lib/features/storage_item/ui/items_list/storage_item_tile.dart 86 | DA:5,1 87 | DA:12,1 88 | DA:14,1 89 | DA:16,2 90 | DA:17,1 91 | DA:18,1 92 | DA:19,2 93 | DA:20,2 94 | LF:8 95 | LH:8 96 | end_of_record 97 | SF:lib/features/storage_item/ui/items_list/upload_progress_dialog.dart 98 | DA:7,1 99 | DA:9,0 100 | DA:11,0 101 | DA:14,0 102 | DA:16,0 103 | DA:18,0 104 | DA:19,0 105 | DA:20,0 106 | DA:22,0 107 | DA:27,0 108 | DA:28,0 109 | DA:31,0 110 | DA:32,0 111 | LF:13 112 | LH:1 113 | end_of_record 114 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | platform :ios, '13.5' 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 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Amplify (1.25.0): 3 | - Amplify/Default (= 1.25.0) 4 | - Amplify/Default (1.25.0) 5 | - amplify_auth_cognito_ios (0.0.1): 6 | - Amplify (= 1.25.0) 7 | - amplify_core 8 | - AmplifyPlugins/AWSCognitoAuthPlugin (= 1.25.0) 9 | - Flutter 10 | - ObjectMapper 11 | - amplify_core (0.0.1): 12 | - Flutter 13 | - SwiftFormat/CLI 14 | - SwiftLint 15 | - amplify_flutter_ios (0.0.1): 16 | - Amplify (= 1.25.0) 17 | - amplify_core 18 | - AmplifyPlugins/AWSCognitoAuthPlugin (= 1.25.0) 19 | - AWSPluginsCore (= 1.25.0) 20 | - Flutter 21 | - SwiftFormat/CLI 22 | - SwiftLint 23 | - amplify_storage_s3_ios (0.0.1): 24 | - Amplify (= 1.25.0) 25 | - amplify_core 26 | - AmplifyPlugins/AWSS3StoragePlugin (= 1.25.0) 27 | - Flutter 28 | - AmplifyPlugins/AWSCognitoAuthPlugin (1.25.0): 29 | - AWSAuthCore (~> 2.27.0) 30 | - AWSCognitoIdentityProvider (~> 2.27.0) 31 | - AWSCognitoIdentityProviderASF (~> 2.27.0) 32 | - AWSCore (~> 2.27.0) 33 | - AWSMobileClient (~> 2.27.0) 34 | - AWSPluginsCore (= 1.25.0) 35 | - AmplifyPlugins/AWSS3StoragePlugin (1.25.0): 36 | - AWSCore (~> 2.27.0) 37 | - AWSPluginsCore (= 1.25.0) 38 | - AWSS3 (~> 2.27.0) 39 | - AWSAuthCore (2.27.13): 40 | - AWSCore (= 2.27.13) 41 | - AWSCognitoIdentityProvider (2.27.13): 42 | - AWSCognitoIdentityProviderASF (= 2.27.13) 43 | - AWSCore (= 2.27.13) 44 | - AWSCognitoIdentityProviderASF (2.27.13): 45 | - AWSCore (= 2.27.13) 46 | - AWSCore (2.27.13) 47 | - AWSMobileClient (2.27.13): 48 | - AWSAuthCore (= 2.27.13) 49 | - AWSCognitoIdentityProvider (= 2.27.13) 50 | - AWSCognitoIdentityProviderASF (= 2.27.13) 51 | - AWSCore (= 2.27.13) 52 | - AWSPluginsCore (1.25.0): 53 | - Amplify (= 1.25.0) 54 | - AWSCore (~> 2.27.0) 55 | - AWSS3 (2.27.13): 56 | - AWSCore (= 2.27.13) 57 | - DKImagePickerController/Core (4.3.4): 58 | - DKImagePickerController/ImageDataManager 59 | - DKImagePickerController/Resource 60 | - DKImagePickerController/ImageDataManager (4.3.4) 61 | - DKImagePickerController/PhotoGallery (4.3.4): 62 | - DKImagePickerController/Core 63 | - DKPhotoGallery 64 | - DKImagePickerController/Resource (4.3.4) 65 | - DKPhotoGallery (0.0.17): 66 | - DKPhotoGallery/Core (= 0.0.17) 67 | - DKPhotoGallery/Model (= 0.0.17) 68 | - DKPhotoGallery/Preview (= 0.0.17) 69 | - DKPhotoGallery/Resource (= 0.0.17) 70 | - SDWebImage 71 | - SwiftyGif 72 | - DKPhotoGallery/Core (0.0.17): 73 | - DKPhotoGallery/Model 74 | - DKPhotoGallery/Preview 75 | - SDWebImage 76 | - SwiftyGif 77 | - DKPhotoGallery/Model (0.0.17): 78 | - SDWebImage 79 | - SwiftyGif 80 | - DKPhotoGallery/Preview (0.0.17): 81 | - DKPhotoGallery/Model 82 | - DKPhotoGallery/Resource 83 | - SDWebImage 84 | - SwiftyGif 85 | - DKPhotoGallery/Resource (0.0.17): 86 | - SDWebImage 87 | - SwiftyGif 88 | - file_picker (0.0.1): 89 | - DKImagePickerController/PhotoGallery 90 | - Flutter 91 | - Flutter (1.0.0) 92 | - FMDB (2.7.5): 93 | - FMDB/standard (= 2.7.5) 94 | - FMDB/standard (2.7.5) 95 | - image_picker_ios (0.0.1): 96 | - Flutter 97 | - ObjectMapper (4.2.0) 98 | - path_provider_ios (0.0.1): 99 | - Flutter 100 | - SDWebImage (5.13.2): 101 | - SDWebImage/Core (= 5.13.2) 102 | - SDWebImage/Core (5.13.2) 103 | - sqflite (0.0.2): 104 | - Flutter 105 | - FMDB (>= 2.7.5) 106 | - SwiftFormat/CLI (0.49.14) 107 | - SwiftLint (0.48.0) 108 | - SwiftyGif (5.4.3) 109 | 110 | DEPENDENCIES: 111 | - amplify_auth_cognito_ios (from `.symlinks/plugins/amplify_auth_cognito_ios/ios`) 112 | - amplify_core (from `.symlinks/plugins/amplify_core/ios`) 113 | - amplify_flutter_ios (from `.symlinks/plugins/amplify_flutter_ios/ios`) 114 | - amplify_storage_s3_ios (from `.symlinks/plugins/amplify_storage_s3_ios/ios`) 115 | - file_picker (from `.symlinks/plugins/file_picker/ios`) 116 | - Flutter (from `Flutter`) 117 | - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`) 118 | - path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) 119 | - sqflite (from `.symlinks/plugins/sqflite/ios`) 120 | 121 | SPEC REPOS: 122 | trunk: 123 | - Amplify 124 | - AmplifyPlugins 125 | - AWSAuthCore 126 | - AWSCognitoIdentityProvider 127 | - AWSCognitoIdentityProviderASF 128 | - AWSCore 129 | - AWSMobileClient 130 | - AWSPluginsCore 131 | - AWSS3 132 | - DKImagePickerController 133 | - DKPhotoGallery 134 | - FMDB 135 | - ObjectMapper 136 | - SDWebImage 137 | - SwiftFormat 138 | - SwiftLint 139 | - SwiftyGif 140 | 141 | EXTERNAL SOURCES: 142 | amplify_auth_cognito_ios: 143 | :path: ".symlinks/plugins/amplify_auth_cognito_ios/ios" 144 | amplify_core: 145 | :path: ".symlinks/plugins/amplify_core/ios" 146 | amplify_flutter_ios: 147 | :path: ".symlinks/plugins/amplify_flutter_ios/ios" 148 | amplify_storage_s3_ios: 149 | :path: ".symlinks/plugins/amplify_storage_s3_ios/ios" 150 | file_picker: 151 | :path: ".symlinks/plugins/file_picker/ios" 152 | Flutter: 153 | :path: Flutter 154 | image_picker_ios: 155 | :path: ".symlinks/plugins/image_picker_ios/ios" 156 | path_provider_ios: 157 | :path: ".symlinks/plugins/path_provider_ios/ios" 158 | sqflite: 159 | :path: ".symlinks/plugins/sqflite/ios" 160 | 161 | SPEC CHECKSUMS: 162 | Amplify: 4e1839747f51c5f28f95ce36ef6d356f032b42b7 163 | amplify_auth_cognito_ios: 8a014f5d5e085265e13a270dc03fbe0818bb1f54 164 | amplify_core: e67fe0c53845db08aced670bfc7370b1329d2798 165 | amplify_flutter_ios: 59c43b6b6ff6ccfc59e18eef279d9d6b8fef8cca 166 | amplify_storage_s3_ios: 958f4989117718621340d7405d792b957adcf764 167 | AmplifyPlugins: 110388250aeaf45eaf3008991616be84b2c605f7 168 | AWSAuthCore: 9898614783bd6375742b58a1df38c6a8b8276eda 169 | AWSCognitoIdentityProvider: c105df15533a029230c325acd2be60ff45e8f3f9 170 | AWSCognitoIdentityProviderASF: e0f40ef2f5c2c357b77553144e8f41a6c0b0b81b 171 | AWSCore: 05edadb5f3d0b92a50ea8c66b06f1a10477878da 172 | AWSMobileClient: a49361347ff5c0cff946b3f777936c0fdf9c190d 173 | AWSPluginsCore: c29c4b91c4ecd7376b85288615bb482f409a0b73 174 | AWSS3: 0ce6101e04b1c8a72eec165155e2f1da43d7229b 175 | DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac 176 | DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 177 | file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 178 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 179 | FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a 180 | image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb 181 | ObjectMapper: 1eb41f610210777375fa806bf161dc39fb832b81 182 | path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02 183 | SDWebImage: 72f86271a6f3139cc7e4a89220946489d4b9a866 184 | sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 185 | SwiftFormat: 09cc5eb67ae49356c4ad9a2be6a0d5a4212b61bb 186 | SwiftLint: 284cea64b6187c5d6bd83e9a548a64104d546447 187 | SwiftyGif: 6c3eafd0ce693cad58bb63d2b2fb9bacb8552780 188 | 189 | PODFILE CHECKSUM: a843a48598f7673f7f2af9f25c841666a29f3416 190 | 191 | COCOAPODS: 1.11.3 192 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 390C93D5AE0606AB340058B0 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E5BCF71839C9F439E675E5CB /* Pods_Runner.framework */; }; 12 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 13 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 14 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 15 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 16 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0CE8B2A560D28491A4BEA1EB /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 5AB10DC220937EC1958A1412 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 38 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 39 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 42 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 43 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | B7CEF3CD2A3D6EDAB9506497 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 49 | E5BCF71839C9F439E675E5CB /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | 390C93D5AE0606AB340058B0 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 7C94A46FC354D45B9FA0DE68 /* Pods */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | 5AB10DC220937EC1958A1412 /* Pods-Runner.debug.xcconfig */, 68 | B7CEF3CD2A3D6EDAB9506497 /* Pods-Runner.release.xcconfig */, 69 | 0CE8B2A560D28491A4BEA1EB /* Pods-Runner.profile.xcconfig */, 70 | ); 71 | name = Pods; 72 | path = Pods; 73 | sourceTree = ""; 74 | }; 75 | 9740EEB11CF90186004384FC /* Flutter */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 79 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 80 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 81 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 82 | ); 83 | name = Flutter; 84 | sourceTree = ""; 85 | }; 86 | 97C146E51CF9000F007C117D = { 87 | isa = PBXGroup; 88 | children = ( 89 | 9740EEB11CF90186004384FC /* Flutter */, 90 | 97C146F01CF9000F007C117D /* Runner */, 91 | 97C146EF1CF9000F007C117D /* Products */, 92 | 7C94A46FC354D45B9FA0DE68 /* Pods */, 93 | E212A94E0F7B93D0AE33FAC1 /* Frameworks */, 94 | ); 95 | sourceTree = ""; 96 | }; 97 | 97C146EF1CF9000F007C117D /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 97C146EE1CF9000F007C117D /* Runner.app */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 97C146F01CF9000F007C117D /* Runner */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 109 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 110 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 111 | 97C147021CF9000F007C117D /* Info.plist */, 112 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 113 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 114 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 115 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 116 | ); 117 | path = Runner; 118 | sourceTree = ""; 119 | }; 120 | E212A94E0F7B93D0AE33FAC1 /* Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | E5BCF71839C9F439E675E5CB /* Pods_Runner.framework */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 97C146ED1CF9000F007C117D /* Runner */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 134 | buildPhases = ( 135 | 7DFCEB58321C389748B69B26 /* [CP] Check Pods Manifest.lock */, 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | 2E2993960E2C454D05BA124F /* [CP] Embed Pods Frameworks */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = Runner; 149 | productName = Runner; 150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 97C146E61CF9000F007C117D /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1300; 160 | ORGANIZATIONNAME = ""; 161 | TargetAttributes = { 162 | 97C146ED1CF9000F007C117D = { 163 | CreatedOnToolsVersion = 7.3.1; 164 | LastSwiftMigration = 1100; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 169 | compatibilityVersion = "Xcode 9.3"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 97C146E51CF9000F007C117D; 177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 97C146ED1CF9000F007C117D /* Runner */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 97C146EC1CF9000F007C117D /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 2E2993960E2C454D05BA124F /* [CP] Embed Pods Frameworks */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputFileListPaths = ( 207 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 208 | ); 209 | name = "[CP] Embed Pods Frameworks"; 210 | outputFileListPaths = ( 211 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | shellPath = /bin/sh; 215 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 216 | showEnvVarsInLog = 0; 217 | }; 218 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 219 | isa = PBXShellScriptBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | ); 223 | inputPaths = ( 224 | ); 225 | name = "Thin Binary"; 226 | outputPaths = ( 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | shellPath = /bin/sh; 230 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 231 | }; 232 | 7DFCEB58321C389748B69B26 /* [CP] Check Pods Manifest.lock */ = { 233 | isa = PBXShellScriptBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | ); 237 | inputFileListPaths = ( 238 | ); 239 | inputPaths = ( 240 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 241 | "${PODS_ROOT}/Manifest.lock", 242 | ); 243 | name = "[CP] Check Pods Manifest.lock"; 244 | outputFileListPaths = ( 245 | ); 246 | outputPaths = ( 247 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | shellPath = /bin/sh; 251 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 252 | showEnvVarsInLog = 0; 253 | }; 254 | 9740EEB61CF901F6004384FC /* Run Script */ = { 255 | isa = PBXShellScriptBuildPhase; 256 | buildActionMask = 2147483647; 257 | files = ( 258 | ); 259 | inputPaths = ( 260 | ); 261 | name = "Run Script"; 262 | outputPaths = ( 263 | ); 264 | runOnlyForDeploymentPostprocessing = 0; 265 | shellPath = /bin/sh; 266 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 267 | }; 268 | /* End PBXShellScriptBuildPhase section */ 269 | 270 | /* Begin PBXSourcesBuildPhase section */ 271 | 97C146EA1CF9000F007C117D /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 276 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXSourcesBuildPhase section */ 281 | 282 | /* Begin PBXVariantGroup section */ 283 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 284 | isa = PBXVariantGroup; 285 | children = ( 286 | 97C146FB1CF9000F007C117D /* Base */, 287 | ); 288 | name = Main.storyboard; 289 | sourceTree = ""; 290 | }; 291 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 292 | isa = PBXVariantGroup; 293 | children = ( 294 | 97C147001CF9000F007C117D /* Base */, 295 | ); 296 | name = LaunchScreen.storyboard; 297 | sourceTree = ""; 298 | }; 299 | /* End PBXVariantGroup section */ 300 | 301 | /* Begin XCBuildConfiguration section */ 302 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_NO_COMMON_BLOCKS = YES; 337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 339 | GCC_WARN_UNDECLARED_SELECTOR = YES; 340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 341 | GCC_WARN_UNUSED_FUNCTION = YES; 342 | GCC_WARN_UNUSED_VARIABLE = YES; 343 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 344 | MTL_ENABLE_DEBUG_INFO = NO; 345 | SDKROOT = iphoneos; 346 | SUPPORTED_PLATFORMS = iphoneos; 347 | TARGETED_DEVICE_FAMILY = "1,2"; 348 | VALIDATE_PRODUCT = YES; 349 | }; 350 | name = Profile; 351 | }; 352 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 353 | isa = XCBuildConfiguration; 354 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | CLANG_ENABLE_MODULES = YES; 358 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 359 | ENABLE_BITCODE = NO; 360 | INFOPLIST_FILE = Runner/Info.plist; 361 | LD_RUNPATH_SEARCH_PATHS = ( 362 | "$(inherited)", 363 | "@executable_path/Frameworks", 364 | ); 365 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyStorageApp; 366 | PRODUCT_NAME = "$(TARGET_NAME)"; 367 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 368 | SWIFT_VERSION = 5.0; 369 | VERSIONING_SYSTEM = "apple-generic"; 370 | }; 371 | name = Profile; 372 | }; 373 | 97C147031CF9000F007C117D /* Debug */ = { 374 | isa = XCBuildConfiguration; 375 | buildSettings = { 376 | ALWAYS_SEARCH_USER_PATHS = NO; 377 | CLANG_ANALYZER_NONNULL = YES; 378 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 379 | CLANG_CXX_LIBRARY = "libc++"; 380 | CLANG_ENABLE_MODULES = YES; 381 | CLANG_ENABLE_OBJC_ARC = YES; 382 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 383 | CLANG_WARN_BOOL_CONVERSION = YES; 384 | CLANG_WARN_COMMA = YES; 385 | CLANG_WARN_CONSTANT_CONVERSION = YES; 386 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 387 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 388 | CLANG_WARN_EMPTY_BODY = YES; 389 | CLANG_WARN_ENUM_CONVERSION = YES; 390 | CLANG_WARN_INFINITE_RECURSION = YES; 391 | CLANG_WARN_INT_CONVERSION = YES; 392 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 393 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 394 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 395 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 396 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 397 | CLANG_WARN_STRICT_PROTOTYPES = YES; 398 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 399 | CLANG_WARN_UNREACHABLE_CODE = YES; 400 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 401 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 402 | COPY_PHASE_STRIP = NO; 403 | DEBUG_INFORMATION_FORMAT = dwarf; 404 | ENABLE_STRICT_OBJC_MSGSEND = YES; 405 | ENABLE_TESTABILITY = YES; 406 | GCC_C_LANGUAGE_STANDARD = gnu99; 407 | GCC_DYNAMIC_NO_PIC = NO; 408 | GCC_NO_COMMON_BLOCKS = YES; 409 | GCC_OPTIMIZATION_LEVEL = 0; 410 | GCC_PREPROCESSOR_DEFINITIONS = ( 411 | "DEBUG=1", 412 | "$(inherited)", 413 | ); 414 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 415 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 416 | GCC_WARN_UNDECLARED_SELECTOR = YES; 417 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 418 | GCC_WARN_UNUSED_FUNCTION = YES; 419 | GCC_WARN_UNUSED_VARIABLE = YES; 420 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 421 | MTL_ENABLE_DEBUG_INFO = YES; 422 | ONLY_ACTIVE_ARCH = YES; 423 | SDKROOT = iphoneos; 424 | TARGETED_DEVICE_FAMILY = "1,2"; 425 | }; 426 | name = Debug; 427 | }; 428 | 97C147041CF9000F007C117D /* Release */ = { 429 | isa = XCBuildConfiguration; 430 | buildSettings = { 431 | ALWAYS_SEARCH_USER_PATHS = NO; 432 | CLANG_ANALYZER_NONNULL = YES; 433 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 434 | CLANG_CXX_LIBRARY = "libc++"; 435 | CLANG_ENABLE_MODULES = YES; 436 | CLANG_ENABLE_OBJC_ARC = YES; 437 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_COMMA = YES; 440 | CLANG_WARN_CONSTANT_CONVERSION = YES; 441 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 442 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 443 | CLANG_WARN_EMPTY_BODY = YES; 444 | CLANG_WARN_ENUM_CONVERSION = YES; 445 | CLANG_WARN_INFINITE_RECURSION = YES; 446 | CLANG_WARN_INT_CONVERSION = YES; 447 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 448 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 449 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 450 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 451 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 452 | CLANG_WARN_STRICT_PROTOTYPES = YES; 453 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 454 | CLANG_WARN_UNREACHABLE_CODE = YES; 455 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 456 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 457 | COPY_PHASE_STRIP = NO; 458 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 459 | ENABLE_NS_ASSERTIONS = NO; 460 | ENABLE_STRICT_OBJC_MSGSEND = YES; 461 | GCC_C_LANGUAGE_STANDARD = gnu99; 462 | GCC_NO_COMMON_BLOCKS = YES; 463 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 464 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 465 | GCC_WARN_UNDECLARED_SELECTOR = YES; 466 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 467 | GCC_WARN_UNUSED_FUNCTION = YES; 468 | GCC_WARN_UNUSED_VARIABLE = YES; 469 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 470 | MTL_ENABLE_DEBUG_INFO = NO; 471 | SDKROOT = iphoneos; 472 | SUPPORTED_PLATFORMS = iphoneos; 473 | SWIFT_COMPILATION_MODE = wholemodule; 474 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 475 | TARGETED_DEVICE_FAMILY = "1,2"; 476 | VALIDATE_PRODUCT = YES; 477 | }; 478 | name = Release; 479 | }; 480 | 97C147061CF9000F007C117D /* Debug */ = { 481 | isa = XCBuildConfiguration; 482 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 483 | buildSettings = { 484 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 485 | CLANG_ENABLE_MODULES = YES; 486 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 487 | ENABLE_BITCODE = NO; 488 | INFOPLIST_FILE = Runner/Info.plist; 489 | LD_RUNPATH_SEARCH_PATHS = ( 490 | "$(inherited)", 491 | "@executable_path/Frameworks", 492 | ); 493 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyStorageApp; 494 | PRODUCT_NAME = "$(TARGET_NAME)"; 495 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 497 | SWIFT_VERSION = 5.0; 498 | VERSIONING_SYSTEM = "apple-generic"; 499 | }; 500 | name = Debug; 501 | }; 502 | 97C147071CF9000F007C117D /* Release */ = { 503 | isa = XCBuildConfiguration; 504 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 505 | buildSettings = { 506 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 507 | CLANG_ENABLE_MODULES = YES; 508 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 509 | ENABLE_BITCODE = NO; 510 | INFOPLIST_FILE = Runner/Info.plist; 511 | LD_RUNPATH_SEARCH_PATHS = ( 512 | "$(inherited)", 513 | "@executable_path/Frameworks", 514 | ); 515 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyStorageApp; 516 | PRODUCT_NAME = "$(TARGET_NAME)"; 517 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 518 | SWIFT_VERSION = 5.0; 519 | VERSIONING_SYSTEM = "apple-generic"; 520 | }; 521 | name = Release; 522 | }; 523 | /* End XCBuildConfiguration section */ 524 | 525 | /* Begin XCConfigurationList section */ 526 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 527 | isa = XCConfigurationList; 528 | buildConfigurations = ( 529 | 97C147031CF9000F007C117D /* Debug */, 530 | 97C147041CF9000F007C117D /* Release */, 531 | 249021D3217E4FDB00AE95B9 /* Profile */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | defaultConfigurationName = Release; 535 | }; 536 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 537 | isa = XCConfigurationList; 538 | buildConfigurations = ( 539 | 97C147061CF9000F007C117D /* Debug */, 540 | 97C147071CF9000F007C117D /* Release */, 541 | 249021D4217E4FDB00AE95B9 /* Profile */, 542 | ); 543 | defaultConfigurationIsVisible = 0; 544 | defaultConfigurationName = Release; 545 | }; 546 | /* End XCConfigurationList section */ 547 | }; 548 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 549 | } 550 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/offlineprogrammer/amplify_storage_app/745ff9589add1d1a34339040beb0df9e34c22456/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /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. -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Amplify Storage App 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | amplify_storage_app 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 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | NSCameraUsageDescription 49 | Some Description 50 | NSMicrophoneUsageDescription 51 | Some Description 52 | NSPhotoLibraryUsageDescription 53 | Some Description 54 | 55 | 56 | -------------------------------------------------------------------------------- /ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/features/storage_file/controller/storage_files_controller.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:amplify_storage_app/features/storage_file/models/storage_file.dart'; 4 | import 'package:amplify_storage_app/features/storage_file/services/storage_service.dart'; 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 7 | 8 | final storageFilesControllerProvider = Provider((ref) { 9 | return StorageFilesController(ref: ref); 10 | }); 11 | 12 | final storageFilesListFutureProvider = FutureProvider>((ref) { 13 | final storageFilesController = ref.watch(storageFilesControllerProvider); 14 | return storageFilesController.getStorageFiles(); 15 | }); 16 | 17 | class StorageFilesController { 18 | StorageFilesController({ 19 | required Ref ref, 20 | }) : service = ref.read(storageServiceProvider); 21 | 22 | final StorageService service; 23 | 24 | Future uploadFile(File file) async { 25 | final fileKey = await service.uploadFile(file); 26 | if (fileKey != null) { 27 | service.resetUploadProgress(); 28 | } 29 | } 30 | 31 | Future deleteFile(String fileKey) => service.deleteFile(fileKey); 32 | 33 | ValueNotifier uploadProgress() => service.getUploadProgress(); 34 | 35 | Future> getStorageFiles() => service.getStorageFiles(); 36 | } 37 | -------------------------------------------------------------------------------- /lib/features/storage_file/models/storage_file.dart: -------------------------------------------------------------------------------- 1 | import 'package:freezed_annotation/freezed_annotation.dart'; 2 | 3 | part 'storage_file.freezed.dart'; 4 | part 'storage_file.g.dart'; 5 | 6 | @Freezed() 7 | class StorageFile with _$StorageFile { 8 | const factory StorageFile({ 9 | required String key, 10 | required String url, 11 | }) = _StorageFile; 12 | 13 | factory StorageFile.fromJson(Map json) => 14 | _$StorageFileFromJson(json); 15 | } 16 | -------------------------------------------------------------------------------- /lib/features/storage_file/models/storage_file.freezed.dart: -------------------------------------------------------------------------------- 1 | // coverage:ignore-file 2 | // GENERATED CODE - DO NOT MODIFY BY HAND 3 | // ignore_for_file: type=lint 4 | // ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target 5 | 6 | part of 'storage_file.dart'; 7 | 8 | // ************************************************************************** 9 | // FreezedGenerator 10 | // ************************************************************************** 11 | 12 | T _$identity(T value) => value; 13 | 14 | final _privateConstructorUsedError = UnsupportedError( 15 | 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods'); 16 | 17 | StorageFile _$StorageFileFromJson(Map json) { 18 | return _StorageFile.fromJson(json); 19 | } 20 | 21 | /// @nodoc 22 | mixin _$StorageFile { 23 | String get key => throw _privateConstructorUsedError; 24 | String get url => throw _privateConstructorUsedError; 25 | 26 | Map toJson() => throw _privateConstructorUsedError; 27 | @JsonKey(ignore: true) 28 | $StorageFileCopyWith get copyWith => 29 | throw _privateConstructorUsedError; 30 | } 31 | 32 | /// @nodoc 33 | abstract class $StorageFileCopyWith<$Res> { 34 | factory $StorageFileCopyWith( 35 | StorageFile value, $Res Function(StorageFile) then) = 36 | _$StorageFileCopyWithImpl<$Res>; 37 | $Res call({String key, String url}); 38 | } 39 | 40 | /// @nodoc 41 | class _$StorageFileCopyWithImpl<$Res> implements $StorageFileCopyWith<$Res> { 42 | _$StorageFileCopyWithImpl(this._value, this._then); 43 | 44 | final StorageFile _value; 45 | // ignore: unused_field 46 | final $Res Function(StorageFile) _then; 47 | 48 | @override 49 | $Res call({ 50 | Object? key = freezed, 51 | Object? url = freezed, 52 | }) { 53 | return _then(_value.copyWith( 54 | key: key == freezed 55 | ? _value.key 56 | : key // ignore: cast_nullable_to_non_nullable 57 | as String, 58 | url: url == freezed 59 | ? _value.url 60 | : url // ignore: cast_nullable_to_non_nullable 61 | as String, 62 | )); 63 | } 64 | } 65 | 66 | /// @nodoc 67 | abstract class _$$_StorageFileCopyWith<$Res> 68 | implements $StorageFileCopyWith<$Res> { 69 | factory _$$_StorageFileCopyWith( 70 | _$_StorageFile value, $Res Function(_$_StorageFile) then) = 71 | __$$_StorageFileCopyWithImpl<$Res>; 72 | @override 73 | $Res call({String key, String url}); 74 | } 75 | 76 | /// @nodoc 77 | class __$$_StorageFileCopyWithImpl<$Res> extends _$StorageFileCopyWithImpl<$Res> 78 | implements _$$_StorageFileCopyWith<$Res> { 79 | __$$_StorageFileCopyWithImpl( 80 | _$_StorageFile _value, $Res Function(_$_StorageFile) _then) 81 | : super(_value, (v) => _then(v as _$_StorageFile)); 82 | 83 | @override 84 | _$_StorageFile get _value => super._value as _$_StorageFile; 85 | 86 | @override 87 | $Res call({ 88 | Object? key = freezed, 89 | Object? url = freezed, 90 | }) { 91 | return _then(_$_StorageFile( 92 | key: key == freezed 93 | ? _value.key 94 | : key // ignore: cast_nullable_to_non_nullable 95 | as String, 96 | url: url == freezed 97 | ? _value.url 98 | : url // ignore: cast_nullable_to_non_nullable 99 | as String, 100 | )); 101 | } 102 | } 103 | 104 | /// @nodoc 105 | @JsonSerializable() 106 | class _$_StorageFile implements _StorageFile { 107 | const _$_StorageFile({required this.key, required this.url}); 108 | 109 | factory _$_StorageFile.fromJson(Map json) => 110 | _$$_StorageFileFromJson(json); 111 | 112 | @override 113 | final String key; 114 | @override 115 | final String url; 116 | 117 | @override 118 | String toString() { 119 | return 'StorageFile(key: $key, url: $url)'; 120 | } 121 | 122 | @override 123 | bool operator ==(dynamic other) { 124 | return identical(this, other) || 125 | (other.runtimeType == runtimeType && 126 | other is _$_StorageFile && 127 | const DeepCollectionEquality().equals(other.key, key) && 128 | const DeepCollectionEquality().equals(other.url, url)); 129 | } 130 | 131 | @JsonKey(ignore: true) 132 | @override 133 | int get hashCode => Object.hash( 134 | runtimeType, 135 | const DeepCollectionEquality().hash(key), 136 | const DeepCollectionEquality().hash(url)); 137 | 138 | @JsonKey(ignore: true) 139 | @override 140 | _$$_StorageFileCopyWith<_$_StorageFile> get copyWith => 141 | __$$_StorageFileCopyWithImpl<_$_StorageFile>(this, _$identity); 142 | 143 | @override 144 | Map toJson() { 145 | return _$$_StorageFileToJson( 146 | this, 147 | ); 148 | } 149 | } 150 | 151 | abstract class _StorageFile implements StorageFile { 152 | const factory _StorageFile( 153 | {required final String key, required final String url}) = _$_StorageFile; 154 | 155 | factory _StorageFile.fromJson(Map json) = 156 | _$_StorageFile.fromJson; 157 | 158 | @override 159 | String get key; 160 | @override 161 | String get url; 162 | @override 163 | @JsonKey(ignore: true) 164 | _$$_StorageFileCopyWith<_$_StorageFile> get copyWith => 165 | throw _privateConstructorUsedError; 166 | } 167 | -------------------------------------------------------------------------------- /lib/features/storage_file/models/storage_file.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'storage_file.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | _$_StorageFile _$$_StorageFileFromJson(Map json) => 10 | _$_StorageFile( 11 | key: json['key'] as String, 12 | url: json['url'] as String, 13 | ); 14 | 15 | Map _$$_StorageFileToJson(_$_StorageFile instance) => 16 | { 17 | 'key': instance.key, 18 | 'url': instance.url, 19 | }; 20 | -------------------------------------------------------------------------------- /lib/features/storage_file/services/storage_service.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_storage_app/features/storage_file/models/storage_file.dart'; 2 | import 'package:amplify_storage_app/utils.dart'; 3 | import 'package:amplify_storage_s3/amplify_storage_s3.dart'; 4 | import 'package:amplify_flutter/amplify_flutter.dart'; 5 | import 'package:flutter/foundation.dart' show ValueNotifier; 6 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 7 | 8 | import 'dart:io'; 9 | import 'package:uuid/uuid.dart'; 10 | import 'package:path/path.dart' as p; 11 | 12 | final storageServiceProvider = Provider((ref) { 13 | return StorageService(); 14 | }); 15 | 16 | class StorageService { 17 | ValueNotifier uploadProgress = ValueNotifier(0); 18 | 19 | Future> getStorageFiles() async { 20 | List storageItemsList = []; 21 | 22 | try { 23 | final ListResult result = await Amplify.Storage.list(); 24 | final List storageItems = result.items; 25 | 26 | if (storageItems.isNotEmpty) { 27 | storageItems.sort((a, b) => b.lastModified!.compareTo(a.lastModified!)); 28 | 29 | await Future.forEach(storageItems, (file) async { 30 | final String fileUrl = await getImageUrl(file.key); 31 | 32 | storageItemsList.add(StorageFile(key: file.key, url: fileUrl)); 33 | }); 34 | } 35 | } on Exception catch (e) { 36 | logger.e(e); 37 | } 38 | return storageItemsList; 39 | } 40 | 41 | Future getImageUrl(String key) async { 42 | final GetUrlResult result = await Amplify.Storage.getUrl( 43 | key: key, 44 | options: S3GetUrlOptions(expires: 60000), 45 | ); 46 | return result.url; 47 | } 48 | 49 | Future deleteFile(String key) async { 50 | try { 51 | await Amplify.Storage.remove(key: key); 52 | } on Exception catch (e) { 53 | logger.e(e); 54 | } 55 | } 56 | 57 | ValueNotifier getUploadProgress() => uploadProgress; 58 | 59 | Future uploadFile(File file) async { 60 | try { 61 | final extension = p.extension(file.path); 62 | final key = const Uuid().v1() + extension; 63 | await Amplify.Storage.uploadFile( 64 | local: file, 65 | key: key, 66 | onProgress: (progress) { 67 | uploadProgress.value = 68 | (progress.getFractionCompleted() * 100).toInt(); 69 | }, 70 | ); 71 | 72 | return key; 73 | } on Exception catch (e) { 74 | logger.e(e); 75 | return null; 76 | } 77 | } 78 | 79 | void resetUploadProgress() { 80 | uploadProgress.value = 0; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lib/features/storage_file/ui/storage_files_list/delete_storage_file_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | class DeleteStorageFileDialog extends StatelessWidget { 4 | const DeleteStorageFileDialog({ 5 | super.key, 6 | }); 7 | 8 | @override 9 | Widget build(BuildContext context) { 10 | return AlertDialog( 11 | title: const Text('Please Confirm'), 12 | content: const Text('Delete this file?'), 13 | actions: [ 14 | TextButton( 15 | onPressed: () async { 16 | Navigator.of(context).pop(true); 17 | }, 18 | child: const Text('Yes')), 19 | TextButton( 20 | onPressed: () { 21 | Navigator.of(context).pop(false); 22 | }, 23 | child: const Text('No')) 24 | ], 25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/features/storage_file/ui/storage_files_list/storage_file_tile.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_storage_app/features/storage_file/models/storage_file.dart'; 2 | import 'package:cached_network_image/cached_network_image.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class StorageFileTile extends StatelessWidget { 6 | const StorageFileTile({ 7 | required this.storageFile, 8 | super.key, 9 | }); 10 | 11 | final StorageFile storageFile; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Card( 16 | elevation: 4.0, 17 | child: CachedNetworkImage( 18 | cacheKey: storageFile.key, 19 | imageUrl: storageFile.url, 20 | height: double.infinity, 21 | width: double.infinity, 22 | fit: BoxFit.cover, 23 | ), 24 | ); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/features/storage_file/ui/storage_files_list/storage_files_list_page.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | 3 | import 'package:amplify_storage_app/features/storage_file/controller/storage_files_controller.dart'; 4 | import 'package:amplify_storage_app/features/storage_file/models/storage_file.dart'; 5 | 6 | import 'package:amplify_storage_app/features/storage_file/ui/storage_files_list/delete_storage_file_dialog.dart'; 7 | import 'package:amplify_storage_app/features/storage_file/ui/storage_files_list/storage_file_tile.dart'; 8 | import 'package:amplify_storage_app/features/storage_file/ui/storage_files_list/upload_progress_dialog.dart'; 9 | import 'package:flutter/material.dart'; 10 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 11 | import 'package:image_picker/image_picker.dart'; 12 | 13 | class StorageFilesListPage extends ConsumerWidget { 14 | const StorageFilesListPage({ 15 | super.key, 16 | }); 17 | 18 | Future uploadImage({ 19 | required BuildContext context, 20 | required WidgetRef ref, 21 | }) async { 22 | final picker = ImagePicker(); 23 | final pickedFile = await picker.pickImage(source: ImageSource.gallery); 24 | if (pickedFile == null) { 25 | return false; 26 | } 27 | 28 | final file = File(pickedFile.path); 29 | showDialog( 30 | context: context, 31 | barrierDismissible: false, 32 | builder: (BuildContext context) { 33 | return const UploadProgressDialog(); 34 | }); 35 | await ref.read(storageFilesControllerProvider).uploadFile(file); 36 | return true; 37 | } 38 | 39 | Future deletestorageFile( 40 | BuildContext context, WidgetRef ref, StorageFile storageFile) async { 41 | var value = await showDialog( 42 | context: context, 43 | builder: (BuildContext context) { 44 | return const DeleteStorageFileDialog(); 45 | }); 46 | value ??= false; 47 | 48 | if (value) { 49 | await ref 50 | .read(storageFilesControllerProvider) 51 | .deleteFile(storageFile.key); 52 | ref.refresh(storageFilesListFutureProvider); 53 | } 54 | } 55 | 56 | @override 57 | Widget build(BuildContext context, WidgetRef ref) { 58 | final storageItems = ref.watch(storageFilesListFutureProvider); 59 | 60 | return Scaffold( 61 | appBar: AppBar( 62 | title: const Text('Amplify Storage'), 63 | ), 64 | floatingActionButton: FloatingActionButton( 65 | onPressed: () { 66 | uploadImage( 67 | context: context, 68 | ref: ref, 69 | ).then((value) { 70 | if (value) { 71 | ref.refresh(storageFilesListFutureProvider); 72 | 73 | Navigator.of(context, rootNavigator: true).pop(); 74 | } 75 | }); 76 | }, 77 | child: const Icon(Icons.add), 78 | ), 79 | body: storageItems.when( 80 | data: (items) => items.isEmpty 81 | ? const Center( 82 | child: Text('No Items'), 83 | ) 84 | : Column( 85 | children: [ 86 | Expanded( 87 | child: GridView.builder( 88 | key: const Key('StorageItemsGridView'), 89 | gridDelegate: 90 | const SliverGridDelegateWithFixedCrossAxisCount( 91 | crossAxisCount: 2, 92 | mainAxisSpacing: 10, 93 | crossAxisSpacing: 5, 94 | ), 95 | itemCount: items.length, 96 | itemBuilder: (context, index) => InkWell( 97 | highlightColor: Colors.red.withOpacity(0.4), 98 | splashColor: Colors.amber.withOpacity(0.5), 99 | onLongPress: (() { 100 | deletestorageFile(context, ref, items[index]); 101 | }), 102 | child: StorageFileTile( 103 | storageFile: items[index], 104 | ), 105 | ), 106 | ), 107 | ), 108 | ], 109 | ), 110 | error: (e, st) => const Center( 111 | child: Text('Error'), 112 | ), 113 | loading: () => const Center( 114 | child: CircularProgressIndicator(), 115 | ))); 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /lib/features/storage_file/ui/storage_files_list/upload_progress_dialog.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_storage_app/features/storage_file/controller/storage_files_controller.dart'; 2 | import 'package:flutter/material.dart'; 3 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 4 | 5 | class UploadProgressDialog extends ConsumerWidget { 6 | const UploadProgressDialog({Key? key}) : super(key: key); 7 | 8 | @override 9 | Widget build(BuildContext context, WidgetRef ref) { 10 | return Dialog( 11 | backgroundColor: Colors.white, 12 | child: Padding( 13 | padding: const EdgeInsets.symmetric(vertical: 20), 14 | child: ValueListenableBuilder( 15 | valueListenable: 16 | ref.read(storageFilesControllerProvider).uploadProgress(), 17 | builder: (context, value, child) { 18 | return Column( 19 | mainAxisSize: MainAxisSize.min, 20 | children: [ 21 | const CircularProgressIndicator(), 22 | const SizedBox(height: 15), 23 | Text('$value %'), 24 | Container( 25 | alignment: Alignment.topCenter, 26 | margin: const EdgeInsets.all(20), 27 | child: LinearProgressIndicator( 28 | value: double.parse(value.toString()) / 100, 29 | backgroundColor: Colors.grey, 30 | color: Colors.purple, 31 | minHeight: 10, 32 | ), 33 | ), 34 | ], 35 | ); 36 | }, 37 | ), 38 | ), 39 | ); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_storage_app/storage_gallery_app.dart'; 2 | import 'package:amplify_storage_app/utils.dart'; 3 | import 'package:flutter/material.dart'; 4 | import 'package:amplify_flutter/amplify_flutter.dart'; 5 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart'; 6 | import 'package:amplify_storage_s3/amplify_storage_s3.dart'; 7 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 8 | import 'amplifyconfiguration.dart'; 9 | 10 | Future main() async { 11 | WidgetsFlutterBinding.ensureInitialized(); 12 | bool isAmplifySuccessfullyConfigured = false; 13 | try { 14 | await _configureAmplify(); 15 | isAmplifySuccessfullyConfigured = true; 16 | } on AmplifyAlreadyConfiguredException { 17 | logger.e('Amplify configuration failed.'); 18 | } 19 | 20 | runApp( 21 | ProviderScope( 22 | child: StorageGalleryApp( 23 | isAmplifySuccessfullyConfigured: isAmplifySuccessfullyConfigured, 24 | ), 25 | ), 26 | ); 27 | } 28 | 29 | Future _configureAmplify() async { 30 | await Amplify.addPlugins([ 31 | AmplifyAuthCognito(), 32 | AmplifyStorageS3(), 33 | ]); 34 | await Amplify.configure(amplifyconfig); 35 | } 36 | -------------------------------------------------------------------------------- /lib/storage_gallery_app.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_authenticator/amplify_authenticator.dart'; 2 | import 'package:amplify_storage_app/features/storage_file/ui/storage_files_list/storage_files_list_page.dart'; 3 | import 'package:flutter/material.dart'; 4 | 5 | class StorageGalleryApp extends StatelessWidget { 6 | const StorageGalleryApp({ 7 | required this.isAmplifySuccessfullyConfigured, 8 | Key? key, 9 | }) : super(key: key); 10 | 11 | final bool isAmplifySuccessfullyConfigured; 12 | 13 | @override 14 | Widget build(BuildContext context) { 15 | return Authenticator( 16 | child: MaterialApp( 17 | builder: Authenticator.builder(), 18 | home: isAmplifySuccessfullyConfigured 19 | ? const StorageFilesListPage() 20 | : const Scaffold( 21 | body: Center( 22 | child: Text( 23 | 'Tried to reconfigure Amplify; ' 24 | 'this can occur when your app restarts on Android.', 25 | ), 26 | ), 27 | ), 28 | ), 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/utils.dart: -------------------------------------------------------------------------------- 1 | import 'package:logger/logger.dart'; 2 | 3 | final logger = Logger(); 4 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | url: "https://pub.dartlang.org" 9 | source: hosted 10 | version: "45.0.0" 11 | amplify_auth_cognito: 12 | dependency: "direct main" 13 | description: 14 | name: amplify_auth_cognito 15 | url: "https://pub.dartlang.org" 16 | source: hosted 17 | version: "0.6.5" 18 | amplify_auth_cognito_android: 19 | dependency: transitive 20 | description: 21 | name: amplify_auth_cognito_android 22 | url: "https://pub.dartlang.org" 23 | source: hosted 24 | version: "0.6.5" 25 | amplify_auth_cognito_ios: 26 | dependency: transitive 27 | description: 28 | name: amplify_auth_cognito_ios 29 | url: "https://pub.dartlang.org" 30 | source: hosted 31 | version: "0.6.5" 32 | amplify_authenticator: 33 | dependency: "direct main" 34 | description: 35 | name: amplify_authenticator 36 | url: "https://pub.dartlang.org" 37 | source: hosted 38 | version: "0.2.2" 39 | amplify_core: 40 | dependency: transitive 41 | description: 42 | name: amplify_core 43 | url: "https://pub.dartlang.org" 44 | source: hosted 45 | version: "0.6.5" 46 | amplify_datastore_plugin_interface: 47 | dependency: transitive 48 | description: 49 | name: amplify_datastore_plugin_interface 50 | url: "https://pub.dartlang.org" 51 | source: hosted 52 | version: "0.6.5" 53 | amplify_flutter: 54 | dependency: "direct main" 55 | description: 56 | name: amplify_flutter 57 | url: "https://pub.dartlang.org" 58 | source: hosted 59 | version: "0.6.5" 60 | amplify_flutter_android: 61 | dependency: transitive 62 | description: 63 | name: amplify_flutter_android 64 | url: "https://pub.dartlang.org" 65 | source: hosted 66 | version: "0.6.5" 67 | amplify_flutter_ios: 68 | dependency: transitive 69 | description: 70 | name: amplify_flutter_ios 71 | url: "https://pub.dartlang.org" 72 | source: hosted 73 | version: "0.6.5" 74 | amplify_storage_s3: 75 | dependency: "direct main" 76 | description: 77 | name: amplify_storage_s3 78 | url: "https://pub.dartlang.org" 79 | source: hosted 80 | version: "0.6.5" 81 | amplify_storage_s3_android: 82 | dependency: transitive 83 | description: 84 | name: amplify_storage_s3_android 85 | url: "https://pub.dartlang.org" 86 | source: hosted 87 | version: "0.6.5" 88 | amplify_storage_s3_ios: 89 | dependency: transitive 90 | description: 91 | name: amplify_storage_s3_ios 92 | url: "https://pub.dartlang.org" 93 | source: hosted 94 | version: "0.6.5" 95 | analyzer: 96 | dependency: transitive 97 | description: 98 | name: analyzer 99 | url: "https://pub.dartlang.org" 100 | source: hosted 101 | version: "4.5.0" 102 | args: 103 | dependency: transitive 104 | description: 105 | name: args 106 | url: "https://pub.dartlang.org" 107 | source: hosted 108 | version: "2.3.1" 109 | async: 110 | dependency: transitive 111 | description: 112 | name: async 113 | url: "https://pub.dartlang.org" 114 | source: hosted 115 | version: "2.8.2" 116 | aws_common: 117 | dependency: transitive 118 | description: 119 | name: aws_common 120 | url: "https://pub.dartlang.org" 121 | source: hosted 122 | version: "0.1.1" 123 | boolean_selector: 124 | dependency: transitive 125 | description: 126 | name: boolean_selector 127 | url: "https://pub.dartlang.org" 128 | source: hosted 129 | version: "2.1.0" 130 | build: 131 | dependency: transitive 132 | description: 133 | name: build 134 | url: "https://pub.dartlang.org" 135 | source: hosted 136 | version: "2.3.0" 137 | build_config: 138 | dependency: transitive 139 | description: 140 | name: build_config 141 | url: "https://pub.dartlang.org" 142 | source: hosted 143 | version: "1.1.0" 144 | build_daemon: 145 | dependency: transitive 146 | description: 147 | name: build_daemon 148 | url: "https://pub.dartlang.org" 149 | source: hosted 150 | version: "3.1.0" 151 | build_resolvers: 152 | dependency: transitive 153 | description: 154 | name: build_resolvers 155 | url: "https://pub.dartlang.org" 156 | source: hosted 157 | version: "2.0.9" 158 | build_runner: 159 | dependency: "direct dev" 160 | description: 161 | name: build_runner 162 | url: "https://pub.dartlang.org" 163 | source: hosted 164 | version: "2.2.0" 165 | build_runner_core: 166 | dependency: transitive 167 | description: 168 | name: build_runner_core 169 | url: "https://pub.dartlang.org" 170 | source: hosted 171 | version: "7.2.3" 172 | built_collection: 173 | dependency: transitive 174 | description: 175 | name: built_collection 176 | url: "https://pub.dartlang.org" 177 | source: hosted 178 | version: "5.1.1" 179 | built_value: 180 | dependency: transitive 181 | description: 182 | name: built_value 183 | url: "https://pub.dartlang.org" 184 | source: hosted 185 | version: "8.4.0" 186 | cached_network_image: 187 | dependency: "direct main" 188 | description: 189 | name: cached_network_image 190 | url: "https://pub.dartlang.org" 191 | source: hosted 192 | version: "3.2.1" 193 | cached_network_image_platform_interface: 194 | dependency: transitive 195 | description: 196 | name: cached_network_image_platform_interface 197 | url: "https://pub.dartlang.org" 198 | source: hosted 199 | version: "1.0.0" 200 | cached_network_image_web: 201 | dependency: transitive 202 | description: 203 | name: cached_network_image_web 204 | url: "https://pub.dartlang.org" 205 | source: hosted 206 | version: "1.0.1" 207 | characters: 208 | dependency: transitive 209 | description: 210 | name: characters 211 | url: "https://pub.dartlang.org" 212 | source: hosted 213 | version: "1.2.0" 214 | charcode: 215 | dependency: transitive 216 | description: 217 | name: charcode 218 | url: "https://pub.dartlang.org" 219 | source: hosted 220 | version: "1.3.1" 221 | checked_yaml: 222 | dependency: transitive 223 | description: 224 | name: checked_yaml 225 | url: "https://pub.dartlang.org" 226 | source: hosted 227 | version: "2.0.1" 228 | clock: 229 | dependency: transitive 230 | description: 231 | name: clock 232 | url: "https://pub.dartlang.org" 233 | source: hosted 234 | version: "1.1.0" 235 | code_builder: 236 | dependency: transitive 237 | description: 238 | name: code_builder 239 | url: "https://pub.dartlang.org" 240 | source: hosted 241 | version: "4.2.0" 242 | collection: 243 | dependency: transitive 244 | description: 245 | name: collection 246 | url: "https://pub.dartlang.org" 247 | source: hosted 248 | version: "1.16.0" 249 | convert: 250 | dependency: transitive 251 | description: 252 | name: convert 253 | url: "https://pub.dartlang.org" 254 | source: hosted 255 | version: "3.0.2" 256 | coverage: 257 | dependency: transitive 258 | description: 259 | name: coverage 260 | url: "https://pub.dartlang.org" 261 | source: hosted 262 | version: "1.3.2" 263 | cross_file: 264 | dependency: transitive 265 | description: 266 | name: cross_file 267 | url: "https://pub.dartlang.org" 268 | source: hosted 269 | version: "0.3.3+1" 270 | crypto: 271 | dependency: transitive 272 | description: 273 | name: crypto 274 | url: "https://pub.dartlang.org" 275 | source: hosted 276 | version: "3.0.2" 277 | cupertino_icons: 278 | dependency: "direct main" 279 | description: 280 | name: cupertino_icons 281 | url: "https://pub.dartlang.org" 282 | source: hosted 283 | version: "1.0.4" 284 | dart_style: 285 | dependency: transitive 286 | description: 287 | name: dart_style 288 | url: "https://pub.dartlang.org" 289 | source: hosted 290 | version: "2.2.3" 291 | fake_async: 292 | dependency: transitive 293 | description: 294 | name: fake_async 295 | url: "https://pub.dartlang.org" 296 | source: hosted 297 | version: "1.3.0" 298 | ffi: 299 | dependency: transitive 300 | description: 301 | name: ffi 302 | url: "https://pub.dartlang.org" 303 | source: hosted 304 | version: "1.2.1" 305 | file: 306 | dependency: transitive 307 | description: 308 | name: file 309 | url: "https://pub.dartlang.org" 310 | source: hosted 311 | version: "6.1.2" 312 | file_picker: 313 | dependency: "direct main" 314 | description: 315 | name: file_picker 316 | url: "https://pub.dartlang.org" 317 | source: hosted 318 | version: "4.6.0" 319 | fixnum: 320 | dependency: transitive 321 | description: 322 | name: fixnum 323 | url: "https://pub.dartlang.org" 324 | source: hosted 325 | version: "1.0.1" 326 | flutter: 327 | dependency: "direct main" 328 | description: flutter 329 | source: sdk 330 | version: "0.0.0" 331 | flutter_blurhash: 332 | dependency: transitive 333 | description: 334 | name: flutter_blurhash 335 | url: "https://pub.dartlang.org" 336 | source: hosted 337 | version: "0.7.0" 338 | flutter_cache_manager: 339 | dependency: transitive 340 | description: 341 | name: flutter_cache_manager 342 | url: "https://pub.dartlang.org" 343 | source: hosted 344 | version: "3.3.0" 345 | flutter_lints: 346 | dependency: "direct dev" 347 | description: 348 | name: flutter_lints 349 | url: "https://pub.dartlang.org" 350 | source: hosted 351 | version: "2.0.1" 352 | flutter_localizations: 353 | dependency: transitive 354 | description: flutter 355 | source: sdk 356 | version: "0.0.0" 357 | flutter_plugin_android_lifecycle: 358 | dependency: transitive 359 | description: 360 | name: flutter_plugin_android_lifecycle 361 | url: "https://pub.dartlang.org" 362 | source: hosted 363 | version: "2.0.6" 364 | flutter_riverpod: 365 | dependency: "direct main" 366 | description: 367 | name: flutter_riverpod 368 | url: "https://pub.dartlang.org" 369 | source: hosted 370 | version: "1.0.4" 371 | flutter_test: 372 | dependency: "direct dev" 373 | description: flutter 374 | source: sdk 375 | version: "0.0.0" 376 | flutter_web_plugins: 377 | dependency: transitive 378 | description: flutter 379 | source: sdk 380 | version: "0.0.0" 381 | freezed: 382 | dependency: "direct dev" 383 | description: 384 | name: freezed 385 | url: "https://pub.dartlang.org" 386 | source: hosted 387 | version: "2.1.0+1" 388 | freezed_annotation: 389 | dependency: "direct main" 390 | description: 391 | name: freezed_annotation 392 | url: "https://pub.dartlang.org" 393 | source: hosted 394 | version: "2.1.0" 395 | frontend_server_client: 396 | dependency: transitive 397 | description: 398 | name: frontend_server_client 399 | url: "https://pub.dartlang.org" 400 | source: hosted 401 | version: "2.1.3" 402 | glob: 403 | dependency: transitive 404 | description: 405 | name: glob 406 | url: "https://pub.dartlang.org" 407 | source: hosted 408 | version: "2.1.0" 409 | graphs: 410 | dependency: transitive 411 | description: 412 | name: graphs 413 | url: "https://pub.dartlang.org" 414 | source: hosted 415 | version: "2.1.0" 416 | http: 417 | dependency: transitive 418 | description: 419 | name: http 420 | url: "https://pub.dartlang.org" 421 | source: hosted 422 | version: "0.13.4" 423 | http_multi_server: 424 | dependency: transitive 425 | description: 426 | name: http_multi_server 427 | url: "https://pub.dartlang.org" 428 | source: hosted 429 | version: "3.2.1" 430 | http_parser: 431 | dependency: transitive 432 | description: 433 | name: http_parser 434 | url: "https://pub.dartlang.org" 435 | source: hosted 436 | version: "4.0.1" 437 | image_picker: 438 | dependency: "direct main" 439 | description: 440 | name: image_picker 441 | url: "https://pub.dartlang.org" 442 | source: hosted 443 | version: "0.8.5+3" 444 | image_picker_android: 445 | dependency: transitive 446 | description: 447 | name: image_picker_android 448 | url: "https://pub.dartlang.org" 449 | source: hosted 450 | version: "0.8.4+13" 451 | image_picker_for_web: 452 | dependency: transitive 453 | description: 454 | name: image_picker_for_web 455 | url: "https://pub.dartlang.org" 456 | source: hosted 457 | version: "2.1.8" 458 | image_picker_ios: 459 | dependency: transitive 460 | description: 461 | name: image_picker_ios 462 | url: "https://pub.dartlang.org" 463 | source: hosted 464 | version: "0.8.5+5" 465 | image_picker_platform_interface: 466 | dependency: transitive 467 | description: 468 | name: image_picker_platform_interface 469 | url: "https://pub.dartlang.org" 470 | source: hosted 471 | version: "2.5.0" 472 | intl: 473 | dependency: transitive 474 | description: 475 | name: intl 476 | url: "https://pub.dartlang.org" 477 | source: hosted 478 | version: "0.17.0" 479 | io: 480 | dependency: transitive 481 | description: 482 | name: io 483 | url: "https://pub.dartlang.org" 484 | source: hosted 485 | version: "1.0.3" 486 | js: 487 | dependency: transitive 488 | description: 489 | name: js 490 | url: "https://pub.dartlang.org" 491 | source: hosted 492 | version: "0.6.4" 493 | json_annotation: 494 | dependency: transitive 495 | description: 496 | name: json_annotation 497 | url: "https://pub.dartlang.org" 498 | source: hosted 499 | version: "4.6.0" 500 | json_serializable: 501 | dependency: "direct dev" 502 | description: 503 | name: json_serializable 504 | url: "https://pub.dartlang.org" 505 | source: hosted 506 | version: "6.3.1" 507 | lints: 508 | dependency: transitive 509 | description: 510 | name: lints 511 | url: "https://pub.dartlang.org" 512 | source: hosted 513 | version: "2.0.0" 514 | logger: 515 | dependency: "direct main" 516 | description: 517 | name: logger 518 | url: "https://pub.dartlang.org" 519 | source: hosted 520 | version: "1.1.0" 521 | logging: 522 | dependency: transitive 523 | description: 524 | name: logging 525 | url: "https://pub.dartlang.org" 526 | source: hosted 527 | version: "1.0.2" 528 | matcher: 529 | dependency: transitive 530 | description: 531 | name: matcher 532 | url: "https://pub.dartlang.org" 533 | source: hosted 534 | version: "0.12.11" 535 | material_color_utilities: 536 | dependency: transitive 537 | description: 538 | name: material_color_utilities 539 | url: "https://pub.dartlang.org" 540 | source: hosted 541 | version: "0.1.4" 542 | meta: 543 | dependency: transitive 544 | description: 545 | name: meta 546 | url: "https://pub.dartlang.org" 547 | source: hosted 548 | version: "1.7.0" 549 | mime: 550 | dependency: transitive 551 | description: 552 | name: mime 553 | url: "https://pub.dartlang.org" 554 | source: hosted 555 | version: "1.0.2" 556 | mocktail: 557 | dependency: "direct dev" 558 | description: 559 | name: mocktail 560 | url: "https://pub.dartlang.org" 561 | source: hosted 562 | version: "0.3.0" 563 | node_preamble: 564 | dependency: transitive 565 | description: 566 | name: node_preamble 567 | url: "https://pub.dartlang.org" 568 | source: hosted 569 | version: "2.0.1" 570 | octo_image: 571 | dependency: transitive 572 | description: 573 | name: octo_image 574 | url: "https://pub.dartlang.org" 575 | source: hosted 576 | version: "1.0.2" 577 | package_config: 578 | dependency: transitive 579 | description: 580 | name: package_config 581 | url: "https://pub.dartlang.org" 582 | source: hosted 583 | version: "2.1.0" 584 | path: 585 | dependency: "direct main" 586 | description: 587 | name: path 588 | url: "https://pub.dartlang.org" 589 | source: hosted 590 | version: "1.8.1" 591 | path_provider: 592 | dependency: transitive 593 | description: 594 | name: path_provider 595 | url: "https://pub.dartlang.org" 596 | source: hosted 597 | version: "2.0.10" 598 | path_provider_android: 599 | dependency: transitive 600 | description: 601 | name: path_provider_android 602 | url: "https://pub.dartlang.org" 603 | source: hosted 604 | version: "2.0.14" 605 | path_provider_ios: 606 | dependency: transitive 607 | description: 608 | name: path_provider_ios 609 | url: "https://pub.dartlang.org" 610 | source: hosted 611 | version: "2.0.9" 612 | path_provider_linux: 613 | dependency: transitive 614 | description: 615 | name: path_provider_linux 616 | url: "https://pub.dartlang.org" 617 | source: hosted 618 | version: "2.1.7" 619 | path_provider_macos: 620 | dependency: transitive 621 | description: 622 | name: path_provider_macos 623 | url: "https://pub.dartlang.org" 624 | source: hosted 625 | version: "2.0.6" 626 | path_provider_platform_interface: 627 | dependency: transitive 628 | description: 629 | name: path_provider_platform_interface 630 | url: "https://pub.dartlang.org" 631 | source: hosted 632 | version: "2.0.4" 633 | path_provider_windows: 634 | dependency: transitive 635 | description: 636 | name: path_provider_windows 637 | url: "https://pub.dartlang.org" 638 | source: hosted 639 | version: "2.0.7" 640 | pedantic: 641 | dependency: transitive 642 | description: 643 | name: pedantic 644 | url: "https://pub.dartlang.org" 645 | source: hosted 646 | version: "1.11.1" 647 | platform: 648 | dependency: transitive 649 | description: 650 | name: platform 651 | url: "https://pub.dartlang.org" 652 | source: hosted 653 | version: "3.1.0" 654 | plugin_platform_interface: 655 | dependency: transitive 656 | description: 657 | name: plugin_platform_interface 658 | url: "https://pub.dartlang.org" 659 | source: hosted 660 | version: "2.1.2" 661 | pool: 662 | dependency: transitive 663 | description: 664 | name: pool 665 | url: "https://pub.dartlang.org" 666 | source: hosted 667 | version: "1.5.1" 668 | process: 669 | dependency: transitive 670 | description: 671 | name: process 672 | url: "https://pub.dartlang.org" 673 | source: hosted 674 | version: "4.2.4" 675 | pub_semver: 676 | dependency: transitive 677 | description: 678 | name: pub_semver 679 | url: "https://pub.dartlang.org" 680 | source: hosted 681 | version: "2.1.1" 682 | pubspec_parse: 683 | dependency: transitive 684 | description: 685 | name: pubspec_parse 686 | url: "https://pub.dartlang.org" 687 | source: hosted 688 | version: "1.2.0" 689 | riverpod: 690 | dependency: transitive 691 | description: 692 | name: riverpod 693 | url: "https://pub.dartlang.org" 694 | source: hosted 695 | version: "1.0.3" 696 | rxdart: 697 | dependency: transitive 698 | description: 699 | name: rxdart 700 | url: "https://pub.dartlang.org" 701 | source: hosted 702 | version: "0.27.4" 703 | shelf: 704 | dependency: transitive 705 | description: 706 | name: shelf 707 | url: "https://pub.dartlang.org" 708 | source: hosted 709 | version: "1.3.2" 710 | shelf_packages_handler: 711 | dependency: transitive 712 | description: 713 | name: shelf_packages_handler 714 | url: "https://pub.dartlang.org" 715 | source: hosted 716 | version: "3.0.1" 717 | shelf_static: 718 | dependency: transitive 719 | description: 720 | name: shelf_static 721 | url: "https://pub.dartlang.org" 722 | source: hosted 723 | version: "1.1.1" 724 | shelf_web_socket: 725 | dependency: transitive 726 | description: 727 | name: shelf_web_socket 728 | url: "https://pub.dartlang.org" 729 | source: hosted 730 | version: "1.0.2" 731 | sky_engine: 732 | dependency: transitive 733 | description: flutter 734 | source: sdk 735 | version: "0.0.99" 736 | source_gen: 737 | dependency: transitive 738 | description: 739 | name: source_gen 740 | url: "https://pub.dartlang.org" 741 | source: hosted 742 | version: "1.2.2" 743 | source_helper: 744 | dependency: transitive 745 | description: 746 | name: source_helper 747 | url: "https://pub.dartlang.org" 748 | source: hosted 749 | version: "1.3.2" 750 | source_map_stack_trace: 751 | dependency: transitive 752 | description: 753 | name: source_map_stack_trace 754 | url: "https://pub.dartlang.org" 755 | source: hosted 756 | version: "2.1.0" 757 | source_maps: 758 | dependency: transitive 759 | description: 760 | name: source_maps 761 | url: "https://pub.dartlang.org" 762 | source: hosted 763 | version: "0.10.10" 764 | source_span: 765 | dependency: transitive 766 | description: 767 | name: source_span 768 | url: "https://pub.dartlang.org" 769 | source: hosted 770 | version: "1.8.2" 771 | sqflite: 772 | dependency: transitive 773 | description: 774 | name: sqflite 775 | url: "https://pub.dartlang.org" 776 | source: hosted 777 | version: "2.0.2+1" 778 | sqflite_common: 779 | dependency: transitive 780 | description: 781 | name: sqflite_common 782 | url: "https://pub.dartlang.org" 783 | source: hosted 784 | version: "2.2.1+1" 785 | stack_trace: 786 | dependency: transitive 787 | description: 788 | name: stack_trace 789 | url: "https://pub.dartlang.org" 790 | source: hosted 791 | version: "1.10.0" 792 | state_notifier: 793 | dependency: transitive 794 | description: 795 | name: state_notifier 796 | url: "https://pub.dartlang.org" 797 | source: hosted 798 | version: "0.7.2+1" 799 | stream_channel: 800 | dependency: transitive 801 | description: 802 | name: stream_channel 803 | url: "https://pub.dartlang.org" 804 | source: hosted 805 | version: "2.1.0" 806 | stream_transform: 807 | dependency: transitive 808 | description: 809 | name: stream_transform 810 | url: "https://pub.dartlang.org" 811 | source: hosted 812 | version: "2.0.0" 813 | string_scanner: 814 | dependency: transitive 815 | description: 816 | name: string_scanner 817 | url: "https://pub.dartlang.org" 818 | source: hosted 819 | version: "1.1.0" 820 | synchronized: 821 | dependency: transitive 822 | description: 823 | name: synchronized 824 | url: "https://pub.dartlang.org" 825 | source: hosted 826 | version: "3.0.0+2" 827 | term_glyph: 828 | dependency: transitive 829 | description: 830 | name: term_glyph 831 | url: "https://pub.dartlang.org" 832 | source: hosted 833 | version: "1.2.0" 834 | test: 835 | dependency: transitive 836 | description: 837 | name: test 838 | url: "https://pub.dartlang.org" 839 | source: hosted 840 | version: "1.21.1" 841 | test_api: 842 | dependency: transitive 843 | description: 844 | name: test_api 845 | url: "https://pub.dartlang.org" 846 | source: hosted 847 | version: "0.4.9" 848 | test_core: 849 | dependency: transitive 850 | description: 851 | name: test_core 852 | url: "https://pub.dartlang.org" 853 | source: hosted 854 | version: "0.4.13" 855 | timing: 856 | dependency: transitive 857 | description: 858 | name: timing 859 | url: "https://pub.dartlang.org" 860 | source: hosted 861 | version: "1.0.0" 862 | typed_data: 863 | dependency: transitive 864 | description: 865 | name: typed_data 866 | url: "https://pub.dartlang.org" 867 | source: hosted 868 | version: "1.3.1" 869 | uuid: 870 | dependency: "direct main" 871 | description: 872 | name: uuid 873 | url: "https://pub.dartlang.org" 874 | source: hosted 875 | version: "3.0.6" 876 | vector_math: 877 | dependency: transitive 878 | description: 879 | name: vector_math 880 | url: "https://pub.dartlang.org" 881 | source: hosted 882 | version: "2.1.2" 883 | vm_service: 884 | dependency: transitive 885 | description: 886 | name: vm_service 887 | url: "https://pub.dartlang.org" 888 | source: hosted 889 | version: "8.3.0" 890 | watcher: 891 | dependency: transitive 892 | description: 893 | name: watcher 894 | url: "https://pub.dartlang.org" 895 | source: hosted 896 | version: "1.0.1" 897 | web_socket_channel: 898 | dependency: transitive 899 | description: 900 | name: web_socket_channel 901 | url: "https://pub.dartlang.org" 902 | source: hosted 903 | version: "2.2.0" 904 | webkit_inspection_protocol: 905 | dependency: transitive 906 | description: 907 | name: webkit_inspection_protocol 908 | url: "https://pub.dartlang.org" 909 | source: hosted 910 | version: "1.1.0" 911 | win32: 912 | dependency: transitive 913 | description: 914 | name: win32 915 | url: "https://pub.dartlang.org" 916 | source: hosted 917 | version: "2.6.1" 918 | xdg_directories: 919 | dependency: transitive 920 | description: 921 | name: xdg_directories 922 | url: "https://pub.dartlang.org" 923 | source: hosted 924 | version: "0.2.0+1" 925 | yaml: 926 | dependency: transitive 927 | description: 928 | name: yaml 929 | url: "https://pub.dartlang.org" 930 | source: hosted 931 | version: "3.1.1" 932 | sdks: 933 | dart: ">=2.17.1 <3.0.0" 934 | flutter: ">=3.0.0" 935 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: amplify_storage_app 2 | description: A new Flutter project. 3 | 4 | 5 | publish_to: 'none' 6 | 7 | version: 1.0.0+1 8 | 9 | environment: 10 | sdk: ">=2.17.1 <3.0.0" 11 | 12 | 13 | dependencies: 14 | flutter: 15 | sdk: flutter 16 | amplify_flutter: ^0.6.5 17 | amplify_auth_cognito: ^0.6.5 18 | amplify_storage_s3: ^0.6.5 19 | flutter_riverpod: ^1.0.3 20 | amplify_authenticator: ^0.2.0 21 | cupertino_icons: ^1.0.2 22 | file_picker: ^4.6.0 23 | image_picker: ^0.8.5+3 24 | cached_network_image: ^3.2.1 25 | uuid: ^3.0.4 26 | path: ^1.8.1 27 | freezed_annotation: ^2.1.0 28 | logger: ^1.1.0 29 | 30 | dev_dependencies: 31 | flutter_test: 32 | sdk: flutter 33 | mocktail: ^0.3.0 34 | flutter_lints: ^2.0.1 35 | build_runner: ^2.2.0 36 | freezed: ^2.1.0+1 37 | json_serializable: ^6.3.1 38 | 39 | flutter: 40 | uses-material-design: true 41 | 42 | -------------------------------------------------------------------------------- /test/items_list_page_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:amplify_storage_app/features/storage_file/controller/storage_files_controller.dart'; 2 | import 'package:amplify_storage_app/features/storage_file/models/storage_file.dart'; 3 | import 'package:amplify_storage_app/features/storage_file/ui/storage_files_list/storage_files_list_page.dart'; 4 | 5 | import 'package:flutter/material.dart'; 6 | import 'package:flutter_riverpod/flutter_riverpod.dart'; 7 | import 'package:flutter_test/flutter_test.dart'; 8 | 9 | void main() { 10 | testWidgets('renders Error on error', (WidgetTester tester) async { 11 | await tester.pumpWidget( 12 | ProviderScope( 13 | overrides: [ 14 | storageFilesListFutureProvider.overrideWithValue( 15 | const AsyncValue.error('Error'), 16 | ), 17 | ], 18 | child: const MaterialApp( 19 | home: StorageFilesListPage(), 20 | ), 21 | ), 22 | ); 23 | 24 | await tester.pumpAndSettle(); 25 | 26 | expect(find.text('Error'), findsOneWidget); 27 | }); 28 | 29 | testWidgets('renders No Items on empty list', (WidgetTester tester) async { 30 | await tester.pumpWidget( 31 | ProviderScope( 32 | overrides: [ 33 | storageFilesListFutureProvider.overrideWithValue( 34 | const AsyncValue.data([]), 35 | ), 36 | ], 37 | child: const MaterialApp( 38 | home: StorageFilesListPage(), 39 | ), 40 | ), 41 | ); 42 | 43 | await tester.pumpAndSettle(); 44 | 45 | expect(find.text('No Items'), findsOneWidget); 46 | }); 47 | 48 | testWidgets('renders images on data', (WidgetTester tester) async { 49 | await tester.pumpWidget( 50 | ProviderScope( 51 | overrides: [ 52 | storageFilesListFutureProvider.overrideWithValue( 53 | const AsyncValue.data([StorageFile(key: 'key1', url: 'url1')]), 54 | ), 55 | ], 56 | child: const MaterialApp( 57 | home: StorageFilesListPage(), 58 | ), 59 | ), 60 | ); 61 | 62 | await tester.pumpAndSettle(); 63 | 64 | final key = find.byKey(const Key('StorageItemsGridView')); 65 | 66 | expect(key, findsOneWidget); 67 | }); 68 | } 69 | --------------------------------------------------------------------------------