Browse Source

base init

master
daivph 5 years ago
parent
commit
83946888ec
49 changed files with 1435 additions and 205 deletions
  1. +46
    -0
      ios/Podfile.lock
  2. +71
    -0
      ios/Runner.xcodeproj/project.pbxproj
  3. +3
    -0
      ios/Runner.xcworkspace/contents.xcworkspacedata
  4. +78
    -0
      lib/app.dart
  5. +0
    -65
      lib/app/my_app.dart
  6. +0
    -42
      lib/app/themes.dart
  7. +1
    -0
      lib/authentication/authentication.dart
  8. +73
    -0
      lib/authentication/bloc/authentication_bloc.dart
  9. +19
    -0
      lib/authentication/bloc/authentication_event.dart
  10. +22
    -0
      lib/authentication/bloc/authentication_state.dart
  11. +44
    -0
      lib/data/api/dio_provider.dart
  12. +14
    -0
      lib/data/api/rest_client.dart
  13. +38
    -0
      lib/data/api/rest_client.g.dart
  14. +13
    -0
      lib/data/repository/repository.dart
  15. +6
    -7
      lib/main.dart
  16. +13
    -0
      lib/models/user.dart
  17. +15
    -0
      lib/models/user.g.dart
  18. +13
    -0
      lib/models/user_request.dart
  19. +20
    -0
      lib/models/user_request.g.dart
  20. +50
    -0
      lib/presentation/custom_widgets/widget_loading.dart
  21. +1
    -0
      lib/presentation/screens/home/home.dart
  22. +34
    -0
      lib/presentation/screens/home/view/home_page.dart
  23. +75
    -0
      lib/presentation/screens/login/bloc/login_bloc.dart
  24. +30
    -0
      lib/presentation/screens/login/bloc/login_event.dart
  25. +28
    -0
      lib/presentation/screens/login/bloc/login_state.dart
  26. +3
    -0
      lib/presentation/screens/login/login.dart
  27. +2
    -0
      lib/presentation/screens/login/models/models.dart
  28. +13
    -0
      lib/presentation/screens/login/models/password.dart
  29. +13
    -0
      lib/presentation/screens/login/models/username.dart
  30. +98
    -0
      lib/presentation/screens/login/view/login_form.dart
  31. +30
    -0
      lib/presentation/screens/login/view/login_page.dart
  32. +2
    -0
      lib/presentation/screens/login/view/view.dart
  33. +1
    -0
      lib/presentation/screens/splash/splash.dart
  34. +14
    -0
      lib/presentation/screens/splash/view/splash_page.dart
  35. +3
    -0
      lib/utils/const_common.dart
  36. +1
    -0
      lib/utils/pref.dart
  37. +3
    -0
      packages/authentication_repository/lib/authentication_repository.dart
  38. +34
    -0
      packages/authentication_repository/lib/src/authentication_repository.dart
  39. +12
    -0
      packages/authentication_repository/pubspec.lock
  40. +9
    -0
      packages/authentication_repository/pubspec.yaml
  41. +1
    -0
      packages/user_repository/lib/src/models/models.dart
  42. +10
    -0
      packages/user_repository/lib/src/models/user.dart
  43. +14
    -0
      packages/user_repository/lib/src/user_repository.dart
  44. +4
    -0
      packages/user_repository/lib/user_repository.dart
  45. +61
    -0
      packages/user_repository/pubspec.lock
  46. +11
    -0
      packages/user_repository/pubspec.yaml
  47. +372
    -1
      pubspec.lock
  48. +17
    -60
      pubspec.yaml
  49. +0
    -30
      test/widget_test.dart

+ 46
- 0
ios/Podfile.lock View File

PODS:
- Flutter (1.0.0)
- path_provider_linux (0.0.1):
- Flutter
- shared_preferences (0.0.1):
- Flutter
- shared_preferences_linux (0.0.1):
- Flutter
- shared_preferences_macos (0.0.1):
- Flutter
- shared_preferences_web (0.0.1):
- Flutter

DEPENDENCIES:
- Flutter (from `Flutter`)
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
- shared_preferences (from `.symlinks/plugins/shared_preferences/ios`)
- shared_preferences_linux (from `.symlinks/plugins/shared_preferences_linux/ios`)
- shared_preferences_macos (from `.symlinks/plugins/shared_preferences_macos/ios`)
- shared_preferences_web (from `.symlinks/plugins/shared_preferences_web/ios`)

EXTERNAL SOURCES:
Flutter:
:path: Flutter
path_provider_linux:
:path: ".symlinks/plugins/path_provider_linux/ios"
shared_preferences:
:path: ".symlinks/plugins/shared_preferences/ios"
shared_preferences_linux:
:path: ".symlinks/plugins/shared_preferences_linux/ios"
shared_preferences_macos:
:path: ".symlinks/plugins/shared_preferences_macos/ios"
shared_preferences_web:
:path: ".symlinks/plugins/shared_preferences_web/ios"

