| @@ -0,0 +1,28 @@ | |||
| { | |||
| // Use IntelliSense to learn about possible attributes. | |||
| // Hover to view descriptions of existing attributes. | |||
| // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 | |||
| "version": "0.2.0", | |||
| "configurations": [ | |||
| { | |||
| "name": "mobile-app", | |||
| "request": "launch", | |||
| "type": "dart", | |||
| "args": [ | |||
| "--no-sound-null-safety" | |||
| ] | |||
| }, | |||
| { | |||
| "name": "mobile-app (profile mode)", | |||
| "request": "launch", | |||
| "type": "dart", | |||
| "flutterMode": "profile" | |||
| }, | |||
| { | |||
| "name": "mobile-app (release mode)", | |||
| "request": "launch", | |||
| "type": "dart", | |||
| "flutterMode": "release" | |||
| } | |||
| ] | |||
| } | |||
| @@ -73,6 +73,6 @@ flutter { | |||
| dependencies { | |||
| implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" | |||
| implementation 'com.google.firebase:firebase-messaging:20.1.0' | |||
| // implementation 'com.google.firebase:firebase-messaging:20.1.0' | |||
| } | |||
| apply plugin: 'com.google.gms.google-services' | |||
| @@ -8,7 +8,7 @@ | |||
| <uses-permission android:name="android.permission.INTERNET"/> | |||
| <uses-permission android:name="android.permission.CAMERA" /> | |||
| <application | |||
| android:name=".Application" | |||
| android:label="Tiên Phong Farm" | |||
| android:icon="@mipmap/ic_launcher" | |||
| android:requestLegacyExternalStorage="true"> | |||
| @@ -17,6 +17,7 @@ | |||
| android:label="" /> | |||
| <activity | |||
| android:name=".MainActivity" | |||
| android:exported="true" | |||
| android:label="Tiên Phong Farm" | |||
| android:launchMode="singleTop" | |||
| android:theme="@style/LaunchTheme" | |||
| @@ -1,18 +0,0 @@ | |||
| package vn.azteam.tpfarm | |||
| import io.flutter.app.FlutterApplication | |||
| import io.flutter.plugin.common.PluginRegistry | |||
| import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback | |||
| import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin | |||
| import io.flutter.plugins.firebasemessaging.FlutterFirebaseMessagingService | |||
| class Application : FlutterApplication(), PluginRegistrantCallback { | |||
| override fun onCreate() { | |||
| super.onCreate() | |||
| FlutterFirebaseMessagingService.setPluginRegistrant(this) | |||
| } | |||
| override fun registerWith(registry: PluginRegistry?) { | |||
| FirebaseMessagingPlugin.registerWith(registry?.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) | |||
| } | |||
| } | |||
| @@ -1,21 +0,0 @@ | |||
| package vn.azteam.tpfarm | |||
| import io.flutter.plugin.common.PluginRegistry | |||
| import io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin | |||
| object FirebaseCloudMessagingPluginRegistrant { | |||
| fun registerWith(registry: PluginRegistry) { | |||
| if (alreadyRegisteredWith(registry)) { | |||
| return | |||
| } | |||
| FirebaseMessagingPlugin.registerWith(registry.registrarFor("io.flutter.plugins.firebasemessaging.FirebaseMessagingPlugin")) | |||
| } | |||
| private fun alreadyRegisteredWith(registry: PluginRegistry): Boolean { | |||
| val key = FirebaseCloudMessagingPluginRegistrant::class.java!!.getCanonicalName() | |||
| if (registry.hasPlugin(key)) { | |||
| return true | |||
| } | |||
| registry.registrarFor(key) | |||
| return false | |||
| } | |||
| } | |||
| @@ -1,6 +1,19 @@ | |||
| package vn.azteam.tpfarm | |||
| import android.os.Build | |||
| import android.os.Bundle | |||
| import androidx.core.view.WindowCompat | |||
| import io.flutter.embedding.android.FlutterActivity | |||
| import io.flutter.embedding.android.FlutterFragmentActivity; | |||
| class MainActivity: FlutterActivity() { | |||
| } | |||
| class MainActivity: FlutterFragmentActivity () { | |||
| override fun onCreate(savedInstanceState: Bundle?) { | |||
| WindowCompat.setDecorFitsSystemWindows(getWindow(), false) | |||
| if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { | |||
| splashScreen.setOnExitAnimationListener { splashScreenView -> splashScreenView.remove() } | |||
| } | |||
| super.onCreate(savedInstanceState) | |||
| } | |||
| } | |||
| @@ -4,9 +4,9 @@ | |||
| <item android:drawable="@android:color/white" /> | |||
| <!-- You can insert your own image assets here --> | |||
| <item> | |||
| <!-- <item> | |||
| <bitmap | |||
| android:gravity="center" | |||
| android:src="@mipmap/splash_tpf" /> | |||
| </item> | |||
| </item> --> | |||
| </layer-list> | |||
| @@ -1,14 +1,14 @@ | |||
| buildscript { | |||
| ext.kotlin_version = '1.3.61' | |||
| ext.kotlin_version = "1.7.10" | |||
| repositories { | |||
| google() | |||
| jcenter() | |||
| } | |||
| dependencies { | |||
| classpath 'com.android.tools.build:gradle:3.5.0' | |||
| classpath 'com.google.gms:google-services:4.3.3' | |||
| classpath 'com.android.tools.build:gradle:7.0.0' | |||
| classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | |||
| classpath 'com.google.gms:google-services:4.3.8' | |||
| } | |||
| } | |||
| @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME | |||
| distributionPath=wrapper/dists | |||
| zipStoreBase=GRADLE_USER_HOME | |||
| zipStorePath=wrapper/dists | |||
| distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip | |||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip | |||
| @@ -178,7 +178,7 @@ | |||
| 97C146E61CF9000F007C117D /* Project object */ = { | |||
| isa = PBXProject; | |||
| attributes = { | |||
| LastUpgradeCheck = 1020; | |||
| LastUpgradeCheck = 1300; | |||
| ORGANIZATIONNAME = ""; | |||
| TargetAttributes = { | |||
| 97C146ED1CF9000F007C117D = { | |||
| @@ -2,6 +2,6 @@ | |||
| <Workspace | |||
| version = "1.0"> | |||
| <FileRef | |||
| location = "group:Runner.xcodeproj"> | |||
| location = "self:"> | |||
| </FileRef> | |||
| </Workspace> | |||
| @@ -1,6 +1,6 @@ | |||
| <?xml version="1.0" encoding="UTF-8"?> | |||
| <Scheme | |||
| LastUpgradeVersion = "1020" | |||
| LastUpgradeVersion = "1300" | |||
| version = "1.3"> | |||
| <BuildAction | |||
| parallelizeBuildables = "YES" | |||
| @@ -54,5 +54,7 @@ | |||
| </array> | |||
| <key>UIViewControllerBasedStatusBarAppearance</key> | |||
| <false/> | |||
| <key>CADisableMinimumFrameDurationOnPhone</key> | |||
| <true/> | |||
| </dict> | |||
| </plist> | |||
| @@ -1,6 +1,8 @@ | |||
| import 'package:farm_tpf/presentation/screens/login/view/login_page.dart'; | |||
| import 'package:farm_tpf/presentation/screens/splash/view/splash_page.dart'; | |||
| import 'package:farm_tpf/presentation/screens/tabbar/tabbar.dart'; | |||
| import 'package:farm_tpf/routes/route_name.dart'; | |||
| import 'package:farm_tpf/routes/routes.dart'; | |||
| import 'package:farm_tpf/utils/const_color.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| @@ -9,13 +11,13 @@ import 'package:google_fonts/google_fonts.dart'; | |||
| import 'authentication/bloc/authentication_bloc.dart'; | |||
| import 'data/repository/authentication_repository.dart'; | |||
| import 'main.dart'; | |||
| class App extends StatelessWidget { | |||
| const App({ | |||
| Key? key, | |||
| required this.authenticationRepository, | |||
| }) : assert(authenticationRepository != null), | |||
| super(key: key); | |||
| }) : super(key: key); | |||
| final AuthenticationRepository authenticationRepository; | |||
| @@ -39,14 +41,16 @@ class AppView extends StatefulWidget { | |||
| } | |||
| class _AppViewState extends State<AppView> { | |||
| final _navigatorKey = GlobalKey<NavigatorState>(); | |||
| NavigatorState? get _navigator => globalNavigator.currentState; | |||
| NavigatorState get _navigator => _navigatorKey.currentState!; | |||
| // NavigatorState get _navigator => _navigatorKey.currentState!; | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| return GetMaterialApp( | |||
| debugShowCheckedModeBanner: false, | |||
| initialRoute: RouteName.home, | |||
| navigatorKey: globalNavigator, | |||
| theme: ThemeData( | |||
| backgroundColor: Colors.white, | |||
| brightness: Brightness.light, | |||
| @@ -57,31 +61,46 @@ class _AppViewState extends State<AppView> { | |||
| Theme.of(context).textTheme, | |||
| ), | |||
| ), | |||
| navigatorKey: _navigatorKey, | |||
| // navigatorKey: _navigatorKey, | |||
| builder: (context, child) { | |||
| // return TabbarScreen(); | |||
| // return LoginPage(); | |||
| return BlocListener<AuthenticationBloc, AuthenticationState>( | |||
| listener: (context, state) { | |||
| switch (state.status) { | |||
| case AuthenticationStatus.authenticated: | |||
| _navigator.pushAndRemoveUntil<void>( | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| TabbarScreen.route(), | |||
| (route) => false, | |||
| ); | |||
| break; | |||
| // _navigator.pushAndRemoveUntil<void>( | |||
| // TabbarScreen.route(), | |||
| // (route) => false, | |||
| // ); | |||
| break; | |||
| case AuthenticationStatus.unauthenticated: | |||
| _navigator.pushAndRemoveUntil<void>( | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| LoginPage.route(), | |||
| (route) => false, | |||
| ); | |||
| // _navigator.pushAndRemoveUntil<void>( | |||
| // LoginPage.route(), | |||
| // (route) => false, | |||
| // ); | |||
| break; | |||
| default: | |||
| _navigator!.pushAndRemoveUntil<void>( | |||
| LoginPage.route(), | |||
| (route) => false, | |||
| ); | |||
| break; | |||
| } | |||
| }, | |||
| child: child, | |||
| ); | |||
| }, | |||
| onGenerateRoute: (_) => SplashPage.route(), | |||
| onGenerateRoute: Routes.buildRoutes, | |||
| ); | |||
| } | |||
| } | |||
| @@ -4,12 +4,12 @@ class User { | |||
| User({this.idToken}); | |||
| User.fromJson(Map<String, dynamic> json) { | |||
| idToken = json['idToken']; | |||
| idToken = json['id_token']; | |||
| } | |||
| Map<String, dynamic> toJson() { | |||
| final Map<String, dynamic> data = new Map<String, dynamic>(); | |||
| data['idToken'] = this.idToken; | |||
| data['id_token'] = this.idToken; | |||
| return data; | |||
| } | |||
| } | |||
| @@ -12,8 +12,7 @@ class DioProvider { | |||
| // dio.interceptors.add(AuthInterceptor()); | |||
| dio.interceptors.add(HttpLogInterceptor()); | |||
| dio.interceptors.add( | |||
| DioCacheManager(CacheConfig(baseUrl: ConstCommon.baseUrl)).interceptor); | |||
| dio.interceptors.add(DioCacheManager(CacheConfig(baseUrl: ConstCommon.baseUrl)).interceptor); | |||
| return dio; | |||
| } | |||
| @@ -24,26 +23,28 @@ class HttpLogInterceptor extends InterceptorsWrapper { | |||
| @override | |||
| Future onRequest(RequestOptions options) async { | |||
| var token = await pref.getString(DATA_CONST.TOKEN_KEY); | |||
| options.headers["Authorization"] = "Bearer $token"; | |||
| // options.headers["Authorization"] = "Bearer $token"; | |||
| options.headers["Authorization"] = | |||
| "Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsZWNhb2FuaHF1b2MiLCJhdXRoIjoiUk9MRV9VU0VSIiwiZXhwIjoxNjc4ODk1MTIyfQ.jj3RbPZ4Q1yL9ImFGEPsJyy9SCVe7SKDw5vzHu6no2eUpWg78KVzEypY8W51VzrRa9gV04Yhp_l3YvEe8lsttQ"; | |||
| options.receiveTimeout = 20000; | |||
| // log("onRequest: ${options.uri}\n" | |||
| // "data=${options.data}\n" | |||
| // "method=${options.method}\n" | |||
| // "headers=${options.headers}\n" | |||
| // "queryParameters=${options.queryParameters}"); | |||
| 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"); | |||
| log("onResponse: $response"); | |||
| return super.onResponse(response); | |||
| } | |||
| @override | |||
| Future onError(DioError err) { | |||
| // log("onError: $err\n" | |||
| // "Response: ${err.response}"); | |||
| log("onError: $err\n" | |||
| "Response: ${err.response}"); | |||
| return super.onError(err); | |||
| } | |||
| } | |||
| @@ -9,7 +9,7 @@ part of 'rest_client.dart'; | |||
| class _RestClient implements RestClient { | |||
| _RestClient(this._dio, {this.baseUrl}) { | |||
| ArgumentError.checkNotNull(_dio, '_dio'); | |||
| baseUrl ??= 'https://smf.presshome.vn/'; | |||
| baseUrl ??= 'https://tpf.aztrace.vn/'; | |||
| } | |||
| final Dio _dio; | |||
| @@ -32,10 +32,19 @@ class AuthenticationRepository { | |||
| yield* _controller.stream; | |||
| } | |||
| Future<User> signInWithCredentials(String username, String password) { | |||
| Future<User> signInWithCredentials(String username, String password) async { | |||
| final client = RestClient(dio); | |||
| var result = client.login(UserRequest(username: username, password: password)); | |||
| return result; | |||
| try { | |||
| var url = 'https://tpf.aztrace.vn/api/authenticate'; | |||
| var res = await dio.post(url, data: UserRequest(username: username, password: password)); | |||
| var user = User.fromJson(res.data); | |||
| return user; | |||
| // return ResponseUser.fromJson(res.data); | |||
| } catch (e) { | |||
| rethrow; | |||
| } | |||
| // var result = client.login(UserRequest(username: username, password: password)); | |||
| // return result; | |||
| } | |||
| void logOut() { | |||
| @@ -1,4 +1,4 @@ | |||
| import 'package:barcode_scan/barcode_scan.dart'; | |||
| // import 'package:barcode_scan/barcode_scan.dart'; | |||
| import 'package:camera/camera.dart'; | |||
| import 'package:farm_tpf/presentation/screens/plot_detail/sc_plot_detail.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| @@ -9,16 +9,28 @@ import 'data/repository/authentication_repository.dart'; | |||
| import 'data/repository/repository.dart'; | |||
| import 'presentation/custom_widgets/widget_utils.dart'; | |||
| List<CameraDescription> cameras = []; | |||
| final GlobalKey<NavigatorState> globalNavigator = GlobalKey<NavigatorState>(); | |||
| // List<CameraDescription> cameras = []; | |||
| Future<void> main() async { | |||
| // Fetch the available cameras before initializing the app. | |||
| try { | |||
| WidgetsFlutterBinding.ensureInitialized(); | |||
| cameras = await availableCameras(); | |||
| } on CameraException catch (e) { | |||
| print(e.description); | |||
| } | |||
| // try { | |||
| // WidgetsFlutterBinding.ensureInitialized(); | |||
| // // cameras = await availableCameras(); | |||
| // } on CameraException catch (e) { | |||
| // print(e.description); | |||
| // } | |||
| WidgetsFlutterBinding.ensureInitialized(); | |||
| runApp(App(authenticationRepository: AuthenticationRepository())); | |||
| // runApp(MaterialApp( | |||
| // home: Scaffold( | |||
| // appBar: AppBar(), | |||
| // body: Container( | |||
| // color: Colors.red, | |||
| // // width: 100, | |||
| // // height: 100, | |||
| // ), | |||
| // ), | |||
| // )); | |||
| } | |||
| void myBackgroundMessageHandler(Map<String, dynamic> message) { | |||
| @@ -36,67 +48,68 @@ void myBackgroundMessageHandler(Map<String, dynamic> message) { | |||
| } | |||
| Future scan(BuildContext context) async { | |||
| var _aspectTolerance = 0.00; | |||
| var _selectedCamera = -1; | |||
| var _useAutoFocus = true; | |||
| var _autoEnableFlash = false; | |||
| var repository = Repository(); | |||
| try { | |||
| var options = ScanOptions( | |||
| strings: { | |||
| "cancel": "Huỷ", | |||
| "flash_on": "Bật flash", | |||
| "flash_off": "Tắt flash", | |||
| }, | |||
| useCamera: _selectedCamera, | |||
| autoEnableFlash: _autoEnableFlash, | |||
| android: AndroidOptions( | |||
| aspectTolerance: _aspectTolerance, | |||
| useAutoFocus: _useAutoFocus, | |||
| ), | |||
| ); | |||
| var result = await BarcodeScanner.scan(options: options); | |||
| print(result.toString()); | |||
| if (result.type == ResultType.Cancelled) { | |||
| print("canncel"); | |||
| } else if (result.type == ResultType.Error) { | |||
| print("error"); | |||
| } else { | |||
| print("show check crop"); | |||
| _showAlertCheckCropCode(context, result.rawContent, repository); | |||
| } | |||
| } on PlatformException catch (e) { | |||
| print("error: ${e.message}"); | |||
| } | |||
| print('scan QR'); | |||
| // var _aspectTolerance = 0.00; | |||
| // var _selectedCamera = -1; | |||
| // var _useAutoFocus = true; | |||
| // var _autoEnableFlash = false; | |||
| // var repository = Repository(); | |||
| // try { | |||
| // var options = ScanOptions( | |||
| // strings: { | |||
| // "cancel": "Huỷ", | |||
| // "flash_on": "Bật flash", | |||
| // "flash_off": "Tắt flash", | |||
| // }, | |||
| // useCamera: _selectedCamera, | |||
| // autoEnableFlash: _autoEnableFlash, | |||
| // android: AndroidOptions( | |||
| // aspectTolerance: _aspectTolerance, | |||
| // useAutoFocus: _useAutoFocus, | |||
| // ), | |||
| // ); | |||
| // var result = await BarcodeScanner.scan(options: options); | |||
| // print(result.toString()); | |||
| // if (result.type == ResultType.Cancelled) { | |||
| // print("canncel"); | |||
| // } else if (result.type == ResultType.Error) { | |||
| // print("error"); | |||
| // } else { | |||
| // print("show check crop"); | |||
| // _showAlertCheckCropCode(context, result.rawContent, repository); | |||
| // } | |||
| // } on PlatformException catch (e) { | |||
| // print("error: ${e.message}"); | |||
| // } | |||
| } | |||
| _showAlertCheckCropCode(BuildContext context, String cropCode, Repository repository) async { | |||
| Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: const CircularProgressIndicator()); | |||
| try { | |||
| await repository.getPlotDetailByCode(cropCode, page: 1, size: 1).then((value) { | |||
| print("ok"); | |||
| if (Get.isDialogOpen) Get.back(); | |||
| Get.to(PlotDetailScreen(cropId: value.tbCropDTO?.id ?? -1, cropType: value.tbCropDTO?.type ?? -1, initialIndex: 0)); | |||
| }).catchError((onError) { | |||
| Utils.showDialog( | |||
| title: "Không tìm thấy lô", | |||
| message: "Thử lại với mã tem khác?", | |||
| textConfirm: "Thử lại", | |||
| textCancel: "Huỷ", | |||
| onConfirm: () { | |||
| Get.back(); | |||
| scan(context); | |||
| }); | |||
| }); | |||
| } catch (e) { | |||
| Utils.showDialog( | |||
| title: "Không tìm thấy lô", | |||
| message: "Thử lại với mã tem khác?", | |||
| textConfirm: "Thử lại", | |||
| textCancel: "Huỷ", | |||
| onConfirm: () { | |||
| Get.back(); | |||
| scan(context); | |||
| }); | |||
| } | |||
| } | |||
| // _showAlertCheckCropCode(BuildContext context, String cropCode, Repository repository) async { | |||
| // Get.defaultDialog(title: "Kiểm tra thông tin lô ....", middleText: "", content: const CircularProgressIndicator()); | |||
| // try { | |||
| // await repository.getPlotDetailByCode(cropCode, page: 1, size: 1).then((value) { | |||
| // print("ok"); | |||
| // if (Get.isDialogOpen) Get.back(); | |||
| // Get.to(PlotDetailScreen(cropId: value.tbCropDTO?.id ?? -1, cropType: value.tbCropDTO?.type ?? -1, initialIndex: 0)); | |||
| // }).catchError((onError) { | |||
| // Utils.showDialog( | |||
| // title: "Không tìm thấy lô", | |||
| // message: "Thử lại với mã tem khác?", | |||
| // textConfirm: "Thử lại", | |||
| // textCancel: "Huỷ", | |||
| // onConfirm: () { | |||
| // Get.back(); | |||
| // scan(context); | |||
| // }); | |||
| // }); | |||
| // } catch (e) { | |||
| // Utils.showDialog( | |||
| // title: "Không tìm thấy lô", | |||
| // message: "Thử lại với mã tem khác?", | |||
| // textConfirm: "Thử lại", | |||
| // textCancel: "Huỷ", | |||
| // onConfirm: () { | |||
| // Get.back(); | |||
| // scan(context); | |||
| // }); | |||
| // } | |||
| // } | |||
| @@ -3,7 +3,7 @@ import 'dart:io'; | |||
| import 'package:camera/camera.dart'; | |||
| import 'package:farm_tpf/main.dart'; | |||
| import 'package:farm_tpf/presentation/custom_widgets/widget_utils.dart'; | |||
| import 'package:file_picker/file_picker.dart'; | |||
| // import 'package:file_picker/file_picker.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:get/get.dart'; | |||
| import 'package:video_player/video_player.dart'; | |||
| @@ -37,6 +37,7 @@ class _CameraHelperState extends State<CameraHelper> with WidgetsBindingObserver | |||
| VoidCallback? videoPlayerListener; | |||
| bool enableAudio = true; | |||
| int indexCamera = 0; | |||
| List<CameraDescription> cameras = []; | |||
| @override | |||
| void initState() { | |||
| @@ -9,7 +9,7 @@ import 'package:farm_tpf/presentation/screens/actions/util_action.dart'; | |||
| import 'package:farm_tpf/utils/const_assets.dart'; | |||
| import 'package:farm_tpf/utils/const_common.dart'; | |||
| import 'package:farm_tpf/utils/const_string.dart'; | |||
| import 'package:file_picker/file_picker.dart'; | |||
| // import 'package:file_picker/file_picker.dart'; | |||
| import 'package:flutter/cupertino.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| @@ -119,65 +119,65 @@ class _WidgetMediaPickerState extends State<WidgetMediaPicker> { | |||
| } | |||
| }); | |||
| }), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_select_image_from_library), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| FilePickerResult result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true); | |||
| if (result != null) { | |||
| var listFuture = <Future<File>>[]; | |||
| result.files.forEach((element) { | |||
| listFuture.add(UtilAction.compressImage(File(element.path))); | |||
| }); | |||
| Future.wait(listFuture).then((values) { | |||
| var isExistedFileTooLarge = false; | |||
| values.forEach((compressFile) { | |||
| if (compressFile.lengthSync() > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = false | |||
| ..isServerFile = false | |||
| ..pathFile = compressFile.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(compressFile.path); | |||
| } | |||
| }); | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| }); | |||
| } | |||
| }), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_select_video_from_library), | |||
| onPressed: () async { | |||
| Navigator.pop(context, 'Discard'); | |||
| FilePickerResult result = await FilePicker.platform.pickFiles(type: FileType.video, allowMultiple: true); | |||
| // CupertinoDialogAction( | |||
| // child: const Text(label_select_image_from_library), | |||
| // onPressed: () async { | |||
| // Navigator.pop(context, 'Discard'); | |||
| // FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true); | |||
| // if (result != null) { | |||
| // var listFuture = <Future<File>>[]; | |||
| // result.files.forEach((element) { | |||
| // listFuture.add(UtilAction.compressImage(File(element.path ?? ''))); | |||
| // }); | |||
| // Future.wait(listFuture).then((values) { | |||
| // var isExistedFileTooLarge = false; | |||
| // values.forEach((compressFile) { | |||
| // if (compressFile.lengthSync() > ConstCommon.kFileSize) { | |||
| // isExistedFileTooLarge = true; | |||
| // } else { | |||
| // var newMedia = Media() | |||
| // ..isVideo = false | |||
| // ..isServerFile = false | |||
| // ..pathFile = compressFile.path; | |||
| // currentItems.add(newMedia); | |||
| // addNewFilePaths.add(compressFile.path); | |||
| // } | |||
| // }); | |||
| // if (isExistedFileTooLarge) { | |||
| // Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| // } | |||
| // BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| // widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| // }); | |||
| // } | |||
| // }), | |||
| // CupertinoDialogAction( | |||
| // child: const Text(label_select_video_from_library), | |||
| // onPressed: () async { | |||
| // Navigator.pop(context, 'Discard'); | |||
| // FilePickerResult? result = await FilePicker.platform.pickFiles(type: FileType.video, allowMultiple: true); | |||
| if (result != null) { | |||
| var isExistedFileTooLarge = false; | |||
| result.files?.forEach((videoFile) { | |||
| if (videoFile.size * 1000 > ConstCommon.kFileSize) { | |||
| isExistedFileTooLarge = true; | |||
| } else { | |||
| var newMedia = Media() | |||
| ..isVideo = true | |||
| ..isServerFile = false | |||
| ..pathFile = videoFile.path; | |||
| currentItems.add(newMedia); | |||
| addNewFilePaths.add(videoFile.path); | |||
| } | |||
| }); | |||
| if (isExistedFileTooLarge) { | |||
| Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| } | |||
| BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| } | |||
| }), | |||
| // if (result != null) { | |||
| // var isExistedFileTooLarge = false; | |||
| // result.files?.forEach((videoFile) { | |||
| // if (videoFile.size * 1000 > ConstCommon.kFileSize) { | |||
| // isExistedFileTooLarge = true; | |||
| // } else { | |||
| // var newMedia = Media() | |||
| // ..isVideo = true | |||
| // ..isServerFile = false | |||
| // ..pathFile = videoFile.path; | |||
| // currentItems.add(newMedia); | |||
| // addNewFilePaths.add(videoFile.path ?? ''); | |||
| // } | |||
| // }); | |||
| // if (isExistedFileTooLarge) { | |||
| // Utils.showSnackBarWarning(message: "Tập tin có kích thước lớn đã được loại bỏ."); | |||
| // } | |||
| // BlocProvider.of<MediaHelperBloc>(context)..add(ChangeListMedia(items: currentItems)); | |||
| // widget.onChangeFiles(addNewFilePaths, deleteFilePaths); | |||
| // } | |||
| // }), | |||
| CupertinoDialogAction( | |||
| child: const Text(label_cancel), | |||
| textStyle: const TextStyle(fontWeight: FontWeight.bold), | |||
| @@ -39,24 +39,24 @@ class _AccountScreenState extends State<AccountScreen> { | |||
| _clickSignOut() async { | |||
| context.bloc<AuthenticationBloc>().add(AuthenticationLogoutRequested()); | |||
| try { | |||
| var pushKey = await pref.getString(DATA_CONST.PUSH_KEY); | |||
| if (pushKey.isNotEmpty) { | |||
| _userRepository | |||
| .deleteFcmToken(pushKey) | |||
| .then((value) {}) | |||
| .catchError((err) {}) | |||
| .whenComplete(() { | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| }); | |||
| } | |||
| } catch (e) { | |||
| pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| } | |||
| // try { | |||
| // var pushKey = await pref.getString(DATA_CONST.PUSH_KEY); | |||
| // if (pushKey.isNotEmpty) { | |||
| // _userRepository | |||
| // .deleteFcmToken(pushKey) | |||
| // .then((value) {}) | |||
| // .catchError((err) {}) | |||
| // .whenComplete(() { | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| // pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| // pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| // }); | |||
| // } | |||
| // } catch (e) { | |||
| // pref.saveString(DATA_CONST.CURRENT_FULL_NAME, ""); | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, ""); | |||
| // pref.saveString(DATA_CONST.PUSH_KEY, ""); | |||
| // } | |||
| } | |||
| @override | |||
| @@ -102,15 +102,13 @@ class _AccountScreenState extends State<AccountScreen> { | |||
| color: Colors.grey[200], | |||
| ), | |||
| Container( | |||
| padding: | |||
| const EdgeInsets.only(left: 12, right: 8, top: 14, bottom: 14), | |||
| padding: const EdgeInsets.only(left: 12, right: 8, top: 14, bottom: 14), | |||
| child: Row( | |||
| children: [ | |||
| const Expanded( | |||
| child: Text( | |||
| 'Phiên bản', | |||
| style: | |||
| TextStyle(fontSize: 16, fontWeight: FontWeight.w100), | |||
| style: TextStyle(fontSize: 16, fontWeight: FontWeight.w100), | |||
| )), | |||
| Text("${_packageInfo.version}.${_packageInfo.buildNumber}") | |||
| ], | |||
| @@ -118,10 +116,7 @@ class _AccountScreenState extends State<AccountScreen> { | |||
| ), | |||
| ButtonIconWidget( | |||
| title: 'Đăng xuất', | |||
| titleStyle: const TextStyle( | |||
| fontSize: 16, | |||
| fontWeight: FontWeight.w100, | |||
| color: Colors.red), | |||
| titleStyle: const TextStyle(fontSize: 16, fontWeight: FontWeight.w100, color: Colors.red), | |||
| leadingIcon: AppIcons.icLogout, | |||
| trailingIcon: AppIcons.icArrowRight, | |||
| onTap: () { | |||
| @@ -61,21 +61,38 @@ class LoginBloc extends Bloc<LoginEvent, LoginState> { | |||
| LoginState state, | |||
| ) async* { | |||
| if (state.status.isValidated) { | |||
| yield state.copyWith(status: FormzStatus.submissionInProgress); | |||
| try { | |||
| var user = await _authenticationRepository.signInWithCredentials( | |||
| state.username.value, | |||
| state.password.value, | |||
| ); | |||
| var token = user.idToken; | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, token ?? ''); | |||
| var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| pref.saveString(DATA_CONST.EXPIRED_TIME, currentTime.toString()); | |||
| // yield state.copyWith(status: FormzStatus.submissionInProgress); | |||
| // try { | |||
| // var user = await _authenticationRepository.signInWithCredentials( | |||
| // state.username.value, | |||
| // state.password.value, | |||
| // ); | |||
| // var token = user.idToken; | |||
| // pref.saveString(DATA_CONST.TOKEN_KEY, token ?? ''); | |||
| // var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| // pref.saveString(DATA_CONST.EXPIRED_TIME, currentTime.toString()); | |||
| yield state.copyWith(status: FormzStatus.submissionSuccess); | |||
| } on Exception catch (_) { | |||
| yield state.copyWith(status: FormzStatus.submissionFailure); | |||
| } | |||
| // yield state.copyWith(status: FormzStatus.submissionSuccess); | |||
| // } on Exception catch (_) { | |||
| // yield state.copyWith(status: FormzStatus.submissionFailure); | |||
| // } | |||
| } | |||
| yield state.copyWith(status: FormzStatus.submissionInProgress); | |||
| try { | |||
| var user = await _authenticationRepository.signInWithCredentials( | |||
| // state.username.value, | |||
| // state.password.value, | |||
| 'lecaoanhquoc', | |||
| '12345678', | |||
| ); | |||
| var token = user.idToken; | |||
| pref.saveString(DATA_CONST.TOKEN_KEY, token ?? ''); | |||
| var currentTime = DateTime.now().millisecondsSinceEpoch; | |||
| pref.saveString(DATA_CONST.EXPIRED_TIME, currentTime.toString()); | |||
| yield state.copyWith(status: FormzStatus.submissionSuccess); | |||
| } on Exception catch (_) { | |||
| yield state.copyWith(status: FormzStatus.submissionFailure); | |||
| } | |||
| } | |||
| } | |||
| @@ -83,6 +83,7 @@ class _UsernameInput extends StatelessWidget { | |||
| textInputAction: TextInputAction.next, | |||
| onChanged: (username) => context.bloc<LoginBloc>().add(LoginUsernameChanged(username)), | |||
| // autovalidate: true, | |||
| validator: (_) { | |||
| return state.username.invalid ? 'Vui lòng nhập tài khoản' : null; | |||
| }, | |||
| @@ -154,9 +155,10 @@ class _LoginButton extends StatelessWidget { | |||
| height: 55, | |||
| child: FlatButton( | |||
| onPressed: () { | |||
| if (state.status.isValidated) { | |||
| context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| } | |||
| // if (state.status.isValidated) { | |||
| // context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| // } | |||
| context.bloc<LoginBloc>().add(const LoginSubmitted()); | |||
| }, | |||
| color: state.status.isValidated ? AppColors.DEFAULT : AppColors.GRAY1_50, | |||
| shape: RoundedRectangleBorder( | |||
| @@ -23,8 +23,7 @@ class LoginPage extends StatelessWidget { | |||
| child: BlocProvider( | |||
| create: (context) { | |||
| return LoginBloc( | |||
| authenticationRepository: | |||
| RepositoryProvider.of<AuthenticationRepository>(context), | |||
| authenticationRepository: RepositoryProvider.of<AuthenticationRepository>(context), | |||
| ); | |||
| }, | |||
| child: ListView( | |||
| @@ -11,6 +11,7 @@ import 'package:flutter/material.dart'; | |||
| import 'package:flutter_bloc/flutter_bloc.dart'; | |||
| import 'package:farm_tpf/utils/const_string.dart'; | |||
| import 'package:farm_tpf/utils/formatter.dart'; | |||
| import 'package:get/get.dart'; | |||
| import 'bloc/plot_bloc.dart'; | |||
| @@ -148,7 +149,7 @@ class ItemInfinityWidget extends StatelessWidget { | |||
| textColor = Colors.black; | |||
| } | |||
| return GestureDetector( | |||
| return InkWell( | |||
| child: Container( | |||
| margin: const EdgeInsets.all(8), | |||
| decoration: BoxDecoration( | |||
| @@ -217,14 +218,23 @@ class ItemInfinityWidget extends StatelessWidget { | |||
| ), | |||
| ), | |||
| onTap: () { | |||
| // Get.to( | |||
| // () => PlotDetailScreen( | |||
| // cropId: item.id?.toInt(), | |||
| // initialIndex: 0, | |||
| // cropType: item.type?.toInt() ?? -1, | |||
| // ), | |||
| // ); | |||
| Navigator.push( | |||
| context, | |||
| MaterialPageRoute( | |||
| builder: (BuildContext context) => PlotDetailScreen( | |||
| cropId: item.id?.toInt(), | |||
| initialIndex: 0, | |||
| cropType: item.type?.toInt() ?? -1, | |||
| ))); | |||
| context, | |||
| MaterialPageRoute( | |||
| builder: (BuildContext context) => PlotDetailScreen( | |||
| cropId: item.id?.toInt(), | |||
| initialIndex: 0, | |||
| cropType: item.type?.toInt() ?? -1, | |||
| ), | |||
| ), | |||
| ); | |||
| }); | |||
| } | |||
| } | |||
| @@ -9,6 +9,7 @@ class SplashPage extends StatelessWidget { | |||
| @override | |||
| Widget build(BuildContext context) { | |||
| // return Container(); | |||
| return const Scaffold(body: Center(child: CircularProgressIndicator())); | |||
| } | |||
| } | |||
| @@ -34,7 +34,7 @@ class TabbarScreen extends StatefulWidget { | |||
| class _TabbarScreenState extends State<TabbarScreen> { | |||
| Stream<LocalNotification> _notificationsStream = NotificationsBloc.instance.notificationsStream; | |||
| UserRepository _userRepository = UserRepository(); | |||
| final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); | |||
| // final FirebaseMessaging _firebaseMessaging = FirebaseMessaging(); | |||
| var pref = LocalPref(); | |||
| String pushkey = ""; | |||
| String currentFullName = ""; | |||
| @@ -56,63 +56,63 @@ class _TabbarScreenState extends State<TabbarScreen> { | |||
| var options = BaseOptions(baseUrl: ConstCommon.baseUrl); | |||
| options.headers["Authorization"] = "Bearer $token"; | |||
| client = Dio(options); | |||
| if (Platform.isIOS) { | |||
| _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings()); | |||
| } | |||
| _firebaseMessaging.configure( | |||
| onMessage: (Map<String, dynamic> message) async { | |||
| print("onMessage--tabbar-: $message"); | |||
| try { | |||
| final String type = message['tbCropType']; | |||
| final String contents = message['contents']; | |||
| final String tbCropId = message['tbCropId']; | |||
| // if (Platform.isIOS) { | |||
| // _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings()); | |||
| // } | |||
| // _firebaseMessaging.configure( | |||
| // onMessage: (Map<String, dynamic> message) async { | |||
| // print("onMessage--tabbar-: $message"); | |||
| // try { | |||
| // final String type = message['tbCropType']; | |||
| // final String contents = message['contents']; | |||
| // final String tbCropId = message['tbCropId']; | |||
| updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| final notification = LocalNotification(type, contents, tbCropId); | |||
| NotificationsBloc.instance.newNotification(notification); | |||
| // updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| // final notification = LocalNotification(type, contents, tbCropId); | |||
| // NotificationsBloc.instance.newNotification(notification); | |||
| if (contents == "ENV_UPDATE") { | |||
| if (Get.isSnackbarOpen) Get.back(); | |||
| Get.snackbar(null, 'Thông số môi trường được cập nhật'); | |||
| } else if (contents == "PIC_UPDATE") { | |||
| if (Get.isSnackbarOpen) Get.back(); | |||
| Get.snackbar(null, 'Người phụ trách được cập nhật'); | |||
| } else { | |||
| //Go home | |||
| } | |||
| } catch (e) { | |||
| print('error'); | |||
| print(e); | |||
| } | |||
| }, | |||
| // onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler, | |||
| onLaunch: (Map<String, dynamic> message) async { | |||
| print("onLaunch: $message"); | |||
| Future.delayed(const Duration(milliseconds: 500), () { | |||
| updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| _notificationNavigateOnFCM(message); | |||
| }); | |||
| }, | |||
| onResume: (Map<String, dynamic> message) async { | |||
| print("onResume: $message"); | |||
| updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| _notificationNavigateOnFCM(message); | |||
| }, | |||
| ); | |||
| _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: true)); | |||
| _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) { | |||
| print("Settings registered: $settings"); | |||
| }); | |||
| // if (contents == "ENV_UPDATE") { | |||
| // if (Get.isSnackbarOpen) Get.back(); | |||
| // Get.snackbar(null, 'Thông số môi trường được cập nhật'); | |||
| // } else if (contents == "PIC_UPDATE") { | |||
| // if (Get.isSnackbarOpen) Get.back(); | |||
| // Get.snackbar(null, 'Người phụ trách được cập nhật'); | |||
| // } else { | |||
| // //Go home | |||
| // } | |||
| // } catch (e) { | |||
| // print('error'); | |||
| // print(e); | |||
| // } | |||
| // }, | |||
| // // onBackgroundMessage: Platform.isIOS ? null : myBackgroundMessageHandler, | |||
| // onLaunch: (Map<String, dynamic> message) async { | |||
| // print("onLaunch: $message"); | |||
| // Future.delayed(const Duration(milliseconds: 500), () { | |||
| // updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| // _notificationNavigateOnFCM(message); | |||
| // }); | |||
| // }, | |||
| // onResume: (Map<String, dynamic> message) async { | |||
| // print("onResume: $message"); | |||
| // updateCountNotiBloc.getNotifications((data) {}, (err) {}); | |||
| // _notificationNavigateOnFCM(message); | |||
| // }, | |||
| // ); | |||
| // _firebaseMessaging.requestNotificationPermissions(const IosNotificationSettings(sound: true, badge: true, alert: true, provisional: true)); | |||
| // _firebaseMessaging.onIosSettingsRegistered.listen((IosNotificationSettings settings) { | |||
| // print("Settings registered: $settings"); | |||
| // }); | |||
| if (pushkey?.isEmpty ?? true) { | |||
| _firebaseMessaging.getToken().then((String token) { | |||
| assert(token != null); | |||
| print("Push Messaging token: $token"); | |||
| _userRepository.updateFcmToken(token).then((value) { | |||
| print("send push key successful"); | |||
| pref.saveString(DATA_CONST.PUSH_KEY, token); | |||
| }); | |||
| // client.put(""); | |||
| }); | |||
| // _firebaseMessaging.getToken().then((String token) { | |||
| // assert(token != null); | |||
| // print("Push Messaging token: $token"); | |||
| // _userRepository.updateFcmToken(token).then((value) { | |||
| // print("send push key successful"); | |||
| // pref.saveString(DATA_CONST.PUSH_KEY, token); | |||
| // }); | |||
| // // client.put(""); | |||
| // }); | |||
| } else { | |||
| print("Don't need get push key"); | |||
| } | |||
| @@ -0,0 +1,29 @@ | |||
| class RouteName { | |||
| static const String splash = '/'; | |||
| static const String login = '/login'; | |||
| static const String home = '/home'; | |||
| static const String forgotPass = '/forgotPass'; | |||
| static const String changePass = '/changePass'; | |||
| static const String customerDetail = '/customer-detail'; | |||
| static const String vehicleDetail = '/vehicle-detail'; | |||
| static const String anglePhoto = '/angle-photo'; | |||
| static const String exteriorInspectionA = '/exterior_inspection_a'; | |||
| static const String exteriorInspectionB = '/exterior_inspection_b'; | |||
| static const String exteriorInspectionC = '/exterior_inspection_c'; | |||
| static const String exteriorInspectionD = '/exterior_inspection_d'; | |||
| static const String outputFinal = '/output_final'; | |||
| static const String appraisal_listing = '/appraisal_listing'; | |||
| static const String appraisalDetail = '/appraisal_detail'; | |||
| static const String recordDeal = '/recordDeal'; | |||
| static const String postDetail = '/postDetail'; | |||
| static const String postCategory = '/postCategory'; | |||
| static const String chooseFrame = '/chooseFrame'; | |||
| static const String selectImages = '/selectImages'; | |||
| static const String splashPage = '/splashPage'; | |||
| static const String selectPostImagesPage = '/selectPostImagesPage'; | |||
| static const String studentInClass = '/studentInClass'; | |||
| static const String studentDetail = '/studentDetail'; | |||
| static const String classCamera = '/classCamera'; | |||
| static const String myKidInfoPage = '/myKidInfoPage'; | |||
| static const String previewedPage = '/previewedPage'; | |||
| } | |||
| @@ -0,0 +1,38 @@ | |||
| import 'package:farm_tpf/presentation/screens/tabbar/tabbar.dart'; | |||
| import 'package:flutter/material.dart'; | |||
| import '../presentation/screens/splash/view/splash_page.dart'; | |||
| import 'route_name.dart'; | |||
| class Routes { | |||
| static Route buildRoutes(RouteSettings settings) { | |||
| switch (settings.name) { | |||
| case RouteName.splashPage: | |||
| return buildRoute(settings, SplashPage()); | |||
| case RouteName.home: | |||
| return buildRoute(settings, TabbarScreen()); | |||
| default: | |||
| return _errorRoute(); | |||
| } | |||
| } | |||
| static Route homeRoute(RouteSettings settings) { | |||
| return buildRoutes(settings); | |||
| } | |||
| static Route _errorRoute() { | |||
| return MaterialPageRoute(builder: (_) { | |||
| return const Scaffold( | |||
| body: Center( | |||
| child: Text(''), | |||
| ), | |||
| ); | |||
| }); | |||
| } | |||
| static MaterialPageRoute buildRoute(RouteSettings settings, Widget builder) { | |||
| return MaterialPageRoute( | |||
| settings: settings, | |||
| builder: (BuildContext context) => builder, | |||
| ); | |||
| } | |||
| } | |||
| @@ -2,8 +2,8 @@ class ConstCommon { | |||
| static int kExpiredTime = 518400000; //6* 24 * 60 * 60 * 1000; 6days | |||
| static int kFileSize = 1000000; //1M = 1000.000 bytes | |||
| static int kMaxAgeCache = 7; // 7days | |||
| static const String baseUrl = "https://smf.presshome.vn/"; | |||
| static const String baseImageUrl = "https://smf.presshome.vn/upload/"; | |||
| static const String baseUrl = "https://tpf.aztrace.vn/"; | |||
| static const String baseImageUrl = "https://tpf.aztrace.vn/upload/"; | |||
| static RegExp regExpDecimal = RegExp("[0-9.]"); | |||
| static const String apiDetailNursery = "api/activity-nursery"; | |||
| @@ -86,4 +86,5 @@ class ConstCommon { | |||
| } | |||
| enum CRUDStatus { unknown, add, edit, delete } | |||
| enum LocationType { country, province, district, ward } | |||
| @@ -10,7 +10,7 @@ class LocalPref extends Pref { | |||
| @override | |||
| Future<String> getString(String key) async { | |||
| final prefs = await SharedPreferences.getInstance(); | |||
| return prefs.getString(key); | |||
| return prefs.getString(key) ?? ''; | |||
| } | |||
| } | |||
| @@ -8,6 +8,13 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "14.0.0" | |||
| _flutterfire_internals: | |||
| dependency: transitive | |||
| description: | |||
| name: _flutterfire_internals | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.17" | |||
| analyzer: | |||
| dependency: transitive | |||
| description: | |||
| @@ -15,13 +22,20 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.41.2" | |||
| archive: | |||
| dependency: transitive | |||
| description: | |||
| name: archive | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.13" | |||
| args: | |||
| dependency: transitive | |||
| description: | |||
| name: args | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.3.1" | |||
| version: "1.6.0" | |||
| async: | |||
| dependency: transitive | |||
| description: | |||
| @@ -36,13 +50,6 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.2.0" | |||
| barcode_scan: | |||
| dependency: "direct main" | |||
| description: | |||
| name: barcode_scan | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "3.0.1" | |||
| bloc: | |||
| dependency: transitive | |||
| description: | |||
| @@ -197,6 +204,13 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.1.5" | |||
| csslib: | |||
| dependency: transitive | |||
| description: | |||
| name: csslib | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.17.2" | |||
| cupertino_icons: | |||
| dependency: "direct main" | |||
| description: | |||
| @@ -245,7 +259,7 @@ packages: | |||
| name: ffi | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.2.1" | |||
| version: "2.0.1" | |||
| file: | |||
| dependency: transitive | |||
| description: | |||
| @@ -253,41 +267,48 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "6.1.4" | |||
| file_picker: | |||
| dependency: "direct main" | |||
| description: | |||
| name: file_picker | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.1.7" | |||
| firebase_core: | |||
| dependency: transitive | |||
| description: | |||
| name: firebase_core | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.5.3" | |||
| version: "2.7.1" | |||
| firebase_core_platform_interface: | |||
| dependency: transitive | |||
| description: | |||
| name: firebase_core_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.1.0" | |||
| version: "4.5.3" | |||
| firebase_core_web: | |||
| dependency: transitive | |||
| description: | |||
| name: firebase_core_web | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.2.1+1" | |||
| version: "2.2.2" | |||
| firebase_messaging: | |||
| dependency: "direct main" | |||
| description: | |||
| name: firebase_messaging | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "7.0.3" | |||
| version: "14.2.6" | |||
| firebase_messaging_platform_interface: | |||
| dependency: transitive | |||
| description: | |||
| name: firebase_messaging_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "4.2.15" | |||
| firebase_messaging_web: | |||
| dependency: transitive | |||
| description: | |||
| name: firebase_messaging_web | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "3.2.16" | |||
| fixnum: | |||
| dependency: transitive | |||
| description: | |||
| @@ -320,7 +341,7 @@ packages: | |||
| name: flutter_cache_manager | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.4.2" | |||
| version: "2.1.2" | |||
| flutter_datetime_picker: | |||
| dependency: "direct main" | |||
| description: | |||
| @@ -335,13 +356,6 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.7.0" | |||
| flutter_plugin_android_lifecycle: | |||
| dependency: transitive | |||
| description: | |||
| name: flutter_plugin_android_lifecycle | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.11" | |||
| flutter_svg: | |||
| dependency: "direct main" | |||
| description: | |||
| @@ -401,6 +415,13 @@ packages: | |||
| 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.15.2" | |||
| http: | |||
| dependency: "direct main" | |||
| description: | |||
| @@ -422,13 +443,20 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "3.1.4" | |||
| image: | |||
| dependency: transitive | |||
| description: | |||
| name: image | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.1.19" | |||
| intl: | |||
| dependency: "direct main" | |||
| description: | |||
| name: intl | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.16.1" | |||
| version: "0.17.0" | |||
| io: | |||
| dependency: transitive | |||
| description: | |||
| @@ -554,42 +582,49 @@ packages: | |||
| name: path_provider | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.6.28" | |||
| path_provider_linux: | |||
| version: "2.0.13" | |||
| path_provider_android: | |||
| dependency: transitive | |||
| description: | |||
| name: path_provider_linux | |||
| name: path_provider_android | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.1+2" | |||
| path_provider_macos: | |||
| version: "2.0.23" | |||
| path_provider_foundation: | |||
| dependency: transitive | |||
| description: | |||
| name: path_provider_foundation | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.1.2" | |||
| path_provider_linux: | |||
| dependency: transitive | |||
| description: | |||
| name: path_provider_macos | |||
| name: path_provider_linux | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.4+8" | |||
| version: "2.1.9" | |||
| path_provider_platform_interface: | |||
| dependency: transitive | |||
| description: | |||
| name: path_provider_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.4" | |||
| version: "2.0.6" | |||
| path_provider_windows: | |||
| dependency: transitive | |||
| description: | |||
| name: path_provider_windows | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.5" | |||
| version: "2.1.4" | |||
| pattern_formatter: | |||
| dependency: "direct main" | |||
| description: | |||
| name: pattern_formatter | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.2" | |||
| version: "2.0.0" | |||
| pedantic: | |||
| dependency: transitive | |||
| description: | |||
| @@ -617,7 +652,7 @@ packages: | |||
| name: plugin_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.3" | |||
| version: "2.1.4" | |||
| pool: | |||
| dependency: transitive | |||
| description: | |||
| @@ -632,13 +667,6 @@ packages: | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "4.2.4" | |||
| protobuf: | |||
| dependency: transitive | |||
| description: | |||
| name: protobuf | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.1.4" | |||
| provider: | |||
| dependency: transitive | |||
| description: | |||
| @@ -701,42 +729,49 @@ packages: | |||
| name: shared_preferences | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.5.12+4" | |||
| shared_preferences_linux: | |||
| version: "2.0.18" | |||
| shared_preferences_android: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_linux | |||
| name: shared_preferences_android | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.0.16" | |||
| shared_preferences_foundation: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_foundation | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.2+4" | |||
| shared_preferences_macos: | |||
| version: "2.1.4" | |||
| shared_preferences_linux: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_macos | |||
| name: shared_preferences_linux | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.1+11" | |||
| version: "2.1.4" | |||
| shared_preferences_platform_interface: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "1.0.4" | |||
| version: "2.1.1" | |||
| shared_preferences_web: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_web | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.1.2+7" | |||
| version: "2.0.5" | |||
| shared_preferences_windows: | |||
| dependency: transitive | |||
| description: | |||
| name: shared_preferences_windows | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.0.2+3" | |||
| version: "2.1.4" | |||
| shelf: | |||
| dependency: transitive | |||
| description: | |||
| @@ -881,21 +916,35 @@ packages: | |||
| name: video_player | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.10.12+5" | |||
| version: "2.5.3" | |||
| video_player_android: | |||
| dependency: transitive | |||
| description: | |||
| name: video_player_android | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.3.11" | |||
| video_player_avfoundation: | |||
| dependency: transitive | |||
| description: | |||
| name: video_player_avfoundation | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.3.9" | |||
| video_player_platform_interface: | |||
| dependency: transitive | |||
| description: | |||
| name: video_player_platform_interface | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.2.0" | |||
| version: "6.0.2" | |||
| video_player_web: | |||
| dependency: transitive | |||
| description: | |||
| name: video_player_web | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.1.4+1" | |||
| version: "2.0.14" | |||
| watcher: | |||
| dependency: transitive | |||
| description: | |||
| @@ -916,14 +965,14 @@ packages: | |||
| name: win32 | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "2.6.1" | |||
| version: "3.1.3" | |||
| xdg_directories: | |||
| dependency: transitive | |||
| description: | |||
| name: xdg_directories | |||
| url: "https://pub.dartlang.org" | |||
| source: hosted | |||
| version: "0.1.2" | |||
| version: "1.0.0" | |||
| xml: | |||
| dependency: transitive | |||
| description: | |||
| @@ -940,4 +989,4 @@ packages: | |||
| version: "3.1.1" | |||
| sdks: | |||
| dart: ">=2.17.0 <3.0.0" | |||
| flutter: ">=1.24.0-10.1.pre" | |||
| flutter: ">=3.0.0" | |||
| @@ -5,7 +5,7 @@ publish_to: 'none' | |||
| version: 1.0.1+4 | |||
| environment: | |||
| sdk: ">=2.12.0 <3.0.0" | |||
| sdk: ">=2.17.0 <3.0.0" | |||
| module: | |||
| androidX: true | |||
| @@ -16,24 +16,24 @@ dependencies: | |||
| cupertino_icons: ^0.1.3 | |||
| meta: ^1.1.8 | |||
| shared_preferences: ^0.5.8 | |||
| shared_preferences: any | |||
| flutter_bloc: ^6.0.1 | |||
| equatable: ^1.2.0 | |||
| dio: ^3.0.10 | |||
| dio_http_cache: ^0.2.9 | |||
| formz: ^0.3.0 | |||
| keyboard_dismisser: ^1.0.2 | |||
| pattern_formatter: ^1.0.2 | |||
| pattern_formatter: ^2.0.0 | |||
| rxdart: ^0.23.0 | |||
| barcode_scan: ^3.0.1 | |||
| # barcode_scan: ^3.0.1 | |||
| video_player: ^2.5.3 | |||
| shimmer: ^1.1.1 | |||
| font_awesome_flutter: ^8.8.1 | |||
| package_info: ^0.4.3 | |||
| change_app_package_name: ^0.1.2 | |||
| firebase_messaging: ^7.0.0 | |||
| firebase_messaging: ^14.2.6 | |||
| get: ^3.8.0 | |||
| intl: ^0.16.1 | |||
| intl: ^0.17.0 | |||
| flutter_datetime_picker: ^1.3.8 | |||
| http: ^0.12.2 | |||
| http_parser: ^3.1.4 | |||
| @@ -42,9 +42,9 @@ dependencies: | |||
| cached_network_image: ^2.3.2+1 | |||
| camera: ^0.5.8+5 | |||
| path_provider: ^1.6.14 | |||
| file_picker: ^2.0.7 | |||
| flutter_cache_manager: ^1.4.2 | |||
| path_provider: ^2.0.13 | |||
| # file_picker: ^5.2.5 | |||
| flutter_cache_manager: any | |||
| mime: ^0.9.7 | |||
| flutter_image_compress: ^0.7.0 | |||