clean up
This commit is contained in:
404
lib/pages/main/home_page.dart
Normal file
404
lib/pages/main/home_page.dart
Normal file
@@ -0,0 +1,404 @@
|
||||
import 'dart:async';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:fcs/data/services/services.dart';
|
||||
import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/localization/transalation.dart';
|
||||
import 'package:fcs/pages/box/box_list.dart';
|
||||
import 'package:fcs/pages/chat/message_detail.dart';
|
||||
import 'package:fcs/pages/chat/model/message_model.dart';
|
||||
import 'package:fcs/pages/customer/customer_list.dart';
|
||||
import 'package:fcs/pages/customer/model/customer_model.dart';
|
||||
import 'package:fcs/pages/delivery/delivery_list.dart';
|
||||
import 'package:fcs/pages/discount/discount_list.dart';
|
||||
import 'package:fcs/pages/faq/faq_list_page.dart';
|
||||
import 'package:fcs/pages/fcs_shipment/fcs_shipment_list.dart';
|
||||
import 'package:fcs/pages/invoice/invoce_list.dart';
|
||||
import 'package:fcs/pages/main/model/language_model.dart';
|
||||
import 'package:fcs/pages/main/model/main_model.dart';
|
||||
import 'package:fcs/pages/package/package_list.dart';
|
||||
import 'package:fcs/pages/rates/shipment_rates.dart';
|
||||
import 'package:fcs/pages/shipment/pickup_list.dart';
|
||||
import 'package:fcs/pages/staff/staff_list.dart';
|
||||
import 'package:fcs/pages/widgets/task_button.dart';
|
||||
import 'package:fcs/pages/widgets/badge.dart';
|
||||
import 'package:fcs/pages/widgets/bottom_up_page_route.dart';
|
||||
import 'package:fcs/pages/widgets/bottom_widgets.dart';
|
||||
import 'package:fcs/pages/widgets/right_left_page_rout.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_icons/flutter_icons.dart';
|
||||
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../profile/profile_page.dart';
|
||||
import '../signin/signin_page.dart';
|
||||
import '../widgets/banner.dart';
|
||||
import '../widgets/offline_redirect.dart';
|
||||
|
||||
final msgLog = Logger('backgroundMessageHandler');
|
||||
|
||||
class HomePage extends StatefulWidget {
|
||||
@override
|
||||
_HomePageState createState() => _HomePageState();
|
||||
}
|
||||
|
||||
class _HomePageState extends State<HomePage> {
|
||||
final log = Logger('_HomePageState');
|
||||
bool login = false;
|
||||
bool customer = true;
|
||||
List<bool> isSelected = [true, false];
|
||||
static FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
|
||||
FlutterLocalNotificationsPlugin();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
||||
|
||||
Services.instance.messagingService.init(
|
||||
(message) {
|
||||
print("Message from FCM:$message");
|
||||
_showNotification(message);
|
||||
},
|
||||
onLaunch: (m) => _showNotiContent(m),
|
||||
onResume: (m) => _showNotiContent(m),
|
||||
onSetupComplete: (token) {
|
||||
mainModel.setMessaginToken = token;
|
||||
});
|
||||
_initLocalNotifications();
|
||||
}
|
||||
|
||||
String notiUserID, notiUserName;
|
||||
_showNotiContent(Map<String, dynamic> message) {
|
||||
try {
|
||||
Map<String, dynamic> map = Map<String, dynamic>.from(message["data"]);
|
||||
notiUserID = map['user_id'];
|
||||
notiUserName = map['user_name'];
|
||||
_startNotiTimer();
|
||||
print("Notification:$map");
|
||||
} catch (e) {
|
||||
print("Error:$e");
|
||||
}
|
||||
}
|
||||
|
||||
_startNotiTimer() async {
|
||||
var _duration = new Duration(milliseconds: 500);
|
||||
new Timer.periodic(_duration, (t) => displayNoti(t));
|
||||
}
|
||||
|
||||
void displayNoti(Timer timer) async {
|
||||
MainModel mainModel = Provider.of<MainModel>(context, listen: false);
|
||||
if (mainModel.isLogin()) {
|
||||
timer.cancel();
|
||||
bool isCustomer = mainModel.isCustomer();
|
||||
String receiverID = isCustomer ? mainModel.user.id : notiUserID;
|
||||
String receiverName = isCustomer ? mainModel.user.name : notiUserName;
|
||||
MessageModel messageModel =
|
||||
Provider.of<MessageModel>(context, listen: false);
|
||||
messageModel.initQuery(receiverID);
|
||||
User user = mainModel.user;
|
||||
if (!isCustomer) {
|
||||
CustomerModel customerModel =
|
||||
Provider.of<CustomerModel>(context, listen: false);
|
||||
user = await customerModel.getUser(receiverID);
|
||||
}
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => MessageDetail(
|
||||
messageModel: messageModel,
|
||||
receiverID: receiverID,
|
||||
receiverName: receiverName,
|
||||
))).then((value) {
|
||||
if (user.userUnseenCount > 0) {
|
||||
messageModel.seenMessages(user.id, true);
|
||||
}
|
||||
});
|
||||
if (user.userUnseenCount > 0) {
|
||||
messageModel.seenMessages(user.id, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_initLocalNotifications() {
|
||||
var initializationSettingsAndroid =
|
||||
new AndroidInitializationSettings('@mipmap/ic_launcher');
|
||||
var initializationSettingsIOS = new IOSInitializationSettings();
|
||||
var initializationSettings = new InitializationSettings(
|
||||
initializationSettingsAndroid, initializationSettingsIOS);
|
||||
_flutterLocalNotificationsPlugin.initialize(initializationSettings);
|
||||
}
|
||||
|
||||
static Future _showNotification(Map<String, dynamic> message) async {
|
||||
var pushTitle;
|
||||
var pushText;
|
||||
var action;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
var nodeData = message['notification'];
|
||||
pushTitle = nodeData['title'];
|
||||
pushText = nodeData['body'];
|
||||
action = nodeData['action'];
|
||||
} else {
|
||||
pushTitle = message['title'];
|
||||
pushText = message['body'];
|
||||
action = message['action'];
|
||||
}
|
||||
print("AppPushs params pushTitle : $pushTitle");
|
||||
print("AppPushs params pushText : $pushText");
|
||||
print("AppPushs params pushAction : $action");
|
||||
|
||||
// @formatter:off
|
||||
var platformChannelSpecificsAndroid = new AndroidNotificationDetails(
|
||||
'your channel id', 'your channel name', 'your channel description',
|
||||
playSound: true,
|
||||
enableVibration: true,
|
||||
importance: Importance.Max,
|
||||
priority: Priority.High);
|
||||
// @formatter:on
|
||||
var platformChannelSpecificsIos =
|
||||
new IOSNotificationDetails(presentSound: true);
|
||||
var platformChannelSpecifics = new NotificationDetails(
|
||||
platformChannelSpecificsAndroid, platformChannelSpecificsIos);
|
||||
|
||||
new Future.delayed(Duration.zero, () {
|
||||
_flutterLocalNotificationsPlugin.show(
|
||||
0,
|
||||
pushTitle,
|
||||
pushText,
|
||||
platformChannelSpecifics,
|
||||
payload: 'No_Sound',
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
User user = Provider.of<MainModel>(context).user;
|
||||
if (user == null) {
|
||||
return Container();
|
||||
}
|
||||
customer = Provider.of<MainModel>(context).isCustomer();
|
||||
|
||||
login = Provider.of<MainModel>(context).isLogin();
|
||||
LanguageModel languageModel = Provider.of<LanguageModel>(context);
|
||||
|
||||
final faqBtn = TaskButton("faq.btn",
|
||||
icon: MaterialCommunityIcons.frequently_asked_questions,
|
||||
btnCallback: () => Navigator.of(context).push(CupertinoPageRoute(
|
||||
builder: (context) => FAQListPage(),
|
||||
)));
|
||||
|
||||
final packagesBtn = TaskButton("package.btn.name",
|
||||
icon: Octicons.package,
|
||||
btnCallback: () => Navigator.of(context).push<void>(
|
||||
CupertinoPageRoute(builder: (context) => PackageList())));
|
||||
|
||||
final boxesBtn = TaskButton("boxes.name",
|
||||
icon: MaterialCommunityIcons.package,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(BoxList())));
|
||||
|
||||
final pickUpBtn = TaskButton("pickup",
|
||||
icon: SimpleLineIcons.direction,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(PickUpList())));
|
||||
|
||||
final shipmentCostBtn = TaskButton("rate",
|
||||
icon: FontAwesomeIcons.calculator,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(ShipmentRates())));
|
||||
|
||||
final fcsShipmentBtn = TaskButton("shipment.title",
|
||||
icon: Ionicons.ios_airplane,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(FcsShipmentList())));
|
||||
|
||||
final notiBtnOrg =
|
||||
TaskButton("message.btn", icon: Icons.message, btnCallback: () {
|
||||
MessageModel messageModel =
|
||||
Provider.of<MessageModel>(context, listen: false);
|
||||
messageModel.initQuery(user.id);
|
||||
Navigator.push(
|
||||
context,
|
||||
BottomUpPageRoute(MessageDetail(
|
||||
messageModel: messageModel,
|
||||
)),
|
||||
).then((value) {
|
||||
if (user.userUnseenCount > 0) {
|
||||
messageModel.seenMessages(user.id, true);
|
||||
}
|
||||
});
|
||||
if (user.userUnseenCount > 0) {
|
||||
messageModel.seenMessages(user.id, true);
|
||||
}
|
||||
});
|
||||
final notiBtn = badgeCounter(notiBtnOrg, user.userUnseenCount);
|
||||
|
||||
final staffBtn = TaskButton(
|
||||
"staff.title",
|
||||
icon: MaterialCommunityIcons.worker,
|
||||
btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
|
||||
builder: (context) => StaffList(),
|
||||
)),
|
||||
);
|
||||
|
||||
final customersBtn = TaskButton("customers.btn",
|
||||
icon: Feather.users,
|
||||
btnCallback: () => Navigator.of(context).push<void>(CupertinoPageRoute(
|
||||
builder: (context) => CustomerList(),
|
||||
)));
|
||||
|
||||
final invoicesBtn = TaskButton("invoices.btn",
|
||||
icon: FontAwesomeIcons.fileInvoice,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(InvoiceList())));
|
||||
|
||||
final discountBtn = TaskButton("discount.btn",
|
||||
icon: Entypo.price_ribbon,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(DiscountList())));
|
||||
|
||||
final deliveryBtn = TaskButton("delivery.title",
|
||||
icon: MaterialCommunityIcons.truck_fast,
|
||||
btnCallback: () =>
|
||||
Navigator.of(context).push(BottomUpPageRoute(DeliverList())));
|
||||
|
||||
List<Widget> widgets = [];
|
||||
widgets.add(faqBtn);
|
||||
if (user != null) {
|
||||
true ? widgets.add(pickUpBtn) : "";
|
||||
!customer ? widgets.add(fcsShipmentBtn) : "";
|
||||
customer ? widgets.add(notiBtn) : "";
|
||||
user.hasStaffs() ? widgets.add(staffBtn) : "";
|
||||
widgets.add(shipmentCostBtn);
|
||||
user.hasPackages() ? widgets.add(packagesBtn) : "";
|
||||
true ? widgets.add(boxesBtn) : "";
|
||||
true ? widgets.add(deliveryBtn) : "";
|
||||
user.hasCustomers() ? widgets.add(customersBtn) : "";
|
||||
true ? widgets.add(invoicesBtn) : "";
|
||||
true ? widgets.add(discountBtn) : "";
|
||||
}
|
||||
return OfflineRedirect(
|
||||
child: FlavorBanner(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
elevation: 0,
|
||||
backgroundColor: primaryColor,
|
||||
title: ClipRRect(
|
||||
child: Image.asset("assets/logo.jpg", height: 40),
|
||||
borderRadius: new BorderRadius.circular(30.0),
|
||||
),
|
||||
actions: login
|
||||
? <Widget>[
|
||||
ToggleButtons(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
'icons/flags/png/us.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
),
|
||||
Image.asset(
|
||||
'icons/flags/png/mm.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
)
|
||||
],
|
||||
onPressed: _langChange,
|
||||
isSelected: languageModel.currentState,
|
||||
selectedBorderColor: Colors.white24,
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.push(RightLeftPageRoute(Profile()));
|
||||
},
|
||||
iconSize: 30,
|
||||
icon: Icon(Icons.account_circle),
|
||||
),
|
||||
]
|
||||
: <Widget>[
|
||||
ToggleButtons(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
'icons/flags/png/us.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
),
|
||||
Image.asset(
|
||||
'icons/flags/png/mm.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
)
|
||||
],
|
||||
onPressed: _langChange,
|
||||
isSelected: languageModel.currentState,
|
||||
),
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.push(BottomUpPageRoute(SigninPage()));
|
||||
},
|
||||
child: Text(
|
||||
"Sign In",
|
||||
style: siginButtonStyle,
|
||||
),
|
||||
),
|
||||
]),
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
Color(0xd0272262),
|
||||
Color(0xfa272262),
|
||||
],
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: ListView(children: [
|
||||
Wrap(
|
||||
alignment: WrapAlignment.center,
|
||||
children: widgets,
|
||||
),
|
||||
]),
|
||||
),
|
||||
BottomWidgets(),
|
||||
],
|
||||
))),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_langChange(index) {
|
||||
var languageModel = Provider.of<LanguageModel>(context, listen: false);
|
||||
languageModel.saveLanguage(Translation().supportedLanguages[index]);
|
||||
setState(() {
|
||||
isSelected.asMap().forEach((i, e) {
|
||||
isSelected[i] = false;
|
||||
});
|
||||
isSelected[index] = !isSelected[index];
|
||||
});
|
||||
}
|
||||
|
||||
// Widget _buildBtn(String title, {IconData icon, BtnCallback btnCallback}) {
|
||||
// return TaskButton(titleKey: title, icon: icon, btnCallback: btnCallback);
|
||||
// }
|
||||
}
|
||||
202
lib/pages/main/initial_language_selection.dart
Normal file
202
lib/pages/main/initial_language_selection.dart
Normal file
@@ -0,0 +1,202 @@
|
||||
import 'package:fcs/helpers/shared_pref.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/localization/transalation.dart';
|
||||
import 'package:fcs/pages/main/model/language_model.dart';
|
||||
import 'package:fcs/pages/main/model/main_model.dart';
|
||||
import 'package:fcs/pages/signin/signin_page.dart';
|
||||
import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:fcs/pages/widgets/progress.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class InitialLanguageSelectionPage extends StatefulWidget {
|
||||
@override
|
||||
_InitialLanguageSelectionPageState createState() =>
|
||||
_InitialLanguageSelectionPageState();
|
||||
}
|
||||
|
||||
class _InitialLanguageSelectionPageState
|
||||
extends State<InitialLanguageSelectionPage> {
|
||||
static final List<String> languagesList = Translation().supportedLanguages;
|
||||
static final List<String> languageCodesList =
|
||||
Translation().supportedLanguagesCodes;
|
||||
|
||||
final Map<dynamic, dynamic> languagesMap = {
|
||||
languagesList[0]: languageCodesList[0],
|
||||
languagesList[1]: languageCodesList[1],
|
||||
};
|
||||
|
||||
String selectedLanguage;
|
||||
int selectedIndex;
|
||||
bool _isLoading;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_isLoading = false;
|
||||
var languageModel = Provider.of<LanguageModel>(context, listen: false);
|
||||
this.selectedIndex = languageModel.isEng ? 0 : 1;
|
||||
loadLaunguage(languageModel);
|
||||
}
|
||||
|
||||
loadLaunguage(LanguageModel languageModel) async {
|
||||
var lan = await languageModel.load();
|
||||
if (this.selectedLanguage != lan) {
|
||||
setState(() {
|
||||
this.selectedLanguage = lan;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return LocalProgress(
|
||||
inAsyncCall: _isLoading,
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
colors: [Color(0xff272282), primaryColor],
|
||||
begin: const FractionalOffset(0.8, 0.9),
|
||||
end: const FractionalOffset(0.9, 0.0),
|
||||
stops: [0.0, 1.0],
|
||||
),
|
||||
),
|
||||
child: Align(
|
||||
alignment: Alignment.center,
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection: Axis.vertical,
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
child: LocalText(context, "language.selection.title",
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.white),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
child: Card(
|
||||
color: Color(0xfff4edec),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(20)),
|
||||
),
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
width: 300,
|
||||
height: 160,
|
||||
child: Column(
|
||||
children: languagesList.asMap().entries.map((e) {
|
||||
var language = e.value;
|
||||
var key = e.key;
|
||||
return InkWell(
|
||||
onTap: () {
|
||||
_select(key, language);
|
||||
},
|
||||
child: Container(
|
||||
padding: EdgeInsets.all(2),
|
||||
decoration: key == languagesList.length - 1
|
||||
? BoxDecoration()
|
||||
: BoxDecoration(
|
||||
border: Border(
|
||||
bottom:
|
||||
BorderSide(color: Colors.grey[300]),
|
||||
),
|
||||
),
|
||||
child: ListTile(
|
||||
leading: language == 'English'
|
||||
? Container(
|
||||
child: CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundImage: AssetImage(
|
||||
"icons/flags/png/gb.png",
|
||||
package: 'country_icons',
|
||||
),
|
||||
),
|
||||
)
|
||||
: Container(
|
||||
child: CircleAvatar(
|
||||
radius: 20,
|
||||
backgroundImage: AssetImage(
|
||||
"icons/flags/png/mm.png",
|
||||
package: 'country_icons',
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Text("$language"),
|
||||
trailing: Theme(
|
||||
data: Theme.of(context).copyWith(
|
||||
unselectedWidgetColor: Colors.grey[400],
|
||||
),
|
||||
child: Radio(
|
||||
value: key,
|
||||
groupValue: selectedIndex,
|
||||
onChanged: (int i) =>
|
||||
_select(key, language),
|
||||
activeColor: primaryColor,
|
||||
),
|
||||
)),
|
||||
),
|
||||
);
|
||||
}).toList()),
|
||||
),
|
||||
),
|
||||
),
|
||||
SizedBox(height: 20.0),
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 230, top: 20),
|
||||
child: Container(
|
||||
width: 50,
|
||||
height: 50,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
_next();
|
||||
},
|
||||
child: CircleAvatar(
|
||||
radius: 25,
|
||||
backgroundColor: Colors.white,
|
||||
child: Center(
|
||||
child: Icon(FontAwesomeIcons.arrowRight,
|
||||
color: Colors.black87)),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_select(int index, String lang) {
|
||||
setState(() {
|
||||
selectedIndex = index;
|
||||
selectedLanguage = lang;
|
||||
Translation().onLocaleChanged(Locale(languagesMap[lang]));
|
||||
Provider.of<LanguageModel>(context, listen: false)
|
||||
.saveLanguage(selectedLanguage);
|
||||
});
|
||||
}
|
||||
|
||||
_next() {
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
try {
|
||||
SharedPref.finishFirstLaunch();
|
||||
bool isLogin = Provider.of<MainModel>(context, listen: false).isLogin();
|
||||
String page = isLogin ? "/home" : "/welcome";
|
||||
Navigator.of(context).pushReplacementNamed(page);
|
||||
} catch (e) {} finally {
|
||||
setState(() {
|
||||
_isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
37
lib/pages/main/model/base_model.dart
Normal file
37
lib/pages/main/model/base_model.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
import 'package:fcs/domain/entities/setting.dart';
|
||||
import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:fcs/helpers/api_helper.dart';
|
||||
|
||||
import 'main_model.dart';
|
||||
|
||||
abstract class BaseModel extends ChangeNotifier {
|
||||
User user;
|
||||
Setting setting;
|
||||
MainModel mainModel;
|
||||
|
||||
void initUser(User user) async {
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
void privilegeChanged() {}
|
||||
|
||||
void initSetting(Setting setting) async {
|
||||
this.setting = setting;
|
||||
}
|
||||
|
||||
void logout() {}
|
||||
|
||||
// request makes http request
|
||||
// if token is null
|
||||
dynamic request(
|
||||
String path,
|
||||
method, {
|
||||
dynamic payload,
|
||||
String token,
|
||||
String url,
|
||||
}) async {
|
||||
return await requestAPI(path, method,
|
||||
payload: payload, token: token, url: url);
|
||||
}
|
||||
}
|
||||
45
lib/pages/main/model/language_model.dart
Normal file
45
lib/pages/main/model/language_model.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
import 'package:fcs/localization/transalation.dart';
|
||||
import 'package:fcs/helpers/shared_pref.dart';
|
||||
import 'package:flutter/painting.dart';
|
||||
|
||||
import 'base_model.dart';
|
||||
|
||||
class LanguageModel extends BaseModel {
|
||||
String language;
|
||||
bool get isEng => this.language == "English";
|
||||
List<bool> get currentState => isEng ? [true, false] : [false, true];
|
||||
|
||||
static final List<String> languageCodesList =
|
||||
Translation().supportedLanguagesCodes;
|
||||
static final List<String> languagesList = Translation().supportedLanguages;
|
||||
|
||||
final Map<dynamic, dynamic> languagesMap = {
|
||||
languagesList[0]: languageCodesList[0],
|
||||
languagesList[1]: languageCodesList[1],
|
||||
};
|
||||
LanguageModel() {
|
||||
load();
|
||||
}
|
||||
@override
|
||||
logout() async {}
|
||||
|
||||
Future<String> load() async {
|
||||
var data = await SharedPref.getLang();
|
||||
String result = languagesList[1]; // defalut to english
|
||||
if (data != null) {
|
||||
result = data;
|
||||
}
|
||||
this.language = result;
|
||||
Translation().onLocaleChanged(Locale(languagesMap[this.language]));
|
||||
notifyListeners();
|
||||
return result;
|
||||
}
|
||||
|
||||
void saveLanguage(String language) async {
|
||||
Translation().onLocaleChanged(Locale(languagesMap[language]));
|
||||
|
||||
SharedPref.saveLang(language);
|
||||
this.language = language;
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
169
lib/pages/main/model/main_model.dart
Normal file
169
lib/pages/main/model/main_model.dart
Normal file
@@ -0,0 +1,169 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fcs/data/services/services.dart';
|
||||
import 'package:fcs/domain/entities/auth_result.dart';
|
||||
import 'package:fcs/domain/entities/setting.dart';
|
||||
import 'package:fcs/domain/entities/user.dart';
|
||||
import 'package:fcs/helpers/network_connectivity.dart';
|
||||
import 'package:fcs/helpers/shared_pref.dart';
|
||||
import 'package:fcs/pages/main/model/base_model.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');
|
||||
List<BaseModel> models = [];
|
||||
|
||||
String messagingToken;
|
||||
User user;
|
||||
PackageInfo packageInfo;
|
||||
|
||||
set setMessaginToken(token) {
|
||||
this.messagingToken = token;
|
||||
uploadMsgToken();
|
||||
}
|
||||
|
||||
Setting setting;
|
||||
|
||||
bool isLoaded = false;
|
||||
bool isOnline = false;
|
||||
bool isFirstLaunch = false;
|
||||
|
||||
MainModel() {
|
||||
NetworkConnectivity.instance.statusStream.listen((data) {
|
||||
bool _isOnline = data["isOnline"];
|
||||
if (_isOnline && !this.isOnline) {
|
||||
_init();
|
||||
}
|
||||
this.isOnline = _isOnline;
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
|
||||
bool faqEditable() {
|
||||
return this.user != null && this.user.hasSupport();
|
||||
}
|
||||
|
||||
bool paymentMethodsEditable() {
|
||||
return this.user != null && this.user.hasSupport();
|
||||
}
|
||||
|
||||
bool termEditable() {
|
||||
return this.user != null && this.user.hasSupport();
|
||||
}
|
||||
|
||||
bool contactEditable() {
|
||||
return this.user != null && this.user.hasSupport();
|
||||
}
|
||||
|
||||
bool isLogin() {
|
||||
return this.user != null;
|
||||
}
|
||||
|
||||
bool isCustomer() {
|
||||
return user != null && user.isCustomer();
|
||||
}
|
||||
|
||||
bool isSysAdmin() {
|
||||
return this.user != null && this.user.hasSysAdmin();
|
||||
}
|
||||
|
||||
bool isAdmin() {
|
||||
return this.user != null && this.user.hasAdmin();
|
||||
}
|
||||
|
||||
// userListener should never be closed
|
||||
StreamSubscription<User> userListener;
|
||||
_init() async {
|
||||
await _listenSetting();
|
||||
this.isFirstLaunch = await SharedPref.isFirstLaunch();
|
||||
this.isFirstLaunch = this.isFirstLaunch ?? true;
|
||||
this.packageInfo = await PackageInfo.fromPlatform();
|
||||
|
||||
if (userListener != null) userListener.cancel();
|
||||
userListener =
|
||||
Services.instance.authService.getUserStream().listen((_user) {
|
||||
if (_user != null) {
|
||||
models.forEach((m) => m.initUser(_user));
|
||||
// call diffPrivileges if privilege changed or first time login
|
||||
if (this.user == null || _user.diffPrivileges(this.user)) {
|
||||
models.forEach((m) => m.privilegeChanged());
|
||||
}
|
||||
if (this.user == null) {
|
||||
uploadMsgToken();
|
||||
}
|
||||
} else {
|
||||
if (this.user != null) {
|
||||
models.forEach((m) => m.logout());
|
||||
}
|
||||
}
|
||||
this.user = _user;
|
||||
isLoaded = true;
|
||||
notifyListeners();
|
||||
});
|
||||
}
|
||||
|
||||
void addModel(BaseModel model) {
|
||||
models.add(model);
|
||||
}
|
||||
|
||||
Future<void> _listenSetting() async {
|
||||
try {
|
||||
Services.instance.authService.getSetting().listen((event) {
|
||||
this.setting = event;
|
||||
models.forEach((m) => m.initSetting(setting));
|
||||
notifyListeners();
|
||||
});
|
||||
} finally {}
|
||||
}
|
||||
|
||||
bool isSupport() {
|
||||
if (packageInfo == null || setting == null) return false;
|
||||
return int.parse(packageInfo.buildNumber) >= setting.supportBuildNum;
|
||||
}
|
||||
|
||||
Future<AuthResult> sendSms(String phoneNumber) {
|
||||
return Services.instance.authService.sendSmsCodeToPhoneNumber(phoneNumber);
|
||||
}
|
||||
|
||||
Future<AuthResult> signin(String smsCode) async {
|
||||
AuthResult authResult =
|
||||
await Services.instance.authService.signInWithSmsCode(smsCode);
|
||||
return authResult;
|
||||
}
|
||||
|
||||
Future<void> uploadMsgToken() {
|
||||
if (messagingToken == null || user == null) return null;
|
||||
return Services.instance.userService.uploadMsgToken(messagingToken);
|
||||
}
|
||||
|
||||
Future<void> removeMsgToken() {
|
||||
if (messagingToken == null || user == null) return null;
|
||||
return Services.instance.userService.removeMsgToken(messagingToken);
|
||||
}
|
||||
|
||||
Future<void> signout() async {
|
||||
await removeMsgToken();
|
||||
await Services.instance.authService.signout();
|
||||
models.forEach((m) => m.logout());
|
||||
}
|
||||
|
||||
Future<bool> hasInvite() async {
|
||||
return Services.instance.authService.hasInvite();
|
||||
}
|
||||
|
||||
Future<void> signup(String userName) async {
|
||||
await Services.instance.authService.signup(userName);
|
||||
}
|
||||
|
||||
Future<void> joinInvite(String userName) async {
|
||||
await Services.instance.authService.joinInvite(userName);
|
||||
notifyListeners();
|
||||
}
|
||||
|
||||
Future<void> updateProfile(String newUserName) async {
|
||||
await Services.instance.authService.updateProfile(newUserName);
|
||||
notifyListeners();
|
||||
}
|
||||
}
|
||||
101
lib/pages/main/splash_page.dart
Normal file
101
lib/pages/main/splash_page.dart
Normal file
@@ -0,0 +1,101 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:fcs/pages/main/model/main_model.dart';
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
class SplashScreen extends StatefulWidget {
|
||||
@override
|
||||
_SplashScreenState createState() => new _SplashScreenState();
|
||||
}
|
||||
|
||||
class _SplashScreenState extends State<SplashScreen> {
|
||||
final log = Logger('_SplashScreenState');
|
||||
String page = "/language_selection";
|
||||
bool _loaded = false;
|
||||
bool _isSupport = false;
|
||||
bool _isOnline = true;
|
||||
Timer timer;
|
||||
|
||||
startTime() async {
|
||||
var _duration = new Duration(milliseconds: 3000);
|
||||
this.timer = new Timer.periodic(_duration, navigationPage);
|
||||
}
|
||||
|
||||
void navigationPage(Timer timer) async {
|
||||
if (_loaded && _isOnline && _isSupport) {
|
||||
timer.cancel();
|
||||
Navigator.of(context).pushReplacementNamed(page);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
startTime();
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
if (timer.isActive) timer.cancel();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
MainModel mainModel = Provider.of<MainModel>(context);
|
||||
|
||||
this._isSupport = mainModel.isSupport();
|
||||
this._isOnline = mainModel.isOnline;
|
||||
if (mainModel.isLoaded) {
|
||||
if (mainModel.isFirstLaunch) {
|
||||
page = "/language_selection";
|
||||
} else if (mainModel.isLogin()) {
|
||||
page = "/home";
|
||||
} else {
|
||||
page = "/welcome";
|
||||
}
|
||||
this._loaded = mainModel.isLoaded;
|
||||
}
|
||||
|
||||
return new Scaffold(
|
||||
backgroundColor: Colors.white,
|
||||
body: new Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
new Image.asset(
|
||||
"assets/logo.jpg",
|
||||
width: 180,
|
||||
),
|
||||
SizedBox(height: 50),
|
||||
Column(
|
||||
children: <Widget>[
|
||||
Text(
|
||||
"FCS Logistics",
|
||||
style: welcomeSubLabelStyle,
|
||||
),
|
||||
],
|
||||
),
|
||||
SizedBox(height: 30),
|
||||
_loaded && !_isOnline
|
||||
? Column(
|
||||
children: <Widget>[
|
||||
LocalText(context, "offline.status"),
|
||||
],
|
||||
)
|
||||
: Container(),
|
||||
Text(
|
||||
_loaded && !_isSupport
|
||||
? "Version outdated, please update your app!"
|
||||
: "",
|
||||
style: TextStyle(
|
||||
color: primaryColor, fontWeight: FontWeight.bold)),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
452
lib/pages/main/util.dart
Normal file
452
lib/pages/main/util.dart
Normal file
@@ -0,0 +1,452 @@
|
||||
import 'package:fcs/helpers/theme.dart';
|
||||
import 'package:fcs/localization/app_translations.dart';
|
||||
import 'package:fcs/pages/main/model/language_model.dart';
|
||||
import 'package:fcs/pages/widgets/local_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
import '../widgets/label_widgets.dart';
|
||||
|
||||
final log = Logger('Util');
|
||||
|
||||
Future showMsgDialog(BuildContext context, String title, String msg) {
|
||||
return showDialog(
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return AlertDialog(
|
||||
title: new Text(title),
|
||||
content: new Text(msg),
|
||||
actions: <Widget>[
|
||||
new FlatButton(
|
||||
child: new Text("Close"),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> showConfirmDialog(
|
||||
BuildContext context, String translationKey, ok(),
|
||||
{List<String> translationVariables}) async {
|
||||
await showDialog(
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return AlertDialog(
|
||||
title: Center(
|
||||
child: LocalText(
|
||||
context,
|
||||
translationKey,
|
||||
translationVariables: translationVariables,
|
||||
color: primaryColor,
|
||||
),
|
||||
),
|
||||
content: Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
FlatButton(
|
||||
color: Colors.grey[300],
|
||||
child: Text(
|
||||
AppTranslations.of(context).text('Cancel'),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle()
|
||||
: TextStyle(fontFamily: 'Myanmar3'),
|
||||
),
|
||||
onPressed: () {
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
SizedBox(
|
||||
width: 0,
|
||||
),
|
||||
FlatButton(
|
||||
color: primaryColor,
|
||||
child: Text(AppTranslations.of(context).text('Ok'),
|
||||
style: Provider.of<LanguageModel>(context).isEng
|
||||
? TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold)
|
||||
: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: 'Myanmar3')),
|
||||
onPressed: () async {
|
||||
Navigator.of(context).pop();
|
||||
await ok();
|
||||
})
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
void showCommentDialog(BuildContext context, commentCallback(comment)) {
|
||||
TextEditingController _comment = new TextEditingController();
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (_) {
|
||||
return AlertDialog(
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.all(Radius.circular(32.0))),
|
||||
content: Container(
|
||||
width: 300.0,
|
||||
height: 80.0,
|
||||
child: Container(
|
||||
child: TextFormField(
|
||||
controller: _comment,
|
||||
autofocus: false,
|
||||
cursorColor: primaryColor,
|
||||
maxLines: 3,
|
||||
style: textStyle,
|
||||
decoration: new InputDecoration(
|
||||
labelText: "Comment",
|
||||
labelStyle: labelStyle,
|
||||
icon: Icon(
|
||||
Icons.add_comment,
|
||||
color: primaryColor,
|
||||
),
|
||||
enabledBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: primaryColor, width: 1.0)),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: primaryColor, width: 1.0)),
|
||||
),
|
||||
validator: (value) {
|
||||
if (value.isEmpty) {
|
||||
return "Please enter comment";
|
||||
}
|
||||
return null;
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
actions: <Widget>[
|
||||
FlatButton(
|
||||
child: Text(
|
||||
"Cancel",
|
||||
style: labelStyle,
|
||||
),
|
||||
onPressed: () {
|
||||
_comment.clear();
|
||||
Navigator.of(context).pop();
|
||||
}),
|
||||
FlatButton(
|
||||
color: primaryColor,
|
||||
child: Text("Submit",
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontWeight: FontWeight.bold)),
|
||||
onPressed: () {
|
||||
commentCallback(_comment.text);
|
||||
Navigator.of(context).pop();
|
||||
})
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Widget getStatus(String status) {
|
||||
return status == "Delivered"
|
||||
? Text(status,
|
||||
style: TextStyle(
|
||||
color: primaryColor, fontSize: 18, fontWeight: FontWeight.bold))
|
||||
: status == "rejected"
|
||||
? Chip(
|
||||
backgroundColor: Colors.red,
|
||||
avatar: Icon(
|
||||
Icons.remove,
|
||||
color: Colors.white,
|
||||
size: 14,
|
||||
),
|
||||
label: Text(
|
||||
status,
|
||||
style: TextStyle(color: Colors.white, fontSize: 12),
|
||||
))
|
||||
: status == "In progress"
|
||||
? Text(
|
||||
status,
|
||||
style: TextStyle(color: Colors.white, fontSize: 12),
|
||||
)
|
||||
: status == "Pickuped"
|
||||
? Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
: status == "Pending" || status == "Rescheduled"
|
||||
? Row(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.schedule),
|
||||
),
|
||||
Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
],
|
||||
)
|
||||
: status == "Assigned"
|
||||
? Row(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.check),
|
||||
),
|
||||
Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
],
|
||||
)
|
||||
: status == "Canceled"
|
||||
? Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
)
|
||||
: status == "Delivered" || status == "Avaliable"
|
||||
? Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: Colors.green, fontSize: 18),
|
||||
)
|
||||
: status == "Used"
|
||||
? Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: Colors.red, fontSize: 18),
|
||||
)
|
||||
: status == "Paid"
|
||||
? Row(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(8.0),
|
||||
child: Icon(Icons.check),
|
||||
),
|
||||
Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight:
|
||||
FontWeight.bold),
|
||||
)
|
||||
],
|
||||
)
|
||||
: Text(
|
||||
status,
|
||||
style: TextStyle(
|
||||
color: primaryColor,
|
||||
fontSize: 18,
|
||||
fontWeight: FontWeight.bold),
|
||||
);
|
||||
}
|
||||
|
||||
call(BuildContext context, String phone) {
|
||||
showConfirmDialog(context, "contact.phone.confim", () => launch("tel:$phone"),
|
||||
translationVariables: ["$phone"]);
|
||||
}
|
||||
|
||||
Widget nameWidget(String name) {
|
||||
return Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.only(left: 10.0, top: 8),
|
||||
child: Text(
|
||||
name,
|
||||
style: TextStyle(
|
||||
color: Colors.black87, fontSize: 18, fontWeight: FontWeight.bold),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget phoneWidget(BuildContext context, String phone) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 10),
|
||||
child: Row(
|
||||
children: <Widget>[
|
||||
Icon(Icons.phone),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: labeledText(context, phone, "user.phone"),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget fcsInput(String label, IconData iconData,
|
||||
{TextEditingController controller,
|
||||
String value,
|
||||
bool autoFocus = false,
|
||||
TextInputType textInputType}) {
|
||||
return TextFormField(
|
||||
initialValue: value,
|
||||
controller: controller,
|
||||
cursorColor: primaryColor,
|
||||
maxLines: null,
|
||||
minLines: 1,
|
||||
autofocus: autoFocus,
|
||||
keyboardType: textInputType,
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
labelText: label,
|
||||
labelStyle: TextStyle(fontSize: 16, color: Colors.grey),
|
||||
filled: true,
|
||||
icon: Icon(
|
||||
iconData,
|
||||
color: primaryColor,
|
||||
),
|
||||
focusedBorder: UnderlineInputBorder(
|
||||
borderSide: BorderSide(color: Colors.grey, width: 1.0)),
|
||||
));
|
||||
}
|
||||
|
||||
Widget fcsInputReadOnly(String label, IconData iconData,
|
||||
{TextEditingController controller, String value}) {
|
||||
return TextFormField(
|
||||
initialValue: value,
|
||||
controller: controller,
|
||||
cursorColor: primaryColor,
|
||||
maxLines: null,
|
||||
minLines: 1,
|
||||
readOnly: true,
|
||||
decoration: InputDecoration(
|
||||
fillColor: Colors.white,
|
||||
border: InputBorder.none,
|
||||
labelText: label,
|
||||
labelStyle: TextStyle(fontSize: 16, color: Colors.grey),
|
||||
filled: true,
|
||||
icon: Icon(
|
||||
iconData,
|
||||
color: primaryColor,
|
||||
),
|
||||
));
|
||||
}
|
||||
|
||||
Widget fcsDropDown(String label, IconData iconData,
|
||||
{TextEditingController controller}) {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(right: 8.0),
|
||||
child: Icon(iconData),
|
||||
),
|
||||
Expanded(
|
||||
child: Container(
|
||||
height: 50.0,
|
||||
child: Row(children: <Widget>[
|
||||
Expanded(child: _dropDown()),
|
||||
]),
|
||||
)),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _dropDown() {
|
||||
return DropdownButton<String>(
|
||||
value: "Ko Nge",
|
||||
icon: Icon(Icons.arrow_downward),
|
||||
iconSize: 24,
|
||||
elevation: 16,
|
||||
// style: TextStyle(color: Colors.deepPurple),
|
||||
underline: Container(
|
||||
height: 2,
|
||||
color: primaryColor,
|
||||
),
|
||||
onChanged: (String newValue) {},
|
||||
items: <String>['Ko Nge', 'Two', 'Free', 'Four']
|
||||
.map<DropdownMenuItem<String>>((String value) {
|
||||
return DropdownMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
);
|
||||
}).toList(),
|
||||
);
|
||||
}
|
||||
|
||||
Widget fcsButton(BuildContext context, String text,
|
||||
{Function callack, IconData iconData}) {
|
||||
var languageModel = Provider.of<LanguageModel>(context);
|
||||
|
||||
var style = languageModel.isEng
|
||||
? TextStyle(
|
||||
fontSize: 16.0, color: Colors.white, fontWeight: FontWeight.bold)
|
||||
: TextStyle(
|
||||
fontSize: 16.0,
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontFamily: "Myanmar3");
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 10, right: 10, top: 10),
|
||||
child: Container(
|
||||
height: 45.0,
|
||||
decoration: BoxDecoration(
|
||||
color: primaryColor,
|
||||
shape: BoxShape.rectangle,
|
||||
),
|
||||
child: ButtonTheme(
|
||||
minWidth: 900.0,
|
||||
height: 100.0,
|
||||
child: FlatButton(
|
||||
onPressed: callack,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
iconData == null
|
||||
? Container()
|
||||
: Icon(
|
||||
iconData,
|
||||
color: Colors.white,
|
||||
),
|
||||
SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
Text(text, style: style),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
String getLocalString(BuildContext context, String key) {
|
||||
return AppTranslations.of(context).text(key);
|
||||
}
|
||||
|
||||
void showToast(GlobalKey key, String text) {
|
||||
final ScaffoldState scaffold = key.currentState;
|
||||
scaffold.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(text),
|
||||
backgroundColor: secondaryColor,
|
||||
duration: Duration(seconds: 1),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
bool hasUnicode(String text) {
|
||||
final int maxBits = 128;
|
||||
List<int> unicodeSymbols =
|
||||
text.codeUnits.where((ch) => ch > maxBits).toList();
|
||||
return unicodeSymbols.length > 0;
|
||||
}
|
||||
156
lib/pages/main/welcome_page.dart
Normal file
156
lib/pages/main/welcome_page.dart
Normal file
@@ -0,0 +1,156 @@
|
||||
import 'package:fcs/localization/transalation.dart';
|
||||
import 'package:fcs/pages/main/model/language_model.dart';
|
||||
import 'package:fcs/pages/main/util.dart';
|
||||
import 'package:fcs/pages/widgets/bottom_widgets.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:logging/logging.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../../helpers/theme.dart';
|
||||
import '../signin/signin_page.dart';
|
||||
import '../widgets/banner.dart';
|
||||
import '../widgets/bottom_up_page_route.dart';
|
||||
import '../widgets/offline_redirect.dart';
|
||||
|
||||
final msgLog = Logger('backgroundMessageHandler');
|
||||
|
||||
class WelcomePage extends StatefulWidget {
|
||||
@override
|
||||
_WelcomePageState createState() => _WelcomePageState();
|
||||
}
|
||||
|
||||
typedef BtnCallback();
|
||||
|
||||
class _WelcomePageState extends State<WelcomePage> {
|
||||
final log = Logger('_HomePageWelcomeState');
|
||||
|
||||
String pin;
|
||||
List<bool> isSelected = [true, false];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadLang();
|
||||
}
|
||||
|
||||
void _loadLang() {
|
||||
isSelected =
|
||||
Provider.of<LanguageModel>(context, listen: false).currentState;
|
||||
}
|
||||
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return OfflineRedirect(
|
||||
child: FlavorBanner(
|
||||
child: Scaffold(
|
||||
body: Container(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment
|
||||
.bottomCenter, // 10% of the width, so there are ten blinds.
|
||||
colors: [
|
||||
Color(0xd0272262),
|
||||
Color(0xfa272262),
|
||||
], // whitish to gray
|
||||
)),
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
children: [
|
||||
ToggleButtons(
|
||||
children: <Widget>[
|
||||
Image.asset(
|
||||
'icons/flags/png/us.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
),
|
||||
Image.asset(
|
||||
'icons/flags/png/mm.png',
|
||||
package: 'country_icons',
|
||||
fit: BoxFit.fitWidth,
|
||||
width: 25,
|
||||
)
|
||||
],
|
||||
selectedBorderColor: Colors.white12,
|
||||
borderColor: Colors.transparent,
|
||||
onPressed: _langChange,
|
||||
isSelected: isSelected,
|
||||
),
|
||||
FlatButton(
|
||||
onPressed: () {
|
||||
Navigator.of(context)
|
||||
.push(BottomUpPageRoute(SigninPage()));
|
||||
},
|
||||
child: Text(
|
||||
getLocalString(context, "welcome.signin"),
|
||||
style: siginButtonStyle,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
Expanded(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: Center(
|
||||
child: Text(
|
||||
getLocalString(context, "welcome.msg"),
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 18,
|
||||
fontFamily: "Roboto"),
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.only(top: 0),
|
||||
child: CircleAvatar(
|
||||
radius: (25),
|
||||
backgroundColor: Colors.white,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(50),
|
||||
child: Image.asset("assets/logo.jpg"),
|
||||
)),
|
||||
),
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(bottom: 10.0, top: 5),
|
||||
child: Text(
|
||||
"by FCS Logistics",
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 11,
|
||||
fontFamily: "Roboto"),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
BottomWidgets(),
|
||||
],
|
||||
))),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
_langChange(index) {
|
||||
var languageModel = Provider.of<LanguageModel>(context, listen: false);
|
||||
languageModel.saveLanguage(Translation().supportedLanguages[index]);
|
||||
setState(() {
|
||||
isSelected.asMap().forEach((i, e) {
|
||||
isSelected[i] = false;
|
||||
});
|
||||
isSelected[index] = !isSelected[index];
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user