From acfab08198baeb3d3aa0419f895628eb30b6ff8d Mon Sep 17 00:00:00 2001 From: Sai Naw Wun Date: Fri, 4 Sep 2020 01:42:58 +0630 Subject: [PATCH] fix mainmodel --- lib/app.dart | 9 +- lib/fcs/common/data/providers/auth_fb.dart | 119 ++++++------ lib/fcs/common/domain/constants.dart | 37 ++++ lib/fcs/common/domain/entities/auth.dart | 13 -- .../common/domain/entities/auth_result.dart | 9 + .../common/domain/entities/bank_account.dart | 31 ++++ lib/fcs/common/domain/entities/setting.dart | 166 +++++++++++++++++ lib/fcs/common/domain/entities/user.dart | 4 +- .../domain/exceiptions/signin_exception.dart | 8 + lib/fcs/common/network_connectivity.dart | 67 +++++++ lib/fcs/common/pages/home_page.dart | 2 +- lib/fcs/common/pages/model/main_model.dart | 170 ++++++++++++++++++ lib/fcs/common/pages/profile_page.dart | 10 +- lib/fcs/common/pages/signin/code_page.dart | 16 +- .../pages/signin/model/signin_model.dart | 25 --- lib/fcs/common/pages/signin/signin_page.dart | 9 +- lib/fcs/common/pages/signin/signup_page.dart | 6 +- lib/fcs/common/pages/splash_page.dart | 71 ++------ lib/fcs/common/pages/welcome_page.dart | 3 +- lib/fcs/common/services/auth_imp.dart | 36 +++- lib/fcs/common/services/auth_interface.dart | 7 - lib/fcs/common/services/auth_service.dart | 13 ++ lib/fcs/common/services/services.dart | 19 ++ lib/main-dev.dart | 4 +- lib/model/main_model.dart | 6 +- 25 files changed, 668 insertions(+), 192 deletions(-) create mode 100644 lib/fcs/common/domain/constants.dart delete mode 100644 lib/fcs/common/domain/entities/auth.dart create mode 100644 lib/fcs/common/domain/entities/auth_result.dart create mode 100644 lib/fcs/common/domain/entities/bank_account.dart create mode 100644 lib/fcs/common/domain/entities/setting.dart create mode 100644 lib/fcs/common/domain/exceiptions/signin_exception.dart create mode 100644 lib/fcs/common/network_connectivity.dart create mode 100644 lib/fcs/common/pages/model/main_model.dart delete mode 100644 lib/fcs/common/pages/signin/model/signin_model.dart delete mode 100644 lib/fcs/common/services/auth_interface.dart create mode 100644 lib/fcs/common/services/auth_service.dart create mode 100644 lib/fcs/common/services/services.dart diff --git a/lib/app.dart b/lib/app.dart index ce29ae6..df6f0c7 100644 --- a/lib/app.dart +++ b/lib/app.dart @@ -1,4 +1,3 @@ -import 'package:fcs/fcs/common/pages/signin/model/signin_model.dart'; import 'package:fcs/model/buyer_model.dart'; import 'package:fcs/model/delivery_model.dart'; import 'package:fcs/model/discount_model.dart'; @@ -17,6 +16,7 @@ import 'package:fcs/pages/login_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart' as fcs; import 'model/announcement_model.dart'; import 'model/chart_model.dart'; @@ -48,6 +48,8 @@ class App extends StatefulWidget { } class _AppState extends State { + final fcs.MainModel mainModel2 = new fcs.MainModel(); + final MainModel mainModel = new MainModel(); final UserModel userModel = new UserModel(); final ProductModel productModel = new ProductModel(); @@ -84,6 +86,7 @@ class _AppState extends State { @override void initState() { super.initState(); + mainModel2.init(); _newLocaleDelegate = AppTranslationsDelegate(newLocale: null); Translation().onLocaleChanged = onLocaleChange; mainModel @@ -174,9 +177,7 @@ class _AppState extends State { ChangeNotifierProvider.value(value: customerModel), ChangeNotifierProvider.value(value: discountModel), ChangeNotifierProvider.value(value: testModel), - ChangeNotifierProvider( - create: (_) => SigninModel(), - ), + ChangeNotifierProvider.value(value: mainModel2), ], child: Consumer( builder: (BuildContext context, LanguageModel value, Widget child) { diff --git a/lib/fcs/common/data/providers/auth_fb.dart b/lib/fcs/common/data/providers/auth_fb.dart index bbb90ba..1c076aa 100644 --- a/lib/fcs/common/data/providers/auth_fb.dart +++ b/lib/fcs/common/data/providers/auth_fb.dart @@ -1,7 +1,12 @@ import 'dart:async'; -import 'package:fcs/fcs/common/domain/entities/auth.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:fcs/fcs/common/domain/constants.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_result.dart' as fcs; import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; +import 'package:fcs/fcs/common/domain/entities/setting.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; +import 'package:fcs/fcs/common/domain/exceiptions/signin_exception.dart'; import 'package:firebase_auth/firebase_auth.dart'; import '../../api_helper.dart'; @@ -11,39 +16,37 @@ class AuthFb { AuthFb._(); static final FirebaseAuth _fb = FirebaseAuth.instance; - static FirebaseUser firebaseUser; static String _verificationId; - Future sendSmsCodeToPhoneNumber(String phoneNumber) { - Completer completer = Completer(); + Future sendSmsCodeToPhoneNumber(String phoneNumber) { + Completer completer = Completer(); final PhoneVerificationCompleted verificationCompleted = - (AuthCredential authCredential) async { - firebaseUser = await _signIn(authCredential); - Auth auth = Auth(authStatus: AuthStatus.AUTH_VERIFIED); - auth.uid = firebaseUser.uid; - auth.name = await _getName(firebaseUser); - auth.phoneNumber = firebaseUser.phoneNumber; + (AuthCredential credential) async { + AuthResult _authResult = await _fb.signInWithCredential(credential); + if (_authResult == null) { + throw SigninException("Sigin error!"); + } + fcs.AuthResult auth = + fcs.AuthResult(authStatus: AuthStatus.AUTH_VERIFIED); completer.complete(auth); print( - 'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: $firebaseUser'); + 'Inside _sendCodeToPhoneNumber: signInWithPhoneNumber auto succeeded: ${_authResult.user}'); }; final PhoneVerificationFailed verificationFailed = (AuthException authException) async { print( 'Phone number verification failed. Code: ${authException.code}. Message: ${authException.message}'); - completer.complete(Auth( - authStatus: AuthStatus.ERROR, - authErrorCode: authException.code, - authErrorMsg: "Phone number verification failed")); + completer + .completeError(SigninException("Phone number verification failed")); }; final PhoneCodeSent codeSent = (String verificationId, [int forceResendingToken]) async { _verificationId = verificationId; print("code sent to " + phoneNumber); - completer.complete(Auth(authStatus: AuthStatus.SMS_SENT)); + completer.complete(fcs.AuthResult(authStatus: AuthStatus.SMS_SENT)); }; final PhoneCodeAutoRetrievalTimeout codeAutoRetrievalTimeout = @@ -62,61 +65,65 @@ class AuthFb { return completer.future; } - Future signInWithPhoneNumber(String smsCode) async { - Auth auth = Auth(); + Future signInWithPhoneNumber(String smsCode) async { + User user; try { final AuthCredential credential = PhoneAuthProvider.getCredential( verificationId: _verificationId, smsCode: smsCode, ); - - firebaseUser = await _signIn(credential); - - auth.uid = firebaseUser.uid; - auth.name = await _getName(firebaseUser); - auth.authStatus = AuthStatus.AUTH_VERIFIED; + AuthResult _authResult = await _fb.signInWithCredential(credential); + if (_authResult == null) { + throw SigninException("Sigin error!"); + } } on Exception catch (e) { - auth.authStatus = AuthStatus.ERROR; - auth.authErrorMsg = e.toString(); + return Future.error(SigninException(e.toString())); } - return Future.value(auth); + if (user == null) Future.error(SigninException("No current user!")); + return Future.value(fcs.AuthResult(authStatus: AuthStatus.AUTH_VERIFIED)); } Future signout() { - firebaseUser = null; return _fb.signOut(); } - Future _signIn(AuthCredential credential) async { - AuthResult _authResult = await _fb.signInWithCredential(credential); - FirebaseUser _fusr = _authResult.user; + Stream get onAuthStatus async* { + await for (FirebaseUser firebaseUser in _fb.onAuthStateChanged) { + if (firebaseUser == null) { + yield null; + } + yield await getUser(); + } + } + + Future getUser({bool refreshIdToken = false}) async { + FirebaseUser firebaseUser = await _fb.currentUser(); + if (firebaseUser == null) return null; + IdTokenResult idToken = + await firebaseUser.getIdToken(refresh: refreshIdToken); + String name = idToken.claims["name"]; + User user = User(); + user.id = firebaseUser.uid; + user.name = name; + user.hasSignup = + idToken.claims.containsKey("signup") && idToken.claims["signup"]; + user.phoneNumber = firebaseUser.phoneNumber; + return user; + } + + Future isLogin() async { final FirebaseUser firebaseUser = await _fb.currentUser(); - assert(_fusr.uid == firebaseUser.uid); - - var idToken = await firebaseUser.getIdToken(); - print("Claims:${idToken.claims}"); - - return firebaseUser; + return Future.value(firebaseUser != null); } - Future _getName(FirebaseUser firebaseUser) async { - IdTokenResult idToken = await firebaseUser.getIdToken(); - return idToken.claims["name"]; - } - - Future hasSignup() async { - IdTokenResult idToken = await firebaseUser.getIdToken(); - return idToken.claims.containsKey("signup") && idToken.claims["signup"]; - } - - Future signup(String name) async { + Future signup(String userName) async { await requestAPI("/signup", "POST", payload: { - 'name': name, + 'user_name': userName, }, token: await getToken()); // refresh token once signup - await firebaseUser.getIdToken(refresh: true); + return getUser(refreshIdToken: true); } static Future getToken() async { @@ -124,4 +131,16 @@ class AuthFb { IdTokenResult token = await firebaseUser.getIdToken(); return token.token; } + + Future getSetting() async { + var snap = await Firestore.instance + .collection(config_collection) + .document(setting_doc_id) + .get(); + if (!snap.exists) { + return null; + } + // _listSetting(); + return Setting.fromMap(snap.data); + } } diff --git a/lib/fcs/common/domain/constants.dart b/lib/fcs/common/domain/constants.dart new file mode 100644 index 0000000..c7d22eb --- /dev/null +++ b/lib/fcs/common/domain/constants.dart @@ -0,0 +1,37 @@ +const ok_doc_id = "ok"; +const setting_doc_id = "setting"; + +const config_collection = "configs"; +const biz_collection = "bizs"; +const product_collection = "products"; +const user_collection = "users"; +const privilege_collection = "privileges"; +const user_level_collection = "user_levels"; +const storage_collection = "storages"; +const buyer_collection = "buyers"; +const buying_pos = "buying_pos"; +const selling_pos = "selling_pos"; +const inventory_takings = "inventory_takings"; +const inventory_lines = "inventory_lines"; +const pds_collection = "pds"; +const pos_collection = "pos"; +const dos_collection = "dos"; +const notification_collection = "notifications"; +const log_collection = "logs"; +const report_collection = "reports"; +const po_product_collection = "po_products"; +const device_collection = "devices"; +const do_po_lines_collection = "do_po_lines"; +const reports_collection = "reports"; +const announcement_collection = "announcements"; +const report_user_collection = "report_users"; + +const po_files_path = "/ok/po"; +const reg_files_path = "/ok/reg"; +const do_files_path = "/ok/do"; +const sign_files_path = "/ok/sign"; +const bank_images_path = "/ok/banks"; + +const po_approved_status = "approved"; +const po_closed_status = "closed"; +const do_approved_status = "approved"; diff --git a/lib/fcs/common/domain/entities/auth.dart b/lib/fcs/common/domain/entities/auth.dart deleted file mode 100644 index 8fd50c5..0000000 --- a/lib/fcs/common/domain/entities/auth.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'auth_status.dart'; - -class Auth { - AuthStatus authStatus; - String authErrorCode; - String authErrorMsg; - - String uid; - String name; - String phoneNumber; - - Auth({this.authStatus, this.authErrorCode, this.authErrorMsg}); -} diff --git a/lib/fcs/common/domain/entities/auth_result.dart b/lib/fcs/common/domain/entities/auth_result.dart new file mode 100644 index 0000000..dd989fd --- /dev/null +++ b/lib/fcs/common/domain/entities/auth_result.dart @@ -0,0 +1,9 @@ +import 'auth_status.dart'; + +class AuthResult { + AuthStatus authStatus; + String authErrorCode; + String authErrorMsg; + + AuthResult({this.authStatus, this.authErrorCode, this.authErrorMsg}); +} diff --git a/lib/fcs/common/domain/entities/bank_account.dart b/lib/fcs/common/domain/entities/bank_account.dart new file mode 100644 index 0000000..98027f0 --- /dev/null +++ b/lib/fcs/common/domain/entities/bank_account.dart @@ -0,0 +1,31 @@ +class BankAccount { + int index; + String bankName; + String bankLogo; + String accountName; + String accountNumber; + BankAccount( + {this.index, + this.bankName, + this.bankLogo, + this.accountName, + this.accountNumber}); + + BankAccount.fromMap(int index, Map json) { + this.index = index; + bankName = json['bank_name']; + bankLogo = json['bank_logo']; + accountName = json['account_name']; + accountNumber = json['account_number']; + } + + Map toMap() { + return { + "index": index, + 'bank_name': bankName, + 'bank_logo': bankLogo, + 'account_name': accountName, + 'account_number': accountNumber, + }; + } +} diff --git a/lib/fcs/common/domain/entities/setting.dart b/lib/fcs/common/domain/entities/setting.dart new file mode 100644 index 0000000..b5f9db1 --- /dev/null +++ b/lib/fcs/common/domain/entities/setting.dart @@ -0,0 +1,166 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; + +import 'bank_account.dart'; + +List dayLists = [ + Day(id: 1, name: 'Sun'), + Day(id: 2, name: 'Mon'), + Day(id: 3, name: 'Tue'), + Day(id: 4, name: 'Wed'), + Day(id: 5, name: 'Thu'), + Day(id: 6, name: 'Fri'), + Day(id: 7, name: 'Sat'), +]; + +class Setting { + final int supportBuildNum; + final String okEnergyId; + final String about; + final String terms; + int poExpireInHours; + int doExpireInHours; + int poOpenAt; + int poCloseAt; + List poCloseOn; + int latestDeliveryDay; + int firstStorageChargeIn; + int firstStorageCharge; + int secondStorageChargeIn; + int secondStorageCharge; + int deliveryStartWaitMin; + String reportURL; + String helpVersion; + String helpURL; + + List phones; + String deliveryPhone; + String address; + String email; + String website; + String facebook; + DateTime priceLastUpdate; + String bankAccountInfo; + List bankAccounts; + + String get getPoOpenAt => poOpenAt > 12 + ? (poOpenAt - 12).toString() + "PM" + : poOpenAt.toString() + "AM"; + + String get getPoCloseAt => poCloseAt > 12 + ? (poCloseAt - 12).toString() + "PM" + : poCloseAt.toString() + "AM"; + + String get getPoCloseOn => poCloseOn.fold( + "", (p, e) => p + (p == "" ? "" : ", ") + dayLists[e - 1].name); + + String get getPoOpenOn => dayLists.fold( + "", + (p, e) => + p + + (p == "" ? "" : poCloseOn.contains(e.id) ? "" : ", ") + + (poCloseOn.contains(e.id) ? "" : e.name)); + + bool get isPOClose { + DateTime now = DateTime.now(); + // dart starts from monday width starting index one + // server starts from sunday with starting index one + var day = (now.weekday + 1) == 8 ? 1 : now.weekday + 1; + return poCloseOn.contains(day) || + (now.hour < poOpenAt || now.hour >= poCloseAt); + } + + Setting( + {this.supportBuildNum, + this.about, + this.okEnergyId, + this.terms, + this.poExpireInHours, + this.doExpireInHours, + this.poOpenAt, + this.poCloseAt, + this.poCloseOn, + this.latestDeliveryDay, + this.firstStorageCharge, + this.firstStorageChargeIn, + this.secondStorageCharge, + this.secondStorageChargeIn, + this.deliveryStartWaitMin, + this.reportURL, + this.helpVersion, + this.helpURL, + this.phones, + this.email, + this.website, + this.facebook, + this.priceLastUpdate, + this.bankAccountInfo, + this.bankAccounts, + this.deliveryPhone, + this.address}); + + factory Setting.fromMap(Map map) { + var ts = (map['price_last_update'] as Timestamp); + var list = (map['bank_accounts'] as List); + List bankAccounts = []; + if (list != null) { + list.asMap().forEach((index, item) { + bankAccounts + .add(BankAccount.fromMap(index, item.cast())); + }); + } + + return Setting( + priceLastUpdate: ts?.toDate(), + supportBuildNum: map['support_build_number'], + about: map['about'], + terms: map['terms'], + okEnergyId: map['ok_energy_id'], + poExpireInHours: map['po_expire_hours'], + doExpireInHours: map['do_expire_hours'], + poOpenAt: map['po_open_at'], + poCloseAt: map['po_close_at'], + latestDeliveryDay: map['latest_delivery_days'], + firstStorageChargeIn: map['first_storage_charge_in'], + firstStorageCharge: map['first_storage_charge'], + secondStorageChargeIn: map['second_storage_charge_in'], + secondStorageCharge: map['second_storage_charge'], + deliveryStartWaitMin: map['delivery_start_wait_min'], + reportURL: map['report_url'], + helpVersion: map['help_version'], + helpURL: map['help_url'], + email: map['email'], + deliveryPhone: map['delivery_phone'], + address: map['address'], + website: map['website'], + facebook: map['facebook'], + bankAccountInfo: map['bank_account_info'], + bankAccounts: bankAccounts); + } + + Map toMap() { + return { + 'terms': terms, + }; + } + + String helpFileName() { + return "help-v$helpVersion.zip"; + } + + @override + String toString() { + return 'Setting{supportBuildNum:$supportBuildNum,about:$about,okEnergyId:$okEnergyId}'; + } +} + +class Day { + int id; + String name; + bool isChecked = false; + Day({this.id, this.name, this.isChecked}); + + @override + String toString() { + return 'Day{id:$id,name:$name,isChecked:$isChecked}'; + } +} diff --git a/lib/fcs/common/domain/entities/user.dart b/lib/fcs/common/domain/entities/user.dart index 51248d6..768d8b1 100644 --- a/lib/fcs/common/domain/entities/user.dart +++ b/lib/fcs/common/domain/entities/user.dart @@ -5,6 +5,8 @@ class User { String id; String name; String phoneNumber; + bool hasSignup; + String fcsID; String shippingAddress; String deliveryAddress; @@ -280,6 +282,6 @@ class User { @override String toString() { - return 'User{name: $name, phoneNumber: $phoneNumber,dateofBirth:$dateofBirth,disable:$disable,gender:$gender,roleName:$roleName,roleID:$roleID,privilegeIds:$privilegeIds,status:$status,frontUrl:$frontUrl,backUrl:$backUrl,selfieUrl:$selfieUrl}'; + return 'User{name: $name, phoneNumber: $phoneNumber,hasSignup:$hasSignup}'; } } diff --git a/lib/fcs/common/domain/exceiptions/signin_exception.dart b/lib/fcs/common/domain/exceiptions/signin_exception.dart new file mode 100644 index 0000000..2715b72 --- /dev/null +++ b/lib/fcs/common/domain/exceiptions/signin_exception.dart @@ -0,0 +1,8 @@ +class SigninException { + final String msg; + + SigninException(this.msg); + + @override + String toString() => msg; +} diff --git a/lib/fcs/common/network_connectivity.dart b/lib/fcs/common/network_connectivity.dart new file mode 100644 index 0000000..be680b4 --- /dev/null +++ b/lib/fcs/common/network_connectivity.dart @@ -0,0 +1,67 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:connectivity/connectivity.dart'; +import 'package:fcs/config.dart'; +import 'package:fcs/fcs/common/api_helper.dart'; +import 'package:logging/logging.dart'; + +class NetworkConnectivity { + final log = Logger('NetworkConnectivity'); + + static final NetworkConnectivity instance = NetworkConnectivity._internal(); + static String hostName; + NetworkConnectivity._internal() { + _initialise(); + var uri = Uri.parse(Config.instance.apiURL); + hostName = uri.host; + log.info("host name:$hostName"); + } + + Connectivity connectivity = Connectivity(); + + final StreamController _controller = StreamController.broadcast(); + + Stream get statusStream => _controller.stream; + + void _initialise() async { + ConnectivityResult result = await connectivity.checkConnectivity(); + _checkStatus(result); + connectivity.onConnectivityChanged.listen((result) { + _checkStatus(result); + }); + } + + void _checkStatus(ConnectivityResult result) async { + bool isOnline = false; + // lookup if connectivity is not none + if (result != ConnectivityResult.none) { + try { + final hostNameLookup = await InternetAddress.lookup(hostName); + if (hostNameLookup.isNotEmpty && + hostNameLookup[0].rawAddress.isNotEmpty) { + if (await checkHeartbeat()) { + isOnline = true; + } + } else + isOnline = false; + } on SocketException catch (_) { + isOnline = false; + } + } + + if (_controller != null && !_controller.isClosed) + _controller.sink.add({"isOnline": isOnline}); + } + + Future checkHeartbeat() async { + var result = await requestAPI("/hb", "GET"); + var status = result["status"]; + if (status != null && status != "") { + return true; + } + return false; + } + + void disposeStream() => _controller.close(); +} diff --git a/lib/fcs/common/pages/home_page.dart b/lib/fcs/common/pages/home_page.dart index abc10e6..5832364 100644 --- a/lib/fcs/common/pages/home_page.dart +++ b/lib/fcs/common/pages/home_page.dart @@ -1,5 +1,5 @@ +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/model/language_model.dart'; -import 'package:fcs/model/main_model.dart'; import 'package:fcs/pages/contact.dart'; import 'package:fcs/pages/discount_list.dart'; import 'package:fcs/pages/notification_list.dart'; diff --git a/lib/fcs/common/pages/model/main_model.dart b/lib/fcs/common/pages/model/main_model.dart new file mode 100644 index 0000000..2462c94 --- /dev/null +++ b/lib/fcs/common/pages/model/main_model.dart @@ -0,0 +1,170 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:device_info/device_info.dart'; +import 'package:dio/dio.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; +import 'package:fcs/fcs/common/domain/entities/setting.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; +import 'package:fcs/fcs/common/network_connectivity.dart'; +import 'package:fcs/fcs/common/services/services.dart'; +import 'package:flutter/foundation.dart'; +import 'package:logging/logging.dart'; +import 'package:package_info/package_info.dart'; + +class MainModel extends ChangeNotifier { + final log = Logger('MainModel'); + + User user; + PackageInfo packageInfo; + + Setting setting = Setting( + terms: + '[{"insert":"* Minimum shipping weight is 1lbs.\n* Oversized goods, Light weight/Large volume items, laptops, phones, tablets may incur extra charges based on pecifications.Please contact us for pricing.\n* Goods with lithium battary needs extra packaging and declaration. Please inform us ahead of time so that we can process your package accordingly.\n* Loose Batteries, Drones, and Prescription medicines are not allowed on aircraft.\n* Payment: We accept money orders, any US bank transfers via Zelle, AYA, KBZ and CB. No COD except for pick-ups.\n*Payments made in Myanmar will incur 2% tranfer fee\n"}]'); + + bool isLoaded = false; + bool isOnline = false; + + MainModel() { + NetworkConnectivity.instance.statusStream.listen((data) { + bool _isOnline = data["isOnline"]; + if (_isOnline && !this.isOnline) { + init(); + } + this.isOnline = _isOnline; + notifyListeners(); + }); + Services.instance.authService.onAuthStatus().listen((event) { + print("main event-->$event"); + }); + } + + bool isLogin() { + return this.user != null; + } + + bool isCustomer() { + return user != null && user.name != "Owner"; + } + + bool isOwner() { + return user != null && user.name == "Owner"; + } + + bool hasEmail() { + return this.user != null && this.user.isEmail(); + } + + bool agreedTerm() { + return this.user != null && this.user.agreeTerms; + } + + bool isBuyer() { + return this.user == null || this.user.isBuyer(); + } + + bool isSysAdmin() { + return this.user != null && this.user.isSysAdmin(); + } + + bool isSysSupport() { + return this.user != null && this.user.isSysSupport(); + } + + bool isBizAdmin() { + return this.user != null && this.user.isBizAdmin(); + } + + bool isOwnerAndAbove() { + return this.user != null && this.user.isOwnerAndAbove(); + } + + bool isAdmin() { + return this.user != null && this.user.hasAdmin(); + } + + bool showHistoryBtn() { + return isSysAdmin() || isSysSupport() || isBizAdmin(); + } + + init() async { + await _loadSetting(); + _loadUser(); + this.packageInfo = await PackageInfo.fromPlatform(); + } + + // void addModel(BaseModel model) { + // models.add(model); + // } + + // void _initUser(User user) { + // models.forEach((m) => m.initUser(user)); + + // if (firebaseMessaging != null) { + // firebaseMessaging.subscribeToTopic(user.docID); + // } + // } + + // void _initSetting(Setting setting) { + // models.forEach((m) => m.initSetting(setting)); + // } + + Future _loadSetting() async { + try { + this.setting = await Services.instance.authService.getSetting(); + } finally {} + // _initSetting(setting); + } + + void _loadUser() async { + try { + this.user = await Services.instance.authService.getUser(); + } finally { + this.isLoaded = true; + notifyListeners(); + } + } + + @override + void dispose() { + super.dispose(); + // if (this.userListener != null) { + // this.userListener.cancel(); + // } + // SharedPref.removeUser(); + // this.user = User(); + } + + bool isSupport() { + if (packageInfo == null || setting == null) return false; + return int.parse(packageInfo.buildNumber) >= setting.supportBuildNum; + } + + Future sendSms(String phoneNumber) { + return Services.instance.authService.sendSmsCodeToPhoneNumber(phoneNumber); + } + + Future signin(String smsCode) async { + AuthResult authResult = + await Services.instance.authService.signInWithSmsCode(smsCode); + if (authResult != null && + authResult.authStatus == AuthStatus.AUTH_VERIFIED) { + this.user = await Services.instance.authService.getUser(); + } + return authResult; + } + + Future signout() { + this.user = null; + notifyListeners(); + return Services.instance.authService.signout(); + } + + Future signup(String userName) async { + await Services.instance.authService.signup(userName); + this.user = await Services.instance.authService.getUser(); + notifyListeners(); + } +} diff --git a/lib/fcs/common/pages/profile_page.dart b/lib/fcs/common/pages/profile_page.dart index 7393725..cb8f876 100644 --- a/lib/fcs/common/pages/profile_page.dart +++ b/lib/fcs/common/pages/profile_page.dart @@ -1,6 +1,5 @@ -import 'package:fcs/fcs/common/pages/signin/model/signin_model.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/model/language_model.dart'; -import 'package:fcs/model/main_model.dart'; import 'package:fcs/model/shipment_model.dart'; import 'package:fcs/model/user_model.dart'; import 'package:fcs/pages/util.dart'; @@ -89,7 +88,9 @@ class _ProfileState extends State { Container( child: Center( child: Text( - mainModel.user == null ? "" : mainModel.user.name, + mainModel.user == null || mainModel.user.name == null + ? "" + : mainModel.user.name, style: TextStyle(fontSize: 16.0, fontStyle: FontStyle.normal), ), @@ -229,8 +230,7 @@ class _ProfileState extends State { setState(() { _isLoading = true; }); - await mainModel.logout(); - await context.read().signout(); + await context.read().signout(); Navigator.of(context).pushNamedAndRemoveUntil( "/welcome", ModalRoute.withName('/welcome')); Future.delayed(Duration(seconds: 1), () { diff --git a/lib/fcs/common/pages/signin/code_page.dart b/lib/fcs/common/pages/signin/code_page.dart index 892ebeb..068df13 100644 --- a/lib/fcs/common/pages/signin/code_page.dart +++ b/lib/fcs/common/pages/signin/code_page.dart @@ -1,9 +1,9 @@ import 'dart:async'; -import 'package:fcs/fcs/common/domain/entities/auth.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; -import 'package:fcs/fcs/common/pages/signin/model/signin_model.dart'; -import 'package:fcs/model/main_model.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/pages/util.dart'; import 'package:fcs/widget/bottom_up_page_route.dart'; import 'package:flutter/material.dart'; @@ -194,16 +194,16 @@ class _CodePageState extends State { _verify() async { try { - Auth auth = await context.read().signin(this.pin); + AuthResult auth = await context.read().signin(this.pin); if (auth.authStatus == AuthStatus.AUTH_VERIFIED) { - bool hasSignup = await context.read().hasSignup(); - if (!hasSignup) { + User user = context.read().user; + if (user != null && !user.hasSignup) { await Navigator.of(context).push(BottomUpPageRoute(SignupPage())); } else { Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false); } - Provider.of(context, listen: false) - .saveUser(pin, widget.phoneNumber); + // Provider.of(context, listen: false) + // .saveUser(pin, widget.phoneNumber); } } catch (e) { showMsgDialog(context, "Error", e.toString()); diff --git a/lib/fcs/common/pages/signin/model/signin_model.dart b/lib/fcs/common/pages/signin/model/signin_model.dart deleted file mode 100644 index 97d7998..0000000 --- a/lib/fcs/common/pages/signin/model/signin_model.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:fcs/fcs/common/data/providers/auth_fb.dart'; -import 'package:fcs/fcs/common/domain/entities/auth.dart'; -import 'package:flutter/foundation.dart'; - -class SigninModel extends ChangeNotifier { - Future sendSms(String phoneNumber) { - return AuthFb.instance.sendSmsCodeToPhoneNumber(phoneNumber); - } - - Future signin(String smsCode) { - return AuthFb.instance.signInWithPhoneNumber(smsCode); - } - - Future signout() { - return AuthFb.instance.signout(); - } - - Future hasSignup() { - return AuthFb.instance.hasSignup(); - } - - Future signup(String name) { - return AuthFb.instance.signup(name); - } -} diff --git a/lib/fcs/common/pages/signin/signin_page.dart b/lib/fcs/common/pages/signin/signin_page.dart index 7454cee..ef19eac 100644 --- a/lib/fcs/common/pages/signin/signin_page.dart +++ b/lib/fcs/common/pages/signin/signin_page.dart @@ -1,7 +1,7 @@ import 'package:country_code_picker/country_code_picker.dart'; -import 'package:fcs/fcs/common/domain/entities/auth.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; import 'package:fcs/fcs/common/domain/entities/auth_status.dart'; -import 'package:fcs/fcs/common/pages/signin/model/signin_model.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/widget/bottom_up_page_route.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; @@ -166,13 +166,12 @@ class _SigninPageState extends State { }); try { - Exception exp; phoneNumber = phoneNumber[0] == "0" ? phoneNumber.replaceFirst("0", "") : phoneNumber; phoneNumber = dialCode + phoneNumber; - Auth auth = await context.read().sendSms(phoneNumber); + AuthResult auth = await context.read().sendSms(phoneNumber); if (auth.authStatus == AuthStatus.SMS_SENT) { await Navigator.of(context) .push(BottomUpPageRoute(CodePage(phoneNumber: phoneNumber))); @@ -181,8 +180,6 @@ class _SigninPageState extends State { if (auth.authStatus == AuthStatus.ERROR) { showMsgDialog(context, "Error", auth.authErrorMsg); } - - if (exp != null) throw exp; } catch (e) { showMsgDialog(context, "Error", e.toString()); } diff --git a/lib/fcs/common/pages/signin/signup_page.dart b/lib/fcs/common/pages/signin/signup_page.dart index bd550b2..b4b766b 100644 --- a/lib/fcs/common/pages/signin/signup_page.dart +++ b/lib/fcs/common/pages/signin/signup_page.dart @@ -1,12 +1,12 @@ -import 'package:fcs/fcs/common/pages/signin/model/signin_model.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:provider/provider.dart'; import '../../../../widget/local_text.dart'; import '../../../../widget/progress.dart'; import '../../theme.dart'; -import 'package:provider/provider.dart'; class SignupPage extends StatefulWidget { @override @@ -108,7 +108,7 @@ class _SignupPageState extends State { } _submit() async { - await context.read().signup(nameCtl.text); + await context.read().signup(nameCtl.text); Navigator.pushNamedAndRemoveUntil(context, "/home", (r) => false); } } diff --git a/lib/fcs/common/pages/splash_page.dart b/lib/fcs/common/pages/splash_page.dart index 9a6f676..e4269d6 100644 --- a/lib/fcs/common/pages/splash_page.dart +++ b/lib/fcs/common/pages/splash_page.dart @@ -1,9 +1,8 @@ import 'dart:async'; -import 'package:fcs/model/main_model.dart'; +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/fcs/common/theme.dart'; import 'package:fcs/widget/local_text.dart'; -import 'package:fcs/widget/localization/app_translations.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; import 'package:provider/provider.dart'; @@ -18,10 +17,7 @@ class _SplashScreenState extends State { bool _loaded = false; bool _isSupport = false; - bool _isGoogleService = true; bool _isLogin = false; - bool _isAgree = false; - bool _hasEmail = false; bool _isOnline = true; Timer timer; @@ -35,44 +31,15 @@ class _SplashScreenState extends State { return; } - // GooglePlayServicesAvailability availability = await GoogleApiAvailability - // .instance - // .checkGooglePlayServicesAvailability(true); - // log.info("GooglePlaysServcie Result1:$availability"); - // if (availability != GooglePlayServicesAvailability.success && - // Platform.isAndroid) { - // timer.cancel(); - // setState(() { - // _isGoogleService = false; - // }); - // return; - // } - if (_loaded) { timer.cancel(); - if (this._isLogin) { - Navigator.of(context).pushReplacementNamed('/home'); - } else { - Navigator.of(context).pushReplacementNamed('/welcome'); + if (_isSupport) { + if (this._isLogin) { + Navigator.of(context).pushReplacementNamed('/home'); + } else { + Navigator.of(context).pushReplacementNamed('/welcome'); + } } - - // if (_isSupport) { - // if (_isLogin) { - // if (!_isAgree) { - // await Navigator.of(context).pushNamed('/term'); - // startTime(); - // } else { - // bool skipped = await SharedPref.getSkippedRecoverEmail(); - // skipped = skipped ?? false; - // if (!this._hasEmail && !skipped) { - // Navigator.of(context).pushReplacementNamed('/email'); - // } else { - // } - // } - // } else { - // Navigator.of(context).pushReplacementNamed('/welcome'); - // } - // } } } @@ -92,10 +59,8 @@ class _SplashScreenState extends State { MainModel mainModel = Provider.of(context); this._loaded = mainModel.isLoaded; - this._isSupport = true; + this._isSupport = mainModel.isSupport(); this._isLogin = mainModel.isLogin(); - // this._isAgree = mainModel.agreedTerm(); - this._hasEmail = mainModel.hasEmail(); this._isOnline = mainModel.isOnline; return new Scaffold( @@ -121,24 +86,18 @@ class _SplashScreenState extends State { ), ], ), - // CircularProgressIndicator( - // valueColor: new AlwaysStoppedAnimation(primaryColor), - // ), SizedBox(height: 30), - _isOnline - ? Container() - : Column( + _loaded && !_isOnline + ? Column( children: [ LocalText(context, "offline.status"), ], - ), - Text(_isGoogleService ? "" : "Google Play service not found."), + ) + : Container(), Text( - _loaded - ? (!_isSupport - ? "Version outdated, please update your app!" - : "") - : AppTranslations.of(context).text("load"), + _loaded && !_isSupport + ? "Version outdated, please update your app!" + : "", style: TextStyle( color: primaryColor, fontWeight: FontWeight.bold)), ], diff --git a/lib/fcs/common/pages/welcome_page.dart b/lib/fcs/common/pages/welcome_page.dart index b4b14eb..d6ab02e 100644 --- a/lib/fcs/common/pages/welcome_page.dart +++ b/lib/fcs/common/pages/welcome_page.dart @@ -1,9 +1,8 @@ +import 'package:fcs/fcs/common/pages/model/main_model.dart'; import 'package:fcs/model/language_model.dart'; -import 'package:fcs/model/main_model.dart'; import 'package:fcs/pages/contact.dart'; import 'package:fcs/widget/banner.dart'; import 'package:fcs/widget/bottom_up_page_route.dart'; -import 'package:fcs/widget/dimension_box.dart'; import 'package:fcs/widget/localization/transalation.dart'; import 'package:fcs/widget/offline_redirect.dart'; import 'package:flutter/cupertino.dart'; diff --git a/lib/fcs/common/services/auth_imp.dart b/lib/fcs/common/services/auth_imp.dart index cef656d..3fdda0f 100644 --- a/lib/fcs/common/services/auth_imp.dart +++ b/lib/fcs/common/services/auth_imp.dart @@ -1,14 +1,16 @@ import 'package:fcs/fcs/common/data/providers/auth_fb.dart'; import 'package:fcs/fcs/common/data/providers/user_fb_data_provider.dart'; import 'package:fcs/fcs/common/data/providers/user_local_data_provider.dart'; -import 'package:fcs/fcs/common/domain/entities/auth.dart'; +import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; import 'package:fcs/fcs/common/domain/entities/connectivity.dart'; +import 'package:fcs/fcs/common/domain/entities/setting.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; import 'package:flutter/material.dart'; -import 'auth_interface.dart'; +import 'auth_service.dart'; -class AuthImp implements AuthInterface { - AuthImp({ +class AuthServiceImp implements AuthService { + AuthServiceImp({ @required this.authFb, @required this.connectivity, @required this.userFBDataProvider, @@ -21,17 +23,37 @@ class AuthImp implements AuthInterface { final AuthFb authFb; @override - Future sendSmsCodeToPhoneNumber(String phoneNumber) { + Future sendSmsCodeToPhoneNumber(String phoneNumber) { return authFb.sendSmsCodeToPhoneNumber(phoneNumber); } @override - Future signInWithSmsCode(String smsCode) { + Future signInWithSmsCode(String smsCode) { return authFb.signInWithPhoneNumber(smsCode); } @override - Future signout() { + Future signout() { return authFb.signout(); } + + @override + Future getUser({bool refreshIdToken = false}) { + return authFb.getUser(refreshIdToken: refreshIdToken); + } + + @override + Future getSetting() { + return authFb.getSetting(); + } + + @override + Future signup(String userName) { + return authFb.signup(userName); + } + + @override + Stream onAuthStatus() { + return authFb.onAuthStatus; + } } diff --git a/lib/fcs/common/services/auth_interface.dart b/lib/fcs/common/services/auth_interface.dart deleted file mode 100644 index bcf5d29..0000000 --- a/lib/fcs/common/services/auth_interface.dart +++ /dev/null @@ -1,7 +0,0 @@ -import 'package:fcs/fcs/common/domain/entities/auth.dart'; - -abstract class AuthInterface { - Future sendSmsCodeToPhoneNumber(String phoneNumber); - Future signInWithSmsCode(String smsCode); - Future signout(); -} diff --git a/lib/fcs/common/services/auth_service.dart b/lib/fcs/common/services/auth_service.dart new file mode 100644 index 0000000..bb9fb83 --- /dev/null +++ b/lib/fcs/common/services/auth_service.dart @@ -0,0 +1,13 @@ +import 'package:fcs/fcs/common/domain/entities/auth_result.dart'; +import 'package:fcs/fcs/common/domain/entities/setting.dart'; +import 'package:fcs/fcs/common/domain/entities/user.dart'; + +abstract class AuthService { + Future sendSmsCodeToPhoneNumber(String phoneNumber); + Future signInWithSmsCode(String smsCode); + Future signout(); + Future getUser({bool refreshIdToken = false}); + Future signup(String userName); + Future getSetting(); + Stream onAuthStatus(); +} diff --git a/lib/fcs/common/services/services.dart b/lib/fcs/common/services/services.dart new file mode 100644 index 0000000..912d376 --- /dev/null +++ b/lib/fcs/common/services/services.dart @@ -0,0 +1,19 @@ +import 'package:fcs/fcs/common/data/providers/auth_fb.dart'; +import 'package:fcs/fcs/common/services/auth_imp.dart'; + +import 'auth_service.dart'; + +class Services { + static final Services instance = Services._(); + + AuthService _authService; + Services._() { + _authService = AuthServiceImp( + authFb: AuthFb.instance, + connectivity: null, + userFBDataProvider: null, + userLocalDataProvider: null); + } + + AuthService get authService => _authService; +} diff --git a/lib/main-dev.dart b/lib/main-dev.dart index 889ea4a..9ebdbaf 100644 --- a/lib/main-dev.dart +++ b/lib/main-dev.dart @@ -8,9 +8,7 @@ void main() { Config( flavor: Flavor.DEV, color: Colors.blue, - apiURL: "http://192.168.100.11:7777", - reportURL: "http://petrok-dev.mokkon.com:8080", - reportProjectID: "dev", + apiURL: "https://asia-northeast1-fcs-dev1.cloudfunctions.net/API", level: Level.ALL); runApp(App()); } diff --git a/lib/model/main_model.dart b/lib/model/main_model.dart index c82615f..62ed57d 100644 --- a/lib/model/main_model.dart +++ b/lib/model/main_model.dart @@ -4,6 +4,7 @@ import 'dart:io'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:device_info/device_info.dart'; import 'package:dio/dio.dart'; +import 'package:fcs/fcs/common/services/services.dart'; import 'package:fcs/vo/payment_method.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; @@ -80,6 +81,9 @@ class MainModel extends ChangeNotifier { // notifyListeners(); // }); _loadFcs(); + Services.instance.authService.onAuthStatus().listen((event) { + print("main event-->$event"); + }); } List get paymentMethods { @@ -300,7 +304,7 @@ class MainModel extends ChangeNotifier { @override void dispose() { - // super.dispose(); + super.dispose(); // if (this.userListener != null) { // this.userListener.cancel(); // }