SPEC CHECKSUMS:
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d
shared_preferences_linux: afefbfe8d921e207f01ede8b60373d9e3b566b78
shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087
shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9

PODFILE CHECKSUM: c34e2287a9ccaa606aeceab922830efb9a6ff69a

COCOAPODS: 1.9.3

+ 71
- 0
ios/Runner.xcodeproj/project.pbxproj View File

1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97280A7711C46F9F9C83E537 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4D01659C26BFB65615058BF0 /* Pods_Runner.framework */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */


/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0BC0F43034414FAB24B626F3 /* 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 = "<group>"; };
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; }; 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
1BA1D19EF353DFCE335E0C1F /* 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 = "<group>"; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
4D01659C26BFB65615058BF0 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
95FEBA268448B96856A798E7 /* 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 = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; }; 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; }; 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
97280A7711C46F9F9C83E537 /* Pods_Runner.framework in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */


/* Begin PBXGroup section */ /* Begin PBXGroup section */
2C5DAD4B82BC146A052F8839 /* Pods */ = {
isa = PBXGroup;
children = (
0BC0F43034414FAB24B626F3 /* Pods-Runner.debug.xcconfig */,
1BA1D19EF353DFCE335E0C1F /* Pods-Runner.release.xcconfig */,
95FEBA268448B96856A798E7 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
9220643F6C3D895C737199D7 /* Frameworks */ = {
isa = PBXGroup;
children = (
4D01659C26BFB65615058BF0 /* Pods_Runner.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = { 9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
9740EEB11CF90186004384FC /* Flutter */, 9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */, 97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */, 97C146EF1CF9000F007C117D /* Products */,
2C5DAD4B82BC146A052F8839 /* Pods */,
9220643F6C3D895C737199D7 /* Frameworks */,
); );
sourceTree = "<group>"; sourceTree = "<group>";
}; };
isa = PBXNativeTarget; isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = ( buildPhases = (
F9CCF48907EF75C488FA6995 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */, 9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */, 97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
8A5D95728F54511932EFB110 /* [CP] Embed Pods Frameworks */,
); );
buildRules = ( buildRules = (
); );
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
}; };
8A5D95728F54511932EFB110 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh",
"${PODS_ROOT}/../Flutter/Flutter.framework",
"${BUILT_PRODUCTS_DIR}/shared_preferences/shared_preferences.framework",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/shared_preferences.framework",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
shellPath = /bin/sh; shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
}; };
F9CCF48907EF75C488FA6995 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
"${PODS_ROOT}/Manifest.lock",
);
name = "[CP] Check Pods Manifest.lock";
outputFileListPaths = (
);
outputPaths = (
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */ /* End PBXShellScriptBuildPhase section */


/* Begin PBXSourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */

+ 3
- 0
ios/Runner.xcworkspace/contents.xcworkspacedata View File

<FileRef <FileRef
location = "group:Runner.xcodeproj"> location = "group:Runner.xcodeproj">
</FileRef> </FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace> </Workspace>

+ 78
- 0
lib/app.dart View File

import 'package:authentication_repository/authentication_repository.dart';
import 'package:farm_tpf/presentation/screens/home/view/home_page.dart';
import 'package:farm_tpf/presentation/screens/login/view/login_page.dart';
import 'package:farm_tpf/presentation/screens/splash/view/splash_page.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:user_repository/user_repository.dart';

import 'authentication/bloc/authentication_bloc.dart';

class App extends StatelessWidget {
const App({
Key key,
@required this.authenticationRepository,
@required this.userRepository,
}) : assert(authenticationRepository != null),
assert(userRepository != null),
super(key: key);

final AuthenticationRepository authenticationRepository;
final UserRepository userRepository;

@override
Widget build(BuildContext context) {
return RepositoryProvider.value(
value: authenticationRepository,
child: BlocProvider(
create: (_) => AuthenticationBloc(
authenticationRepository: authenticationRepository,
userRepository: userRepository,
),
child: AppView(),
),
);
}
}

class AppView extends StatefulWidget {
@override
_AppViewState createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
final _navigatorKey = GlobalKey<NavigatorState>();

NavigatorState get _navigator => _navigatorKey.currentState;

@override
Widget build(BuildContext context) {
return MaterialApp(
navigatorKey: _navigatorKey,
builder: (context, child) {
return BlocListener<AuthenticationBloc, AuthenticationState>(
listener: (context, state) {
switch (state.status) {
case AuthenticationStatus.authenticated:
_navigator.pushAndRemoveUntil<void>(
HomePage.route(),
(route) => false,
);
break;
case AuthenticationStatus.unauthenticated:
_navigator.pushAndRemoveUntil<void>(
LoginPage.route(),
(route) => false,
);
break;
default:
break;
}
},
child: child,
);
},
onGenerateRoute: (_) => SplashPage.route(),
);
}
}

+ 0
- 65
lib/app/my_app.dart View File

import 'package:farm_tpf/app/themes.dart';
import 'package:farm_tpf/utils/const_string.dart';
import 'package:flutter/material.dart';

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: AppTheme.of(context, listen: true).currentTheme,
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;

AppTheme _theme;

@override
void didChangeDependencies() {
if (_theme == null) {
_theme = AppTheme.of(context);
}

super.didChangeDependencies();
}

void _incrementCounter() {
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
actions: [
IconButton(
icon: Icon(Icons.flip, color: Colors.white),
onPressed: _theme?.switchTheme,
),
],
),
body: Center(child: Text(app_name)));
}
}

