| 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 |
| 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 */ |
| <FileRef | <FileRef | ||||
| location = "group:Runner.xcodeproj"> | location = "group:Runner.xcodeproj"> | ||||
| </FileRef> | </FileRef> | ||||
| <FileRef | |||||
| location = "group:Pods/Pods.xcodeproj"> | |||||
| </FileRef> | |||||
| </Workspace> | </Workspace> |
| 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(), | |||||
| ); | |||||
| } | |||||
| } |
| 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))); | |||||
| } | |||||
| } |
| 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(); | |||||
| } | |||||
| } |
| export 'bloc/authentication_bloc.dart'; |
| 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; | |||||
| } | |||||
| } | |||||
| } |
| 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 {} |
| 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]; | |||||
| } |
| 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); | |||||
| } | |||||
| } |
| 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); | |||||
| } |
| // 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; | |||||
| } | |||||
| } |
| 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)); | |||||
| } | |||||
| } |
| 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(), | |||||
| )); | )); | ||||
| } | } |
| 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); | |||||
| } |
| // 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, | |||||
| }; |
| 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); | |||||
| } |
| // 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, | |||||
| }; |
| 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, ""); | |||||
| } | |||||
| } |
| export 'view/home_page.dart'; |
| 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()); | |||||
| }, | |||||
| ), | |||||
| ], | |||||
| ), | |||||
| ), | |||||
| ); | |||||
| } | |||||
| } |
| 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); | |||||
| } | |||||
| } | |||||
| } | |||||
| } |
| 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(); | |||||
| } |
| 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]; | |||||
| } |
| export 'bloc/login_bloc.dart'; | |||||
| export 'models/models.dart'; | |||||
| export 'view/view.dart'; |
| export 'password.dart'; | |||||
| export 'username.dart'; |
| 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; | |||||
| } | |||||
| } |
| 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; | |||||
| } | |||||
| } |
| 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, | |||||
| ); | |||||
| }, | |||||
| ); | |||||
| } | |||||
| } |
| 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(), | |||||
| ), | |||||
| ), | |||||
| ); | |||||
| } | |||||
| } |
| export 'login_form.dart'; | |||||
| export 'login_page.dart'; |
| export 'view/splash_page.dart'; |
| 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()), | |||||
| ); | |||||
| } | |||||
| } |
| class ConstCommon { | |||||
| static int kExpiredTime = 12 * 60 * 60 * 1000; //24h | |||||
| } |
| 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 | |||||
| } | } |
| library authentication_repository; | |||||
| export 'src/authentication_repository.dart'; |
| 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(); | |||||
| } |
| # 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" |
| 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 |
| export 'user.dart'; |
| import 'package:equatable/equatable.dart'; | |||||
| class User extends Equatable { | |||||
| const User(this.id); | |||||
| final String id; | |||||
| @override | |||||
| List<Object> get props => [id]; | |||||
| } |
| 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"), | |||||
| ); | |||||
| } | |||||
| } |
| library user_repository; | |||||
| export 'src/models/models.dart'; | |||||
| export 'src/user_repository.dart'; |
| # 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" |
| 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 |
| # 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" |
| 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 |
| // 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); | |||||
| }); | |||||
| } |