├── .gitignore
├── .metadata
├── .vscode
└── settings.json
├── README.md
├── amplify
├── .config
│ └── project-config.json
├── backend
│ ├── analytics
│ │ └── amplifytodoapp
│ │ │ ├── parameters.json
│ │ │ └── pinpoint-cloudformation-template.json
│ ├── api
│ │ └── amplifytodoapp
│ │ │ ├── parameters.json
│ │ │ ├── resolvers
│ │ │ └── README.md
│ │ │ ├── schema.graphql
│ │ │ ├── stacks
│ │ │ └── CustomResources.json
│ │ │ └── transform.conf.json
│ ├── auth
│ │ └── amplifytodoapp
│ │ │ ├── amplifytodoapp-cloudformation-template.yml
│ │ │ └── parameters.json
│ ├── backend-config.json
│ ├── storage
│ │ └── s385ebe3d5
│ │ │ ├── parameters.json
│ │ │ ├── s3-cloudformation-template.json
│ │ │ └── storage-params.json
│ └── tags.json
├── cli.json
└── team-provider-info.json
├── android
├── .gitignore
├── app
│ ├── build.gradle
│ └── src
│ │ ├── debug
│ │ └── AndroidManifest.xml
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── kotlin
│ │ │ └── com
│ │ │ │ └── example
│ │ │ │ └── amplify_todo
│ │ │ │ └── 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
├── images
├── amazon-logo.png
├── applogo.png
├── aws.png
├── facebook-logo.png
├── google-logo.png
├── profile.png
└── profile_image.png
├── 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
├── account_screens_enum.dart
├── app_routes.dart
├── buttons_enum.dart
├── controllers
│ ├── authController.dart
│ ├── bindings
│ │ ├── controllers_bindings.dart
│ │ └── homepage_bindings.dart
│ ├── todoController.dart
│ └── userController.dart
├── main.dart
├── models
│ ├── ModelProvider.dart
│ ├── Todo.dart
│ └── Users.dart
├── pages
│ ├── email_sign_in_page.dart
│ ├── home_page.dart
│ ├── loading_page.dart
│ └── sign_in_page.dart
├── services
│ ├── amplify_service.dart
│ ├── auth_service.dart
│ └── datastore_service.dart
└── widgets
│ ├── email_sign_in_form.dart
│ ├── sign_in_button.dart
│ └── todo_card.dart
├── pubspec.lock
├── pubspec.yaml
├── test
└── widget_test.dart
└── youtube.png
/.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 | #amplify
49 | amplify/\#current-cloud-backend
50 | amplify/.config/local-*
51 | amplify/logs
52 | amplify/mock-data
53 | amplify/backend/amplify-meta.json
54 | amplify/backend/awscloudformation
55 | amplify/backend/.temp
56 | build/
57 | dist/
58 | node_modules/
59 | aws-exports.js
60 | awsconfiguration.json
61 | amplifyconfiguration.json
62 | amplifyconfiguration.dart
63 | amplify-build-config.json
64 | amplify-gradle-config.json
65 | amplifytools.xcconfig
66 | .secret-*
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled and should not be manually edited.
5 |
6 | version:
7 | revision: adc687823a831bbebe28bdccfac1a628ca621513
8 | channel: stable
9 |
10 | project_type: app
11 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.exclude": {
3 | "amplify/.config": true,
4 | "amplify/**/*-parameters.json": true,
5 | "amplify/**/amplify.state": true,
6 | "amplify/**/transform.conf.json": true,
7 | "amplify/#current-cloud-backend": true,
8 | "amplify/backend/amplify-meta.json": true,
9 | "amplify/backend/awscloudformation": true
10 | }
11 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # A Flutter Todo App using AWS Amplify & GetX
2 |
3 |
4 | A simple To-Do List app created using AWS Amplify and GetX.
5 |
6 | - [Read about it here](https://dev.to/offlineprogrammer/a-flutter-todo-app-using-awsamplify-getx-2oii)
7 |
8 | With this project you will learn how to:
9 |
10 | 1. Use AWSAmplify Auth.
11 | 2. Use AWSAmplify DataStore.
12 | 3. Manage the state of the application using GetXController.
13 | 4. 4. Make the UI reactive efficiently, rebuilding only the necessary widgets.
14 |
15 | YouTube video demo here:
16 |
17 | [](https://youtu.be/thrhO2Oxqqc)
18 |
--------------------------------------------------------------------------------
/amplify/.config/project-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "providers": [
3 | "awscloudformation"
4 | ],
5 | "projectName": "amplifytodoapp",
6 | "version": "3.1",
7 | "frontend": "flutter",
8 | "flutter": {
9 | "config": {
10 | "ResDir": "./lib/"
11 | }
12 | }
13 | }
--------------------------------------------------------------------------------
/amplify/backend/analytics/amplifytodoapp/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "appName": "amplifytodoapp",
3 | "roleName": "pinpointLambdaRole62d4b472",
4 | "cloudformationPolicyName": "cloudformationPolicy62d4b472",
5 | "cloudWatchPolicyName": "cloudWatchPolicy62d4b472",
6 | "pinpointPolicyName": "pinpointPolicy62d4b472",
7 | "authPolicyName": "pinpoint_amplify_62d4b472",
8 | "unauthPolicyName": "pinpoint_amplify_62d4b472",
9 | "authRoleName": {
10 | "Ref": "AuthRoleName"
11 | },
12 | "unauthRoleName": {
13 | "Ref": "UnauthRoleName"
14 | },
15 | "authRoleArn": {
16 | "Fn::GetAtt": [
17 | "AuthRole",
18 | "Arn"
19 | ]
20 | }
21 | }
--------------------------------------------------------------------------------
/amplify/backend/analytics/amplifytodoapp/pinpoint-cloudformation-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "Pinpoint resource stack creation using Amplify CLI",
4 | "Parameters": {
5 | "appName": {
6 | "Type": "String"
7 | },
8 | "appId": {
9 | "Type": "String",
10 | "Default": "NONE"
11 | },
12 | "roleName": {
13 | "Type": "String"
14 | },
15 | "cloudformationPolicyName": {
16 | "Type": "String"
17 | },
18 | "cloudWatchPolicyName": {
19 | "Type": "String"
20 | },
21 | "pinpointPolicyName": {
22 | "Type": "String"
23 | },
24 | "authPolicyName": {
25 | "Type": "String"
26 | },
27 | "unauthPolicyName": {
28 | "Type": "String"
29 | },
30 | "authRoleName": {
31 | "Type": "String"
32 | },
33 | "unauthRoleName": {
34 | "Type": "String"
35 | },
36 | "authRoleArn": {
37 | "Type": "String"
38 | },
39 | "env": {
40 | "Type": "String"
41 | }
42 | },
43 | "Metadata": {
44 | "AWS::CloudFormation::Interface": {
45 | "ParameterGroups": [
46 | {
47 | "Label": {
48 | "default": "Creating pinpoint app"
49 | },
50 | "Parameters": [
51 | "appName"
52 | ]
53 | }
54 | ]
55 | }
56 | },
57 | "Conditions": {
58 | "ShouldCreatePinpointApp": {
59 | "Fn::Equals": [
60 | {
61 | "Ref": "appId"
62 | },
63 | "NONE"
64 | ]
65 | },
66 | "ShouldNotCreateEnvResources": {
67 | "Fn::Equals": [
68 | {
69 | "Ref": "env"
70 | },
71 | "NONE"
72 | ]
73 | }
74 | },
75 | "Resources": {
76 | "LambdaExecutionRole": {
77 | "Condition": "ShouldCreatePinpointApp",
78 | "Type": "AWS::IAM::Role",
79 | "Properties": {
80 | "RoleName": {
81 | "Fn::If": [
82 | "ShouldNotCreateEnvResources",
83 | {
84 | "Ref": "roleName"
85 | },
86 | {
87 | "Fn::Join": [
88 | "",
89 | [
90 | {
91 | "Ref": "roleName"
92 | },
93 | "-",
94 | {
95 | "Ref": "env"
96 | }
97 | ]
98 | ]
99 | }
100 | ]
101 | },
102 | "AssumeRolePolicyDocument": {
103 | "Version": "2012-10-17",
104 | "Statement": [
105 | {
106 | "Effect": "Allow",
107 | "Principal": {
108 | "Service": [
109 | "lambda.amazonaws.com"
110 | ]
111 | },
112 | "Action": [
113 | "sts:AssumeRole"
114 | ]
115 | }
116 | ]
117 | },
118 | "Policies": [
119 | {
120 | "PolicyName": {
121 | "Ref": "cloudWatchPolicyName"
122 | },
123 | "PolicyDocument": {
124 | "Version": "2012-10-17",
125 | "Statement": [
126 | {
127 | "Effect": "Allow",
128 | "Action": [
129 | "logs:CreateLogGroup",
130 | "logs:CreateLogStream",
131 | "logs:PutLogEvents"
132 | ],
133 | "Resource": "arn:aws:logs:*:*:*"
134 | }
135 | ]
136 | }
137 | },
138 | {
139 | "PolicyName": {
140 | "Ref": "pinpointPolicyName"
141 | },
142 | "PolicyDocument": {
143 | "Version": "2012-10-17",
144 | "Statement": [
145 | {
146 | "Effect": "Allow",
147 | "Action": [
148 | "mobileanalytics:*",
149 | "mobiletargeting:*"
150 | ],
151 | "Resource": "*"
152 | }
153 | ]
154 | }
155 | },
156 | {
157 | "PolicyName": {
158 | "Ref": "cloudformationPolicyName"
159 | },
160 | "PolicyDocument": {
161 | "Version": "2012-10-17",
162 | "Statement": [
163 | {
164 | "Effect": "Allow",
165 | "Action": [
166 | "cloudformation:*"
167 | ],
168 | "Resource": "*"
169 | }
170 | ]
171 | }
172 | }
173 | ]
174 | }
175 | },
176 | "PinpointFunction": {
177 | "Type": "AWS::Lambda::Function",
178 | "Condition": "ShouldCreatePinpointApp",
179 | "Properties": {
180 | "Code": {
181 | "ZipFile": {
182 | "Fn::Join": [
183 | "\n",
184 | [
185 | "const response = require('cfn-response');",
186 | "const aws = require('aws-sdk');",
187 | "exports.handler = function(event, context) {",
188 | " if (event.RequestType == 'Delete') {",
189 | " const stackID = event.StackId;",
190 | " const cloudFormationClient = new aws.CloudFormation({ apiVersion: '2016-12-01', region: event.ResourceProperties.region });",
191 | " cloudFormationClient.describeStacks({ StackName: stackID }).promise()",
192 | " .then(describeStacksOutput => {",
193 | " let appId;",
194 | " if (describeStacksOutput.Stacks && describeStacksOutput.Stacks.length > 0) {",
195 | " const { Outputs } = describeStacksOutput.Stacks[0];",
196 | " const appIdOutput = Outputs.find((output)=>{ return output.OutputKey === 'Id'});",
197 | " appId = appIdOutput ? appIdOutput.OutputValue : undefined; ",
198 | " }",
199 | " return appId;",
200 | " })",
201 | " .then(appId => {",
202 | " if (appId) {",
203 | " const pinpointClient = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
204 | " const params = {",
205 | " ApplicationId: appId,",
206 | " };",
207 | " pinpointClient.deleteApp(params).promise();",
208 | " }",
209 | " })",
210 | " .then(()=>{",
211 | " response.send(event, context, response.SUCCESS, {'message': `Successfully deleted pinpoint project`});",
212 | " })",
213 | " .catch(e=>{",
214 | " response.send(event, context, response.FAILED, {'message': `Failed to deleted Pinpoint project`, 'exception': e});",
215 | " }); ",
216 | " }",
217 | " if (event.RequestType == 'Update') {",
218 | " response.send(event, context, response.SUCCESS);",
219 | " return;",
220 | " }",
221 | " if (event.RequestType == 'Create') {",
222 | " const appName = event.ResourceProperties.appName;",
223 | " let responseData = {};",
224 | " const params = {",
225 | " CreateApplicationRequest: {",
226 | " Name: appName",
227 | " }",
228 | " };",
229 | " const pinpoint = new aws.Pinpoint({ apiVersion: '2016-12-01', region: event.ResourceProperties.pingPointRegion });",
230 | " pinpoint.createApp(params).promise()",
231 | " .then((res) => {",
232 | " responseData = res.ApplicationResponse;",
233 | " response.send(event, context, response.SUCCESS, responseData);",
234 | " }).catch((err) => {",
235 | " console.log(err.stack);",
236 | " responseData = {Error: err};",
237 | " response.send(event, context, response.FAILED, responseData);",
238 | " throw err;",
239 | " });",
240 | " }",
241 | "};"
242 | ]
243 | ]
244 | }
245 | },
246 | "Handler": "index.handler",
247 | "Runtime": "nodejs12.x",
248 | "Timeout": "300",
249 | "Role": {
250 | "Fn::GetAtt": [
251 | "LambdaExecutionRole",
252 | "Arn"
253 | ]
254 | }
255 | }
256 | },
257 | "PinpointFunctionOutputs": {
258 | "Type": "Custom::LambdaCallout",
259 | "Condition": "ShouldCreatePinpointApp",
260 | "Properties": {
261 | "ServiceToken": {
262 | "Fn::GetAtt": [
263 | "PinpointFunction",
264 | "Arn"
265 | ]
266 | },
267 | "region": {
268 | "Ref": "AWS::Region"
269 | },
270 | "pingPointRegion": {
271 | "Fn::FindInMap": [
272 | "RegionMapping",
273 | {
274 | "Ref": "AWS::Region"
275 | },
276 | "pinpointRegion"
277 | ]
278 | },
279 | "appName": {
280 | "Fn::If": [
281 | "ShouldNotCreateEnvResources",
282 | {
283 | "Ref": "appName"
284 | },
285 | {
286 | "Fn::Join": [
287 | "",
288 | [
289 | {
290 | "Ref": "appName"
291 | },
292 | "-",
293 | {
294 | "Ref": "env"
295 | }
296 | ]
297 | ]
298 | }
299 | ]
300 | }
301 | },
302 | "DependsOn": "PinpointFunction"
303 | },
304 | "CognitoUnauthPolicy": {
305 | "Type": "AWS::IAM::Policy",
306 | "Condition": "ShouldCreatePinpointApp",
307 | "Properties": {
308 | "PolicyName": {
309 | "Ref": "unauthPolicyName"
310 | },
311 | "Roles": [
312 | {
313 | "Ref": "unauthRoleName"
314 | }
315 | ],
316 | "PolicyDocument": {
317 | "Version": "2012-10-17",
318 | "Statement": [
319 | {
320 | "Effect": "Allow",
321 | "Action": [
322 | "mobiletargeting:PutEvents",
323 | "mobiletargeting:UpdateEndpoint"
324 | ],
325 | "Resource": [
326 | {
327 | "Fn::If": [
328 | "ShouldCreatePinpointApp",
329 | {
330 | "Fn::Join": [
331 | "",
332 | [
333 | "arn:aws:mobiletargeting:*:",
334 | {
335 | "Fn::Select": [
336 | "4",
337 | {
338 | "Fn::Split": [
339 | ":",
340 | {
341 | "Ref": "authRoleArn"
342 | }
343 | ]
344 | }
345 | ]
346 | },
347 | ":apps/",
348 | {
349 | "Fn::GetAtt": [
350 | "PinpointFunctionOutputs",
351 | "Id"
352 | ]
353 | },
354 | "*"
355 | ]
356 | ]
357 | },
358 | {
359 | "Fn::Join": [
360 | "",
361 | [
362 | "arn:aws:mobiletargeting:*:",
363 | {
364 | "Fn::Select": [
365 | "4",
366 | {
367 | "Fn::Split": [
368 | ":",
369 | {
370 | "Ref": "authRoleArn"
371 | }
372 | ]
373 | }
374 | ]
375 | },
376 | ":apps/",
377 | {
378 | "Ref": "appId"
379 | },
380 | "*"
381 | ]
382 | ]
383 | }
384 | ]
385 | }
386 | ]
387 | }
388 | ]
389 | }
390 | }
391 | },
392 | "CognitoAuthPolicy": {
393 | "Type": "AWS::IAM::Policy",
394 | "Condition": "ShouldCreatePinpointApp",
395 | "Properties": {
396 | "PolicyName": {
397 | "Ref": "authPolicyName"
398 | },
399 | "Roles": [
400 | {
401 | "Ref": "authRoleName"
402 | }
403 | ],
404 | "PolicyDocument": {
405 | "Version": "2012-10-17",
406 | "Statement": [
407 | {
408 | "Effect": "Allow",
409 | "Action": [
410 | "mobiletargeting:PutEvents",
411 | "mobiletargeting:UpdateEndpoint"
412 | ],
413 | "Resource": [
414 | {
415 | "Fn::If": [
416 | "ShouldCreatePinpointApp",
417 | {
418 | "Fn::Join": [
419 | "",
420 | [
421 | "arn:aws:mobiletargeting:*:",
422 | {
423 | "Fn::Select": [
424 | "4",
425 | {
426 | "Fn::Split": [
427 | ":",
428 | {
429 | "Ref": "authRoleArn"
430 | }
431 | ]
432 | }
433 | ]
434 | },
435 | ":apps/",
436 | {
437 | "Fn::GetAtt": [
438 | "PinpointFunctionOutputs",
439 | "Id"
440 | ]
441 | },
442 | "*"
443 | ]
444 | ]
445 | },
446 | {
447 | "Fn::Join": [
448 | "",
449 | [
450 | "arn:aws:mobiletargeting:*:",
451 | {
452 | "Fn::Select": [
453 | "4",
454 | {
455 | "Fn::Split": [
456 | ":",
457 | {
458 | "Ref": "authRoleArn"
459 | }
460 | ]
461 | }
462 | ]
463 | },
464 | ":apps/",
465 | {
466 | "Ref": "appId"
467 | },
468 | "*"
469 | ]
470 | ]
471 | }
472 | ]
473 | }
474 | ]
475 | }
476 | ]
477 | }
478 | }
479 | }
480 | },
481 | "Outputs": {
482 | "Region": {
483 | "Value": {
484 | "Fn::FindInMap": [
485 | "RegionMapping",
486 | {
487 | "Ref": "AWS::Region"
488 | },
489 | "pinpointRegion"
490 | ]
491 | }
492 | },
493 | "Id": {
494 | "Value": {
495 | "Fn::If": [
496 | "ShouldCreatePinpointApp",
497 | {
498 | "Fn::GetAtt": [
499 | "PinpointFunctionOutputs",
500 | "Id"
501 | ]
502 | },
503 | {
504 | "Ref": "appId"
505 | }
506 | ]
507 | }
508 | },
509 | "appName": {
510 | "Value": {
511 | "Fn::If": [
512 | "ShouldCreatePinpointApp",
513 | {
514 | "Fn::GetAtt": [
515 | "PinpointFunctionOutputs",
516 | "Name"
517 | ]
518 | },
519 | {
520 | "Ref": "appName"
521 | }
522 | ]
523 | }
524 | }
525 | },
526 | "Mappings": {
527 | "RegionMapping": {
528 | "us-east-1": {
529 | "pinpointRegion": "us-east-1"
530 | },
531 | "us-east-2": {
532 | "pinpointRegion": "us-east-1"
533 | },
534 | "sa-east-1": {
535 | "pinpointRegion": "us-east-1"
536 | },
537 | "ca-central-1": {
538 | "pinpointRegion": "us-east-1"
539 | },
540 | "us-west-1": {
541 | "pinpointRegion": "us-west-2"
542 | },
543 | "us-west-2": {
544 | "pinpointRegion": "us-west-2"
545 | },
546 | "cn-north-1": {
547 | "pinpointRegion": "us-west-2"
548 | },
549 | "cn-northwest-1": {
550 | "pinpointRegion": "us-west-2"
551 | },
552 | "ap-south-1": {
553 | "pinpointRegion": "us-west-2"
554 | },
555 | "ap-northeast-3": {
556 | "pinpointRegion": "us-west-2"
557 | },
558 | "ap-northeast-2": {
559 | "pinpointRegion": "us-west-2"
560 | },
561 | "ap-southeast-1": {
562 | "pinpointRegion": "us-west-2"
563 | },
564 | "ap-southeast-2": {
565 | "pinpointRegion": "us-west-2"
566 | },
567 | "ap-northeast-1": {
568 | "pinpointRegion": "us-west-2"
569 | },
570 | "eu-central-1": {
571 | "pinpointRegion": "eu-central-1"
572 | },
573 | "eu-west-1": {
574 | "pinpointRegion": "eu-west-1"
575 | },
576 | "eu-west-2": {
577 | "pinpointRegion": "eu-west-1"
578 | },
579 | "eu-west-3": {
580 | "pinpointRegion": "eu-west-1"
581 | }
582 | }
583 | }
584 | }
--------------------------------------------------------------------------------
/amplify/backend/api/amplifytodoapp/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "AppSyncApiName": "amplifytodoapp",
3 | "DynamoDBBillingMode": "PAY_PER_REQUEST",
4 | "DynamoDBEnableServerSideEncryption": false
5 | }
--------------------------------------------------------------------------------
/amplify/backend/api/amplifytodoapp/resolvers/README.md:
--------------------------------------------------------------------------------
1 | Any resolvers that you add in this directory will override the ones automatically generated by Amplify CLI and will be directly copied to the cloud.
2 | For more information, visit [https://docs.amplify.aws/cli/graphql-transformer/resolvers](https://docs.amplify.aws/cli/graphql-transformer/resolvers)
--------------------------------------------------------------------------------
/amplify/backend/api/amplifytodoapp/schema.graphql:
--------------------------------------------------------------------------------
1 | type Todo @model @auth(rules: [{allow: public}]) @key(name: "byUser", fields: ["userId"]) {
2 | id: ID!
3 | name: String!
4 | createdAt: AWSDateTime
5 | updatedAt: AWSDateTime
6 | isDone: Boolean
7 | userId: ID!
8 | }
9 |
10 | type Users @model @auth(rules: [{allow: public}]) {
11 | id: ID!
12 | username: String
13 | email: AWSEmail
14 | imageKey: String!
15 | imageUrl: String!
16 | isVerified: Boolean
17 | createdAt: AWSDateTime
18 | todos: [Todo] @connection(keyName: "byUser", fields: ["id"])
19 |
20 | }
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/amplify/backend/api/amplifytodoapp/stacks/CustomResources.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "An auto-generated nested stack.",
4 | "Metadata": {},
5 | "Parameters": {
6 | "AppSyncApiId": {
7 | "Type": "String",
8 | "Description": "The id of the AppSync API associated with this project."
9 | },
10 | "AppSyncApiName": {
11 | "Type": "String",
12 | "Description": "The name of the AppSync API",
13 | "Default": "AppSyncSimpleTransform"
14 | },
15 | "env": {
16 | "Type": "String",
17 | "Description": "The environment name. e.g. Dev, Test, or Production",
18 | "Default": "NONE"
19 | },
20 | "S3DeploymentBucket": {
21 | "Type": "String",
22 | "Description": "The S3 bucket containing all deployment assets for the project."
23 | },
24 | "S3DeploymentRootKey": {
25 | "Type": "String",
26 | "Description": "An S3 key relative to the S3DeploymentBucket that points to the root\nof the deployment directory."
27 | }
28 | },
29 | "Resources": {
30 | "EmptyResource": {
31 | "Type": "Custom::EmptyResource",
32 | "Condition": "AlwaysFalse"
33 | }
34 | },
35 | "Conditions": {
36 | "HasEnvironmentParameter": {
37 | "Fn::Not": [
38 | {
39 | "Fn::Equals": [
40 | {
41 | "Ref": "env"
42 | },
43 | "NONE"
44 | ]
45 | }
46 | ]
47 | },
48 | "AlwaysFalse": {
49 | "Fn::Equals": ["true", "false"]
50 | }
51 | },
52 | "Outputs": {
53 | "EmptyOutput": {
54 | "Description": "An empty output. You may delete this if you have at least one resource above.",
55 | "Value": ""
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/amplify/backend/api/amplifytodoapp/transform.conf.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": 5,
3 | "ElasticsearchWarning": true,
4 | "ResolverConfig": {
5 | "project": {
6 | "ConflictHandler": "AUTOMERGE",
7 | "ConflictDetection": "VERSION"
8 | }
9 | }
10 | }
--------------------------------------------------------------------------------
/amplify/backend/auth/amplifytodoapp/amplifytodoapp-cloudformation-template.yml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: 2010-09-09
2 |
3 | Parameters:
4 | env:
5 | Type: String
6 | authRoleArn:
7 | Type: String
8 | unauthRoleArn:
9 | Type: String
10 |
11 |
12 |
13 |
14 | identityPoolName:
15 | Type: String
16 |
17 |
18 |
19 | allowUnauthenticatedIdentities:
20 | Type: String
21 |
22 | resourceNameTruncated:
23 | Type: String
24 |
25 |
26 | userPoolName:
27 | Type: String
28 |
29 |
30 |
31 | autoVerifiedAttributes:
32 | Type: CommaDelimitedList
33 |
34 | mfaConfiguration:
35 | Type: String
36 |
37 |
38 |
39 | mfaTypes:
40 | Type: CommaDelimitedList
41 |
42 | smsAuthenticationMessage:
43 | Type: String
44 |
45 |
46 | smsVerificationMessage:
47 | Type: String
48 |
49 |
50 | emailVerificationSubject:
51 | Type: String
52 |
53 |
54 | emailVerificationMessage:
55 | Type: String
56 |
57 |
58 |
59 | defaultPasswordPolicy:
60 | Type: String
61 |
62 |
63 | passwordPolicyMinLength:
64 | Type: Number
65 |
66 |
67 | passwordPolicyCharacters:
68 | Type: CommaDelimitedList
69 |
70 |
71 | requiredAttributes:
72 | Type: CommaDelimitedList
73 |
74 |
75 | userpoolClientGenerateSecret:
76 | Type: String
77 |
78 |
79 | userpoolClientRefreshTokenValidity:
80 | Type: Number
81 |
82 |
83 | userpoolClientWriteAttributes:
84 | Type: CommaDelimitedList
85 |
86 |
87 | userpoolClientReadAttributes:
88 | Type: CommaDelimitedList
89 |
90 | userpoolClientLambdaRole:
91 | Type: String
92 |
93 |
94 |
95 | userpoolClientSetAttributes:
96 | Type: String
97 |
98 | sharedId:
99 | Type: String
100 |
101 |
102 | resourceName:
103 | Type: String
104 |
105 |
106 | authSelections:
107 | Type: String
108 |
109 |
110 |
111 |
112 | serviceName:
113 | Type: String
114 |
115 |
116 |
117 | usernameAttributes:
118 | Type: CommaDelimitedList
119 |
120 | useDefault:
121 | Type: String
122 |
123 |
124 |
125 | userPoolGroups:
126 | Type: String
127 |
128 |
129 | userPoolGroupList:
130 | Type: CommaDelimitedList
131 |
132 |
133 | adminQueries:
134 | Type: String
135 |
136 |
137 | thirdPartyAuth:
138 | Type: String
139 |
140 |
141 | authProviders:
142 | Type: CommaDelimitedList
143 |
144 |
145 | usernameCaseSensitive:
146 | Type: String
147 |
148 |
149 | dependsOn:
150 | Type: CommaDelimitedList
151 |
152 | Conditions:
153 | ShouldNotCreateEnvResources: !Equals [ !Ref env, NONE ]
154 |
155 | ShouldOutputAppClientSecrets: !Equals [!Ref userpoolClientGenerateSecret, true ]
156 |
157 |
158 | Resources:
159 |
160 |
161 | # BEGIN SNS ROLE RESOURCE
162 | SNSRole:
163 | # Created to allow the UserPool SMS Config to publish via the Simple Notification Service during MFA Process
164 | Type: AWS::IAM::Role
165 | Properties:
166 | RoleName: !If [ShouldNotCreateEnvResources, 'amplif249d9f98_sns-role', !Join ['',[ 'sns', '249d9f98', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
167 | AssumeRolePolicyDocument:
168 | Version: "2012-10-17"
169 | Statement:
170 | - Sid: ""
171 | Effect: "Allow"
172 | Principal:
173 | Service: "cognito-idp.amazonaws.com"
174 | Action:
175 | - "sts:AssumeRole"
176 | Condition:
177 | StringEquals:
178 | sts:ExternalId: amplif249d9f98_role_external_id
179 | Policies:
180 | -
181 | PolicyName: amplif249d9f98-sns-policy
182 | PolicyDocument:
183 | Version: "2012-10-17"
184 | Statement:
185 | -
186 | Effect: "Allow"
187 | Action:
188 | - "sns:Publish"
189 | Resource: "*"
190 | # BEGIN USER POOL RESOURCES
191 | UserPool:
192 | # Created upon user selection
193 | # Depends on SNS Role for Arn if MFA is enabled
194 | Type: AWS::Cognito::UserPool
195 | UpdateReplacePolicy: Retain
196 | Properties:
197 | UserPoolName: !If [ShouldNotCreateEnvResources, !Ref userPoolName, !Join ['',[!Ref userPoolName, '-', !Ref env]]]
198 |
199 |
200 | UsernameConfiguration:
201 | CaseSensitive: false
202 |
203 | Schema:
204 |
205 | -
206 | Name: email
207 | Required: true
208 | Mutable: true
209 |
210 |
211 |
212 |
213 | AutoVerifiedAttributes: !Ref autoVerifiedAttributes
214 |
215 |
216 | EmailVerificationMessage: !Ref emailVerificationMessage
217 | EmailVerificationSubject: !Ref emailVerificationSubject
218 |
219 | Policies:
220 | PasswordPolicy:
221 | MinimumLength: !Ref passwordPolicyMinLength
222 | RequireLowercase: true
223 | RequireNumbers: true
224 | RequireSymbols: true
225 | RequireUppercase: true
226 |
227 | UsernameAttributes: !Ref usernameAttributes
228 |
229 | MfaConfiguration: !Ref mfaConfiguration
230 | SmsVerificationMessage: !Ref smsVerificationMessage
231 | SmsAuthenticationMessage: !Ref smsAuthenticationMessage
232 | SmsConfiguration:
233 | SnsCallerArn: !GetAtt SNSRole.Arn
234 | ExternalId: amplif249d9f98_role_external_id
235 |
236 |
237 | UserPoolClientWeb:
238 | # Created provide application access to user pool
239 | # Depends on UserPool for ID reference
240 | Type: "AWS::Cognito::UserPoolClient"
241 | Properties:
242 | ClientName: amplif249d9f98_app_clientWeb
243 |
244 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
245 | UserPoolId: !Ref UserPool
246 | DependsOn: UserPool
247 | UserPoolClient:
248 | # Created provide application access to user pool
249 | # Depends on UserPool for ID reference
250 | Type: "AWS::Cognito::UserPoolClient"
251 | Properties:
252 | ClientName: amplif249d9f98_app_client
253 |
254 | GenerateSecret: !Ref userpoolClientGenerateSecret
255 | RefreshTokenValidity: !Ref userpoolClientRefreshTokenValidity
256 | UserPoolId: !Ref UserPool
257 | DependsOn: UserPool
258 | # BEGIN USER POOL LAMBDA RESOURCES
259 | UserPoolClientRole:
260 | # Created to execute Lambda which gets userpool app client config values
261 | Type: 'AWS::IAM::Role'
262 | Properties:
263 | RoleName: !If [ShouldNotCreateEnvResources, !Ref userpoolClientLambdaRole, !Join ['',['upClientLambdaRole', '249d9f98', !Select [3, !Split ['-', !Ref 'AWS::StackName']], '-', !Ref env]]]
264 | AssumeRolePolicyDocument:
265 | Version: '2012-10-17'
266 | Statement:
267 | - Effect: Allow
268 | Principal:
269 | Service:
270 | - lambda.amazonaws.com
271 | Action:
272 | - 'sts:AssumeRole'
273 | DependsOn: UserPoolClient
274 | UserPoolClientLambda:
275 | # Lambda which gets userpool app client config values
276 | # Depends on UserPool for id
277 | # Depends on UserPoolClientRole for role ARN
278 | Type: 'AWS::Lambda::Function'
279 | Properties:
280 | Code:
281 | ZipFile: !Join
282 | - |+
283 | - - 'const response = require(''cfn-response'');'
284 | - 'const aws = require(''aws-sdk'');'
285 | - 'const identity = new aws.CognitoIdentityServiceProvider();'
286 | - 'exports.handler = (event, context, callback) => {'
287 | - ' if (event.RequestType == ''Delete'') { '
288 | - ' response.send(event, context, response.SUCCESS, {})'
289 | - ' }'
290 | - ' if (event.RequestType == ''Update'' || event.RequestType == ''Create'') {'
291 | - ' const params = {'
292 | - ' ClientId: event.ResourceProperties.clientId,'
293 | - ' UserPoolId: event.ResourceProperties.userpoolId'
294 | - ' };'
295 | - ' identity.describeUserPoolClient(params).promise()'
296 | - ' .then((res) => {'
297 | - ' response.send(event, context, response.SUCCESS, {''appSecret'': res.UserPoolClient.ClientSecret});'
298 | - ' })'
299 | - ' .catch((err) => {'
300 | - ' response.send(event, context, response.FAILED, {err});'
301 | - ' });'
302 | - ' }'
303 | - '};'
304 | Handler: index.handler
305 | Runtime: nodejs12.x
306 | Timeout: '300'
307 | Role: !GetAtt
308 | - UserPoolClientRole
309 | - Arn
310 | DependsOn: UserPoolClientRole
311 | UserPoolClientLambdaPolicy:
312 | # Sets userpool policy for the role that executes the Userpool Client Lambda
313 | # Depends on UserPool for Arn
314 | # Marked as depending on UserPoolClientRole for easier to understand CFN sequencing
315 | Type: 'AWS::IAM::Policy'
316 | Properties:
317 | PolicyName: amplif249d9f98_userpoolclient_lambda_iam_policy
318 | Roles:
319 | - !Ref UserPoolClientRole
320 | PolicyDocument:
321 | Version: '2012-10-17'
322 | Statement:
323 | - Effect: Allow
324 | Action:
325 | - 'cognito-idp:DescribeUserPoolClient'
326 | Resource: !GetAtt UserPool.Arn
327 | DependsOn: UserPoolClientLambda
328 | UserPoolClientLogPolicy:
329 | # Sets log policy for the role that executes the Userpool Client Lambda
330 | # Depends on UserPool for Arn
331 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
332 | Type: 'AWS::IAM::Policy'
333 | Properties:
334 | PolicyName: amplif249d9f98_userpoolclient_lambda_log_policy
335 | Roles:
336 | - !Ref UserPoolClientRole
337 | PolicyDocument:
338 | Version: 2012-10-17
339 | Statement:
340 | - Effect: Allow
341 | Action:
342 | - 'logs:CreateLogGroup'
343 | - 'logs:CreateLogStream'
344 | - 'logs:PutLogEvents'
345 | Resource: !Sub
346 | - arn:aws:logs:${region}:${account}:log-group:/aws/lambda/${lambda}:log-stream:*
347 | - { region: !Ref "AWS::Region", account: !Ref "AWS::AccountId", lambda: !Ref UserPoolClientLambda}
348 | DependsOn: UserPoolClientLambdaPolicy
349 | UserPoolClientInputs:
350 | # Values passed to Userpool client Lambda
351 | # Depends on UserPool for Id
352 | # Depends on UserPoolClient for Id
353 | # Marked as depending on UserPoolClientLambdaPolicy for easier to understand CFN sequencing
354 | Type: 'Custom::LambdaCallout'
355 | Properties:
356 | ServiceToken: !GetAtt UserPoolClientLambda.Arn
357 | clientId: !Ref UserPoolClient
358 | userpoolId: !Ref UserPool
359 | DependsOn: UserPoolClientLogPolicy
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 | # BEGIN IDENTITY POOL RESOURCES
368 |
369 |
370 | IdentityPool:
371 | # Always created
372 | Type: AWS::Cognito::IdentityPool
373 | Properties:
374 | IdentityPoolName: !If [ShouldNotCreateEnvResources, 'testAuthIdentityPool', !Join ['',['testAuthIdentityPool', '__', !Ref env]]]
375 |
376 | CognitoIdentityProviders:
377 | - ClientId: !Ref UserPoolClient
378 | ProviderName: !Sub
379 | - cognito-idp.${region}.amazonaws.com/${client}
380 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
381 | - ClientId: !Ref UserPoolClientWeb
382 | ProviderName: !Sub
383 | - cognito-idp.${region}.amazonaws.com/${client}
384 | - { region: !Ref "AWS::Region", client: !Ref UserPool}
385 |
386 | AllowUnauthenticatedIdentities: !Ref allowUnauthenticatedIdentities
387 |
388 |
389 | DependsOn: UserPoolClientInputs
390 |
391 |
392 | IdentityPoolRoleMap:
393 | # Created to map Auth and Unauth roles to the identity pool
394 | # Depends on Identity Pool for ID ref
395 | Type: AWS::Cognito::IdentityPoolRoleAttachment
396 | Properties:
397 | IdentityPoolId: !Ref IdentityPool
398 | Roles:
399 | unauthenticated: !Ref unauthRoleArn
400 | authenticated: !Ref authRoleArn
401 | DependsOn: IdentityPool
402 |
403 |
404 | Outputs :
405 |
406 | IdentityPoolId:
407 | Value: !Ref 'IdentityPool'
408 | Description: Id for the identity pool
409 | IdentityPoolName:
410 | Value: !GetAtt IdentityPool.Name
411 |
412 |
413 |
414 |
415 | UserPoolId:
416 | Value: !Ref 'UserPool'
417 | Description: Id for the user pool
418 | UserPoolArn:
419 | Value: !GetAtt UserPool.Arn
420 | Description: Arn for the user pool
421 | UserPoolName:
422 | Value: !Ref userPoolName
423 | AppClientIDWeb:
424 | Value: !Ref 'UserPoolClientWeb'
425 | Description: The user pool app client id for web
426 | AppClientID:
427 | Value: !Ref 'UserPoolClient'
428 | Description: The user pool app client id
429 | AppClientSecret:
430 | Value: !GetAtt UserPoolClientInputs.appSecret
431 | Condition: ShouldOutputAppClientSecrets
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
--------------------------------------------------------------------------------
/amplify/backend/auth/amplifytodoapp/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "identityPoolName": "testAuthIdentityPool",
3 | "allowUnauthenticatedIdentities": true,
4 | "resourceNameTruncated": "amplif249d9f98",
5 | "userPoolName": "amplifytodoapp",
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 auth code: {####}",
16 | "emailVerificationMessage": "auth code: {####}",
17 | "defaultPasswordPolicy": false,
18 | "passwordPolicyMinLength": 8,
19 | "passwordPolicyCharacters": [
20 | "Requires Lowercase",
21 | "Requires Numbers",
22 | "Requires Symbols",
23 | "Requires Uppercase"
24 | ],
25 | "requiredAttributes": [
26 | "email"
27 | ],
28 | "userpoolClientGenerateSecret": false,
29 | "userpoolClientRefreshTokenValidity": 30,
30 | "userpoolClientWriteAttributes": [],
31 | "userpoolClientReadAttributes": [],
32 | "userpoolClientLambdaRole": "amplif249d9f98_userpoolclient_lambda_role",
33 | "userpoolClientSetAttributes": false,
34 | "sharedId": "249d9f98",
35 | "resourceName": "amplifytodoapp",
36 | "authSelections": "identityPoolAndUserPool",
37 | "authRoleArn": {
38 | "Fn::GetAtt": [
39 | "AuthRole",
40 | "Arn"
41 | ]
42 | },
43 | "unauthRoleArn": {
44 | "Fn::GetAtt": [
45 | "UnauthRole",
46 | "Arn"
47 | ]
48 | },
49 | "serviceName": "Cognito",
50 | "usernameAttributes": [
51 | "email"
52 | ],
53 | "useDefault": "manual",
54 | "userPoolGroups": false,
55 | "userPoolGroupList": [],
56 | "adminQueries": false,
57 | "thirdPartyAuth": false,
58 | "authProviders": [],
59 | "usernameCaseSensitive": false,
60 | "dependsOn": []
61 | }
--------------------------------------------------------------------------------
/amplify/backend/backend-config.json:
--------------------------------------------------------------------------------
1 | {
2 | "auth": {
3 | "amplifytodoapp": {
4 | "service": "Cognito",
5 | "providerPlugin": "awscloudformation",
6 | "dependsOn": [],
7 | "customAuth": false
8 | }
9 | },
10 | "api": {
11 | "amplifytodoapp": {
12 | "service": "AppSync",
13 | "providerPlugin": "awscloudformation",
14 | "output": {
15 | "authConfig": {
16 | "defaultAuthentication": {
17 | "authenticationType": "API_KEY",
18 | "apiKeyConfig": {
19 | "apiKeyExpirationDays": 365,
20 | "description": "ToDoAPIKey"
21 | }
22 | },
23 | "additionalAuthenticationProviders": []
24 | }
25 | }
26 | }
27 | },
28 | "analytics": {
29 | "amplifytodoapp": {
30 | "service": "Pinpoint",
31 | "providerPlugin": "awscloudformation"
32 | }
33 | },
34 | "storage": {
35 | "s385ebe3d5": {
36 | "service": "S3",
37 | "providerPlugin": "awscloudformation"
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/amplify/backend/storage/s385ebe3d5/parameters.json:
--------------------------------------------------------------------------------
1 | {
2 | "bucketName": "amplifytodoapp09fdff3699294a6c95477320411e6ed6",
3 | "authPolicyName": "s3_amplify_85ebe3d5",
4 | "unauthPolicyName": "s3_amplify_85ebe3d5",
5 | "authRoleName": {
6 | "Ref": "AuthRoleName"
7 | },
8 | "unauthRoleName": {
9 | "Ref": "UnauthRoleName"
10 | },
11 | "selectedGuestPermissions": [
12 | "s3:GetObject",
13 | "s3:ListBucket"
14 | ],
15 | "selectedAuthenticatedPermissions": [
16 | "s3:PutObject",
17 | "s3:GetObject",
18 | "s3:ListBucket",
19 | "s3:DeleteObject"
20 | ],
21 | "s3PermissionsAuthenticatedPublic": "s3:PutObject,s3:GetObject,s3:DeleteObject",
22 | "s3PublicPolicy": "Public_policy_285916c6",
23 | "s3PermissionsAuthenticatedUploads": "s3:PutObject",
24 | "s3UploadsPolicy": "Uploads_policy_285916c6",
25 | "s3PermissionsAuthenticatedProtected": "s3:PutObject,s3:GetObject,s3:DeleteObject",
26 | "s3ProtectedPolicy": "Protected_policy_285916c6",
27 | "s3PermissionsAuthenticatedPrivate": "s3:PutObject,s3:GetObject,s3:DeleteObject",
28 | "s3PrivatePolicy": "Private_policy_285916c6",
29 | "AuthenticatedAllowList": "ALLOW",
30 | "s3ReadPolicy": "read_policy_285916c6",
31 | "s3PermissionsGuestPublic": "DISALLOW",
32 | "s3PermissionsGuestUploads": "DISALLOW",
33 | "GuestAllowList": "DISALLOW",
34 | "triggerFunction": "NONE"
35 | }
--------------------------------------------------------------------------------
/amplify/backend/storage/s385ebe3d5/s3-cloudformation-template.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion": "2010-09-09",
3 | "Description": "S3 resource stack creation using Amplify CLI",
4 | "Parameters": {
5 | "bucketName": {
6 | "Type": "String"
7 | },
8 | "authPolicyName": {
9 | "Type": "String"
10 | },
11 | "unauthPolicyName": {
12 | "Type": "String"
13 | },
14 | "authRoleName": {
15 | "Type": "String"
16 | },
17 | "unauthRoleName": {
18 | "Type": "String"
19 | },
20 | "s3PublicPolicy": {
21 | "Type": "String",
22 | "Default" : "NONE"
23 | },
24 | "s3PrivatePolicy": {
25 | "Type": "String",
26 | "Default" : "NONE"
27 | },
28 | "s3ProtectedPolicy": {
29 | "Type": "String",
30 | "Default" : "NONE"
31 | },
32 | "s3UploadsPolicy": {
33 | "Type": "String",
34 | "Default" : "NONE"
35 | },
36 | "s3ReadPolicy": {
37 | "Type": "String",
38 | "Default" : "NONE"
39 | },
40 | "s3PermissionsAuthenticatedPublic": {
41 | "Type": "String",
42 | "Default" : "DISALLOW"
43 | },
44 | "s3PermissionsAuthenticatedProtected": {
45 | "Type": "String",
46 | "Default" : "DISALLOW"
47 | },
48 | "s3PermissionsAuthenticatedPrivate": {
49 | "Type": "String",
50 | "Default" : "DISALLOW"
51 | },
52 | "s3PermissionsAuthenticatedUploads": {
53 | "Type": "String",
54 | "Default" : "DISALLOW"
55 | },
56 | "s3PermissionsGuestPublic": {
57 | "Type": "String",
58 | "Default" : "DISALLOW"
59 | },
60 | "s3PermissionsGuestUploads": {
61 | "Type": "String",
62 | "Default" : "DISALLOW" },
63 | "AuthenticatedAllowList": {
64 | "Type": "String",
65 | "Default" : "DISALLOW"
66 | },
67 | "GuestAllowList": {
68 | "Type": "String",
69 | "Default" : "DISALLOW"
70 | },
71 | "selectedGuestPermissions": {
72 | "Type": "CommaDelimitedList",
73 | "Default" : "NONE"
74 | },
75 | "selectedAuthenticatedPermissions": {
76 | "Type": "CommaDelimitedList",
77 | "Default" : "NONE"
78 | },
79 | "env": {
80 | "Type": "String"
81 | },
82 | "triggerFunction": {
83 | "Type": "String"
84 | }
85 |
86 |
87 | },
88 | "Conditions": {
89 | "ShouldNotCreateEnvResources": {
90 | "Fn::Equals": [
91 | {
92 | "Ref": "env"
93 | },
94 | "NONE"
95 | ]
96 | },
97 | "CreateAuthPublic": {
98 | "Fn::Not" : [{
99 | "Fn::Equals" : [
100 | {"Ref" : "s3PermissionsAuthenticatedPublic"},
101 | "DISALLOW"
102 | ]
103 | }]
104 | },
105 | "CreateAuthProtected": {
106 | "Fn::Not" : [{
107 | "Fn::Equals" : [
108 | {"Ref" : "s3PermissionsAuthenticatedProtected"},
109 | "DISALLOW"
110 | ]
111 | }]
112 | },
113 | "CreateAuthPrivate": {
114 | "Fn::Not" : [{
115 | "Fn::Equals" : [
116 | {"Ref" : "s3PermissionsAuthenticatedPrivate"},
117 | "DISALLOW"
118 | ]
119 | }]
120 | },
121 | "CreateAuthUploads": {
122 | "Fn::Not" : [{
123 | "Fn::Equals" : [
124 | {"Ref" : "s3PermissionsAuthenticatedUploads"},
125 | "DISALLOW"
126 | ]
127 | }]
128 | },
129 | "CreateGuestPublic": {
130 | "Fn::Not" : [{
131 | "Fn::Equals" : [
132 | {"Ref" : "s3PermissionsGuestPublic"},
133 | "DISALLOW"
134 | ]
135 | }]
136 | },
137 | "CreateGuestUploads": {
138 | "Fn::Not" : [{
139 | "Fn::Equals" : [
140 | {"Ref" : "s3PermissionsGuestUploads"},
141 | "DISALLOW"
142 | ]
143 | }]
144 | },
145 | "AuthReadAndList": {
146 | "Fn::Not" : [{
147 | "Fn::Equals" : [
148 | {"Ref" : "AuthenticatedAllowList"},
149 | "DISALLOW"
150 | ]
151 | }]
152 | },
153 | "GuestReadAndList": {
154 | "Fn::Not" : [{
155 | "Fn::Equals" : [
156 | {"Ref" : "GuestAllowList"},
157 | "DISALLOW"
158 | ]
159 | }]
160 | }
161 | },
162 | "Resources": {
163 | "S3Bucket": {
164 | "Type": "AWS::S3::Bucket",
165 |
166 | "DeletionPolicy" : "Retain",
167 | "Properties": {
168 | "BucketName": {
169 | "Fn::If": [
170 | "ShouldNotCreateEnvResources",
171 | {
172 | "Ref": "bucketName"
173 | },
174 | {
175 | "Fn::Join": [
176 | "",
177 | [
178 | {
179 | "Ref": "bucketName"
180 | },
181 | {
182 | "Fn::Select": [
183 | 3,
184 | {
185 | "Fn::Split": [
186 | "-",
187 | {
188 | "Ref": "AWS::StackName"
189 | }
190 | ]
191 | }
192 | ]
193 | },
194 | "-",
195 | {
196 | "Ref": "env"
197 | }
198 | ]
199 | ]
200 | }
201 | ]
202 | },
203 |
204 | "CorsConfiguration": {
205 | "CorsRules": [
206 | {
207 | "AllowedHeaders": [
208 | "*"
209 | ],
210 | "AllowedMethods": [
211 | "GET",
212 | "HEAD",
213 | "PUT",
214 | "POST",
215 | "DELETE"
216 | ],
217 | "AllowedOrigins": [
218 | "*"
219 | ],
220 | "ExposedHeaders": [
221 | "x-amz-server-side-encryption",
222 | "x-amz-request-id",
223 | "x-amz-id-2",
224 | "ETag"
225 | ],
226 | "Id": "S3CORSRuleId1",
227 | "MaxAge": "3000"
228 | }
229 | ]
230 | }
231 | }
232 | },
233 |
234 |
235 | "S3AuthPublicPolicy": {
236 | "DependsOn": [
237 | "S3Bucket"
238 | ],
239 | "Condition": "CreateAuthPublic",
240 | "Type": "AWS::IAM::Policy",
241 | "Properties": {
242 | "PolicyName": {
243 | "Ref": "s3PublicPolicy"
244 | },
245 | "Roles": [
246 | {
247 | "Ref": "authRoleName"
248 | }
249 | ],
250 | "PolicyDocument": {
251 | "Version": "2012-10-17",
252 | "Statement": [
253 | {
254 | "Effect": "Allow",
255 | "Action": {
256 | "Fn::Split" : [ "," , {
257 | "Ref": "s3PermissionsAuthenticatedPublic"
258 | } ]
259 | },
260 | "Resource": [
261 | {
262 | "Fn::Join": [
263 | "",
264 | [
265 | "arn:aws:s3:::",
266 | {
267 | "Ref": "S3Bucket"
268 | },
269 | "/public/*"
270 | ]
271 | ]
272 | }
273 | ]
274 | }
275 | ]
276 | }
277 | }
278 | },
279 | "S3AuthProtectedPolicy": {
280 | "DependsOn": [
281 | "S3Bucket"
282 | ],
283 | "Condition": "CreateAuthProtected",
284 | "Type": "AWS::IAM::Policy",
285 | "Properties": {
286 | "PolicyName": {
287 | "Ref": "s3ProtectedPolicy"
288 | },
289 | "Roles": [
290 | {
291 | "Ref": "authRoleName"
292 | }
293 | ],
294 | "PolicyDocument": {
295 | "Version": "2012-10-17",
296 | "Statement": [
297 | {
298 | "Effect": "Allow",
299 | "Action": {
300 | "Fn::Split" : [ "," , {
301 | "Ref": "s3PermissionsAuthenticatedProtected"
302 | } ]
303 | },
304 | "Resource": [
305 | {
306 | "Fn::Join": [
307 | "",
308 | [
309 | "arn:aws:s3:::",
310 | {
311 | "Ref": "S3Bucket"
312 | },
313 | "/protected/${cognito-identity.amazonaws.com:sub}/*"
314 | ]
315 | ]
316 | }
317 | ]
318 | }
319 | ]
320 | }
321 | }
322 | },
323 | "S3AuthPrivatePolicy": {
324 | "DependsOn": [
325 | "S3Bucket"
326 | ],
327 | "Condition": "CreateAuthPrivate",
328 | "Type": "AWS::IAM::Policy",
329 | "Properties": {
330 | "PolicyName": {
331 | "Ref": "s3PrivatePolicy"
332 | },
333 | "Roles": [
334 | {
335 | "Ref": "authRoleName"
336 | }
337 | ],
338 | "PolicyDocument": {
339 | "Version": "2012-10-17",
340 | "Statement": [
341 | {
342 | "Effect": "Allow",
343 | "Action": {
344 | "Fn::Split" : [ "," , {
345 | "Ref": "s3PermissionsAuthenticatedPrivate"
346 | } ]
347 | },
348 | "Resource": [
349 | {
350 | "Fn::Join": [
351 | "",
352 | [
353 | "arn:aws:s3:::",
354 | {
355 | "Ref": "S3Bucket"
356 | },
357 | "/private/${cognito-identity.amazonaws.com:sub}/*"
358 | ]
359 | ]
360 | }
361 | ]
362 | }
363 | ]
364 | }
365 | }
366 | },
367 | "S3AuthUploadPolicy": {
368 | "DependsOn": [
369 | "S3Bucket"
370 | ],
371 | "Condition": "CreateAuthUploads",
372 | "Type": "AWS::IAM::Policy",
373 | "Properties": {
374 | "PolicyName": {
375 | "Ref": "s3UploadsPolicy"
376 | },
377 | "Roles": [
378 | {
379 | "Ref": "authRoleName"
380 | }
381 | ],
382 | "PolicyDocument": {
383 | "Version": "2012-10-17",
384 | "Statement": [
385 | {
386 | "Effect": "Allow",
387 | "Action": {
388 | "Fn::Split" : [ "," , {
389 | "Ref": "s3PermissionsAuthenticatedUploads"
390 | } ]
391 | },
392 | "Resource": [
393 | {
394 | "Fn::Join": [
395 | "",
396 | [
397 | "arn:aws:s3:::",
398 | {
399 | "Ref": "S3Bucket"
400 | },
401 | "/uploads/*"
402 | ]
403 | ]
404 | }
405 | ]
406 | }
407 | ]
408 | }
409 | }
410 | },
411 | "S3AuthReadPolicy": {
412 | "DependsOn": [
413 | "S3Bucket"
414 | ],
415 | "Condition": "AuthReadAndList",
416 | "Type": "AWS::IAM::Policy",
417 | "Properties": {
418 | "PolicyName": {
419 | "Ref": "s3ReadPolicy"
420 | },
421 | "Roles": [
422 | {
423 | "Ref": "authRoleName"
424 | }
425 | ],
426 | "PolicyDocument": {
427 | "Version": "2012-10-17",
428 | "Statement": [
429 | {
430 | "Effect": "Allow",
431 | "Action": [
432 | "s3:GetObject"
433 | ],
434 | "Resource": [
435 | {
436 | "Fn::Join": [
437 | "",
438 | [
439 | "arn:aws:s3:::",
440 | {
441 | "Ref": "S3Bucket"
442 | },
443 | "/protected/*"
444 | ]
445 | ]
446 | }
447 | ]
448 | },
449 | {
450 | "Effect": "Allow",
451 | "Action": [
452 | "s3:ListBucket"
453 | ],
454 | "Resource": [
455 | {
456 | "Fn::Join": [
457 | "",
458 | [
459 | "arn:aws:s3:::",
460 | {
461 | "Ref": "S3Bucket"
462 | }
463 | ]
464 | ]
465 | }
466 | ],
467 | "Condition": {
468 | "StringLike": {
469 | "s3:prefix": [
470 | "public/",
471 | "public/*",
472 | "protected/",
473 | "protected/*",
474 | "private/${cognito-identity.amazonaws.com:sub}/",
475 | "private/${cognito-identity.amazonaws.com:sub}/*"
476 | ]
477 | }
478 | }
479 | }
480 | ]
481 | }
482 | }
483 | },
484 | "S3GuestPublicPolicy": {
485 | "DependsOn": [
486 | "S3Bucket"
487 | ],
488 | "Condition": "CreateGuestPublic",
489 | "Type": "AWS::IAM::Policy",
490 | "Properties": {
491 | "PolicyName": {
492 | "Ref": "s3PublicPolicy"
493 | },
494 | "Roles": [
495 | {
496 | "Ref": "unauthRoleName"
497 | }
498 | ],
499 | "PolicyDocument": {
500 | "Version": "2012-10-17",
501 | "Statement": [
502 | {
503 | "Effect": "Allow",
504 | "Action": {
505 | "Fn::Split" : [ "," , {
506 | "Ref": "s3PermissionsGuestPublic"
507 | } ]
508 | },
509 | "Resource": [
510 | {
511 | "Fn::Join": [
512 | "",
513 | [
514 | "arn:aws:s3:::",
515 | {
516 | "Ref": "S3Bucket"
517 | },
518 | "/public/*"
519 | ]
520 | ]
521 | }
522 | ]
523 | }
524 | ]
525 | }
526 | }
527 | },
528 | "S3GuestUploadPolicy": {
529 | "DependsOn": [
530 | "S3Bucket"
531 | ],
532 | "Condition": "CreateGuestUploads",
533 | "Type": "AWS::IAM::Policy",
534 | "Properties": {
535 | "PolicyName": {
536 | "Ref": "s3UploadsPolicy"
537 | },
538 | "Roles": [
539 | {
540 | "Ref": "unauthRoleName"
541 | }
542 | ],
543 | "PolicyDocument": {
544 | "Version": "2012-10-17",
545 | "Statement": [
546 | {
547 | "Effect": "Allow",
548 | "Action": {
549 | "Fn::Split" : [ "," , {
550 | "Ref": "s3PermissionsGuestUploads"
551 | } ]
552 | },
553 | "Resource": [
554 | {
555 | "Fn::Join": [
556 | "",
557 | [
558 | "arn:aws:s3:::",
559 | {
560 | "Ref": "S3Bucket"
561 | },
562 | "/uploads/*"
563 | ]
564 | ]
565 | }
566 | ]
567 | }
568 | ]
569 | }
570 | }
571 | },
572 | "S3GuestReadPolicy": {
573 | "DependsOn": [
574 | "S3Bucket"
575 | ],
576 | "Condition": "GuestReadAndList",
577 | "Type": "AWS::IAM::Policy",
578 | "Properties": {
579 | "PolicyName": {
580 | "Ref": "s3ReadPolicy"
581 | },
582 | "Roles": [
583 | {
584 | "Ref": "unauthRoleName"
585 | }
586 | ],
587 | "PolicyDocument": {
588 | "Version": "2012-10-17",
589 | "Statement": [
590 | {
591 | "Effect": "Allow",
592 | "Action": [
593 | "s3:GetObject"
594 | ],
595 | "Resource": [
596 | {
597 | "Fn::Join": [
598 | "",
599 | [
600 | "arn:aws:s3:::",
601 | {
602 | "Ref": "S3Bucket"
603 | },
604 | "/protected/*"
605 | ]
606 | ]
607 | }
608 | ]
609 | },
610 | {
611 | "Effect": "Allow",
612 | "Action": [
613 | "s3:ListBucket"
614 | ],
615 | "Resource": [
616 | {
617 | "Fn::Join": [
618 | "",
619 | [
620 | "arn:aws:s3:::",
621 | {
622 | "Ref": "S3Bucket"
623 | }
624 | ]
625 | ]
626 | }
627 | ],
628 | "Condition": {
629 | "StringLike": {
630 | "s3:prefix": [
631 | "public/",
632 | "public/*",
633 | "protected/",
634 | "protected/*"
635 | ]
636 | }
637 | }
638 | }
639 | ]
640 | }
641 | }
642 | }
643 | },
644 | "Outputs": {
645 | "BucketName": {
646 | "Value": {
647 | "Ref": "S3Bucket"
648 | },
649 | "Description": "Bucket name for the S3 bucket"
650 | },
651 | "Region": {
652 | "Value": {
653 | "Ref": "AWS::Region"
654 | }
655 | }
656 | }
657 | }
658 |
--------------------------------------------------------------------------------
/amplify/backend/storage/s385ebe3d5/storage-params.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/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/cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "features": {
3 | "graphqltransformer": {
4 | "addmissingownerfields": true,
5 | "validatetypenamereservedwords": true,
6 | "useexperimentalpipelinedtransformer": false,
7 | "enableiterativegsiupdates": true,
8 | "secondarykeyasgsi": true,
9 | "skipoverridemutationinputtypes": true
10 | },
11 | "frontend-ios": {
12 | "enablexcodeintegration": true
13 | },
14 | "auth": {
15 | "enablecaseinsensitivity": true,
16 | "useinclusiveterminology": true
17 | },
18 | "codegen": {
19 | "useappsyncmodelgenplugin": true,
20 | "usedocsgeneratorplugin": true,
21 | "usetypesgeneratorplugin": true,
22 | "cleangeneratedmodelsdirectory": true,
23 | "retaincasestyle": true,
24 | "enableDartNullSafety": true
25 | },
26 | "appsync": {
27 | "generategraphqlpermissions": true
28 | }
29 | }
30 | }
--------------------------------------------------------------------------------
/amplify/team-provider-info.json:
--------------------------------------------------------------------------------
1 | {
2 | "staging": {
3 | "awscloudformation": {
4 | "AuthRoleName": "amplify-amplifytodoapp-staging-221527-authRole",
5 | "UnauthRoleArn": "arn:aws:iam::279012124572:role/amplify-amplifytodoapp-staging-221527-unauthRole",
6 | "AuthRoleArn": "arn:aws:iam::279012124572:role/amplify-amplifytodoapp-staging-221527-authRole",
7 | "Region": "us-east-1",
8 | "DeploymentBucketName": "amplify-amplifytodoapp-staging-221527-deployment",
9 | "UnauthRoleName": "amplify-amplifytodoapp-staging-221527-unauthRole",
10 | "StackName": "amplify-amplifytodoapp-staging-221527",
11 | "StackId": "arn:aws:cloudformation:us-east-1:279012124572:stack/amplify-amplifytodoapp-staging-221527/ba4f1900-af81-11eb-b8f5-0e892a71c9a9",
12 | "AmplifyAppId": "d56396euhmf0k"
13 | },
14 | "categories": {
15 | "auth": {
16 | "amplifytodoapp": {}
17 | }
18 | }
19 | }
20 | }
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/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 30
30 |
31 | sourceSets {
32 | main.java.srcDirs += 'src/main/kotlin'
33 | }
34 |
35 | defaultConfig {
36 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
37 | applicationId "com.example.amplify_todo"
38 | minSdkVersion 16
39 | targetSdkVersion 30
40 | versionCode flutterVersionCode.toInteger()
41 | versionName flutterVersionName
42 | }
43 |
44 | buildTypes {
45 | release {
46 | // TODO: Add your own signing config for the release build.
47 | // Signing with the debug keys for now, so `flutter run --release` works.
48 | signingConfig signingConfigs.debug
49 | }
50 | }
51 | }
52 |
53 | flutter {
54 | source '../..'
55 | }
56 |
57 | dependencies {
58 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
59 | }
60 |
--------------------------------------------------------------------------------
/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
6 |
13 |
17 |
21 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
37 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/android/app/src/main/kotlin/com/example/amplify_todo/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.example.amplify_todo
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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.3.50'
3 | repositories {
4 | google()
5 | jcenter()
6 | }
7 |
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:4.1.0'
10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
11 | }
12 | }
13 |
14 | allprojects {
15 | repositories {
16 | google()
17 | jcenter()
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-6.7-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 |
--------------------------------------------------------------------------------
/images/amazon-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/amazon-logo.png
--------------------------------------------------------------------------------
/images/applogo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/applogo.png
--------------------------------------------------------------------------------
/images/aws.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/aws.png
--------------------------------------------------------------------------------
/images/facebook-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/facebook-logo.png
--------------------------------------------------------------------------------
/images/google-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/google-logo.png
--------------------------------------------------------------------------------
/images/profile.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/profile.png
--------------------------------------------------------------------------------
/images/profile_image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/images/profile_image.png
--------------------------------------------------------------------------------
/ios/.gitignore:
--------------------------------------------------------------------------------
1 | *.mode1v3
2 | *.mode2v3
3 | *.moved-aside
4 | *.pbxuser
5 | *.perspectivev3
6 | **/*sync/
7 | .sconsign.dblite
8 | .tags*
9 | **/.vagrant/
10 | **/DerivedData/
11 | Icon?
12 | **/Pods/
13 | **/.symlinks/
14 | profile
15 | xcuserdata
16 | **/.generated/
17 | Flutter/App.framework
18 | Flutter/Flutter.framework
19 | Flutter/Flutter.podspec
20 | Flutter/Generated.xcconfig
21 | Flutter/app.flx
22 | Flutter/app.zip
23 | Flutter/flutter_assets/
24 | Flutter/flutter_export_environment.sh
25 | ServiceDefinitions.json
26 | Runner/GeneratedPluginRegistrant.*
27 |
28 | # Exceptions to above rules.
29 | !default.mode1v3
30 | !default.mode2v3
31 | !default.pbxuser
32 | !default.perspectivev3
33 |
--------------------------------------------------------------------------------
/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 | 8.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.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | 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.11.0):
3 | - Amplify/Default (= 1.11.0)
4 | - Amplify/Default (1.11.0)
5 | - amplify_analytics_pinpoint (0.0.1):
6 | - Amplify (~> 1.11.0)
7 | - amplify_core
8 | - AmplifyPlugins/AWSPinpointAnalyticsPlugin (~> 1.11.0)
9 | - Flutter
10 | - amplify_api (0.0.1):
11 | - Amplify (~> 1.11.0)
12 | - amplify_core
13 | - AmplifyPlugins/AWSAPIPlugin (~> 1.11.0)
14 | - Flutter
15 | - amplify_auth_cognito (0.0.1):
16 | - Amplify (~> 1.11.0)
17 | - amplify_core
18 | - AmplifyPlugins/AWSCognitoAuthPlugin (~> 1.11.0)
19 | - Flutter
20 | - ObjectMapper
21 | - amplify_core (0.0.1):
22 | - Flutter
23 | - amplify_datastore (0.0.1):
24 | - Amplify (~> 1.11.0)
25 | - amplify_core
26 | - AmplifyPlugins/AWSDataStorePlugin (~> 1.11.0)
27 | - Flutter
28 | - amplify_flutter (0.0.1):
29 | - Amplify (~> 1.11.0)
30 | - amplify_core
31 | - AmplifyPlugins/AWSCognitoAuthPlugin (~> 1.11.0)
32 | - AWSPluginsCore (~> 1.11.0)
33 | - Flutter
34 | - amplify_storage_s3 (0.0.1):
35 | - Amplify (~> 1.11.0)
36 | - amplify_core
37 | - AmplifyPlugins/AWSS3StoragePlugin (~> 1.11.0)
38 | - Flutter
39 | - AmplifyPlugins/AWSAPIPlugin (1.11.0):
40 | - AppSyncRealTimeClient (~> 1.4)
41 | - AWSCore (~> 2.24.0)
42 | - AWSPluginsCore (= 1.11.0)
43 | - AmplifyPlugins/AWSCognitoAuthPlugin (1.11.0):
44 | - AWSAuthCore (~> 2.24.0)
45 | - AWSCognitoIdentityProvider (~> 2.24.0)
46 | - AWSCognitoIdentityProviderASF (~> 2.24.0)
47 | - AWSCore (~> 2.24.0)
48 | - AWSMobileClient (~> 2.24.0)
49 | - AWSPluginsCore (= 1.11.0)
50 | - AmplifyPlugins/AWSDataStorePlugin (1.11.0):
51 | - AWSCore (~> 2.24.0)
52 | - AWSPluginsCore (= 1.11.0)
53 | - SQLite.swift (= 0.12.2)
54 | - AmplifyPlugins/AWSPinpointAnalyticsPlugin (1.11.0):
55 | - AWSCore (~> 2.24.0)
56 | - AWSPinpoint (~> 2.24.0)
57 | - AWSPluginsCore (= 1.11.0)
58 | - AmplifyPlugins/AWSS3StoragePlugin (1.11.0):
59 | - AWSCore (~> 2.24.0)
60 | - AWSPluginsCore (= 1.11.0)
61 | - AWSS3 (~> 2.24.0)
62 | - AppSyncRealTimeClient (1.5.0):
63 | - Starscream (~> 3.1.1)
64 | - AWSAuthCore (2.24.2):
65 | - AWSCore (= 2.24.2)
66 | - AWSCognitoIdentityProvider (2.24.2):
67 | - AWSCognitoIdentityProviderASF (= 2.24.2)
68 | - AWSCore (= 2.24.2)
69 | - AWSCognitoIdentityProviderASF (2.24.2)
70 | - AWSCore (2.24.2)
71 | - AWSMobileClient (2.24.2):
72 | - AWSAuthCore (= 2.24.2)
73 | - AWSCognitoIdentityProvider (= 2.24.2)
74 | - AWSCognitoIdentityProviderASF (= 2.24.2)
75 | - AWSCore (= 2.24.2)
76 | - AWSPinpoint (2.24.2):
77 | - AWSCore (= 2.24.2)
78 | - AWSPluginsCore (1.11.0):
79 | - Amplify (= 1.11.0)
80 | - AWSCore (~> 2.24.0)
81 | - AWSS3 (2.24.2):
82 | - AWSCore (= 2.24.2)
83 | - Flutter (1.0.0)
84 | - image_picker (0.0.1):
85 | - Flutter
86 | - ObjectMapper (4.2.0)
87 | - SQLite.swift (0.12.2):
88 | - SQLite.swift/standard (= 0.12.2)
89 | - SQLite.swift/standard (0.12.2)
90 | - Starscream (3.1.1)
91 |
92 | DEPENDENCIES:
93 | - amplify_analytics_pinpoint (from `.symlinks/plugins/amplify_analytics_pinpoint/ios`)
94 | - amplify_api (from `.symlinks/plugins/amplify_api/ios`)
95 | - amplify_auth_cognito (from `.symlinks/plugins/amplify_auth_cognito/ios`)
96 | - amplify_core (from `.symlinks/plugins/amplify_core/ios`)
97 | - amplify_datastore (from `.symlinks/plugins/amplify_datastore/ios`)
98 | - amplify_flutter (from `.symlinks/plugins/amplify_flutter/ios`)
99 | - amplify_storage_s3 (from `.symlinks/plugins/amplify_storage_s3/ios`)
100 | - Flutter (from `Flutter`)
101 | - image_picker (from `.symlinks/plugins/image_picker/ios`)
102 |
103 | SPEC REPOS:
104 | trunk:
105 | - Amplify
106 | - AmplifyPlugins
107 | - AppSyncRealTimeClient
108 | - AWSAuthCore
109 | - AWSCognitoIdentityProvider
110 | - AWSCognitoIdentityProviderASF
111 | - AWSCore
112 | - AWSMobileClient
113 | - AWSPinpoint
114 | - AWSPluginsCore
115 | - AWSS3
116 | - ObjectMapper
117 | - SQLite.swift
118 | - Starscream
119 |
120 | EXTERNAL SOURCES:
121 | amplify_analytics_pinpoint:
122 | :path: ".symlinks/plugins/amplify_analytics_pinpoint/ios"
123 | amplify_api:
124 | :path: ".symlinks/plugins/amplify_api/ios"
125 | amplify_auth_cognito:
126 | :path: ".symlinks/plugins/amplify_auth_cognito/ios"
127 | amplify_core:
128 | :path: ".symlinks/plugins/amplify_core/ios"
129 | amplify_datastore:
130 | :path: ".symlinks/plugins/amplify_datastore/ios"
131 | amplify_flutter:
132 | :path: ".symlinks/plugins/amplify_flutter/ios"
133 | amplify_storage_s3:
134 | :path: ".symlinks/plugins/amplify_storage_s3/ios"
135 | Flutter:
136 | :path: Flutter
137 | image_picker:
138 | :path: ".symlinks/plugins/image_picker/ios"
139 |
140 | SPEC CHECKSUMS:
141 | Amplify: cf25ee17b0762b3bacd4d4d49891ddada6bee912
142 | amplify_analytics_pinpoint: 883dfa68ed6688c0c75c9b8f1733da7a0f5e2e94
143 | amplify_api: 5ef7294d41dadf25acb1c145869931d82022a9b2
144 | amplify_auth_cognito: 38761b51a433d49ecf5927de45488fcbf81a8c29
145 | amplify_core: 8b38d20089fe4f225c14db6892f586bd03824a42
146 | amplify_datastore: c0f2bcf9410731862612c986a9f331cb4f8691e4
147 | amplify_flutter: 77665b732c1b8d04ed7f3eeb5a743f0b75838db1
148 | amplify_storage_s3: 703f62456f65b84aed6f29d73427ed5581056c00
149 | AmplifyPlugins: bb73475de41297a7244e8f3fdbf40cdad8115048
150 | AppSyncRealTimeClient: 2b4482b1770a3e5cf64f9714a6d198550017b5a2
151 | AWSAuthCore: d2cb921db598ea03d67284977a3c691e9a1aee83
152 | AWSCognitoIdentityProvider: f9d68c563718fa5aa76e077752df06c73810efba
153 | AWSCognitoIdentityProviderASF: 21681469334e286df6e5470f3cbab3b10edbf818
154 | AWSCore: 08a61ac2b1d98b2d43f59ee40c4bd68e58dfdea3
155 | AWSMobileClient: 6af7fff9e58f8d427acf3381cbbae2f0c34d52ab
156 | AWSPinpoint: a422ed2d24e0cc94499aaf60e2fbb7666954c8bf
157 | AWSPluginsCore: 1670f03a8612d60bd84c541ffa34f538e4037052
158 | AWSS3: 1782d0db43a1219a118ea6263d4ea01f76f8cdf4
159 | Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
160 | image_picker: e06f7a68f000bd36f552c1847e33cda96ed31f1f
161 | ObjectMapper: 1eb41f610210777375fa806bf161dc39fb832b81
162 | SQLite.swift: d2b4642190917051ce6bd1d49aab565fe794eea3
163 | Starscream: 4bb2f9942274833f7b4d296a55504dcfc7edb7b0
164 |
165 | PODFILE CHECKSUM: cc1f88378b4bfcf93a6ce00d2c587857c6008d3b
166 |
167 | COCOAPODS: 1.10.1
168 |
--------------------------------------------------------------------------------
/ios/Runner.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
11 | 16DA5870F6ED87EA2DE88B19 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA0985E0B2368CC61C1400E8 /* 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 | 0A0D6664BD51D2C2E75DE271 /* 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 = ""; };
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 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
38 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
40 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
41 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
42 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
43 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
44 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
45 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
46 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
47 | A2DA71C38B5950A3E2760C33 /* 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 = ""; };
48 | EA0985E0B2368CC61C1400E8 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
49 | EF673D65B93492E61B5E635B /* 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 = ""; };
50 | /* End PBXFileReference section */
51 |
52 | /* Begin PBXFrameworksBuildPhase section */
53 | 97C146EB1CF9000F007C117D /* Frameworks */ = {
54 | isa = PBXFrameworksBuildPhase;
55 | buildActionMask = 2147483647;
56 | files = (
57 | 16DA5870F6ED87EA2DE88B19 /* Pods_Runner.framework in Frameworks */,
58 | );
59 | runOnlyForDeploymentPostprocessing = 0;
60 | };
61 | /* End PBXFrameworksBuildPhase section */
62 |
63 | /* Begin PBXGroup section */
64 | 4A1B0A4DFC32ACE0EC95140A /* Frameworks */ = {
65 | isa = PBXGroup;
66 | children = (
67 | EA0985E0B2368CC61C1400E8 /* Pods_Runner.framework */,
68 | );
69 | name = Frameworks;
70 | sourceTree = "";
71 | };
72 | 9740EEB11CF90186004384FC /* Flutter */ = {
73 | isa = PBXGroup;
74 | children = (
75 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
76 | 9740EEB21CF90195004384FC /* Debug.xcconfig */,
77 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
78 | 9740EEB31CF90195004384FC /* Generated.xcconfig */,
79 | );
80 | name = Flutter;
81 | sourceTree = "";
82 | };
83 | 97C146E51CF9000F007C117D = {
84 | isa = PBXGroup;
85 | children = (
86 | 9740EEB11CF90186004384FC /* Flutter */,
87 | 97C146F01CF9000F007C117D /* Runner */,
88 | 97C146EF1CF9000F007C117D /* Products */,
89 | BB8AA0EDE6249BB31E2AEC14 /* Pods */,
90 | 4A1B0A4DFC32ACE0EC95140A /* Frameworks */,
91 | );
92 | sourceTree = "";
93 | };
94 | 97C146EF1CF9000F007C117D /* Products */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 97C146EE1CF9000F007C117D /* Runner.app */,
98 | );
99 | name = Products;
100 | sourceTree = "";
101 | };
102 | 97C146F01CF9000F007C117D /* Runner */ = {
103 | isa = PBXGroup;
104 | children = (
105 | 97C146FA1CF9000F007C117D /* Main.storyboard */,
106 | 97C146FD1CF9000F007C117D /* Assets.xcassets */,
107 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
108 | 97C147021CF9000F007C117D /* Info.plist */,
109 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
110 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
111 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
112 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
113 | );
114 | path = Runner;
115 | sourceTree = "";
116 | };
117 | BB8AA0EDE6249BB31E2AEC14 /* Pods */ = {
118 | isa = PBXGroup;
119 | children = (
120 | A2DA71C38B5950A3E2760C33 /* Pods-Runner.debug.xcconfig */,
121 | 0A0D6664BD51D2C2E75DE271 /* Pods-Runner.release.xcconfig */,
122 | EF673D65B93492E61B5E635B /* Pods-Runner.profile.xcconfig */,
123 | );
124 | name = Pods;
125 | path = Pods;
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 | 63EC73F7852E3FAE8251129D /* [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 | A5DE5287E6AB7243D569807B /* [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 = 1020;
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 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
202 | isa = PBXShellScriptBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | inputPaths = (
207 | );
208 | name = "Thin Binary";
209 | outputPaths = (
210 | );
211 | runOnlyForDeploymentPostprocessing = 0;
212 | shellPath = /bin/sh;
213 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
214 | };
215 | 63EC73F7852E3FAE8251129D /* [CP] Check Pods Manifest.lock */ = {
216 | isa = PBXShellScriptBuildPhase;
217 | buildActionMask = 2147483647;
218 | files = (
219 | );
220 | inputFileListPaths = (
221 | );
222 | inputPaths = (
223 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
224 | "${PODS_ROOT}/Manifest.lock",
225 | );
226 | name = "[CP] Check Pods Manifest.lock";
227 | outputFileListPaths = (
228 | );
229 | outputPaths = (
230 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
231 | );
232 | runOnlyForDeploymentPostprocessing = 0;
233 | shellPath = /bin/sh;
234 | 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";
235 | showEnvVarsInLog = 0;
236 | };
237 | 9740EEB61CF901F6004384FC /* Run Script */ = {
238 | isa = PBXShellScriptBuildPhase;
239 | buildActionMask = 2147483647;
240 | files = (
241 | );
242 | inputPaths = (
243 | );
244 | name = "Run Script";
245 | outputPaths = (
246 | );
247 | runOnlyForDeploymentPostprocessing = 0;
248 | shellPath = /bin/sh;
249 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
250 | };
251 | A5DE5287E6AB7243D569807B /* [CP] Embed Pods Frameworks */ = {
252 | isa = PBXShellScriptBuildPhase;
253 | buildActionMask = 2147483647;
254 | files = (
255 | );
256 | inputFileListPaths = (
257 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
258 | );
259 | name = "[CP] Embed Pods Frameworks";
260 | outputFileListPaths = (
261 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
262 | );
263 | runOnlyForDeploymentPostprocessing = 0;
264 | shellPath = /bin/sh;
265 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
266 | showEnvVarsInLog = 0;
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 = "$(inherited) @executable_path/Frameworks";
362 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyTodo;
363 | PRODUCT_NAME = "$(TARGET_NAME)";
364 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
365 | SWIFT_VERSION = 5.0;
366 | VERSIONING_SYSTEM = "apple-generic";
367 | };
368 | name = Profile;
369 | };
370 | 97C147031CF9000F007C117D /* Debug */ = {
371 | isa = XCBuildConfiguration;
372 | buildSettings = {
373 | ALWAYS_SEARCH_USER_PATHS = NO;
374 | CLANG_ANALYZER_NONNULL = YES;
375 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
376 | CLANG_CXX_LIBRARY = "libc++";
377 | CLANG_ENABLE_MODULES = YES;
378 | CLANG_ENABLE_OBJC_ARC = YES;
379 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
380 | CLANG_WARN_BOOL_CONVERSION = YES;
381 | CLANG_WARN_COMMA = YES;
382 | CLANG_WARN_CONSTANT_CONVERSION = YES;
383 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
384 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
385 | CLANG_WARN_EMPTY_BODY = YES;
386 | CLANG_WARN_ENUM_CONVERSION = YES;
387 | CLANG_WARN_INFINITE_RECURSION = YES;
388 | CLANG_WARN_INT_CONVERSION = YES;
389 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
390 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
391 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
393 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
394 | CLANG_WARN_STRICT_PROTOTYPES = YES;
395 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
396 | CLANG_WARN_UNREACHABLE_CODE = YES;
397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
398 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
399 | COPY_PHASE_STRIP = NO;
400 | DEBUG_INFORMATION_FORMAT = dwarf;
401 | ENABLE_STRICT_OBJC_MSGSEND = YES;
402 | ENABLE_TESTABILITY = YES;
403 | GCC_C_LANGUAGE_STANDARD = gnu99;
404 | GCC_DYNAMIC_NO_PIC = NO;
405 | GCC_NO_COMMON_BLOCKS = YES;
406 | GCC_OPTIMIZATION_LEVEL = 0;
407 | GCC_PREPROCESSOR_DEFINITIONS = (
408 | "DEBUG=1",
409 | "$(inherited)",
410 | );
411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
413 | GCC_WARN_UNDECLARED_SELECTOR = YES;
414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
415 | GCC_WARN_UNUSED_FUNCTION = YES;
416 | GCC_WARN_UNUSED_VARIABLE = YES;
417 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
418 | MTL_ENABLE_DEBUG_INFO = YES;
419 | ONLY_ACTIVE_ARCH = YES;
420 | SDKROOT = iphoneos;
421 | TARGETED_DEVICE_FAMILY = "1,2";
422 | };
423 | name = Debug;
424 | };
425 | 97C147041CF9000F007C117D /* Release */ = {
426 | isa = XCBuildConfiguration;
427 | buildSettings = {
428 | ALWAYS_SEARCH_USER_PATHS = NO;
429 | CLANG_ANALYZER_NONNULL = YES;
430 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
431 | CLANG_CXX_LIBRARY = "libc++";
432 | CLANG_ENABLE_MODULES = YES;
433 | CLANG_ENABLE_OBJC_ARC = YES;
434 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
435 | CLANG_WARN_BOOL_CONVERSION = YES;
436 | CLANG_WARN_COMMA = YES;
437 | CLANG_WARN_CONSTANT_CONVERSION = YES;
438 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
439 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
440 | CLANG_WARN_EMPTY_BODY = YES;
441 | CLANG_WARN_ENUM_CONVERSION = YES;
442 | CLANG_WARN_INFINITE_RECURSION = YES;
443 | CLANG_WARN_INT_CONVERSION = YES;
444 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
445 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
446 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
447 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
449 | CLANG_WARN_STRICT_PROTOTYPES = YES;
450 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
451 | CLANG_WARN_UNREACHABLE_CODE = YES;
452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
453 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
454 | COPY_PHASE_STRIP = NO;
455 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
456 | ENABLE_NS_ASSERTIONS = NO;
457 | ENABLE_STRICT_OBJC_MSGSEND = YES;
458 | GCC_C_LANGUAGE_STANDARD = gnu99;
459 | GCC_NO_COMMON_BLOCKS = YES;
460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
462 | GCC_WARN_UNDECLARED_SELECTOR = YES;
463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
464 | GCC_WARN_UNUSED_FUNCTION = YES;
465 | GCC_WARN_UNUSED_VARIABLE = YES;
466 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
467 | MTL_ENABLE_DEBUG_INFO = NO;
468 | SDKROOT = iphoneos;
469 | SUPPORTED_PLATFORMS = iphoneos;
470 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
471 | TARGETED_DEVICE_FAMILY = "1,2";
472 | VALIDATE_PRODUCT = YES;
473 | };
474 | name = Release;
475 | };
476 | 97C147061CF9000F007C117D /* Debug */ = {
477 | isa = XCBuildConfiguration;
478 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
479 | buildSettings = {
480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
481 | CLANG_ENABLE_MODULES = YES;
482 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
483 | ENABLE_BITCODE = NO;
484 | INFOPLIST_FILE = Runner/Info.plist;
485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
486 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyTodo;
487 | PRODUCT_NAME = "$(TARGET_NAME)";
488 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
489 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
490 | SWIFT_VERSION = 5.0;
491 | VERSIONING_SYSTEM = "apple-generic";
492 | };
493 | name = Debug;
494 | };
495 | 97C147071CF9000F007C117D /* Release */ = {
496 | isa = XCBuildConfiguration;
497 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
498 | buildSettings = {
499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
500 | CLANG_ENABLE_MODULES = YES;
501 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
502 | ENABLE_BITCODE = NO;
503 | INFOPLIST_FILE = Runner/Info.plist;
504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
505 | PRODUCT_BUNDLE_IDENTIFIER = com.example.amplifyTodo;
506 | PRODUCT_NAME = "$(TARGET_NAME)";
507 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
508 | SWIFT_VERSION = 5.0;
509 | VERSIONING_SYSTEM = "apple-generic";
510 | };
511 | name = Release;
512 | };
513 | /* End XCBuildConfiguration section */
514 |
515 | /* Begin XCConfigurationList section */
516 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
517 | isa = XCConfigurationList;
518 | buildConfigurations = (
519 | 97C147031CF9000F007C117D /* Debug */,
520 | 97C147041CF9000F007C117D /* Release */,
521 | 249021D3217E4FDB00AE95B9 /* Profile */,
522 | );
523 | defaultConfigurationIsVisible = 0;
524 | defaultConfigurationName = Release;
525 | };
526 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
527 | isa = XCConfigurationList;
528 | buildConfigurations = (
529 | 97C147061CF9000F007C117D /* Debug */,
530 | 97C147071CF9000F007C117D /* Release */,
531 | 249021D4217E4FDB00AE95B9 /* Profile */,
532 | );
533 | defaultConfigurationIsVisible = 0;
534 | defaultConfigurationName = Release;
535 | };
536 | /* End XCConfigurationList section */
537 | };
538 | rootObject = 97C146E61CF9000F007C117D /* Project object */;
539 | }
540 |
--------------------------------------------------------------------------------
/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 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/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_todo/a73225e52755edb069d0903784424a6f03603017/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/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 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | amplify_todo
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | $(FLUTTER_BUILD_NAME)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 | UIViewControllerBasedStatusBarAppearance
43 |
44 | NSPhotoLibraryUsageDescription
45 | Allow access to photo library
46 | NSCameraUsageDescription
47 | Allow access to camera to capture photos
48 | NSMicrophoneUsageDescription
49 | Allow access to microphone
50 |
51 |
52 |
--------------------------------------------------------------------------------
/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/lib/account_screens_enum.dart:
--------------------------------------------------------------------------------
1 | enum AccountStatus {
2 | sign_in,
3 | sign_up,
4 | reset_password,
5 | confirm_code,
6 | main_screen
7 | }
8 |
--------------------------------------------------------------------------------
/lib/app_routes.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/bindings/homepage_bindings.dart';
2 | import 'package:amplify_todo/pages/email_sign_in_page.dart';
3 | import 'package:amplify_todo/pages/home_page.dart';
4 | import 'package:amplify_todo/pages/sign_in_page.dart';
5 | import 'package:get/get.dart';
6 |
7 | class AppRoutes {
8 | static final routes = [
9 | GetPage(name: '/home', page: () => HomePage(), binding: HomeBindings()),
10 | GetPage(
11 | name: '/emaillogin',
12 | page: () => EmailSignInPage(),
13 | ),
14 | GetPage(
15 | name: '/signin',
16 | page: () => SignInPage(),
17 | ),
18 | ];
19 | }
20 |
--------------------------------------------------------------------------------
/lib/buttons_enum.dart:
--------------------------------------------------------------------------------
1 | enum Buttons {
2 | /// This is a list of all the library built buttons.
3 | Email,
4 | Google,
5 | Facebook,
6 | Amazon,
7 | Apple,
8 | }
9 |
--------------------------------------------------------------------------------
/lib/controllers/authController.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
2 | import 'package:amplify_todo/services/auth_service.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 |
6 | enum EmailSignInFormType { signIn, register, confirm }
7 |
8 | class AuthController extends GetxController {
9 | static AuthController to = Get.find();
10 | AuthService _authService = AuthService();
11 | Rx emailformType = EmailSignInFormType.signIn.obs;
12 | RxBool isLoading = false.obs;
13 | RxBool isSignedIn = false.obs;
14 | bool submitted = false;
15 | RxBool submitEnabled = false.obs;
16 |
17 | final TextEditingController emailController = TextEditingController();
18 | final TextEditingController passwordController = TextEditingController();
19 | final TextEditingController codeController = TextEditingController();
20 | final FocusNode codeFocusNode = FocusNode();
21 | final FocusNode emailFocusNode = FocusNode();
22 | final FocusNode passwordFocusNode = FocusNode();
23 | final String invalidEmailErrorText = 'Email can\'t be empty';
24 | final String invalidPasswordErrorText = 'Password can\'t be empty';
25 |
26 | String get primaryButtonText {
27 | switch (emailformType.value) {
28 | case EmailSignInFormType.signIn:
29 | return 'Sign In';
30 | case EmailSignInFormType.register:
31 | return 'Create an account';
32 | case EmailSignInFormType.confirm:
33 | return 'Confirm Sign Up';
34 | }
35 | }
36 |
37 | String get secondaryButtonText {
38 | return emailformType.value == EmailSignInFormType.signIn
39 | ? 'Need an account? Register'
40 | : 'Have an account? Sign in';
41 | }
42 |
43 | String? get emailErrorText {
44 | bool showErrorText = submitted && !GetUtils.isEmail(emailController.text);
45 | return showErrorText ? invalidEmailErrorText : null;
46 | }
47 |
48 | void toggleFormType() {
49 | emailformType.value = emailformType.value == EmailSignInFormType.signIn
50 | ? EmailSignInFormType.register
51 | : EmailSignInFormType.signIn;
52 |
53 | emailController.clear();
54 | passwordController.clear();
55 | submitted = false;
56 | }
57 |
58 | Future submitEmailAndPassword() async {
59 | submitted = true;
60 | isLoading.value = true;
61 |
62 | try {
63 | switch (emailformType.value) {
64 | case EmailSignInFormType.signIn:
65 | isSignedIn.value = await _authService.signInWithEmailAndPassword(
66 | emailController.text, passwordController.text);
67 | break;
68 | case EmailSignInFormType.register:
69 | final isSignedUp = await _authService.registerWithEmailAndPassword(
70 | emailController.text, passwordController.text);
71 | if (!isSignedUp) {
72 | emailformType.value = EmailSignInFormType.confirm;
73 | }
74 | break;
75 | case EmailSignInFormType.confirm:
76 | isSignedIn.value = (await _authService.confirmRegisterWithCode(
77 | emailController.text,
78 | passwordController.text,
79 | codeController.text))!;
80 | }
81 | } catch (e) {
82 | rethrow;
83 | } finally {
84 | isLoading.value = false;
85 | }
86 | }
87 |
88 | @override
89 | void onReady() {
90 | isUserSignedIn();
91 | ever(isSignedIn, handleAuthChanged);
92 | super.onReady();
93 | }
94 |
95 | void isUserSignedIn() async {
96 | try {
97 | isLoading.value = true;
98 | isSignedIn.value = await _authService.isSignedIn();
99 | } catch (e) {
100 | throw e;
101 | } finally {
102 | isLoading.value = false;
103 | }
104 | }
105 |
106 | handleAuthChanged(isSignedIn) {
107 | if (!isSignedIn) {
108 | Get.offAllNamed("/signin");
109 | } else {
110 | Get.offAllNamed("/home");
111 | }
112 | }
113 |
114 | void signIn(AuthProvider authProvider) async {
115 | try {
116 | await _authService.signIn(authProvider);
117 | isSignedIn.value = true;
118 | //_setuplistener();
119 | } catch (e) {
120 | throw e;
121 | }
122 | }
123 |
124 | void signOut() async {
125 | try {
126 | await _authService.signOut();
127 | isSignedIn.value = false;
128 | isLoading.value = false;
129 | } on AuthException catch (e) {
130 | print(e.message);
131 | }
132 | }
133 |
134 | void updateform(String value) {
135 | submitEnabled.value = GetUtils.isEmail(emailController.text) &&
136 | !GetUtils.isBlank(passwordController.text)! &&
137 | !isLoading.value;
138 | }
139 | }
140 |
--------------------------------------------------------------------------------
/lib/controllers/bindings/controllers_bindings.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/authController.dart';
2 | import 'package:get/get.dart';
3 |
4 | class ControllersBindings extends Bindings {
5 | @override
6 | void dependencies() {
7 | Get.lazyPut(() => AuthController());
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/lib/controllers/bindings/homepage_bindings.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/authController.dart';
2 |
3 | import 'package:amplify_todo/controllers/todoController.dart';
4 | import 'package:amplify_todo/controllers/userController.dart';
5 | import 'package:get/get.dart';
6 |
7 | class HomeBindings extends Bindings {
8 | @override
9 | void dependencies() {
10 | Get.put(AuthController(), permanent: true);
11 | //Get.lazyPut(() => AuthController());
12 | Get.put(TodoController(), permanent: true);
13 | //Get.lazyPut(() => TodoController());
14 | Get.put(UserController(), permanent: true);
15 |
16 | //Get.lazyPut(() => UserController());
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/lib/controllers/todoController.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
2 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
3 | import 'package:amplify_datastore/amplify_datastore.dart';
4 | import 'package:amplify_flutter/amplify.dart';
5 | import 'package:amplify_todo/models/ModelProvider.dart';
6 | import 'package:amplify_todo/models/Todo.dart';
7 | import 'package:amplify_todo/services/auth_service.dart';
8 | import 'package:amplify_todo/services/datastore_service.dart';
9 | import 'package:flutter/material.dart';
10 | import 'package:get/get.dart';
11 |
12 | class TodoController extends GetxController {
13 | static TodoController to = Get.find();
14 | DataStoreService _datastoreService = DataStoreService();
15 | AuthService _authService = AuthService();
16 | final TextEditingController todoTitleController = TextEditingController();
17 |
18 | List todoList = [].obs;
19 |
20 | @override
21 | void onReady() {
22 | getTodos();
23 | super.onReady();
24 | }
25 |
26 | Future getTodos() async {
27 | AuthUser _authUser = await _authService.getCurrentUser();
28 | List? _list = await _datastoreService.getTodos(_authUser.userId);
29 | if (_list != null) {
30 | todoList.addAll(_list);
31 | }
32 | }
33 |
34 | Future addTodo() async {
35 | AuthUser _authUser = await _authService.getCurrentUser();
36 | Todo todo = new Todo(
37 | name: todoTitleController.text.toString(),
38 | isDone: false,
39 | createdAt: TemporalDateTime.now(),
40 | updatedAt: TemporalDateTime.now(),
41 | userId: _authUser.userId);
42 | await _datastoreService.saveTodo(todo);
43 | AnalyticsEvent event = AnalyticsEvent('add_todo');
44 | Amplify.Analytics.recordEvent(event: event);
45 | todoList.add(todo);
46 | }
47 |
48 | Future removeTodo(Todo todo) async {
49 | await _datastoreService.removeTodo(todo);
50 | AnalyticsEvent event = AnalyticsEvent('remove_todo');
51 | Amplify.Analytics.recordEvent(event: event);
52 | todoList.remove(todo);
53 | }
54 |
55 | Future setToDoDone(Todo todo, bool newValue) async {
56 | await _datastoreService.setToDoDone(todo, newValue);
57 | AnalyticsEvent event = AnalyticsEvent('done_todo');
58 | Amplify.Analytics.recordEvent(event: event);
59 | todoList[todoList.indexWhere((element) => element.id == todo.id)] =
60 | todo.copyWith(isDone: newValue);
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/lib/controllers/userController.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
4 | import 'package:amplify_flutter/amplify.dart';
5 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
6 | import 'package:amplify_todo/models/Users.dart';
7 | import 'package:amplify_todo/services/auth_service.dart';
8 | import 'package:amplify_todo/services/datastore_service.dart';
9 | import 'package:get/get.dart';
10 | import 'package:image_picker/image_picker.dart';
11 | import 'package:uuid/uuid.dart';
12 |
13 | class UserController extends GetxController {
14 | static UserController to = Get.find();
15 | DataStoreService _datastoreService = DataStoreService();
16 | AuthService _authService = AuthService();
17 | Rxn currentUser = Rxn();
18 | RxBool isLoading = false.obs;
19 | RxString imageUrl = ''.obs;
20 |
21 | Users? get user => currentUser.value;
22 |
23 | @override
24 | void onInit() {
25 | super.onInit();
26 | }
27 |
28 | @override
29 | void onReady() {
30 | getCurrUser();
31 | super.onReady();
32 | }
33 |
34 | Future getCurrUser() async {
35 | AuthUser authUser = await _authService.getCurrentUser();
36 | currentUser.value = await _datastoreService.getUser(authUser.userId);
37 | print(currentUser.value);
38 | }
39 |
40 | Future setUserImage() async {
41 | File _image;
42 | final picker = ImagePicker();
43 |
44 | try {
45 | isLoading.value = true;
46 | final pickedFile = await picker.getImage(source: ImageSource.gallery);
47 | if (pickedFile != null) {
48 | _image = File(pickedFile.path);
49 |
50 | _image.existsSync();
51 | final userImageKey = currentUser.value!.id + Uuid().v1() + '.png';
52 | print(userImageKey);
53 |
54 | Map metadata = {};
55 | metadata['name'] = currentUser.value!.id;
56 | metadata['desc'] = 'A test file';
57 | S3UploadFileOptions options = S3UploadFileOptions(
58 | accessLevel: StorageAccessLevel.guest, metadata: metadata);
59 | UploadFileResult result = await Amplify.Storage.uploadFile(
60 | key: userImageKey, local: _image, options: options);
61 | print('uploaded');
62 | GetUrlOptions _getUrlOptions = GetUrlOptions(expires: 60000);
63 | GetUrlResult resultUrl = await Amplify.Storage.getUrl(
64 | key: userImageKey, options: _getUrlOptions);
65 | print('URL: ' + resultUrl.url);
66 |
67 | currentUser.value = currentUser.value!
68 | .copyWith(imageKey: userImageKey, imageUrl: resultUrl.url);
69 |
70 | print(currentUser.value);
71 |
72 | imageUrl.value = resultUrl.url;
73 |
74 | await _datastoreService.saveUser(currentUser.value!);
75 | } else {
76 | return null;
77 | }
78 | } catch (e) {
79 | print(e.toString());
80 | } finally {
81 | isLoading.value = false;
82 | }
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/app_routes.dart';
2 | import 'package:amplify_todo/controllers/bindings/controllers_bindings.dart';
3 | import 'package:amplify_todo/pages/loading_page.dart';
4 | import 'package:amplify_todo/services/amplify_service.dart';
5 |
6 | import 'package:flutter/material.dart';
7 | import 'package:get/get.dart';
8 |
9 | void main() {
10 | runApp(MyApp());
11 | }
12 |
13 | class MyApp extends StatefulWidget {
14 | // This widget is the root of your application.
15 | @override
16 | _MyAppState createState() => _MyAppState();
17 | }
18 |
19 | class _MyAppState extends State {
20 | bool _amplifyConfigured = false;
21 |
22 | @override
23 | void initState() {
24 | super.initState();
25 | WidgetsBinding.instance!.addPostFrameCallback((_) {
26 | _configureAmplify();
27 | });
28 | }
29 |
30 | void _configureAmplify() async {
31 | await AmplifyService.configureAmplify();
32 | try {
33 | setState(() {
34 | _amplifyConfigured = true;
35 | });
36 | } catch (e) {
37 | print(e);
38 | }
39 | }
40 |
41 | @override
42 | Widget build(BuildContext context) {
43 | return GetMaterialApp(
44 | initialBinding: ControllersBindings(),
45 | title: 'ToDo',
46 | theme: ThemeData(
47 | primarySwatch: Colors.indigo,
48 | ),
49 | home: _amplifyConfigured ? LoadingPage() : _waitForAmplify(),
50 | getPages: AppRoutes.routes,
51 | );
52 | }
53 |
54 | Scaffold _waitForAmplify() {
55 | return Scaffold(
56 | body: Container(
57 | child: Center(
58 | child: CircularProgressIndicator(),
59 | ),
60 | ),
61 | );
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/lib/models/ModelProvider.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | // ignore_for_file: public_member_api_docs
17 |
18 | import 'package:amplify_datastore_plugin_interface/amplify_datastore_plugin_interface.dart';
19 | import 'Todo.dart';
20 | import 'Users.dart';
21 |
22 | export 'Todo.dart';
23 | export 'Users.dart';
24 |
25 | class ModelProvider implements ModelProviderInterface {
26 | @override
27 | String version = "3698b77bc12dd60cac275fa34d4ba22b";
28 | @override
29 | List modelSchemas = [Todo.schema, Users.schema];
30 | static final ModelProvider _instance = ModelProvider();
31 |
32 | static ModelProvider get instance => _instance;
33 |
34 | ModelType getModelTypeByModelName(String modelName) {
35 | switch(modelName) {
36 | case "Todo": {
37 | return Todo.classType;
38 | }
39 | break;
40 | case "Users": {
41 | return Users.classType;
42 | }
43 | break;
44 | default: {
45 | throw Exception("Failed to find model in model provider for model name: " + modelName);
46 | }
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/lib/models/Todo.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | // ignore_for_file: public_member_api_docs
17 |
18 | import 'package:amplify_datastore_plugin_interface/amplify_datastore_plugin_interface.dart';
19 | import 'package:flutter/foundation.dart';
20 |
21 |
22 | /** This is an auto generated class representing the Todo type in your schema. */
23 | @immutable
24 | class Todo extends Model {
25 | static const classType = const _TodoModelType();
26 | final String id;
27 | final String? _name;
28 | final TemporalDateTime? _createdAt;
29 | final TemporalDateTime? _updatedAt;
30 | final bool? _isDone;
31 | final String? _userId;
32 |
33 | @override
34 | getInstanceType() => classType;
35 |
36 | @override
37 | String getId() {
38 | return id;
39 | }
40 |
41 | String get name {
42 | try {
43 | return _name!;
44 | } catch(e) {
45 | throw new DataStoreException(DataStoreExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage, recoverySuggestion: DataStoreExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion, underlyingException: e.toString());
46 | }
47 | }
48 |
49 | TemporalDateTime? get createdAt {
50 | return _createdAt;
51 | }
52 |
53 | TemporalDateTime? get updatedAt {
54 | return _updatedAt;
55 | }
56 |
57 | bool? get isDone {
58 | return _isDone;
59 | }
60 |
61 | String get userId {
62 | try {
63 | return _userId!;
64 | } catch(e) {
65 | throw new DataStoreException(DataStoreExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage, recoverySuggestion: DataStoreExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion, underlyingException: e.toString());
66 | }
67 | }
68 |
69 | const Todo._internal({required this.id, required name, createdAt, updatedAt, isDone, required userId}): _name = name, _createdAt = createdAt, _updatedAt = updatedAt, _isDone = isDone, _userId = userId;
70 |
71 | factory Todo({String? id, required String name, TemporalDateTime? createdAt, TemporalDateTime? updatedAt, bool? isDone, required String userId}) {
72 | return Todo._internal(
73 | id: id == null ? UUID.getUUID() : id,
74 | name: name,
75 | createdAt: createdAt,
76 | updatedAt: updatedAt,
77 | isDone: isDone,
78 | userId: userId);
79 | }
80 |
81 | bool equals(Object other) {
82 | return this == other;
83 | }
84 |
85 | @override
86 | bool operator ==(Object other) {
87 | if (identical(other, this)) return true;
88 | return other is Todo &&
89 | id == other.id &&
90 | _name == other._name &&
91 | _createdAt == other._createdAt &&
92 | _updatedAt == other._updatedAt &&
93 | _isDone == other._isDone &&
94 | _userId == other._userId;
95 | }
96 |
97 | @override
98 | int get hashCode => toString().hashCode;
99 |
100 | @override
101 | String toString() {
102 | var buffer = new StringBuffer();
103 |
104 | buffer.write("Todo {");
105 | buffer.write("id=" + "$id" + ", ");
106 | buffer.write("name=" + "$_name" + ", ");
107 | buffer.write("createdAt=" + (_createdAt != null ? _createdAt!.format() : "null") + ", ");
108 | buffer.write("updatedAt=" + (_updatedAt != null ? _updatedAt!.format() : "null") + ", ");
109 | buffer.write("isDone=" + (_isDone != null ? _isDone!.toString() : "null") + ", ");
110 | buffer.write("userId=" + "$_userId");
111 | buffer.write("}");
112 |
113 | return buffer.toString();
114 | }
115 |
116 | Todo copyWith({String? id, String? name, TemporalDateTime? createdAt, TemporalDateTime? updatedAt, bool? isDone, String? userId}) {
117 | return Todo(
118 | id: id ?? this.id,
119 | name: name ?? this.name,
120 | createdAt: createdAt ?? this.createdAt,
121 | updatedAt: updatedAt ?? this.updatedAt,
122 | isDone: isDone ?? this.isDone,
123 | userId: userId ?? this.userId);
124 | }
125 |
126 | Todo.fromJson(Map json)
127 | : id = json['id'],
128 | _name = json['name'],
129 | _createdAt = json['createdAt'] != null ? TemporalDateTime.fromString(json['createdAt']) : null,
130 | _updatedAt = json['updatedAt'] != null ? TemporalDateTime.fromString(json['updatedAt']) : null,
131 | _isDone = json['isDone'],
132 | _userId = json['userId'];
133 |
134 | Map toJson() => {
135 | 'id': id, 'name': _name, 'createdAt': _createdAt?.format(), 'updatedAt': _updatedAt?.format(), 'isDone': _isDone, 'userId': _userId
136 | };
137 |
138 | static final QueryField ID = QueryField(fieldName: "todo.id");
139 | static final QueryField NAME = QueryField(fieldName: "name");
140 | static final QueryField CREATEDAT = QueryField(fieldName: "createdAt");
141 | static final QueryField UPDATEDAT = QueryField(fieldName: "updatedAt");
142 | static final QueryField ISDONE = QueryField(fieldName: "isDone");
143 | static final QueryField USERID = QueryField(fieldName: "userId");
144 | static var schema = Model.defineSchema(define: (ModelSchemaDefinition modelSchemaDefinition) {
145 | modelSchemaDefinition.name = "Todo";
146 | modelSchemaDefinition.pluralName = "Todos";
147 |
148 | modelSchemaDefinition.authRules = [
149 | AuthRule(
150 | authStrategy: AuthStrategy.PUBLIC,
151 | operations: [
152 | ModelOperation.CREATE,
153 | ModelOperation.UPDATE,
154 | ModelOperation.DELETE,
155 | ModelOperation.READ
156 | ])
157 | ];
158 |
159 | modelSchemaDefinition.addField(ModelFieldDefinition.id());
160 |
161 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
162 | key: Todo.NAME,
163 | isRequired: true,
164 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
165 | ));
166 |
167 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
168 | key: Todo.CREATEDAT,
169 | isRequired: false,
170 | ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)
171 | ));
172 |
173 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
174 | key: Todo.UPDATEDAT,
175 | isRequired: false,
176 | ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)
177 | ));
178 |
179 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
180 | key: Todo.ISDONE,
181 | isRequired: false,
182 | ofType: ModelFieldType(ModelFieldTypeEnum.bool)
183 | ));
184 |
185 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
186 | key: Todo.USERID,
187 | isRequired: true,
188 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
189 | ));
190 | });
191 | }
192 |
193 | class _TodoModelType extends ModelType {
194 | const _TodoModelType();
195 |
196 | @override
197 | Todo fromJson(Map jsonData) {
198 | return Todo.fromJson(jsonData);
199 | }
200 | }
--------------------------------------------------------------------------------
/lib/models/Users.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License").
5 | * You may not use this file except in compliance with the License.
6 | * A copy of the License is located at
7 | *
8 | * http://aws.amazon.com/apache2.0
9 | *
10 | * or in the "license" file accompanying this file. This file is distributed
11 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12 | * express or implied. See the License for the specific language governing
13 | * permissions and limitations under the License.
14 | */
15 |
16 | // ignore_for_file: public_member_api_docs
17 |
18 | import 'ModelProvider.dart';
19 | import 'package:amplify_datastore_plugin_interface/amplify_datastore_plugin_interface.dart';
20 | import 'package:collection/collection.dart';
21 | import 'package:flutter/foundation.dart';
22 |
23 |
24 | /** This is an auto generated class representing the Users type in your schema. */
25 | @immutable
26 | class Users extends Model {
27 | static const classType = const _UsersModelType();
28 | final String id;
29 | final String? _username;
30 | final String? _email;
31 | final String? _imageKey;
32 | final String? _imageUrl;
33 | final bool? _isVerified;
34 | final TemporalDateTime? _createdAt;
35 | final List? _todos;
36 |
37 | @override
38 | getInstanceType() => classType;
39 |
40 | @override
41 | String getId() {
42 | return id;
43 | }
44 |
45 | String? get username {
46 | return _username;
47 | }
48 |
49 | String? get email {
50 | return _email;
51 | }
52 |
53 | String get imageKey {
54 | try {
55 | return _imageKey!;
56 | } catch(e) {
57 | throw new DataStoreException(DataStoreExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage, recoverySuggestion: DataStoreExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion, underlyingException: e.toString());
58 | }
59 | }
60 |
61 | String get imageUrl {
62 | try {
63 | return _imageUrl!;
64 | } catch(e) {
65 | throw new DataStoreException(DataStoreExceptionMessages.codeGenRequiredFieldForceCastExceptionMessage, recoverySuggestion: DataStoreExceptionMessages.codeGenRequiredFieldForceCastRecoverySuggestion, underlyingException: e.toString());
66 | }
67 | }
68 |
69 | bool? get isVerified {
70 | return _isVerified;
71 | }
72 |
73 | TemporalDateTime? get createdAt {
74 | return _createdAt;
75 | }
76 |
77 | List? get todos {
78 | return _todos;
79 | }
80 |
81 | const Users._internal({required this.id, username, email, required imageKey, required imageUrl, isVerified, createdAt, todos}): _username = username, _email = email, _imageKey = imageKey, _imageUrl = imageUrl, _isVerified = isVerified, _createdAt = createdAt, _todos = todos;
82 |
83 | factory Users({String? id, String? username, String? email, required String imageKey, required String imageUrl, bool? isVerified, TemporalDateTime? createdAt, List? todos}) {
84 | return Users._internal(
85 | id: id == null ? UUID.getUUID() : id,
86 | username: username,
87 | email: email,
88 | imageKey: imageKey,
89 | imageUrl: imageUrl,
90 | isVerified: isVerified,
91 | createdAt: createdAt,
92 | todos: todos != null ? List.unmodifiable(todos) : todos);
93 | }
94 |
95 | bool equals(Object other) {
96 | return this == other;
97 | }
98 |
99 | @override
100 | bool operator ==(Object other) {
101 | if (identical(other, this)) return true;
102 | return other is Users &&
103 | id == other.id &&
104 | _username == other._username &&
105 | _email == other._email &&
106 | _imageKey == other._imageKey &&
107 | _imageUrl == other._imageUrl &&
108 | _isVerified == other._isVerified &&
109 | _createdAt == other._createdAt &&
110 | DeepCollectionEquality().equals(_todos, other._todos);
111 | }
112 |
113 | @override
114 | int get hashCode => toString().hashCode;
115 |
116 | @override
117 | String toString() {
118 | var buffer = new StringBuffer();
119 |
120 | buffer.write("Users {");
121 | buffer.write("id=" + "$id" + ", ");
122 | buffer.write("username=" + "$_username" + ", ");
123 | buffer.write("email=" + "$_email" + ", ");
124 | buffer.write("imageKey=" + "$_imageKey" + ", ");
125 | buffer.write("imageUrl=" + "$_imageUrl" + ", ");
126 | buffer.write("isVerified=" + (_isVerified != null ? _isVerified!.toString() : "null") + ", ");
127 | buffer.write("createdAt=" + (_createdAt != null ? _createdAt!.format() : "null"));
128 | buffer.write("}");
129 |
130 | return buffer.toString();
131 | }
132 |
133 | Users copyWith({String? id, String? username, String? email, String? imageKey, String? imageUrl, bool? isVerified, TemporalDateTime? createdAt, List? todos}) {
134 | return Users(
135 | id: id ?? this.id,
136 | username: username ?? this.username,
137 | email: email ?? this.email,
138 | imageKey: imageKey ?? this.imageKey,
139 | imageUrl: imageUrl ?? this.imageUrl,
140 | isVerified: isVerified ?? this.isVerified,
141 | createdAt: createdAt ?? this.createdAt,
142 | todos: todos ?? this.todos);
143 | }
144 |
145 | Users.fromJson(Map json)
146 | : id = json['id'],
147 | _username = json['username'],
148 | _email = json['email'],
149 | _imageKey = json['imageKey'],
150 | _imageUrl = json['imageUrl'],
151 | _isVerified = json['isVerified'],
152 | _createdAt = json['createdAt'] != null ? TemporalDateTime.fromString(json['createdAt']) : null,
153 | _todos = json['todos'] is List
154 | ? (json['todos'] as List)
155 | .where((e) => e?['serializedData'] != null)
156 | .map((e) => Todo.fromJson(new Map.from(e['serializedData'])))
157 | .toList()
158 | : null;
159 |
160 | Map toJson() => {
161 | 'id': id, 'username': _username, 'email': _email, 'imageKey': _imageKey, 'imageUrl': _imageUrl, 'isVerified': _isVerified, 'createdAt': _createdAt?.format(), 'todos': _todos?.map((e) => e?.toJson())?.toList()
162 | };
163 |
164 | static final QueryField ID = QueryField(fieldName: "users.id");
165 | static final QueryField USERNAME = QueryField(fieldName: "username");
166 | static final QueryField EMAIL = QueryField(fieldName: "email");
167 | static final QueryField IMAGEKEY = QueryField(fieldName: "imageKey");
168 | static final QueryField IMAGEURL = QueryField(fieldName: "imageUrl");
169 | static final QueryField ISVERIFIED = QueryField(fieldName: "isVerified");
170 | static final QueryField CREATEDAT = QueryField(fieldName: "createdAt");
171 | static final QueryField TODOS = QueryField(
172 | fieldName: "todos",
173 | fieldType: ModelFieldType(ModelFieldTypeEnum.model, ofModelName: (Todo).toString()));
174 | static var schema = Model.defineSchema(define: (ModelSchemaDefinition modelSchemaDefinition) {
175 | modelSchemaDefinition.name = "Users";
176 | modelSchemaDefinition.pluralName = "Users";
177 |
178 | modelSchemaDefinition.authRules = [
179 | AuthRule(
180 | authStrategy: AuthStrategy.PUBLIC,
181 | operations: [
182 | ModelOperation.CREATE,
183 | ModelOperation.UPDATE,
184 | ModelOperation.DELETE,
185 | ModelOperation.READ
186 | ])
187 | ];
188 |
189 | modelSchemaDefinition.addField(ModelFieldDefinition.id());
190 |
191 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
192 | key: Users.USERNAME,
193 | isRequired: false,
194 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
195 | ));
196 |
197 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
198 | key: Users.EMAIL,
199 | isRequired: false,
200 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
201 | ));
202 |
203 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
204 | key: Users.IMAGEKEY,
205 | isRequired: true,
206 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
207 | ));
208 |
209 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
210 | key: Users.IMAGEURL,
211 | isRequired: true,
212 | ofType: ModelFieldType(ModelFieldTypeEnum.string)
213 | ));
214 |
215 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
216 | key: Users.ISVERIFIED,
217 | isRequired: false,
218 | ofType: ModelFieldType(ModelFieldTypeEnum.bool)
219 | ));
220 |
221 | modelSchemaDefinition.addField(ModelFieldDefinition.field(
222 | key: Users.CREATEDAT,
223 | isRequired: false,
224 | ofType: ModelFieldType(ModelFieldTypeEnum.dateTime)
225 | ));
226 |
227 | modelSchemaDefinition.addField(ModelFieldDefinition.hasMany(
228 | key: Users.TODOS,
229 | isRequired: false,
230 | ofModelName: (Todo).toString(),
231 | associatedKey: Todo.USERID
232 | ));
233 | });
234 | }
235 |
236 | class _UsersModelType extends ModelType {
237 | const _UsersModelType();
238 |
239 | @override
240 | Users fromJson(Map jsonData) {
241 | return Users.fromJson(jsonData);
242 | }
243 | }
--------------------------------------------------------------------------------
/lib/pages/email_sign_in_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/widgets/email_sign_in_form.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | class EmailSignInPage extends StatelessWidget {
5 | @override
6 | Widget build(BuildContext context) {
7 | return Scaffold(
8 | appBar: AppBar(
9 | title: Text('Sign In'),
10 | elevation: 10,
11 | ),
12 | body: SingleChildScrollView(
13 | child: Padding(
14 | padding: const EdgeInsets.all(16.0),
15 | child: Card(
16 | child: EmailSignInForm(),
17 | ),
18 | ),
19 | ),
20 | backgroundColor: Colors.grey[200],
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/pages/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/authController.dart';
2 | import 'package:amplify_todo/controllers/todoController.dart';
3 | import 'package:amplify_todo/controllers/userController.dart';
4 | import 'package:amplify_todo/widgets/todo_card.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:get/get.dart';
7 | import 'package:get/get_state_manager/get_state_manager.dart';
8 |
9 | class HomePage extends GetWidget {
10 | TodoController _todocontroller = Get.find();
11 | AuthController _authcontroller = Get.find();
12 |
13 | get kTransparentImage => null;
14 | @override
15 | Widget build(BuildContext context) {
16 | return Scaffold(
17 | backgroundColor: Color(0xffE1E5E4),
18 | appBar: AppBar(
19 | title: GetX(
20 | initState: (_) async {
21 | await Get.find().getCurrUser();
22 | },
23 | builder: (_) {
24 | return Text(controller.user?.email ?? '',
25 | style: TextStyle(fontSize: 12));
26 | },
27 | ),
28 | centerTitle: true,
29 | actions: [
30 | IconButton(
31 | icon: Icon(Icons.logout),
32 | onPressed: () {
33 | _authcontroller.signOut();
34 | },
35 | ),
36 | ],
37 | ),
38 | floatingActionButton: FloatingActionButton(
39 | onPressed: () {
40 | Get.dialog(AlertDialog(
41 | title: Text('Add Todo here'),
42 | content: TextFormField(
43 | controller: _todocontroller.todoTitleController,
44 | decoration: InputDecoration(hintText: "Title"),
45 | ),
46 | actions: [
47 | TextButton(
48 | child: Text('OK'),
49 | onPressed: () async {
50 | if (_todocontroller.todoTitleController.text != "") {
51 | await _todocontroller.addTodo();
52 | _todocontroller.todoTitleController.clear();
53 | }
54 | Get.back();
55 | },
56 | ),
57 | ],
58 | ));
59 | },
60 | child: Icon(Icons.add),
61 | ),
62 | body: Padding(
63 | padding: EdgeInsets.all(16),
64 | child: Column(
65 | //mainAxisAlignment: MainAxisAlignment.center,
66 | crossAxisAlignment: CrossAxisAlignment.stretch,
67 | children: [
68 | Obx(
69 | () => (controller.imageUrl.value != null &&
70 | controller.imageUrl.value.isEmpty == false)
71 | ? Container(
72 | height: 150,
73 | child: controller.isLoading.value == true
74 | ? const Center(child: CircularProgressIndicator())
75 | : Image.network(controller.imageUrl.value))
76 | : Container(
77 | color: Color(0xffE1E5E4),
78 | height: 150,
79 | child: Image.asset(
80 | 'images/profile_image.png',
81 | fit: BoxFit.contain,
82 | ),
83 | ),
84 | ),
85 | SizedBox(
86 | height: 8,
87 | ),
88 | new Row(
89 | mainAxisAlignment: MainAxisAlignment.center,
90 | children: [
91 | new IconButton(
92 | onPressed: () => controller.setUserImage(),
93 | icon: Icon(Icons.camera_alt),
94 | ),
95 | ],
96 | ),
97 | Text(
98 | "Your Todos",
99 | textAlign: TextAlign.center,
100 | style: TextStyle(
101 | fontSize: 20,
102 | fontWeight: FontWeight.bold,
103 | ),
104 | ),
105 | SizedBox(
106 | height: 8,
107 | ),
108 | Obx(
109 | () => Expanded(
110 | child: ListView.builder(
111 | itemCount: _todocontroller.todoList.length,
112 | itemBuilder: (_, index) {
113 | return TodoCard(todo: _todocontroller.todoList[index]);
114 | },
115 | ),
116 | ),
117 | ),
118 | ],
119 | ),
120 | ));
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/lib/pages/loading_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/authController.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class LoadingPage extends StatelessWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | AuthController controller = Get.find();
9 | return Scaffold(
10 | appBar: AppBar(title: Text('ToDo App')),
11 | body: Container(
12 | // color: Color(0xff90CCE6),
13 | child: Center(
14 | child: Column(
15 | mainAxisAlignment: MainAxisAlignment.center,
16 | crossAxisAlignment: CrossAxisAlignment.stretch,
17 | children: [
18 | Container(
19 | color: Color(0xffE1E5E4),
20 | // height: 200,
21 | child: Image.asset(
22 | 'images/aws.png',
23 | fit: BoxFit.cover,
24 | ),
25 | ),
26 | SizedBox(
27 | height: 48.0,
28 | ),
29 | Padding(
30 | padding: const EdgeInsets.all(8.0),
31 | child: Center(
32 | child: CircularProgressIndicator(),
33 | ),
34 | ),
35 | ],
36 | ),
37 | ),
38 | ),
39 | backgroundColor: Color(0xffE1E5E4),
40 | );
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/lib/pages/sign_in_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
2 | import 'package:amplify_todo/buttons_enum.dart';
3 | import 'package:amplify_todo/controllers/authController.dart';
4 | import 'package:amplify_todo/widgets/sign_in_button.dart';
5 | import 'package:flutter/material.dart';
6 | import 'package:get/get.dart';
7 |
8 | class SignInPage extends GetWidget {
9 | @override
10 | Widget build(BuildContext context) {
11 | return Scaffold(
12 | appBar: AppBar(
13 | title: Text('ToDo'),
14 | elevation: 10,
15 | ),
16 | body: _buildContent(context),
17 | backgroundColor: Colors.grey[200],
18 | );
19 | }
20 |
21 | Widget _buildContent(BuildContext context) {
22 | return Padding(
23 | padding: EdgeInsets.all(16),
24 | child: Column(
25 | mainAxisAlignment: MainAxisAlignment.center,
26 | crossAxisAlignment: CrossAxisAlignment.stretch,
27 | children: [
28 | SizedBox(
29 | child: Text(
30 | 'Sign In',
31 | textAlign: TextAlign.center,
32 | style: TextStyle(
33 | fontSize: 32,
34 | fontWeight: FontWeight.w600,
35 | ),
36 | ),
37 | height: 50.0,
38 | ),
39 | SizedBox(
40 | height: 48.0,
41 | ),
42 | SocialSignInButton(
43 | button: Buttons.Google,
44 | onPressed: () => controller.signIn(AuthProvider.google),
45 | color: Colors.white,
46 | text: 'Sign in with Google',
47 | textColor: Colors.black87,
48 | ),
49 | SizedBox(
50 | height: 8.0,
51 | ),
52 | SocialSignInButton(
53 | button: Buttons.Facebook,
54 | onPressed: () => controller.signIn(AuthProvider.facebook),
55 | color: Color(0xFF334D92),
56 | text: 'Sign in with Facebook',
57 | textColor: Colors.white,
58 | ),
59 | SizedBox(
60 | height: 8.0,
61 | ),
62 | SocialSignInButton(
63 | button: Buttons.Apple,
64 | onPressed: () => controller.signIn(AuthProvider.apple),
65 | color: Colors.black54,
66 | text: 'Sign in with Apple',
67 | textColor: Colors.white,
68 | ),
69 | SizedBox(
70 | height: 8.0,
71 | ),
72 | SocialSignInButton(
73 | button: Buttons.Amazon,
74 | onPressed: () => controller.signIn(AuthProvider.amazon),
75 | color: Colors.black87,
76 | text: 'Sign in with Amazon',
77 | textColor: Colors.white,
78 | ),
79 | SizedBox(
80 | height: 8.0,
81 | ),
82 | Text(
83 | 'Or',
84 | style: TextStyle(
85 | fontSize: 14,
86 | color: Colors.black87,
87 | ),
88 | textAlign: TextAlign.center,
89 | ),
90 | SizedBox(
91 | height: 8.0,
92 | ),
93 | SocialSignInButton(
94 | button: Buttons.Email,
95 | onPressed: () => Get.toNamed("/emaillogin"),
96 | color: Colors.deepOrange,
97 | text: 'Sign in with email',
98 | textColor: Colors.white,
99 | ),
100 | ],
101 | ),
102 | );
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/lib/services/amplify_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_analytics_pinpoint/amplify_analytics_pinpoint.dart';
2 | import 'package:amplify_api/amplify_api.dart';
3 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
4 | import 'package:amplify_datastore/amplify_datastore.dart';
5 | import 'package:amplify_flutter/amplify.dart';
6 | import 'package:amplify_storage_s3/amplify_storage_s3.dart';
7 | import 'package:amplify_todo/models/ModelProvider.dart';
8 | import '../amplifyconfiguration.dart';
9 |
10 | class AmplifyService {
11 | static configureAmplify() async {
12 | AmplifyAuthCognito authPlugin = AmplifyAuthCognito();
13 |
14 | AmplifyDataStore datastorePlugin =
15 | AmplifyDataStore(modelProvider: ModelProvider.instance);
16 | AmplifyStorageS3 storage = AmplifyStorageS3();
17 | Amplify.addPlugins([
18 | authPlugin,
19 | datastorePlugin,
20 | AmplifyAnalyticsPinpoint(),
21 | storage,
22 | AmplifyAPI()
23 | ]);
24 |
25 | try {
26 | await Amplify.configure(amplifyconfig);
27 | print('Amplify Configured');
28 | } catch (e) {
29 | print("Tried to reconfigure Amplify");
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/lib/services/auth_service.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:amplify_auth_cognito/amplify_auth_cognito.dart';
4 | import 'package:amplify_datastore/amplify_datastore.dart';
5 | import 'package:amplify_flutter/amplify.dart';
6 | import 'package:amplify_todo/models/Users.dart';
7 | import 'package:amplify_todo/services/datastore_service.dart';
8 |
9 | class AuthService {
10 | DataStoreService _dataStoreService = DataStoreService();
11 | Future signIn(AuthProvider authProvider) async {
12 | try {
13 | await Amplify.Auth.signInWithWebUI(provider: authProvider);
14 | } catch (e) {
15 | throw e;
16 | }
17 | }
18 |
19 | Future signOut() async {
20 | try {
21 | await Amplify.DataStore.clear();
22 | await Amplify.Auth.signOut();
23 | } on AuthException catch (e) {
24 | print(e.message);
25 | }
26 | }
27 |
28 | Future isSignedIn() async {
29 | AuthSession authSessions = await Amplify.Auth.fetchAuthSession();
30 | return authSessions.isSignedIn;
31 | }
32 |
33 | Future getCurrentUser() async {
34 | AuthUser authUser = await Amplify.Auth.getCurrentUser();
35 | return authUser;
36 | }
37 |
38 | Future registerWithEmailAndPassword(
39 | String email, String password) async {
40 | try {
41 | Map userAttributes = {
42 | 'email': email,
43 | 'preferred_username': email,
44 | };
45 | SignUpResult res = await Amplify.Auth.signUp(
46 | username: email,
47 | password: password,
48 | options: CognitoSignUpOptions(userAttributes: userAttributes));
49 | return res.isSignUpComplete;
50 | } on AuthException catch (e) {
51 | print(e.message);
52 | throw e;
53 | }
54 | }
55 |
56 | Future signInWithEmailAndPassword(String email, String password) async {
57 | try {
58 | await signOut();
59 | SignInResult res = await Amplify.Auth.signIn(
60 | username: email.trim(),
61 | password: password.trim(),
62 | );
63 |
64 | await saveUser(email);
65 |
66 | return res.isSignedIn;
67 | } catch (e) {
68 | throw e;
69 | }
70 | }
71 |
72 | Future saveUser(String email) async {
73 | AuthUser authUser = await Amplify.Auth.getCurrentUser();
74 | Users user = new Users(
75 | id: authUser.userId,
76 | username: email,
77 | email: email,
78 | isVerified: true,
79 | createdAt: TemporalDateTime.now(),
80 | imageKey: '',
81 | imageUrl: '');
82 | await _dataStoreService.saveUser(user);
83 | }
84 |
85 | Future confirmRegisterWithCode(
86 | String email, String password, String code) async {
87 | try {
88 | SignUpResult res = await Amplify.Auth.confirmSignUp(
89 | username: email, confirmationCode: code);
90 |
91 | if (res.isSignUpComplete) {
92 | final signInRes = await signInWithEmailAndPassword(email, password);
93 | await saveUser(email);
94 | return signInRes;
95 | }
96 | } catch (e) {
97 | throw e;
98 | }
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/lib/services/datastore_service.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_flutter/amplify.dart';
2 | import 'package:amplify_todo/models/Todo.dart';
3 | import 'package:amplify_todo/models/Users.dart';
4 |
5 | class DataStoreService {
6 | Future saveUser(Users user) async {
7 | try {
8 | await Amplify.DataStore.save(user);
9 | } catch (e) {
10 | throw e;
11 | }
12 | }
13 |
14 | Future getUser(String userId) async {
15 | try {
16 | List user = await Amplify.DataStore.query(Users.classType,
17 | where: Users.ID.eq(userId));
18 | if (user.length > 0) {
19 | return user.first;
20 | } else
21 | print('null');
22 | return null;
23 | } catch (e) {
24 | throw e;
25 | }
26 | }
27 |
28 | Future?> getTodos(String userId) async {
29 | try {
30 | List todos = await Amplify.DataStore.query(Todo.classType,
31 | where: Todo.USERID.eq(userId));
32 | if (todos.length > 0) {
33 | return todos;
34 | } else
35 | return null;
36 | } catch (e) {
37 | throw e;
38 | }
39 | }
40 |
41 | Future removeTodo(Todo todo) async {
42 | try {
43 | await Amplify.DataStore.delete(todo);
44 | } catch (e) {
45 | throw e;
46 | }
47 | }
48 |
49 | Future saveTodo(Todo todo) async {
50 | try {
51 | await Amplify.DataStore.save(todo);
52 | } catch (e) {
53 | throw e;
54 | }
55 | }
56 |
57 | Future setToDoDone(Todo todo, bool newValue) async {
58 | try {
59 | Todo todoData = (await Amplify.DataStore.query(Todo.classType,
60 | where: Todo.ID.eq(todo.id)))[0];
61 | await Amplify.DataStore.save(todoData.copyWith(isDone: newValue));
62 | } catch (e) {
63 | throw e;
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/lib/widgets/email_sign_in_form.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/authController.dart';
2 | import 'package:flutter/material.dart';
3 | import 'package:get/get.dart';
4 |
5 | class EmailSignInForm extends GetWidget {
6 | @override
7 | Widget build(BuildContext context) {
8 | return Obx(() {
9 | return Padding(
10 | padding: const EdgeInsets.all(16.0),
11 | child: Column(
12 | crossAxisAlignment: CrossAxisAlignment.stretch,
13 | mainAxisSize: MainAxisSize.min,
14 | children:
15 | controller.emailformType.value == EmailSignInFormType.confirm
16 | ? _buildConfirmchildren()
17 | : _buildFormchildren(),
18 | ),
19 | );
20 | });
21 | }
22 |
23 | Future _submit() async {
24 | try {} catch (e) {}
25 | }
26 |
27 | List _buildFormchildren() {
28 | return [
29 | TextField(
30 | decoration: InputDecoration(
31 | enabled: controller.isLoading.value == false,
32 | labelText: 'Email',
33 | hintText: 'test@test.com',
34 | errorText: controller.emailErrorText,
35 | ),
36 | controller: controller.emailController,
37 | autocorrect: false,
38 | keyboardType: TextInputType.emailAddress,
39 | textInputAction: TextInputAction.next,
40 | focusNode: controller.emailFocusNode,
41 | onChanged: controller.updateform
42 | //onEditingComplete: () => _emailEditingComplete(),
43 | ),
44 | SizedBox(
45 | height: 8.0,
46 | ),
47 | TextField(
48 | decoration: InputDecoration(
49 | // enabled: model.isLoading == false,
50 | labelText: 'Password',
51 | // errorText: model.passwordErrorText,
52 | ),
53 | obscureText: true,
54 | controller: controller.passwordController,
55 | textInputAction: TextInputAction.done,
56 | focusNode: controller.passwordFocusNode,
57 | onEditingComplete: controller.submitEmailAndPassword,
58 | onChanged: controller.updateform),
59 | SizedBox(
60 | height: 8.0,
61 | ),
62 | ElevatedButton(
63 | onPressed: controller.submitEnabled.value
64 | ? controller.submitEmailAndPassword
65 | : null, //
66 | child: Text(
67 | controller.primaryButtonText,
68 | ),
69 | ),
70 | SizedBox(
71 | height: 8.0,
72 | ),
73 | TextButton(
74 | onPressed:
75 | !controller.isLoading.value ? controller.toggleFormType : null,
76 | child: Text(controller.secondaryButtonText),
77 | )
78 | ];
79 | }
80 |
81 | List _buildConfirmchildren() {
82 | return [
83 | TextField(
84 | decoration: InputDecoration(
85 | enabled: controller.isLoading.value == false,
86 | labelText: 'Confirmation Code',
87 | hintText: 'The code we sent you',
88 | errorText: controller.emailErrorText,
89 | ),
90 | controller: controller.codeController,
91 | autocorrect: false,
92 | keyboardType: TextInputType.text,
93 | textInputAction: TextInputAction.done,
94 | focusNode: controller.codeFocusNode,
95 | onEditingComplete: controller.submitEmailAndPassword,
96 | ),
97 | SizedBox(
98 | height: 8.0,
99 | ),
100 | ElevatedButton(
101 | onPressed: controller.submitEnabled.value
102 | ? controller.submitEmailAndPassword
103 | : null,
104 | child: Text(
105 | controller.primaryButtonText,
106 | ),
107 | ),
108 | SizedBox(
109 | height: 8.0,
110 | ),
111 | ];
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/lib/widgets/sign_in_button.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/buttons_enum.dart';
2 | import 'package:flutter/material.dart';
3 |
4 | import 'package:font_awesome_flutter/font_awesome_flutter.dart';
5 |
6 | class SocialSignInButton extends StatelessWidget {
7 | final Color color;
8 | final String text;
9 | final Color textColor;
10 | final double height;
11 | static const double borderRadius = 4.0;
12 | final VoidCallback onPressed;
13 | final Buttons button;
14 |
15 | const SocialSignInButton({
16 | Key? key,
17 | required this.color,
18 | required this.onPressed,
19 | this.height: 50,
20 | required this.button,
21 | required this.text,
22 | required this.textColor,
23 | }) : super(key: key);
24 | @override
25 | Widget build(BuildContext context) {
26 | return SizedBox(
27 | height: height,
28 | child: ElevatedButton(
29 | onPressed: onPressed,
30 | style: ElevatedButton.styleFrom(
31 | primary: color,
32 | shape: const RoundedRectangleBorder(
33 | borderRadius: BorderRadius.all(Radius.circular(borderRadius))),
34 | ),
35 | child: buildRow(),
36 | ),
37 | );
38 | }
39 |
40 | Row buildRow() {
41 | switch (button) {
42 | case Buttons.Google:
43 | return Row(
44 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
45 | children: [
46 | Image.asset('images/google-logo.png'),
47 | Text(
48 | text,
49 | style: TextStyle(color: textColor, fontSize: 15),
50 | ),
51 | Opacity(opacity: 0.0, child: Image.asset('images/google-logo.png')),
52 | ],
53 | );
54 | case Buttons.Email:
55 | return Row(
56 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
57 | children: [
58 | Icon(
59 | Icons.email,
60 | ),
61 | Text(
62 | text,
63 | style: TextStyle(color: textColor, fontSize: 15),
64 | ),
65 | Opacity(
66 | opacity: 0.0,
67 | child: Icon(
68 | Icons.email,
69 | ),
70 | ),
71 | ],
72 | );
73 |
74 | case Buttons.Facebook:
75 | return Row(
76 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
77 | children: [
78 | Image.asset('images/facebook-logo.png'),
79 | Text(
80 | text,
81 | style: TextStyle(color: textColor, fontSize: 15),
82 | ),
83 | Opacity(
84 | opacity: 0.0, child: Image.asset('images/facebook-logo.png')),
85 | ],
86 | );
87 |
88 | case Buttons.Amazon:
89 | return Row(
90 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
91 | children: [
92 | Image.asset('images/amazon-logo.png'),
93 | Text(
94 | text,
95 | style: TextStyle(color: textColor, fontSize: 15),
96 | ),
97 | Opacity(opacity: 0.0, child: Image.asset('images/amazon-logo.png')),
98 | ],
99 | );
100 |
101 | case Buttons.Apple:
102 | return Row(
103 | mainAxisAlignment: MainAxisAlignment.spaceBetween,
104 | children: [
105 | Icon(
106 | FontAwesomeIcons.apple,
107 | color: Colors.white,
108 | ),
109 | Text(
110 | text,
111 | style: TextStyle(color: textColor, fontSize: 15),
112 | ),
113 | Opacity(
114 | opacity: 0.0,
115 | child: Icon(
116 | FontAwesomeIcons.apple,
117 | ),
118 | ),
119 | ],
120 | );
121 | }
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/lib/widgets/todo_card.dart:
--------------------------------------------------------------------------------
1 | import 'package:amplify_todo/controllers/todoController.dart';
2 | import 'package:amplify_todo/models/Todo.dart';
3 | import 'package:flutter/material.dart';
4 | import 'package:get/get.dart';
5 | import 'package:intl/intl.dart';
6 |
7 | class TodoCard extends StatelessWidget {
8 | final Todo todo;
9 | const TodoCard({required this.todo});
10 |
11 | @override
12 | Widget build(BuildContext context) {
13 | TodoController _todocontroller = Get.find();
14 | return _buildContent(_todocontroller);
15 | }
16 |
17 | Dismissible _buildContent(TodoController _todocontroller) {
18 | return Dismissible(
19 | direction: DismissDirection.startToEnd,
20 | onDismissed: (DismissDirection direction) {
21 | if (direction == DismissDirection.startToEnd) {
22 | _todocontroller.removeTodo(todo);
23 | }
24 | },
25 | background: Container(
26 | alignment: Alignment.centerLeft,
27 | color: Colors.red,
28 | child: Padding(
29 | padding: const EdgeInsets.all(8.0),
30 | child: Icon(
31 | Icons.delete,
32 | color: Colors.white,
33 | ),
34 | ),
35 | ),
36 | key: ValueKey(todo.id),
37 | child: _buildCard(_todocontroller),
38 | );
39 | }
40 |
41 | Card _buildCard(TodoController _todocontroller) {
42 | return Card(
43 | margin: EdgeInsets.symmetric(horizontal: 10, vertical: 5),
44 | child: ListTile(
45 | leading: Checkbox(
46 | value: todo.isDone,
47 | onChanged: (newValue) {
48 | _todocontroller.setToDoDone(todo, newValue!);
49 | },
50 | ),
51 | title: Text(
52 | todo.name,
53 | style: TextStyle(
54 | color: Colors.black,
55 | fontSize: 15,
56 | fontWeight: FontWeight.bold,
57 | ),
58 | ),
59 | subtitle: Column(
60 | crossAxisAlignment: CrossAxisAlignment.start,
61 | children: [
62 | Text(
63 | DateFormat.yMMMMEEEEd()
64 | .format(todo.createdAt!.getDateTimeInUtc()),
65 | style: TextStyle(
66 | color: Colors.grey,
67 | fontSize: 10,
68 | ),
69 | ),
70 | ],
71 | ),
72 | ),
73 | );
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/pubspec.lock:
--------------------------------------------------------------------------------
1 | # Generated by pub
2 | # See https://dart.dev/tools/pub/glossary#lockfile
3 | packages:
4 | amplify_analytics_pinpoint:
5 | dependency: "direct main"
6 | description:
7 | name: amplify_analytics_pinpoint
8 | url: "https://pub.dartlang.org"
9 | source: hosted
10 | version: "0.2.0"
11 | amplify_analytics_plugin_interface:
12 | dependency: transitive
13 | description:
14 | name: amplify_analytics_plugin_interface
15 | url: "https://pub.dartlang.org"
16 | source: hosted
17 | version: "0.2.0"
18 | amplify_api:
19 | dependency: "direct main"
20 | description:
21 | name: amplify_api
22 | url: "https://pub.dartlang.org"
23 | source: hosted
24 | version: "0.2.0"
25 | amplify_api_plugin_interface:
26 | dependency: transitive
27 | description:
28 | name: amplify_api_plugin_interface
29 | url: "https://pub.dartlang.org"
30 | source: hosted
31 | version: "0.2.0"
32 | amplify_auth_cognito:
33 | dependency: "direct main"
34 | description:
35 | name: amplify_auth_cognito
36 | url: "https://pub.dartlang.org"
37 | source: hosted
38 | version: "0.2.0"
39 | amplify_auth_plugin_interface:
40 | dependency: transitive
41 | description:
42 | name: amplify_auth_plugin_interface
43 | url: "https://pub.dartlang.org"
44 | source: hosted
45 | version: "0.2.0"
46 | amplify_core:
47 | dependency: transitive
48 | description:
49 | name: amplify_core
50 | url: "https://pub.dartlang.org"
51 | source: hosted
52 | version: "0.2.0"
53 | amplify_datastore:
54 | dependency: "direct main"
55 | description:
56 | name: amplify_datastore
57 | url: "https://pub.dartlang.org"
58 | source: hosted
59 | version: "0.2.0"
60 | amplify_datastore_plugin_interface:
61 | dependency: transitive
62 | description:
63 | name: amplify_datastore_plugin_interface
64 | url: "https://pub.dartlang.org"
65 | source: hosted
66 | version: "0.2.0"
67 | amplify_flutter:
68 | dependency: "direct main"
69 | description:
70 | name: amplify_flutter
71 | url: "https://pub.dartlang.org"
72 | source: hosted
73 | version: "0.2.0"
74 | amplify_storage_plugin_interface:
75 | dependency: transitive
76 | description:
77 | name: amplify_storage_plugin_interface
78 | url: "https://pub.dartlang.org"
79 | source: hosted
80 | version: "0.2.0"
81 | amplify_storage_s3:
82 | dependency: "direct main"
83 | description:
84 | name: amplify_storage_s3
85 | url: "https://pub.dartlang.org"
86 | source: hosted
87 | version: "0.2.0"
88 | async:
89 | dependency: transitive
90 | description:
91 | name: async
92 | url: "https://pub.dartlang.org"
93 | source: hosted
94 | version: "2.6.1"
95 | boolean_selector:
96 | dependency: transitive
97 | description:
98 | name: boolean_selector
99 | url: "https://pub.dartlang.org"
100 | source: hosted
101 | version: "2.1.0"
102 | characters:
103 | dependency: transitive
104 | description:
105 | name: characters
106 | url: "https://pub.dartlang.org"
107 | source: hosted
108 | version: "1.1.0"
109 | charcode:
110 | dependency: transitive
111 | description:
112 | name: charcode
113 | url: "https://pub.dartlang.org"
114 | source: hosted
115 | version: "1.2.0"
116 | clock:
117 | dependency: transitive
118 | description:
119 | name: clock
120 | url: "https://pub.dartlang.org"
121 | source: hosted
122 | version: "1.1.0"
123 | collection:
124 | dependency: transitive
125 | description:
126 | name: collection
127 | url: "https://pub.dartlang.org"
128 | source: hosted
129 | version: "1.15.0"
130 | crypto:
131 | dependency: transitive
132 | description:
133 | name: crypto
134 | url: "https://pub.dartlang.org"
135 | source: hosted
136 | version: "3.0.1"
137 | cupertino_icons:
138 | dependency: "direct main"
139 | description:
140 | name: cupertino_icons
141 | url: "https://pub.dartlang.org"
142 | source: hosted
143 | version: "1.0.3"
144 | date_time_format:
145 | dependency: transitive
146 | description:
147 | name: date_time_format
148 | url: "https://pub.dartlang.org"
149 | source: hosted
150 | version: "2.0.1"
151 | fake_async:
152 | dependency: transitive
153 | description:
154 | name: fake_async
155 | url: "https://pub.dartlang.org"
156 | source: hosted
157 | version: "1.2.0"
158 | flutter:
159 | dependency: "direct main"
160 | description: flutter
161 | source: sdk
162 | version: "0.0.0"
163 | flutter_plugin_android_lifecycle:
164 | dependency: transitive
165 | description:
166 | name: flutter_plugin_android_lifecycle
167 | url: "https://pub.dartlang.org"
168 | source: hosted
169 | version: "2.0.2"
170 | flutter_test:
171 | dependency: "direct dev"
172 | description: flutter
173 | source: sdk
174 | version: "0.0.0"
175 | flutter_web_plugins:
176 | dependency: transitive
177 | description: flutter
178 | source: sdk
179 | version: "0.0.0"
180 | font_awesome_flutter:
181 | dependency: "direct main"
182 | description:
183 | name: font_awesome_flutter
184 | url: "https://pub.dartlang.org"
185 | source: hosted
186 | version: "9.0.0"
187 | get:
188 | dependency: "direct main"
189 | description:
190 | name: get
191 | url: "https://pub.dartlang.org"
192 | source: hosted
193 | version: "4.1.4"
194 | http:
195 | dependency: transitive
196 | description:
197 | name: http
198 | url: "https://pub.dartlang.org"
199 | source: hosted
200 | version: "0.13.3"
201 | http_parser:
202 | dependency: transitive
203 | description:
204 | name: http_parser
205 | url: "https://pub.dartlang.org"
206 | source: hosted
207 | version: "4.0.0"
208 | image_picker:
209 | dependency: "direct main"
210 | description:
211 | name: image_picker
212 | url: "https://pub.dartlang.org"
213 | source: hosted
214 | version: "0.8.1+1"
215 | image_picker_for_web:
216 | dependency: transitive
217 | description:
218 | name: image_picker_for_web
219 | url: "https://pub.dartlang.org"
220 | source: hosted
221 | version: "2.0.0"
222 | image_picker_platform_interface:
223 | dependency: transitive
224 | description:
225 | name: image_picker_platform_interface
226 | url: "https://pub.dartlang.org"
227 | source: hosted
228 | version: "2.1.0"
229 | intl:
230 | dependency: "direct main"
231 | description:
232 | name: intl
233 | url: "https://pub.dartlang.org"
234 | source: hosted
235 | version: "0.17.0"
236 | js:
237 | dependency: transitive
238 | description:
239 | name: js
240 | url: "https://pub.dartlang.org"
241 | source: hosted
242 | version: "0.6.3"
243 | matcher:
244 | dependency: transitive
245 | description:
246 | name: matcher
247 | url: "https://pub.dartlang.org"
248 | source: hosted
249 | version: "0.12.10"
250 | meta:
251 | dependency: transitive
252 | description:
253 | name: meta
254 | url: "https://pub.dartlang.org"
255 | source: hosted
256 | version: "1.3.0"
257 | path:
258 | dependency: transitive
259 | description:
260 | name: path
261 | url: "https://pub.dartlang.org"
262 | source: hosted
263 | version: "1.8.0"
264 | pedantic:
265 | dependency: transitive
266 | description:
267 | name: pedantic
268 | url: "https://pub.dartlang.org"
269 | source: hosted
270 | version: "1.11.1"
271 | plugin_platform_interface:
272 | dependency: transitive
273 | description:
274 | name: plugin_platform_interface
275 | url: "https://pub.dartlang.org"
276 | source: hosted
277 | version: "2.0.0"
278 | sky_engine:
279 | dependency: transitive
280 | description: flutter
281 | source: sdk
282 | version: "0.0.99"
283 | source_span:
284 | dependency: transitive
285 | description:
286 | name: source_span
287 | url: "https://pub.dartlang.org"
288 | source: hosted
289 | version: "1.8.1"
290 | stack_trace:
291 | dependency: transitive
292 | description:
293 | name: stack_trace
294 | url: "https://pub.dartlang.org"
295 | source: hosted
296 | version: "1.10.0"
297 | stream_channel:
298 | dependency: transitive
299 | description:
300 | name: stream_channel
301 | url: "https://pub.dartlang.org"
302 | source: hosted
303 | version: "2.1.0"
304 | string_scanner:
305 | dependency: transitive
306 | description:
307 | name: string_scanner
308 | url: "https://pub.dartlang.org"
309 | source: hosted
310 | version: "1.1.0"
311 | term_glyph:
312 | dependency: transitive
313 | description:
314 | name: term_glyph
315 | url: "https://pub.dartlang.org"
316 | source: hosted
317 | version: "1.2.0"
318 | test_api:
319 | dependency: transitive
320 | description:
321 | name: test_api
322 | url: "https://pub.dartlang.org"
323 | source: hosted
324 | version: "0.3.0"
325 | transparent_image:
326 | dependency: "direct main"
327 | description:
328 | name: transparent_image
329 | url: "https://pub.dartlang.org"
330 | source: hosted
331 | version: "2.0.0"
332 | typed_data:
333 | dependency: transitive
334 | description:
335 | name: typed_data
336 | url: "https://pub.dartlang.org"
337 | source: hosted
338 | version: "1.3.0"
339 | uuid:
340 | dependency: "direct main"
341 | description:
342 | name: uuid
343 | url: "https://pub.dartlang.org"
344 | source: hosted
345 | version: "3.0.4"
346 | vector_math:
347 | dependency: transitive
348 | description:
349 | name: vector_math
350 | url: "https://pub.dartlang.org"
351 | source: hosted
352 | version: "2.1.0"
353 | sdks:
354 | dart: ">=2.12.0 <3.0.0"
355 | flutter: ">=2.0.0"
356 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: amplify_todo
2 | description: A new Flutter project.
3 |
4 | # The following line prevents the package from being accidentally published to
5 | # pub.dev using `pub publish`. This is preferred for private packages.
6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
7 |
8 | # The following defines the version and build number for your application.
9 | # A version number is three numbers separated by dots, like 1.2.43
10 | # followed by an optional build number separated by a +.
11 | # Both the version and the builder number may be overridden in flutter
12 | # build by specifying --build-name and --build-number, respectively.
13 | # In Android, build-name is used as versionName while build-number used as versionCode.
14 | # Read more about Android versioning at https://developer.android.com/studio/publish/versioning
15 | # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
16 | # Read more about iOS versioning at
17 | # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
18 | version: 1.0.0+1
19 |
20 | environment:
21 | sdk: ">=2.12.0 <3.0.0"
22 |
23 | dependencies:
24 | flutter:
25 | sdk: flutter
26 | get: ^4.1.4
27 | amplify_flutter: ^0.2.0
28 | amplify_auth_cognito: ^0.2.0
29 | amplify_datastore: ^0.2.0
30 | amplify_analytics_pinpoint: ^0.2.0
31 | font_awesome_flutter: ^9.0.0
32 | amplify_storage_s3: ^0.2.0
33 | amplify_api: ^0.2.0
34 | intl: ^0.17.0
35 | image_picker: ^0.8.0+3
36 | uuid: ^3.0.4
37 | transparent_image: ^2.0.0
38 |
39 |
40 | # The following adds the Cupertino Icons font to your application.
41 | # Use with the CupertinoIcons class for iOS style icons.
42 | cupertino_icons: ^1.0.2
43 |
44 | dev_dependencies:
45 | flutter_test:
46 | sdk: flutter
47 |
48 | # For information on the generic Dart part of this file, see the
49 | # following page: https://dart.dev/tools/pub/pubspec
50 |
51 | # The following section is specific to Flutter.
52 | flutter:
53 |
54 | # The following line ensures that the Material Icons font is
55 | # included with your application, so that you can use the icons in
56 | # the material Icons class.
57 | uses-material-design: true
58 |
59 | # To add assets to your application, add an assets section, like this:
60 | assets:
61 | - images/facebook-logo.png
62 | - images/google-logo.png
63 | - images/amazon-logo.png
64 | - images/applogo.png
65 | - images/aws.png
66 | - images/profile.png
67 | - images/profile_image.png
68 |
69 | # An image asset can refer to one or more resolution-specific "variants", see
70 | # https://flutter.dev/assets-and-images/#resolution-aware.
71 |
72 | # For details regarding adding assets from package dependencies, see
73 | # https://flutter.dev/assets-and-images/#from-packages
74 |
75 | # To add custom fonts to your application, add a fonts section here,
76 | # in this "flutter" section. Each entry in this list should have a
77 | # "family" key with the font family name, and a "fonts" key with a
78 | # list giving the asset and other descriptors for the font. For
79 | # example:
80 | # fonts:
81 | # - family: Schyler
82 | # fonts:
83 | # - asset: fonts/Schyler-Regular.ttf
84 | # - asset: fonts/Schyler-Italic.ttf
85 | # style: italic
86 | # - family: Trajan Pro
87 | # fonts:
88 | # - asset: fonts/TrajanPro.ttf
89 | # - asset: fonts/TrajanPro_Bold.ttf
90 | # weight: 700
91 | #
92 | # For details regarding fonts from package dependencies,
93 | # see https://flutter.dev/custom-fonts/#from-packages
94 |
--------------------------------------------------------------------------------
/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility that Flutter provides. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:amplify_todo/main.dart';
12 |
13 | void main() {
14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(MyApp());
17 |
18 | // Verify that our counter starts at 0.
19 | expect(find.text('0'), findsOneWidget);
20 | expect(find.text('1'), findsNothing);
21 |
22 | // Tap the '+' icon and trigger a frame.
23 | await tester.tap(find.byIcon(Icons.add));
24 | await tester.pump();
25 |
26 | // Verify that our counter has incremented.
27 | expect(find.text('0'), findsNothing);
28 | expect(find.text('1'), findsOneWidget);
29 | });
30 | }
31 |
--------------------------------------------------------------------------------
/youtube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/offlineprogrammer/amplify_todo/a73225e52755edb069d0903784424a6f03603017/youtube.png
--------------------------------------------------------------------------------