+ 0
- 42
lib/app/themes.dart View File

import 'package:farm_tpf/utils/const_color.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

enum AppThemeStyle { light, dark }

final Map<AppThemeStyle, ThemeData> _themes = {
AppThemeStyle.light: ThemeData(
primaryColor: Colors.green,
accentColor: Colors.green,
brightness: Brightness.light,
),
AppThemeStyle.dark: ThemeData(
primaryColor: Colors.blue,
accentColor: Colors.blue,
brightness: Brightness.dark,
),
};

class AppTheme extends ChangeNotifier {
static AppTheme of(BuildContext context, {bool listen = false}) =>
Provider.of<AppTheme>(context, listen: listen);

AppThemeStyle _themeKey = AppThemeStyle.light;

ThemeData get currentTheme => _themes[_themeKey];
AppThemeStyle get currentThemeKey => _themeKey;

void setTheme(AppThemeStyle themeKey) {
_themeKey = themeKey;
notifyListeners();
}

void switchTheme() {
if (_themeKey == AppThemeStyle.dark) {
_themeKey = AppThemeStyle.light;
} else {
_themeKey = AppThemeStyle.dark;
}
notifyListeners();
}
}

+ 1
- 0
lib/authentication/authentication.dart View File

export 'bloc/authentication_bloc.dart';

+ 73
- 0
lib/authentication/bloc/authentication_bloc.dart View File

import 'dart:async';

import 'package:authentication_repository/authentication_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:meta/meta.dart';
import 'package:user_repository/user_repository.dart';

part 'authentication_event.dart';
part 'authentication_state.dart';

class AuthenticationBloc
extends Bloc<AuthenticationEvent, AuthenticationState> {
AuthenticationBloc({
@required AuthenticationRepository authenticationRepository,
@required UserRepository userRepository,
}) : assert(authenticationRepository != null),
assert(userRepository != null),
_authenticationRepository = authenticationRepository,
_userRepository = userRepository,
super(const AuthenticationState.unknown()) {
_authenticationStatusSubscription = _authenticationRepository.status.listen(
(status) => add(AuthenticationStatusChanged(status)),
);
}

final AuthenticationRepository _authenticationRepository;
final UserRepository _userRepository;
StreamSubscription<AuthenticationStatus> _authenticationStatusSubscription;

@override
Stream<AuthenticationState> mapEventToState(
AuthenticationEvent event,
) async* {
if (event is AuthenticationStatusChanged) {
yield await _mapAuthenticationStatusChangedToState(event);
} else if (event is AuthenticationLogoutRequested) {
_authenticationRepository.logOut();
}
}

@override
Future<void> close() {
_authenticationStatusSubscription?.cancel();
_authenticationRepository.dispose();
return super.close();
}

Future<AuthenticationState> _mapAuthenticationStatusChangedToState(
AuthenticationStatusChanged event,
) async {
switch (event.status) {
case AuthenticationStatus.unauthenticated:
return const AuthenticationState.unauthenticated();
case AuthenticationStatus.authenticated:
final user = await _tryGetUser();
return user != null
? AuthenticationState.authenticated(user)
: const AuthenticationState.unauthenticated();
default:
return const AuthenticationState.unknown();
}
}

Future<User> _tryGetUser() async {
try {
final user = await _userRepository.getUser();
return user;
} on Exception {
return null;
}
}
}

+ 19
- 0
lib/authentication/bloc/authentication_event.dart View File

part of 'authentication_bloc.dart';

abstract class AuthenticationEvent extends Equatable {
const AuthenticationEvent();

@override
List<Object> get props => [];
}

class AuthenticationStatusChanged extends AuthenticationEvent {
const AuthenticationStatusChanged(this.status);

final AuthenticationStatus status;

@override
List<Object> get props => [status];
}

class AuthenticationLogoutRequested extends AuthenticationEvent {}

+ 22
- 0
lib/authentication/bloc/authentication_state.dart View File

part of 'authentication_bloc.dart';

class AuthenticationState extends Equatable {
const AuthenticationState._({
this.status = AuthenticationStatus.unknown,
this.user,
});

const AuthenticationState.unknown() : this._();

const AuthenticationState.authenticated(User user)
: this._(status: AuthenticationStatus.authenticated, user: user);

const AuthenticationState.unauthenticated()
: this._(status: AuthenticationStatus.unauthenticated);

final AuthenticationStatus status;
final User user;

@override
List<Object> get props => [status, user];
}

+ 44
- 0
lib/data/api/dio_provider.dart View File

import 'dart:developer';

import 'package:dio/dio.dart';
import 'package:farm_tpf/utils/pref.dart';

class DioProvider {
static Dio instance() {
final dio = Dio();

// dio.interceptors.add(AuthInterceptor());
dio.interceptors.add(HttpLogInterceptor());

return dio;
}
}

class HttpLogInterceptor extends InterceptorsWrapper {
var pref = LocalPref();
@override
Future onRequest(RequestOptions options) async {
var token = await pref.getString(PrefKey.token_key);
options.headers["Authorization"] = "Bearer $token";
options.receiveTimeout = 20000;
// log("onRequest: ${options.uri}\n"
// "data=${options.data}\n"
// "method=${options.method}\n"
// "headers=${options.headers}\n"
// "queryParameters=${options.queryParameters}");
return options;
}

@override
Future onResponse(Response response) {
// log("onResponse: $response");
return super.onResponse(response);
}

@override
Future onError(DioError err) {
// log("onError: $err\n"
// "Response: ${err.response}");
return super.onError(err);
}
}

+ 14
- 0
lib/data/api/rest_client.dart View File

import 'package:dio/dio.dart';
import 'package:farm_tpf/models/user.dart';
import 'package:farm_tpf/models/user_request.dart';
import 'package:retrofit/retrofit.dart';

part 'rest_client.g.dart';

@RestApi(baseUrl: "https://aquaman.aztrace.vn")
abstract class RestClient {
factory RestClient(Dio dio, {String baseUrl}) = _RestClient;

@POST("/api/authenticate")
Future<User> login(@Body() UserRequest userRequest);
}

+ 38
- 0
lib/data/api/rest_client.g.dart View File

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'rest_client.dart';

// **************************************************************************
// RetrofitGenerator
// **************************************************************************

class _RestClient implements RestClient {
_RestClient(this._dio, {this.baseUrl}) {
ArgumentError.checkNotNull(_dio, '_dio');
this.baseUrl ??= 'https://aquaman.aztrace.vn';
}

final Dio _dio;

String baseUrl;

@override
login(userRequest) async {
ArgumentError.checkNotNull(userRequest, 'userRequest');
const _extra = <String, dynamic>{};
final queryParameters = <String, dynamic>{};
final _data = <String, dynamic>{};
_data.addAll(userRequest?.toJson() ?? <String, dynamic>{});
final Response<Map<String, dynamic>> _result = await _dio.request(
'/api/authenticate',
queryParameters: queryParameters,
options: RequestOptions(
method: 'POST',
headers: <String, dynamic>{},
extra: _extra,
baseUrl: baseUrl),
data: _data);
final value = User.fromJson(_result.data);
return value;
}
}

+ 13
- 0
lib/data/repository/repository.dart View File

import 'package:farm_tpf/data/api/dio_provider.dart';
import 'package:farm_tpf/data/api/rest_client.dart';
import 'package:farm_tpf/models/user.dart';
import 'package:farm_tpf/models/user_request.dart';

class Repository {
final dio = DioProvider.instance();

Future<User> signInWithCredentials(String username, String password) {
final client = RestClient(dio);
return client.login(UserRequest(username: username, password: password));
}
}

+ 6
- 7
lib/main.dart View File

import 'package:farm_tpf/app/themes.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'app/my_app.dart';
import 'package:authentication_repository/authentication_repository.dart';
import 'package:user_repository/user_repository.dart';
import 'app.dart';


void main() { void main() {
runApp(ChangeNotifierProvider(
create: (_) => AppTheme(),
child: MyApp(),
runApp(App(
authenticationRepository: AuthenticationRepository(),
userRepository: UserRepository(),
)); ));
} }

+ 13
- 0
lib/models/user.dart View File

import 'package:json_annotation/json_annotation.dart';

part 'user.g.dart';

@JsonSerializable()
class User {
User();

String idToken;

factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json);
Map<String, dynamic> toJson() => _$UserToJson(this);
}

+ 15
- 0
lib/models/user.g.dart View File

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

User _$UserFromJson(Map<String, dynamic> json) {
return User()..idToken = json['id_token'] as String;
}

Map<String, dynamic> _$UserToJson(User instance) => <String, dynamic>{
'id_token': instance.idToken,
};

+ 13
- 0
lib/models/user_request.dart View File

import 'package:json_annotation/json_annotation.dart';
part 'user_request.g.dart';

@JsonSerializable()
class UserRequest {
final String username;
final String password;
UserRequest({this.username, this.password});

factory UserRequest.fromJson(Map<String, dynamic> json) =>
_$UserRequestFromJson(json);
Map<String, dynamic> toJson() => _$UserRequestToJson(this);
}

+ 20
- 0
lib/models/user_request.g.dart View File

// GENERATED CODE - DO NOT MODIFY BY HAND

part of 'user_request.dart';

// **************************************************************************
// JsonSerializableGenerator
// **************************************************************************

UserRequest _$UserRequestFromJson(Map<String, dynamic> json) {
return UserRequest(
username: json['username'] as String,
password: json['password'] as String,
);
}

Map<String, dynamic> _$UserRequestToJson(UserRequest instance) =>
<String, dynamic>{
'username': instance.username,
'password': instance.password,
};

+ 50
- 0
lib/presentation/custom_widgets/widget_loading.dart View File

import 'package:flutter/material.dart';

class LoadingDialog {
static void showLoadingDialog(BuildContext context) {
showDialog(
context: context,
barrierDismissible: false,
builder: (context) {
return WillPopScope(
onWillPop: () async => false,
child: Opacity(
opacity: 1,
child: Stack(
children: <Widget>[
Align(
alignment: Alignment.center,
child: Container(
decoration: new BoxDecoration(
color: Colors.white,
borderRadius:
new BorderRadius.all(Radius.circular(16.0))),
width: 80.0,
height: 80.0),
),
Container(
alignment: Alignment.center,
child: FlutterLogo(
size: 25,
),
),
Container(
alignment: Alignment.center,
child: SizedBox(
child: CircularProgressIndicator(
strokeWidth: 2.0,
),
width: 60.0,
height: 60.0,
),
)
],
)),
);
});
}

static void hideLoadingDialog(BuildContext context) {
Navigator.pop(context, "");
}
}

+ 1
- 0
lib/presentation/screens/home/home.dart View File

export 'view/home_page.dart';

+ 34
- 0
lib/presentation/screens/home/view/home_page.dart View File

import 'package:farm_tpf/authentication/bloc/authentication_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class HomePage extends StatelessWidget {
static Route route() {
return MaterialPageRoute<void>(builder: (_) => HomePage());
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'UserID: ${context.bloc<AuthenticationBloc>().state.user.id}',
),
RaisedButton(
child: const Text('Đăng xuất'),
onPressed: () {
context
.bloc<AuthenticationBloc>()
.add(AuthenticationLogoutRequested());
},
),
],
),
),
);
}
}

+ 75
- 0
lib/presentation/screens/login/bloc/login_bloc.dart View File

import 'dart:async';

import 'package:authentication_repository/authentication_repository.dart';
import 'package:bloc/bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:farm_tpf/presentation/screens/login/models/password.dart';
import 'package:farm_tpf/presentation/screens/login/models/username.dart';
import 'package:formz/formz.dart';
import 'package:meta/meta.dart';

part 'login_event.dart';
part 'login_state.dart';

class LoginBloc extends Bloc<LoginEvent, LoginState> {
LoginBloc({
@required AuthenticationRepository authenticationRepository,
}) : assert(authenticationRepository != null),
_authenticationRepository = authenticationRepository,
super(const LoginState());

final AuthenticationRepository _authenticationRepository;

@override
Stream<LoginState> mapEventToState(
LoginEvent event,
) async* {
if (event is LoginUsernameChanged) {
yield _mapUsernameChangedToState(event, state);
} else if (event is LoginPasswordChanged) {
yield _mapPasswordChangedToState(event, state);
} else if (event is LoginSubmitted) {
yield* _mapLoginSubmittedToState(event, state);
}
}

LoginState _mapUsernameChangedToState(
LoginUsernameChanged event,
LoginState state,
) {
final username = Username.dirty(event.username);
return state.copyWith(
username: username,
status: Formz.validate([state.password, username]),
);
}

LoginState _mapPasswordChangedToState(
LoginPasswordChanged event,
LoginState state,
) {
final password = Password.dirty(event.password);
return state.copyWith(
password: password,
status: Formz.validate([password, state.username]),
);
}

Stream<LoginState> _mapLoginSubmittedToState(
LoginSubmitted event,
LoginState state,
) async* {
if (state.status.isValidated) {
yield state.copyWith(status: FormzStatus.submissionInProgress);
try {
await _authenticationRepository.logIn(
username: state.username.value,
password: state.password.value,
);
yield state.copyWith(status: FormzStatus.submissionSuccess);
} on Exception catch (_) {
yield state.copyWith(status: FormzStatus.submissionFailure);
}
}
}
}

+ 30
- 0
lib/presentation/screens/login/bloc/login_event.dart View File

part of 'login_bloc.dart';

abstract class LoginEvent extends Equatable {
const LoginEvent();

@override
List<Object> get props => [];
}

class LoginUsernameChanged extends LoginEvent {
const LoginUsernameChanged(this.username);

final String username;

@override
List<Object> get props => [username];
}

class LoginPasswordChanged extends LoginEvent {
const LoginPasswordChanged(this.password);

final String password;

@override
List<Object> get props => [password];
}

class LoginSubmitted extends LoginEvent {
const LoginSubmitted();
}

+ 28
- 0
lib/presentation/screens/login/bloc/login_state.dart View File

part of 'login_bloc.dart';

class LoginState extends Equatable {
const LoginState({
this.status = FormzStatus.pure,
this.username = const Username.pure(),
this.password = const Password.pure(),
});

final FormzStatus status;
final Username username;
final Password password;

LoginState copyWith({
FormzStatus status,
Username username,
Password password,
}) {
return LoginState(
status: status ?? this.status,
username: username ?? this.username,
password: password ?? this.password,
);
}

@override
List<Object> get props => [status, username, password];
}

+ 3
- 0
lib/presentation/screens/login/login.dart View File

export 'bloc/login_bloc.dart';
export 'models/models.dart';
export 'view/view.dart';

+ 2
- 0
lib/presentation/screens/login/models/models.dart View File

export 'password.dart';
export 'username.dart';

+ 13
- 0
lib/presentation/screens/login/models/password.dart View File

import 'package:formz/formz.dart';

enum PasswordValidationError { empty }

class Password extends FormzInput<String, PasswordValidationError> {
const Password.pure() : super.pure('');
const Password.dirty([String value = '']) : super.dirty(value);

@override
PasswordValidationError validator(String value) {
return value?.isNotEmpty == true ? null : PasswordValidationError.empty;
}
}

+ 13
- 0
lib/presentation/screens/login/models/username.dart View File

import 'package:formz/formz.dart';

enum UsernameValidationError { empty }

class Username extends FormzInput<String, UsernameValidationError> {
const Username.pure() : super.pure('');
const Username.dirty([String value = '']) : super.dirty(value);

@override
UsernameValidationError validator(String value) {
return value?.isNotEmpty == true ? null : UsernameValidationError.empty;
}
}

+ 98
- 0
lib/presentation/screens/login/view/login_form.dart View File

import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart';
import 'package:flutter/material.dart';
import 'package:formz/formz.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

class LoginForm extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocListener<LoginBloc, LoginState>(
listener: (context, state) {
if (state.status.isSubmissionFailure) {
Scaffold.of(context)
..hideCurrentSnackBar()
..showSnackBar(
const SnackBar(content: Text('Authentication Failure')),
);
}
},
child: Align(
alignment: const Alignment(0, -1 / 3),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
_UsernameInput(),
const Padding(padding: EdgeInsets.all(12)),
_PasswordInput(),
const Padding(padding: EdgeInsets.all(12)),
_LoginButton(),
],
),
),
);
}
}

class _UsernameInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginBloc, LoginState>(
buildWhen: (previous, current) => previous.username != current.username,
builder: (context, state) {
return TextField(
key: const Key('loginForm_usernameInput_textField'),
onChanged: (username) =>
context.bloc<LoginBloc>().add(LoginUsernameChanged(username)),
decoration: InputDecoration(
labelText: 'Tên đăng nhập',
errorText:
state.username.invalid ? 'Vui lòng nhập tên đăng nhập' : null,
),
);
},
);
}
}

class _PasswordInput extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginBloc, LoginState>(
buildWhen: (previous, current) => previous.password != current.password,
builder: (context, state) {
return TextField(
key: const Key('loginForm_passwordInput_textField'),
onChanged: (password) =>
context.bloc<LoginBloc>().add(LoginPasswordChanged(password)),
obscureText: true,
decoration: InputDecoration(
labelText: 'Mật khẩu',
errorText: state.password.invalid ? 'Vui lòng nhập mật khẩu' : null,
),
);
},
);
}
}

class _LoginButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocBuilder<LoginBloc, LoginState>(
buildWhen: (previous, current) => previous.status != current.status,
builder: (context, state) {
return state.status.isSubmissionInProgress
? const CircularProgressIndicator()
: RaisedButton(
key: const Key('loginForm_continue_raisedButton'),
child: const Text('Đăng nhập'),
onPressed: state.status.isValidated
? () {
context.bloc<LoginBloc>().add(const LoginSubmitted());
}
: null,
);
},
);
}
}

+ 30
- 0
lib/presentation/screens/login/view/login_page.dart View File

import 'package:authentication_repository/authentication_repository.dart';
import 'package:farm_tpf/presentation/screens/login/bloc/login_bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter/material.dart';

import 'login_form.dart';

class LoginPage extends StatelessWidget {
static Route route() {
return MaterialPageRoute<void>(builder: (_) => LoginPage());
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(12),
child: BlocProvider(
create: (context) {
return LoginBloc(
authenticationRepository:
RepositoryProvider.of<AuthenticationRepository>(context),
);
},
child: LoginForm(),
),
),
);
}
}

+ 2
- 0
lib/presentation/screens/login/view/view.dart View File

export 'login_form.dart';
export 'login_page.dart';

+ 1
- 0
lib/presentation/screens/splash/splash.dart View File

export 'view/splash_page.dart';

+ 14
- 0
lib/presentation/screens/splash/view/splash_page.dart View File

import 'package:flutter/material.dart';

class SplashPage extends StatelessWidget {
static Route route() {
return MaterialPageRoute<void>(builder: (_) => SplashPage());
}

@override
Widget build(BuildContext context) {
return const Scaffold(
body: Center(child: CircularProgressIndicator()),
);
}
}

+ 3
- 0
lib/utils/const_common.dart View File

class ConstCommon {
static int kExpiredTime = 12 * 60 * 60 * 1000; //24h
}

+ 1
- 0
lib/utils/pref.dart View File

class PrefKey { class PrefKey {
static const String token_key = "token_key"; static const String token_key = "token_key";
static const String expired_time = "expired_time"; static const String expired_time = "expired_time";
static int kExpiredTime = 12 * 60 * 60 * 1000; //24h
} }

+ 3
- 0
packages/authentication_repository/lib/authentication_repository.dart View File

library authentication_repository;

export 'src/authentication_repository.dart';

+ 34
- 0
packages/authentication_repository/lib/src/authentication_repository.dart View File

import 'dart:async';

import 'package:meta/meta.dart';

enum AuthenticationStatus { unknown, authenticated, unauthenticated }

class AuthenticationRepository {
final _controller = StreamController<AuthenticationStatus>();

Stream<AuthenticationStatus> get status async* {
await Future<void>.delayed(const Duration(seconds: 1));
yield AuthenticationStatus.unauthenticated;
yield* _controller.stream;
}

Future<void> logIn({
@required String username,
@required String password,
}) async {
assert(username != null);
assert(password != null);

await Future.delayed(
const Duration(milliseconds: 300),
() => _controller.add(AuthenticationStatus.authenticated),
);
}

void logOut() {
_controller.add(AuthenticationStatus.unauthenticated);
}

void dispose() => _controller.close();
}

+ 12
- 0
packages/authentication_repository/pubspec.lock View File

# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
meta:
dependency: "direct main"
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
sdks:
dart: ">=2.1.0 <3.0.0"

+ 9
- 0
packages/authentication_repository/pubspec.yaml View File

name: authentication_repository
description: Dart package which manages the authentication domain.
version: 1.0.0

environment:
sdk: ">=2.1.0 <3.0.0"

dependencies:
meta: ^1.1.8

+ 1
- 0
packages/user_repository/lib/src/models/models.dart View File

export 'user.dart';

+ 10
- 0
packages/user_repository/lib/src/models/user.dart View File

import 'package:equatable/equatable.dart';

class User extends Equatable {
const User(this.id);

final String id;

@override
List<Object> get props => [id];
}

+ 14
- 0
packages/user_repository/lib/src/user_repository.dart View File

import 'dart:async';
import 'models/models.dart';

class UserRepository {
User _user;

Future<User> getUser() async {
if (_user != null) return _user;
return Future.delayed(
const Duration(milliseconds: 300),
() => _user = User("usertest"),
);
}
}

+ 4
- 0
packages/user_repository/lib/user_repository.dart View File

library user_repository;

export 'src/models/models.dart';
export 'src/user_repository.dart';

+ 61
- 0
packages/user_repository/pubspec.lock View File

# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.13"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
equatable:
dependency: "direct main"
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.3"
meta:
dependency: "direct main"
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.2"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
uuid:
dependency: "direct main"
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
sdks:
dart: ">=2.4.0 <3.0.0"

+ 11
- 0
packages/user_repository/pubspec.yaml View File

name: user_repository
description: Dart package which manages the user domain.
version: 1.0.0

environment:
sdk: ">=2.1.0 <3.0.0"

dependencies:
equatable: ^1.2.0
meta: ^1.1.8
uuid: ^2.1.0

+ 372
- 1
pubspec.lock View File

# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
_fe_analyzer_shared:
dependency: transitive
description:
name: _fe_analyzer_shared
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
url: "https://pub.dartlang.org"
source: hosted
version: "0.39.16"
archive: archive:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.4.1" version: "2.4.1"
authentication_repository:
dependency: "direct main"
description:
path: "packages/authentication_repository"
relative: true
source: path
version: "1.0.0"
bloc:
dependency: transitive
description:
name: bloc
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
build:
dependency: transitive
description:
name: build
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
build_config:
dependency: transitive
description:
name: build_config
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.2"
build_daemon:
dependency: transitive
description:
name: build_daemon
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
build_resolvers:
dependency: transitive
description:
name: build_resolvers
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.10"
build_runner:
dependency: "direct dev"
description:
name: build_runner
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
build_runner_core:
dependency: transitive
description:
name: build_runner_core
url: "https://pub.dartlang.org"
source: hosted
version: "5.2.0"
built_collection:
dependency: transitive
description:
name: built_collection
url: "https://pub.dartlang.org"
source: hosted
version: "4.3.2"
built_value:
dependency: transitive
description:
name: built_value
url: "https://pub.dartlang.org"
source: hosted
version: "7.1.0"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.3" version: "1.1.3"
checked_yaml:
dependency: transitive
description:
name: checked_yaml
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
code_builder:
dependency: transitive
description:
name: code_builder
url: "https://pub.dartlang.org"
source: hosted
version: "3.4.0"
collection: collection:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.4" version: "2.1.4"
csslib:
dependency: transitive
description:
name: csslib
url: "https://pub.dartlang.org"
source: hosted
version: "0.16.2"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.3" version: "0.1.3"
dart_style:
dependency: transitive
description:
name: dart_style
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.6"
dio:
dependency: "direct main"
description:
name: dio
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.9"
equatable:
dependency: "direct main"
description:
name: equatable
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.3"
file: file:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.2.1" version: "5.2.1"
fixnum:
dependency: transitive
description:
name: fixnum
url: "https://pub.dartlang.org"
source: hosted
version: "0.10.11"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
flutter_bloc:
dependency: "direct main"
description:
name: flutter_bloc
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
formz:
dependency: "direct main"
description:
name: formz
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.0"
glob:
dependency: transitive
description:
name: glob
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
graphs:
dependency: transitive
description:
name: graphs
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
html:
dependency: transitive
description:
name: html
url: "https://pub.dartlang.org"
source: hosted
version: "0.14.0+3"
http_multi_server:
dependency: transitive
description:
name: http_multi_server
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.4"
image: image:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.16.1" version: "0.16.1"
io:
dependency: transitive
description:
name: io
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.4"
js:
dependency: transitive
description:
name: js
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.2"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
json_serializable:
dependency: "direct dev"
description:
name: json_serializable
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.0"
logging:
dependency: transitive
description:
name: logging
url: "https://pub.dartlang.org"
source: hosted
version: "0.11.4"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.8" version: "1.1.8"
mime:
dependency: transitive
description:
name: mime
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.6+3"
nested: nested:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.0.4" version: "0.0.4"
node_interop:
dependency: transitive
description:
name: node_interop
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
node_io:
dependency: transitive
description:
name: node_io
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.1"
package_config:
dependency: transitive
description:
name: package_config
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.3"
path: path:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.9.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.2" version: "1.0.2"
pool:
dependency: transitive
description:
name: pool
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.0"
process: process:
dependency: transitive dependency: transitive
description: description:
source: hosted source: hosted
version: "3.0.13" version: "3.0.13"
provider: provider:
dependency: "direct main"
dependency: transitive
description: description:
name: provider name: provider
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "4.3.1" version: "4.3.1"
pub_semver:
dependency: transitive
description:
name: pub_semver
url: "https://pub.dartlang.org"
source: hosted
version: "1.4.4"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.5"
quiver: quiver:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.3" version: "2.1.3"
retrofit:
dependency: transitive
description:
name: retrofit
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.4"
retrofit_generator:
dependency: "direct dev"
description:
name: retrofit_generator
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.7+5"
shared_preferences: shared_preferences:
dependency: "direct main" dependency: "direct main"
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.2+7" version: "0.1.2+7"
shelf:
dependency: transitive
description:
name: shelf
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.7"
shelf_web_socket:
dependency: transitive
description:
name: shelf_web_socket
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.3"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.99" version: "0.0.99"
source_gen:
dependency: transitive
description:
name: source_gen
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.6"
source_span: source_span:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
stream_transform:
dependency: transitive
description:
name: stream_transform
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.15" version: "0.2.15"
timing:
dependency: transitive
description:
name: timing
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.1+2"
tuple:
dependency: transitive
description:
name: tuple
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.3"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.6" version: "1.1.6"
user_repository:
dependency: "direct main"
description:
path: "packages/user_repository"
relative: true
source: path
version: "1.0.0"
uuid:
dependency: transitive
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.0.8" version: "2.0.8"
watcher:
dependency: transitive
description:
name: watcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.9.7+15"
web_socket_channel:
dependency: transitive
description:
name: web_socket_channel
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.6.1" version: "3.6.1"
yaml:
dependency: transitive
description:
name: yaml
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1"
sdks: sdks:
dart: ">=2.7.0 <3.0.0" dart: ">=2.7.0 <3.0.0"
flutter: ">=1.16.0 <2.0.0" flutter: ">=1.16.0 <2.0.0"

+ 17
- 60
pubspec.yaml View File

name: farm_tpf name: farm_tpf
description: A new Flutter project. description: A new Flutter project.


# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
publish_to: 'none'
version: 1.0.0+1 version: 1.0.0+1


environment: environment:
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter


# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.3 cupertino_icons: ^0.1.3
provider: ^4.3.1
shared_preferences: ^0.5.8 shared_preferences: ^0.5.8
flutter_bloc: ^6.0.1
equatable: ^1.2.0
dio: 3.0.9
formz: ^0.3.0

authentication_repository:
path: packages/authentication_repository
user_repository:
path: packages/user_repository


dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter

# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec

# The following section is specific to Flutter.
retrofit_generator: ^1.3.7
# json_model: ^0.0.2
build_runner: any
json_serializable: any
flutter: flutter:

# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true

# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg

# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.

# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages

# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
uses-material-design: true

+ 0
- 30
test/widget_test.dart View File

// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.


import 'package:farm_tpf/app/my_app.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';

import 'package:farm_tpf/main.dart';

void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.
await tester.pumpWidget(MyApp());

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();

// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
});
}

Loading…
Cancel
Save