backup.
This commit is contained in:
8
lib/constants.dart
Normal file
8
lib/constants.dart
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
class Constants {
|
||||
static const bool DEBUG = false;
|
||||
static const BASE_API_URL = 'https://api.minipos.us/';
|
||||
static const String API_SECRET = 'pei326sami1223HellowWorldabcdEd';
|
||||
static const KEY_USER_ID = 'user_id';
|
||||
static const KEY_ACCESS_TOKEN = 'access_token';
|
||||
}
|
||||
4
lib/events/eventbus.dart
Normal file
4
lib/events/eventbus.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
import 'package:event_bus/event_bus.dart';
|
||||
|
||||
final eventBus = new EventBus();
|
||||
4
lib/events/events.dart
Normal file
4
lib/events/events.dart
Normal file
@@ -0,0 +1,4 @@
|
||||
|
||||
class OpenDrawer {
|
||||
|
||||
}
|
||||
@@ -16,16 +16,20 @@ import 'package:intl/message_lookup_by_library.dart';
|
||||
import 'package:intl/src/intl_helpers.dart';
|
||||
|
||||
import 'messages_en.dart' as messages_en;
|
||||
import 'messages_zh_CN.dart' as messages_zh_cn;
|
||||
|
||||
typedef Future<dynamic> LibraryLoader();
|
||||
Map<String, LibraryLoader> _deferredLibraries = {
|
||||
'en': () => new Future.value(null),
|
||||
'zh_CN': () => new Future.value(null),
|
||||
};
|
||||
|
||||
MessageLookupByLibrary _findExact(String localeName) {
|
||||
switch (localeName) {
|
||||
case 'en':
|
||||
return messages_en.messages;
|
||||
case 'zh_CN':
|
||||
return messages_zh_cn.messages;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,35 @@ class MessageLookup extends MessageLookupByLibrary {
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
|
||||
"about" : MessageLookupByLibrary.simpleMessage("About"),
|
||||
"about_us" : MessageLookupByLibrary.simpleMessage("About us"),
|
||||
"blog" : MessageLookupByLibrary.simpleMessage("Blog"),
|
||||
"contact_us" : MessageLookupByLibrary.simpleMessage("Contact us"),
|
||||
"developer_of" : MessageLookupByLibrary.simpleMessage("Developers of"),
|
||||
"download" : MessageLookupByLibrary.simpleMessage("Download"),
|
||||
"home" : MessageLookupByLibrary.simpleMessage("Home"),
|
||||
"information" : MessageLookupByLibrary.simpleMessage("Information"),
|
||||
"learn_more" : MessageLookupByLibrary.simpleMessage("Learn more..."),
|
||||
"license_agreement" : MessageLookupByLibrary.simpleMessage("License agreement"),
|
||||
"loading_please_wait" : MessageLookupByLibrary.simpleMessage("Loading, please wait..."),
|
||||
"login" : MessageLookupByLibrary.simpleMessage("Login"),
|
||||
"logout" : MessageLookupByLibrary.simpleMessage("Logout"),
|
||||
"main_content_1" : MessageLookupByLibrary.simpleMessage("Since 1999, we have been committed to developing a complete and powerful sales system, helping thousands of small businesses handle sales smoothly. Currently we have two main products."),
|
||||
"minipos" : MessageLookupByLibrary.simpleMessage("MiniPOS"),
|
||||
"navigation" : MessageLookupByLibrary.simpleMessage("Navigation"),
|
||||
"point_of_sale_system_solution" : MessageLookupByLibrary.simpleMessage("Point of sale system solution"),
|
||||
"privacy_policy" : MessageLookupByLibrary.simpleMessage("Privacy policy"),
|
||||
"recalculating" : MessageLookupByLibrary.simpleMessage("Recalculating..."),
|
||||
"renew_license" : MessageLookupByLibrary.simpleMessage("Renew license"),
|
||||
"return_policy" : MessageLookupByLibrary.simpleMessage("Return policy"),
|
||||
"service_policy" : MessageLookupByLibrary.simpleMessage("Service policy"),
|
||||
"shop" : MessageLookupByLibrary.simpleMessage("Shop"),
|
||||
"submitting" : MessageLookupByLibrary.simpleMessage("Submitting..."),
|
||||
"submitting_please_wait" : MessageLookupByLibrary.simpleMessage("Submitting, please wait..."),
|
||||
"support" : MessageLookupByLibrary.simpleMessage("Support"),
|
||||
"support_ticket" : MessageLookupByLibrary.simpleMessage("Support ticket"),
|
||||
"tap_back_again_to_exit" : MessageLookupByLibrary.simpleMessage("Tap back again to exit"),
|
||||
"tutorials" : MessageLookupByLibrary.simpleMessage("Tutorials"),
|
||||
"wiki" : MessageLookupByLibrary.simpleMessage("Wiki")
|
||||
};
|
||||
}
|
||||
|
||||
55
lib/generated/intl/messages_zh_CN.dart
Normal file
55
lib/generated/intl/messages_zh_CN.dart
Normal file
@@ -0,0 +1,55 @@
|
||||
// DO NOT EDIT. This is code generated via package:intl/generate_localized.dart
|
||||
// This is a library that provides messages for a zh_CN locale. All the
|
||||
// messages from the main program should be duplicated here with the same
|
||||
// function name.
|
||||
|
||||
// Ignore issues from commonly used lints in this file.
|
||||
// ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new
|
||||
// ignore_for_file:prefer_single_quotes,comment_references, directives_ordering
|
||||
// ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases
|
||||
// ignore_for_file:unused_import, file_names
|
||||
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:intl/message_lookup_by_library.dart';
|
||||
|
||||
final messages = new MessageLookup();
|
||||
|
||||
typedef String MessageIfAbsent(String messageStr, List<dynamic> args);
|
||||
|
||||
class MessageLookup extends MessageLookupByLibrary {
|
||||
String get localeName => 'zh_CN';
|
||||
|
||||
final messages = _notInlinedMessages(_notInlinedMessages);
|
||||
static _notInlinedMessages(_) => <String, Function> {
|
||||
"about" : MessageLookupByLibrary.simpleMessage("关于"),
|
||||
"about_us" : MessageLookupByLibrary.simpleMessage("关于我们"),
|
||||
"blog" : MessageLookupByLibrary.simpleMessage("博客"),
|
||||
"contact_us" : MessageLookupByLibrary.simpleMessage("联系我们"),
|
||||
"developer_of" : MessageLookupByLibrary.simpleMessage("开发者"),
|
||||
"download" : MessageLookupByLibrary.simpleMessage("下载"),
|
||||
"home" : MessageLookupByLibrary.simpleMessage("首页"),
|
||||
"information" : MessageLookupByLibrary.simpleMessage("信息"),
|
||||
"learn_more" : MessageLookupByLibrary.simpleMessage("了解更多..."),
|
||||
"license_agreement" : MessageLookupByLibrary.simpleMessage("许可协议"),
|
||||
"loading_please_wait" : MessageLookupByLibrary.simpleMessage("装载中,清稍候..."),
|
||||
"login" : MessageLookupByLibrary.simpleMessage("登入"),
|
||||
"logout" : MessageLookupByLibrary.simpleMessage("登出"),
|
||||
"main_content_1" : MessageLookupByLibrary.simpleMessage("自从1999年来,我们一直致力于开发完整的强大的销售系统,帮助了上千小企业平滑的处理销售业务。当前我们有两个主要的产品。"),
|
||||
"minipos" : MessageLookupByLibrary.simpleMessage("MiniPOS"),
|
||||
"navigation" : MessageLookupByLibrary.simpleMessage("导航"),
|
||||
"point_of_sale_system_solution" : MessageLookupByLibrary.simpleMessage("收款系统方案"),
|
||||
"privacy_policy" : MessageLookupByLibrary.simpleMessage("私隐条款"),
|
||||
"recalculating" : MessageLookupByLibrary.simpleMessage("运算中..."),
|
||||
"renew_license" : MessageLookupByLibrary.simpleMessage("证书续期"),
|
||||
"return_policy" : MessageLookupByLibrary.simpleMessage("退货条款"),
|
||||
"service_policy" : MessageLookupByLibrary.simpleMessage("服务条款"),
|
||||
"shop" : MessageLookupByLibrary.simpleMessage("线上购买"),
|
||||
"submitting" : MessageLookupByLibrary.simpleMessage("提交中..."),
|
||||
"submitting_please_wait" : MessageLookupByLibrary.simpleMessage("提交中,清稍候..."),
|
||||
"support" : MessageLookupByLibrary.simpleMessage("技术支持"),
|
||||
"support_ticket" : MessageLookupByLibrary.simpleMessage("客户提问"),
|
||||
"tap_back_again_to_exit" : MessageLookupByLibrary.simpleMessage("再次点击返回退出"),
|
||||
"tutorials" : MessageLookupByLibrary.simpleMessage("教程"),
|
||||
"wiki" : MessageLookupByLibrary.simpleMessage("维基")
|
||||
};
|
||||
}
|
||||
@@ -35,7 +35,305 @@ class S {
|
||||
return Localizations.of<S>(context, S);
|
||||
}
|
||||
|
||||
/// `About`
|
||||
String get about {
|
||||
return Intl.message(
|
||||
'About',
|
||||
name: 'about',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Navigation`
|
||||
String get navigation {
|
||||
return Intl.message(
|
||||
'Navigation',
|
||||
name: 'navigation',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Submitting...`
|
||||
String get submitting {
|
||||
return Intl.message(
|
||||
'Submitting...',
|
||||
name: 'submitting',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Submitting, please wait...`
|
||||
String get submitting_please_wait {
|
||||
return Intl.message(
|
||||
'Submitting, please wait...',
|
||||
name: 'submitting_please_wait',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Recalculating...`
|
||||
String get recalculating {
|
||||
return Intl.message(
|
||||
'Recalculating...',
|
||||
name: 'recalculating',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Loading, please wait...`
|
||||
String get loading_please_wait {
|
||||
return Intl.message(
|
||||
'Loading, please wait...',
|
||||
name: 'loading_please_wait',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Tap back again to exit`
|
||||
String get tap_back_again_to_exit {
|
||||
return Intl.message(
|
||||
'Tap back again to exit',
|
||||
name: 'tap_back_again_to_exit',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Since 1999, we have been committed to developing a complete and powerful sales system, helping thousands of small businesses handle sales smoothly. Currently we have two main products.`
|
||||
String get main_content_1 {
|
||||
return Intl.message(
|
||||
'Since 1999, we have been committed to developing a complete and powerful sales system, helping thousands of small businesses handle sales smoothly. Currently we have two main products.',
|
||||
name: 'main_content_1',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `MiniPOS`
|
||||
String get minipos {
|
||||
return Intl.message(
|
||||
'MiniPOS',
|
||||
name: 'minipos',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Point of sale system solution`
|
||||
String get point_of_sale_system_solution {
|
||||
return Intl.message(
|
||||
'Point of sale system solution',
|
||||
name: 'point_of_sale_system_solution',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Learn more...`
|
||||
String get learn_more {
|
||||
return Intl.message(
|
||||
'Learn more...',
|
||||
name: 'learn_more',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Information`
|
||||
String get information {
|
||||
return Intl.message(
|
||||
'Information',
|
||||
name: 'information',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Service policy`
|
||||
String get service_policy {
|
||||
return Intl.message(
|
||||
'Service policy',
|
||||
name: 'service_policy',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Return policy`
|
||||
String get return_policy {
|
||||
return Intl.message(
|
||||
'Return policy',
|
||||
name: 'return_policy',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Privacy policy`
|
||||
String get privacy_policy {
|
||||
return Intl.message(
|
||||
'Privacy policy',
|
||||
name: 'privacy_policy',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `License agreement`
|
||||
String get license_agreement {
|
||||
return Intl.message(
|
||||
'License agreement',
|
||||
name: 'license_agreement',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Support`
|
||||
String get support {
|
||||
return Intl.message(
|
||||
'Support',
|
||||
name: 'support',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Wiki`
|
||||
String get wiki {
|
||||
return Intl.message(
|
||||
'Wiki',
|
||||
name: 'wiki',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Support ticket`
|
||||
String get support_ticket {
|
||||
return Intl.message(
|
||||
'Support ticket',
|
||||
name: 'support_ticket',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Contact us`
|
||||
String get contact_us {
|
||||
return Intl.message(
|
||||
'Contact us',
|
||||
name: 'contact_us',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `About us`
|
||||
String get about_us {
|
||||
return Intl.message(
|
||||
'About us',
|
||||
name: 'about_us',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Renew license`
|
||||
String get renew_license {
|
||||
return Intl.message(
|
||||
'Renew license',
|
||||
name: 'renew_license',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Developers of`
|
||||
String get developer_of {
|
||||
return Intl.message(
|
||||
'Developers of',
|
||||
name: 'developer_of',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Home`
|
||||
String get home {
|
||||
return Intl.message(
|
||||
'Home',
|
||||
name: 'home',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Download`
|
||||
String get download {
|
||||
return Intl.message(
|
||||
'Download',
|
||||
name: 'download',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Tutorials`
|
||||
String get tutorials {
|
||||
return Intl.message(
|
||||
'Tutorials',
|
||||
name: 'tutorials',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Shop`
|
||||
String get shop {
|
||||
return Intl.message(
|
||||
'Shop',
|
||||
name: 'shop',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Blog`
|
||||
String get blog {
|
||||
return Intl.message(
|
||||
'Blog',
|
||||
name: 'blog',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Login`
|
||||
String get login {
|
||||
return Intl.message(
|
||||
'Login',
|
||||
name: 'login',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Logout`
|
||||
String get logout {
|
||||
return Intl.message(
|
||||
'Logout',
|
||||
name: 'logout',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||
@@ -44,6 +342,7 @@ class AppLocalizationDelegate extends LocalizationsDelegate<S> {
|
||||
List<Locale> get supportedLocales {
|
||||
return const <Locale>[
|
||||
Locale.fromSubtags(languageCode: 'en'),
|
||||
Locale.fromSubtags(languageCode: 'zh', countryCode: 'CN'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,32 @@
|
||||
{}
|
||||
{
|
||||
"about": "About",
|
||||
"navigation": "Navigation",
|
||||
"submitting": "Submitting...",
|
||||
"submitting_please_wait": "Submitting, please wait...",
|
||||
"recalculating": "Recalculating...",
|
||||
"loading_please_wait": "Loading, please wait...",
|
||||
"tap_back_again_to_exit": "Tap back again to exit",
|
||||
"main_content_1": "Since 1999, we have been committed to developing a complete and powerful sales system, helping thousands of small businesses handle sales smoothly. Currently we have two main products.",
|
||||
"minipos": "MiniPOS",
|
||||
"point_of_sale_system_solution": "Point of sale system solution",
|
||||
"learn_more": "Learn more...",
|
||||
"information": "Information",
|
||||
"service_policy": "Service policy",
|
||||
"return_policy": "Return policy",
|
||||
"privacy_policy": "Privacy policy",
|
||||
"license_agreement": "License agreement",
|
||||
"support": "Support",
|
||||
"wiki": "Wiki",
|
||||
"support_ticket": "Support ticket",
|
||||
"contact_us": "Contact us",
|
||||
"about_us": "About us",
|
||||
"renew_license": "Renew license",
|
||||
"developer_of": "Developers of",
|
||||
"home": "Home",
|
||||
"download": "Download",
|
||||
"tutorials": "Tutorials",
|
||||
"shop": "Shop",
|
||||
"blog": "Blog",
|
||||
"login": "Login",
|
||||
"logout": "Logout"
|
||||
}
|
||||
32
lib/l10n/intl_zh_CN.arb
Normal file
32
lib/l10n/intl_zh_CN.arb
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"about": "关于",
|
||||
"navigation": "导航",
|
||||
"submitting": "提交中...",
|
||||
"submitting_please_wait": "提交中,清稍候...",
|
||||
"recalculating": "运算中...",
|
||||
"loading_please_wait": "装载中,清稍候...",
|
||||
"tap_back_again_to_exit": "再次点击返回退出",
|
||||
"main_content_1": "自从1999年来,我们一直致力于开发完整的强大的销售系统,帮助了上千小企业平滑的处理销售业务。当前我们有两个主要的产品。",
|
||||
"minipos": "MiniPOS",
|
||||
"point_of_sale_system_solution": "收款系统方案",
|
||||
"learn_more": "了解更多...",
|
||||
"information": "信息",
|
||||
"service_policy": "服务条款",
|
||||
"return_policy": "退货条款",
|
||||
"privacy_policy": "私隐条款",
|
||||
"license_agreement": "许可协议",
|
||||
"support": "技术支持",
|
||||
"wiki": "维基",
|
||||
"support_ticket": "客户提问",
|
||||
"contact_us": "联系我们",
|
||||
"about_us": "关于我们",
|
||||
"renew_license": "证书续期",
|
||||
"developer_of": "开发者",
|
||||
"home": "首页",
|
||||
"download": "下载",
|
||||
"tutorials": "教程",
|
||||
"shop": "线上购买",
|
||||
"blog": "博客",
|
||||
"login": "登入",
|
||||
"logout": "登出"
|
||||
}
|
||||
170
lib/main.dart
170
lib/main.dart
@@ -1,113 +1,87 @@
|
||||
import 'package:catcher/catcher.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_device_locale/flutter_device_locale.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:flutter_redux/flutter_redux.dart';
|
||||
import 'package:flutter_wisetronic/events/events.dart';
|
||||
import 'package:flutter_wisetronic/routes.dart';
|
||||
import 'package:flutter_wisetronic/store/actions.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/navigationbar.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/mobile_navigation_drawer.dart';
|
||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
import 'package:splashscreen/splashscreen.dart';
|
||||
|
||||
void main() {
|
||||
runApp(MyApp());
|
||||
import 'constants.dart';
|
||||
import 'events/eventbus.dart';
|
||||
import 'generated/l10n.dart';
|
||||
import 'pages/home.dart';
|
||||
import 'store/store.dart';
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
Locale locale = await DeviceLocale.getCurrentLocale();
|
||||
|
||||
runApp(MyApp(locale));
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
final Locale localLocate;
|
||||
|
||||
MyApp(this.localLocate) {
|
||||
Routes.configure();
|
||||
store.dispatch(UpdateLocale(localLocate));
|
||||
}
|
||||
|
||||
// This widget is the root of your application.
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
Widget _buildBody() {
|
||||
return SplashScreen(
|
||||
seconds: 5,
|
||||
routeName: '/',
|
||||
navigateAfterSeconds: Home(localLocate, title: 'Welcome',),
|
||||
styleTextUnderTheLoader: new TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 20.0,
|
||||
),
|
||||
// imageBackground: (Image.network(Constants.BASE_API_URL + 'gallery/get-wisetronic-slpash')).image,
|
||||
imageBackground: (new Image.network(Constants.BASE_API_URL + 'gallery/get-minimanager-splash/')).image,
|
||||
backgroundColor: Colors.white,
|
||||
onClick: () {
|
||||
|
||||
},
|
||||
loaderColor: Colors.blue,
|
||||
);
|
||||
}
|
||||
|
||||
return MaterialApp(
|
||||
title: 'Flutter Demo',
|
||||
debugShowCheckedModeBanner: Constants.DEBUG,
|
||||
navigatorKey: kIsWeb ? null : Catcher.navigatorKey,
|
||||
localizationsDelegates: [
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
RefreshLocalizations.delegate,
|
||||
S.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
localeResolutionCallback: (Locale locale, Iterable<Locale> supportedLocales) {
|
||||
print('Language code: ${localLocate.languageCode}');
|
||||
for (final supportedLocale in supportedLocales) {
|
||||
return supportedLocale;
|
||||
}
|
||||
return supportedLocales.first;
|
||||
},
|
||||
title: 'Wisetronic Inc.',
|
||||
theme: ThemeData(
|
||||
// This is the theme of your application.
|
||||
//
|
||||
// Try running your application with "flutter run". You'll see the
|
||||
// application has a blue toolbar. Then, without quitting the app, try
|
||||
// changing the primarySwatch below to Colors.green and then invoke
|
||||
// "hot reload" (press "r" in the console where you ran "flutter run",
|
||||
// or simply save your changes to "hot reload" in a Flutter IDE).
|
||||
// Notice that the counter didn't reset back to zero; the application
|
||||
// is not restarted.
|
||||
primarySwatch: Colors.blue,
|
||||
),
|
||||
home: MyHomePage(title: 'Flutter Demo Home Page'),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MyHomePage extends StatefulWidget {
|
||||
MyHomePage({Key key, this.title}) : super(key: key);
|
||||
|
||||
// This widget is the home page of your application. It is stateful, meaning
|
||||
// that it has a State object (defined below) that contains fields that affect
|
||||
// how it looks.
|
||||
|
||||
// This class is the configuration for the state. It holds the values (in this
|
||||
// case the title) provided by the parent (in this case the App widget) and
|
||||
// used by the build method of the State. Fields in a Widget subclass are
|
||||
// always marked "final".
|
||||
|
||||
final String title;
|
||||
|
||||
@override
|
||||
_MyHomePageState createState() => _MyHomePageState();
|
||||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
int _counter = 0;
|
||||
|
||||
void _incrementCounter() {
|
||||
setState(() {
|
||||
// This call to setState tells the Flutter framework that something has
|
||||
// changed in this State, which causes it to rerun the build method below
|
||||
// so that the display can reflect the updated values. If we changed
|
||||
// _counter without calling setState(), then the build method would not be
|
||||
// called again, and so nothing would appear to happen.
|
||||
_counter++;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
// This method is rerun every time setState is called, for instance as done
|
||||
// by the _incrementCounter method above.
|
||||
//
|
||||
// The Flutter framework has been optimized to make rerunning build methods
|
||||
// fast, so that you can just rebuild anything that needs updating rather
|
||||
// than having to individually change instances of widgets.
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
// Here we take the value from the MyHomePage object that was created by
|
||||
// the App.build method, and use it to set our appbar title.
|
||||
title: Text(widget.title),
|
||||
),
|
||||
body: Center(
|
||||
// Center is a layout widget. It takes a single child and positions it
|
||||
// in the middle of the parent.
|
||||
child: Column(
|
||||
// Column is also a layout widget. It takes a list of children and
|
||||
// arranges them vertically. By default, it sizes itself to fit its
|
||||
// children horizontally, and tries to be as tall as its parent.
|
||||
//
|
||||
// Invoke "debug painting" (press "p" in the console, choose the
|
||||
// "Toggle Debug Paint" action from the Flutter Inspector in Android
|
||||
// Studio, or the "Toggle Debug Paint" command in Visual Studio Code)
|
||||
// to see the wireframe for each widget.
|
||||
//
|
||||
// Column has various properties to control how it sizes itself and
|
||||
// how it positions its children. Here we use mainAxisAlignment to
|
||||
// center the children vertically; the main axis here is the vertical
|
||||
// axis because Columns are vertical (the cross axis would be
|
||||
// horizontal).
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Text(
|
||||
'You have pushed the button this many times:',
|
||||
),
|
||||
Text(
|
||||
'$_counter',
|
||||
style: Theme.of(context).textTheme.headline4,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
floatingActionButton: FloatingActionButton(
|
||||
onPressed: _incrementCounter,
|
||||
tooltip: 'Increment',
|
||||
child: Icon(Icons.add),
|
||||
), // This trailing comma makes auto-formatting nicer for build methods.
|
||||
home: StoreProvider(
|
||||
store: store,
|
||||
child: _buildBody(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
24
lib/models/gallery.dart
Normal file
24
lib/models/gallery.dart
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
class Gallery {
|
||||
int id;
|
||||
String image;
|
||||
String linkUrl;
|
||||
|
||||
Gallery.fromJson(Map<String, dynamic> json)
|
||||
: id = json['id'],
|
||||
image = json['image'],
|
||||
linkUrl = json['link_url'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'image': image,
|
||||
'link_url': linkUrl
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return json.encode(this);
|
||||
}
|
||||
}
|
||||
46
lib/models/stripe_payment_method.dart
Normal file
46
lib/models/stripe_payment_method.dart
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
class StripePaymentMethod {
|
||||
int id;
|
||||
String customerId;
|
||||
String paymentMethodId;
|
||||
String paymentMethodType;
|
||||
String cardBrand;
|
||||
String cardCountry;
|
||||
int cardExpMonth;
|
||||
int cardExpYear;
|
||||
String cardFunding;
|
||||
String cardLast4;
|
||||
|
||||
StripePaymentMethod.fromJson(Map<String, dynamic> json) :
|
||||
id = json['id'],
|
||||
customerId = json['customer_id'],
|
||||
paymentMethodId = json['payment_method_id'],
|
||||
paymentMethodType = json['payment_method_type'],
|
||||
cardBrand = json['card_brand'],
|
||||
cardCountry = json['card_country'],
|
||||
cardExpMonth = json['card_exp_month'],
|
||||
cardExpYear = json['card_exp_year'],
|
||||
cardFunding = json['card_funding'],
|
||||
cardLast4 = json['card_last4'];
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'customer_id': customerId,
|
||||
'payment_method_id': paymentMethodId,
|
||||
'payment_method_type': paymentMethodType,
|
||||
'card_brand': cardBrand,
|
||||
'card_country': cardCountry,
|
||||
'card_exp_month': cardExpMonth,
|
||||
'card_exp_year': cardExpYear,
|
||||
'card_funding': cardFunding,
|
||||
'card_last4': cardLast4,
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return json.encode(this);
|
||||
}
|
||||
|
||||
}
|
||||
68
lib/models/user.dart
Normal file
68
lib/models/user.dart
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'stripe_payment_method.dart';
|
||||
|
||||
class User {
|
||||
int id;
|
||||
String username;
|
||||
String nickname;
|
||||
String mobile;
|
||||
String email;
|
||||
String avatarUrl;
|
||||
int lastAddressId;
|
||||
String passCode;
|
||||
double credit;
|
||||
double wallet;
|
||||
int coupon;
|
||||
int points;
|
||||
int orderNum;
|
||||
double pointsToCreditsConversionRate;
|
||||
String contactNumber;
|
||||
String flutterMiniStoreToken;
|
||||
List<StripePaymentMethod> stripePaymentMethods;
|
||||
|
||||
User.fromJson(Map<String, dynamic> json)
|
||||
: id = json['id'],
|
||||
username = json['username'],
|
||||
nickname = json['nickname'],
|
||||
mobile = json['mobile'],
|
||||
email = json['email'],
|
||||
avatarUrl = json['avatar_url'],
|
||||
lastAddressId = json['last_address_id'],
|
||||
passCode = json['pass_code'],
|
||||
credit = double.parse(json['credit'].toString()),
|
||||
wallet = double.parse((json['wallet'] == null) ? "0": json['wallet'].toString()),
|
||||
coupon = json['coupon'],
|
||||
points = json['points'],
|
||||
orderNum = json['order_num'],
|
||||
pointsToCreditsConversionRate = double.parse(json['points_to_credits_conversion_rate'].toString()),
|
||||
contactNumber = json['contact_number'],
|
||||
flutterMiniStoreToken = json['flutter_ministore_token'],
|
||||
stripePaymentMethods = (json['stripe_payment_methods'] as List).map((e) => StripePaymentMethod.fromJson(e)).toList();
|
||||
|
||||
Map<String, dynamic> toJson() => {
|
||||
'id': id,
|
||||
'username': username,
|
||||
'nickname': nickname,
|
||||
'mobile': mobile,
|
||||
'email': email,
|
||||
'avatar_url': avatarUrl,
|
||||
'last_address_id': lastAddressId,
|
||||
'pass_code': passCode,
|
||||
'credit': credit,
|
||||
'wallet': wallet,
|
||||
'coupon': coupon,
|
||||
'points': points,
|
||||
'order_num': orderNum,
|
||||
'points_to_credits_conversion_rate': pointsToCreditsConversionRate,
|
||||
'contact_number': contactNumber,
|
||||
'flutter_ministore_token': flutterMiniStoreToken,
|
||||
'stripe_payment_methods': stripePaymentMethods,
|
||||
};
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return json.encode(this);
|
||||
}
|
||||
}
|
||||
96
lib/pages/home.dart
Normal file
96
lib/pages/home.dart
Normal file
@@ -0,0 +1,96 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/gallery.dart';
|
||||
import '../widgets/general/bottom_nav.dart';
|
||||
import '../widgets/general/index_carousel.dart';
|
||||
import '../widgets/general/index_main_content_1.dart';
|
||||
import '../widgets/general/index_main_content_2.dart';
|
||||
import '../widgets/general/index_main_content_3.dart';
|
||||
import '../events/eventbus.dart';
|
||||
import '../events/events.dart';
|
||||
import '../generated/l10n.dart';
|
||||
import '../store/actions.dart';
|
||||
import '../store/store.dart';
|
||||
import '../utils/http_util.dart';
|
||||
import '../utils/double_back_to_close_app.dart';
|
||||
import '../widgets/general/navigationbar.dart';
|
||||
import '../widgets/mobile/mobile_navigation_drawer.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class Home extends StatefulWidget {
|
||||
final Locale locale;
|
||||
final String title;
|
||||
|
||||
Home(this.locale, {Key key, this.title}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return HomeState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class HomeState extends State<Home> {
|
||||
final _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
List<Gallery> galleries = [];
|
||||
String content1Message = '';
|
||||
Map<String, dynamic> content2;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
store.dispatch(UpdateContext(context));
|
||||
|
||||
return ResponsiveBuilder(
|
||||
builder: (context, sizingInformation) =>
|
||||
Scaffold(
|
||||
key: _scaffoldKey,
|
||||
appBar: NavigationBar(),
|
||||
drawer: sizingInformation.deviceScreenType == DeviceScreenType.mobile ? MobileNavigationDrawer() : null,
|
||||
body: DoubleBackToCloseApp(
|
||||
snackBar: SnackBar(
|
||||
content: Text(S.of(context).tap_back_again_to_exit),
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
IndexCarousel(galleries),
|
||||
IndexMainContent1(content1Message),
|
||||
IndexMainContent2(content2),
|
||||
IndexMainContent3(content2),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
bottomNavigationBar: BottomNav(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_loadData();
|
||||
eventBus.on<OpenDrawer>().listen((event) {
|
||||
if (mounted) {
|
||||
_scaffoldKey.currentState.openDrawer();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void _loadData() {
|
||||
HttpUtil.httpGet('v1/get-wisetronic-index-carousel')
|
||||
.then((value) {
|
||||
print('$value');
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
galleries = (value['index_carousel'] as List).map((i) => Gallery.fromJson(i)).toList();
|
||||
content1Message = value['content']['index_content_1'];
|
||||
content2 = value['content']['index_content_2'];
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
16
lib/routes.dart
Normal file
16
lib/routes.dart
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
import 'package:fluro/fluro.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class Routes {
|
||||
static final router = FluroRouter();
|
||||
|
||||
static void configure() {
|
||||
router.define('/', handler: new Handler(
|
||||
handlerFunc: (BuildContext context, Map<String, List<String>> params) {
|
||||
return null;
|
||||
}),
|
||||
transitionType: TransitionType.fadeIn
|
||||
);
|
||||
}
|
||||
}
|
||||
18
lib/store/actions.dart
Normal file
18
lib/store/actions.dart
Normal file
@@ -0,0 +1,18 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/user.dart';
|
||||
|
||||
class UpdateContext {
|
||||
final BuildContext context;
|
||||
UpdateContext(this.context);
|
||||
}
|
||||
|
||||
class UpdateLocale {
|
||||
final Locale locale;
|
||||
UpdateLocale(this.locale);
|
||||
}
|
||||
|
||||
class UpdateCurrentUser {
|
||||
final User user;
|
||||
UpdateCurrentUser(this.user);
|
||||
}
|
||||
13
lib/store/reducer/app_reducer.dart
Normal file
13
lib/store/reducer/app_reducer.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
import 'package:flutter_wisetronic/store/reducer/context_reducer.dart';
|
||||
import 'package:flutter_wisetronic/store/reducer/locale_reducer.dart';
|
||||
import 'package:flutter_wisetronic/store/reducer/user_reducer.dart';
|
||||
import 'package:flutter_wisetronic/store/state/app_state.dart';
|
||||
|
||||
AppState appReducer(AppState state, action) {
|
||||
return AppState(
|
||||
context: contextReducer(state.context, action),
|
||||
locale: localeReducer(state.locale, action),
|
||||
user: userReducer(state.user, action),
|
||||
);
|
||||
}
|
||||
12
lib/store/reducer/context_reducer.dart
Normal file
12
lib/store/reducer/context_reducer.dart
Normal file
@@ -0,0 +1,12 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/store/actions.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
|
||||
final contextReducer = combineReducers<BuildContext>([
|
||||
TypedReducer<BuildContext, UpdateContext>(_updateContext)
|
||||
]);
|
||||
|
||||
BuildContext _updateContext(BuildContext context, action) {
|
||||
return action.context;
|
||||
}
|
||||
11
lib/store/reducer/locale_reducer.dart
Normal file
11
lib/store/reducer/locale_reducer.dart
Normal file
@@ -0,0 +1,11 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/store/actions.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
|
||||
final localeReducer = combineReducers<Locale>([
|
||||
TypedReducer<Locale, UpdateLocale>(_updateLocale)
|
||||
]);
|
||||
|
||||
Locale _updateLocale(Locale locale, action) {
|
||||
return action.locale;
|
||||
}
|
||||
13
lib/store/reducer/user_reducer.dart
Normal file
13
lib/store/reducer/user_reducer.dart
Normal file
@@ -0,0 +1,13 @@
|
||||
|
||||
import 'package:redux/redux.dart';
|
||||
import 'package:flutter_wisetronic/models/user.dart';
|
||||
|
||||
import '../actions.dart';
|
||||
|
||||
final userReducer = combineReducers<User>([
|
||||
TypedReducer<User, UpdateCurrentUser>(_updateCurrentUser)
|
||||
]);
|
||||
|
||||
User _updateCurrentUser(User user, action) {
|
||||
return action.user;
|
||||
}
|
||||
42
lib/store/state/app_state.dart
Normal file
42
lib/store/state/app_state.dart
Normal file
@@ -0,0 +1,42 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/user.dart';
|
||||
|
||||
@immutable
|
||||
class AppState {
|
||||
final BuildContext context;
|
||||
final Locale locale;
|
||||
final User user;
|
||||
|
||||
AppState({this.context, this.locale, this.user});
|
||||
|
||||
factory AppState.init() => AppState();
|
||||
|
||||
AppState copyWith({
|
||||
BuildContext context,
|
||||
Locale locale}) {
|
||||
return AppState(
|
||||
context: context ?? this.context,
|
||||
locale: locale ?? this.locale,
|
||||
user: user ?? this.user,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
int get hashCode =>
|
||||
context.hashCode ^
|
||||
locale.hashCode ^
|
||||
user.hashCode;
|
||||
|
||||
@override
|
||||
bool operator ==(Object other) =>
|
||||
identical(this, other) ||
|
||||
other is AppState &&
|
||||
context == other.context &&
|
||||
locale == other.locale &&
|
||||
user == other.user;
|
||||
|
||||
@override
|
||||
String toString() =>
|
||||
'AppState(context: $context, locale: $locale), user: $user';
|
||||
}
|
||||
9
lib/store/store.dart
Normal file
9
lib/store/store.dart
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
import 'package:flutter_wisetronic/store/reducer/app_reducer.dart';
|
||||
import 'package:redux/redux.dart';
|
||||
import 'state/app_state.dart';
|
||||
|
||||
final store = Store<AppState>(
|
||||
appReducer,
|
||||
initialState: AppState.init(),
|
||||
);
|
||||
98
lib/utils/double_back_to_close_app.dart
Normal file
98
lib/utils/double_back_to_close_app.dart
Normal file
@@ -0,0 +1,98 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// Allows the user to close the app by double tapping the back-button.
|
||||
///
|
||||
/// You must specify a [SnackBar], so it can be shown when the user taps the
|
||||
/// back-button. Notice that the value you set for [SnackBar.duration] is going
|
||||
/// to be considered to decide whether the snack-bar is currently visible or
|
||||
/// not.
|
||||
///
|
||||
/// Since the back-button is an Android feature, this Widget is going to be
|
||||
/// nothing but the own [child] if the current platform is anything but Android.
|
||||
class DoubleBackToCloseApp extends StatefulWidget {
|
||||
/// The [SnackBar] shown when the user taps the back-button.
|
||||
final SnackBar snackBar;
|
||||
|
||||
/// The widget below this widget in the tree.
|
||||
final Widget child;
|
||||
|
||||
/// Creates a widget that allows the user to close the app by double tapping
|
||||
/// the back-button.
|
||||
const DoubleBackToCloseApp({
|
||||
Key key,
|
||||
@required this.snackBar,
|
||||
@required this.child,
|
||||
}) : assert(snackBar != null),
|
||||
assert(child != null),
|
||||
super(key: key);
|
||||
|
||||
@override
|
||||
_DoubleBackToCloseAppState createState() => _DoubleBackToCloseAppState();
|
||||
}
|
||||
|
||||
class _DoubleBackToCloseAppState extends State<DoubleBackToCloseApp> {
|
||||
/// The last time the user tapped Android's back-button.
|
||||
DateTime _lastTimeBackButtonWasTapped;
|
||||
|
||||
/// Returns whether the current platform is Android.
|
||||
bool get _isAndroid => Theme.of(context).platform == TargetPlatform.android;
|
||||
|
||||
/// Returns whether the [DoubleBackToCloseApp.snackBar] is currently visible.
|
||||
///
|
||||
/// The snack-bar is going to be considered visible if the duration of the
|
||||
/// snack-bar is greater than the difference from now to the
|
||||
/// [_lastTimeBackButtonWasTapped].
|
||||
///
|
||||
/// This is not quite accurate since the snack-bar could've been dismissed by
|
||||
/// the user, so this algorithm needs to be improved, as described in #2.
|
||||
bool get _isSnackBarVisible =>
|
||||
(_lastTimeBackButtonWasTapped != null) &&
|
||||
(widget.snackBar.duration >
|
||||
DateTime.now().difference(_lastTimeBackButtonWasTapped));
|
||||
|
||||
/// Returns whether the next back navigation of this route will be handled
|
||||
/// internally.
|
||||
///
|
||||
/// Returns true when there's a widget that inserted an entry into the
|
||||
/// local-history of the current route, in order to handle pop. This is done
|
||||
/// by [Drawer], for example, so it can close on pop.
|
||||
bool get _willHandlePopInternally =>
|
||||
ModalRoute.of(context).willHandlePopInternally;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
_ensureThatContextContainsScaffold();
|
||||
|
||||
if (_isAndroid) {
|
||||
return WillPopScope(
|
||||
onWillPop: _handleWillPop,
|
||||
child: widget.child,
|
||||
);
|
||||
} else {
|
||||
return widget.child;
|
||||
}
|
||||
}
|
||||
|
||||
/// Handles [WillPopScope.onWillPop].
|
||||
Future<bool> _handleWillPop() async {
|
||||
if (_isSnackBarVisible || _willHandlePopInternally) {
|
||||
return true;
|
||||
} else {
|
||||
_lastTimeBackButtonWasTapped = DateTime.now();
|
||||
// Scaffold.of(context).showSnackBar(widget.snackBar);
|
||||
ScaffoldMessenger.of(context).showSnackBar(widget.snackBar);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// Throws a [FlutterError] if this widget was not wrapped in a [Scaffold].
|
||||
void _ensureThatContextContainsScaffold() {
|
||||
if (Scaffold.maybeOf(context) == null) {
|
||||
throw FlutterError(
|
||||
'`DoubleBackToCloseApp` must be wrapped in a `Scaffold`.',
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
370
lib/utils/http_util.dart
Normal file
370
lib/utils/http_util.dart
Normal file
@@ -0,0 +1,370 @@
|
||||
|
||||
|
||||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
import '../store/store.dart';
|
||||
import 'utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
|
||||
import '../constants.dart';
|
||||
|
||||
typedef void PostCallback(Response response);
|
||||
|
||||
String generateSignature(String string, {String key}) {
|
||||
if (key == null) {
|
||||
key = Constants.API_SECRET;
|
||||
}
|
||||
Hmac mac = new Hmac(sha256, utf8.encode(key));
|
||||
Digest digest = mac.convert(utf8.encode(string + key));
|
||||
String base64Mac = base64.encode(utf8.encode("$digest"));
|
||||
return base64Mac;
|
||||
}
|
||||
|
||||
class HttpUtil {
|
||||
static String platformName = Utils.getPlatformName();
|
||||
|
||||
static final Map<String, String> headers = {
|
||||
'Accept': 'application/json',
|
||||
// 'Content-Type': 'application/json',
|
||||
'Http-Signature': '',
|
||||
// 'Http-Group-Id': Constants.GROUP_ID,
|
||||
'Http-Business-Id': '0',
|
||||
'Http-App-Key': '',
|
||||
'Http-Contact-Authorization': '',
|
||||
'Http-Device-Type': Platform.isIOS ? 'ios' : (Platform.isAndroid ? 'android' : 'web'),
|
||||
'Http-Api-Branch': 'flutter',
|
||||
'Http-Language-Code': store.state.locale.languageCode,
|
||||
};
|
||||
|
||||
static Future<dynamic> httpGet(String url,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
int businessId = 0,
|
||||
Function(int, int) receiveProgress,
|
||||
bool returnError = false,
|
||||
Map<String, String> additionalHeaders,
|
||||
}) async {
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
localHeaders.addAll(additionalHeaders);
|
||||
}
|
||||
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
|
||||
if (url.startsWith('http')) {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(queryParameters);
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
Response response = await dio.get(requestUrl,
|
||||
queryParameters: queryParameters,
|
||||
options: Options(
|
||||
headers: localHeaders
|
||||
),
|
||||
onReceiveProgress: receiveProgress,
|
||||
).timeout(const Duration(seconds: 30));
|
||||
|
||||
print('HttpGet success. Request: $requestUrl, Response: ${response.statusCode}, Headers: ${response.request.headers}');
|
||||
// print(response.data);
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
print('error $e');
|
||||
if (returnError) {
|
||||
return e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPost(String url, PostCallback callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
int businessId = 0,
|
||||
bool isFormData = false,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
localHeaders.addAll(additionalHeaders);
|
||||
}
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
if (url.startsWith('http')) {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
// Don't print body will cause upload Multipart file failed
|
||||
//Utils.jsonPrettyPrint(body);
|
||||
|
||||
Dio dio = Dio();
|
||||
dio.interceptors.add(LogInterceptor());
|
||||
try {
|
||||
Response response = await dio.post(
|
||||
requestUrl,
|
||||
queryParameters: queryParameters == null ? {} : queryParameters,
|
||||
data: isFormData ? FormData.fromMap(body) : json.encode(body),
|
||||
options: Options(
|
||||
headers: localHeaders,
|
||||
// contentType: isFormData ? Headers.formUrlEncodedContentType : Headers.jsonContentType,
|
||||
),
|
||||
onSendProgress: sendProgress,
|
||||
onReceiveProgress: receiveProgress,
|
||||
).timeout(Duration(seconds: 30));
|
||||
|
||||
print('HttpPost Success. Request: ${response.request.uri}, Response: ${response.statusCode}, Headers: ${response.request.headers}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
if (e.response != null) {
|
||||
print('HttpPost failed. Request: ${e.request.uri}, Headers: ${e.response.request.headers}');
|
||||
try {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
} catch (err) {
|
||||
print(e.response.data);
|
||||
}
|
||||
}
|
||||
if (returnError) {
|
||||
return e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPut(String url, PostCallback callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
localHeaders.addAll(additionalHeaders);
|
||||
}
|
||||
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
localHeaders['Content-Type'] = Headers.jsonContentType;
|
||||
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
|
||||
if (url.startsWith('http')) {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
Response response = await dio.put(
|
||||
requestUrl,
|
||||
queryParameters: queryParameters == null ? {} : queryParameters,
|
||||
data: json.encode(body),
|
||||
options: Options(
|
||||
headers: localHeaders,
|
||||
),
|
||||
onSendProgress: sendProgress,
|
||||
onReceiveProgress: receiveProgress,
|
||||
).timeout(Duration(seconds: 30));
|
||||
|
||||
print('HttpPost Success. Request: ${response.request.uri}, Response: ${response.statusCode}, Headers: ${response.request.headers}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
print('HttpPost failed. Request: ${e.request.uri}');
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
}
|
||||
if (returnError) {
|
||||
return e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpPatch(String url, PostCallback callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
Function(int, int) sendProgress,
|
||||
Function(int, int) receiveProgress,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
localHeaders.addAll(additionalHeaders);
|
||||
}
|
||||
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
localHeaders['Content-Type'] = Headers.jsonContentType;
|
||||
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
|
||||
if (url.startsWith('http')) {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(body);
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
Response response = await dio.patch(
|
||||
requestUrl,
|
||||
queryParameters: queryParameters == null ? {} : queryParameters,
|
||||
data: json.encode(body),
|
||||
options: Options(
|
||||
headers: localHeaders,
|
||||
),
|
||||
onSendProgress: sendProgress,
|
||||
onReceiveProgress: receiveProgress,
|
||||
).timeout(Duration(seconds: 30));
|
||||
|
||||
print('HttpPost Success. Request: ${response.request.uri}, Response: ${response.statusCode}, Headers: ${response.request.headers}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
print('HttpPost failed. Request: ${e.request.uri}');
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
}
|
||||
if (returnError) {
|
||||
return e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
static Future<dynamic> httpDelete(String url, PostCallback callback,
|
||||
{
|
||||
Map<String, dynamic> queryParameters,
|
||||
int businessId = 0,
|
||||
Map<String, String> additionalHeaders,
|
||||
Map<String, dynamic> body,
|
||||
bool returnError = false,
|
||||
}) async {
|
||||
|
||||
Map<String, dynamic> localHeaders = json.decode(json.encode(headers));
|
||||
if (additionalHeaders != null) {
|
||||
localHeaders.addAll(additionalHeaders);
|
||||
}
|
||||
|
||||
if (!url.startsWith('http')) {
|
||||
localHeaders['Http-Signature'] = generateSignature(url);
|
||||
}
|
||||
|
||||
localHeaders['Http-Business-Id'] = businessId.toString();
|
||||
Box box = await Utils.getBox();
|
||||
localHeaders['Http-Contact-Authorization'] = box.get(Constants.KEY_ACCESS_TOKEN, defaultValue: '');
|
||||
localHeaders['Http-App-Key'] = platformName;
|
||||
localHeaders['Http-Device-Type'] = platformName;
|
||||
|
||||
localHeaders['Content-Type'] = Headers.jsonContentType;
|
||||
|
||||
String requestUrl = Constants.BASE_API_URL + url;
|
||||
|
||||
if (url.startsWith('http')) {
|
||||
requestUrl = url;
|
||||
}
|
||||
|
||||
Utils.jsonPrettyPrint(body);
|
||||
|
||||
Dio dio = Dio();
|
||||
try {
|
||||
Response response = await dio.delete(
|
||||
requestUrl,
|
||||
queryParameters: queryParameters == null ? {} : queryParameters,
|
||||
data: json.encode(body),
|
||||
options: Options(
|
||||
headers: localHeaders,
|
||||
),
|
||||
).timeout(Duration(seconds: 30));
|
||||
|
||||
print('HttpPost Success. Request: ${response.request.uri}, Response: ${response.statusCode}, Headers: ${response.request.headers}');
|
||||
// Utils.jsonPrettyPrint(response.data);
|
||||
|
||||
int statusCode = response.statusCode;
|
||||
if (callback != null) {
|
||||
callback(response);
|
||||
}
|
||||
return response.data;
|
||||
} on DioError catch(e) {
|
||||
print('HttpPost failed. Request: ${e.request.uri}');
|
||||
if (e.response != null) {
|
||||
Utils.jsonPrettyPrint(e.response.data);
|
||||
}
|
||||
if(returnError) {
|
||||
return e;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
46
lib/utils/util_io.dart
Normal file
46
lib/utils/util_io.dart
Normal file
@@ -0,0 +1,46 @@
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../routes.dart';
|
||||
import 'utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
class Util {
|
||||
static Future<Box> getBox() async {
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
Hive.init(dir.path);
|
||||
Box box = await Hive.openBox('app_data');
|
||||
return box;
|
||||
}
|
||||
|
||||
static Widget showImage(String imageUrl, {double width, double height,
|
||||
BoxFit fit, Widget Function(BuildContext, String, dynamic) errorWidget}) {
|
||||
if (imageUrl == null || imageUrl.isEmpty) {
|
||||
return Container(
|
||||
width: width,
|
||||
height: height,
|
||||
child: Text(''),
|
||||
);
|
||||
}
|
||||
return CachedNetworkImage(
|
||||
imageUrl: imageUrl,
|
||||
width: width,
|
||||
height: width,
|
||||
fit: fit,
|
||||
placeholder: (context, url) => Utils.imageLoadingIndicator(),
|
||||
errorWidget: errorWidget != null ? errorWidget : (context, url, error) {
|
||||
return Image.asset(
|
||||
'assets/images/not_found.png',
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void openWebUrl(BuildContext context, String link) {
|
||||
Routes.router.navigateTo(context, '/webview/$link');
|
||||
}
|
||||
}
|
||||
52
lib/utils/util_web.dart
Normal file
52
lib/utils/util_web.dart
Normal file
@@ -0,0 +1,52 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'utils.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:hive_flutter/hive_flutter.dart';
|
||||
|
||||
class Util {
|
||||
|
||||
static Future<Box> getBox() async {
|
||||
Hive.initFlutter();
|
||||
Box box = await Hive.openBox('wisetronic_app_data');
|
||||
return box;
|
||||
}
|
||||
|
||||
static Widget showImage(String imageUrl, {double width, double height,
|
||||
BoxFit fit, Widget Function(BuildContext, String, dynamic) errorWidget}) {
|
||||
return Image.network(imageUrl,
|
||||
fit: fit,
|
||||
width: width,
|
||||
height: height,
|
||||
cacheWidth: width != null ? width.round() : null,
|
||||
cacheHeight: height != null ? height.round() : null,
|
||||
loadingBuilder: (BuildContext context, Widget child, ImageChunkEvent loadingProgress) {
|
||||
if (loadingProgress == null) return child;
|
||||
return Center(
|
||||
child: Utils.imageLoadingIndicator(),
|
||||
);
|
||||
},
|
||||
errorBuilder: (BuildContext context, Object object, StackTrace stackTrace) {
|
||||
if (errorWidget != null) {
|
||||
return errorWidget(context, null, null);
|
||||
}
|
||||
return Image.asset(
|
||||
'assets/images/not_found.png',
|
||||
width: width,
|
||||
height: height,
|
||||
fit: fit,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static void openWebUrl(BuildContext context, String link) async {
|
||||
var url = 'https://${link}';
|
||||
if (await canLaunch(url)) {
|
||||
await launch('$url');
|
||||
} else {
|
||||
print('Could not launch $url');
|
||||
}
|
||||
}
|
||||
}
|
||||
277
lib/utils/utils.dart
Normal file
277
lib/utils/utils.dart
Normal file
@@ -0,0 +1,277 @@
|
||||
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dio/dio.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:fluttertoast/fluttertoast.dart';
|
||||
import 'package:hive/hive.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
import 'util_web.dart' if (dart.library.io) 'util_io.dart';
|
||||
|
||||
import '../routes.dart';
|
||||
import 'http_util.dart';
|
||||
|
||||
typedef void OnSuccess(Response response);
|
||||
typedef void OnError(dynamic error);
|
||||
typedef void OnComplete(dynamic data);
|
||||
|
||||
typedef void OnOk();
|
||||
|
||||
class Utils {
|
||||
|
||||
static bool equalsIgnoreCase(String a, String b) =>
|
||||
(a == null && b == null) ||
|
||||
(a != null && b != null && a.toLowerCase() == b.toLowerCase());
|
||||
|
||||
static int selectionsContains(Map<String, dynamic> selections, String key, String name) {
|
||||
if (selections.containsKey(key.toUpperCase())) {
|
||||
for (var i = 0; i < (selections[key.toUpperCase()] as List).length; i++) {
|
||||
Map<String, dynamic> item = (selections[key.toUpperCase()] as List)[i];
|
||||
if (Utils.equalsIgnoreCase(item['name'], name)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static List<String> getSelectedAttributeValue(Map<String, dynamic> selections, String key) {
|
||||
List<String> valueArr = [];
|
||||
if (selections.containsKey(key.toUpperCase())) {
|
||||
for (var i = 0; i < (selections[key.toUpperCase()] as List).length; i++) {
|
||||
valueArr.add((selections[key.toUpperCase()][i]['name'] as String).toLowerCase());
|
||||
}
|
||||
}
|
||||
return valueArr;
|
||||
}
|
||||
|
||||
static bool selectionsNotEmptyAt(Map<String, dynamic> selections, String key) {
|
||||
if (selections.containsKey(key.toUpperCase()) && (selections[key.toUpperCase()] as List).length > 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static Map<String, dynamic> stringToJson(String string) {
|
||||
if (string == null || string.isEmpty) {
|
||||
return null;
|
||||
}
|
||||
return json.decode(string);
|
||||
}
|
||||
|
||||
static void jsonPrettyPrint(Map<String, dynamic> map) {
|
||||
JsonEncoder encoder = new JsonEncoder.withIndent(' ');
|
||||
String prettyPrint = encoder.convert(map);
|
||||
debugPrint(prettyPrint);
|
||||
}
|
||||
|
||||
static launchURL(String url) async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
}
|
||||
|
||||
static String getPlatformName() {
|
||||
String platformName = '';
|
||||
if (kIsWeb) {
|
||||
platformName = 'web';
|
||||
} else if (Platform.isAndroid) {
|
||||
platformName = 'android';
|
||||
} else if (Platform.isIOS) {
|
||||
platformName = 'ios';
|
||||
}
|
||||
return platformName;
|
||||
}
|
||||
|
||||
static Future<Box> getBox() async {
|
||||
return Util.getBox();
|
||||
}
|
||||
|
||||
static Widget imageLoadingIndicator() {
|
||||
return SizedBox(
|
||||
width: 30,
|
||||
height: 30,
|
||||
child: Container(
|
||||
child: CupertinoActivityIndicator(),
|
||||
color: Colors.transparent,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static String safePhoneNumber(String phone) {
|
||||
if (phone.length < 8) {
|
||||
return phone;
|
||||
}
|
||||
String start = phone.substring(0, 3);
|
||||
String end = phone.substring(phone.length - 3);
|
||||
return '${start}****${end}';
|
||||
}
|
||||
|
||||
static String safeString(String string) {
|
||||
if (string == null || string.length == 0) {
|
||||
return '';
|
||||
}
|
||||
String start = string.substring(0, 1);
|
||||
String end = string.substring(string.length - 1);
|
||||
return '${start}****${end}';
|
||||
}
|
||||
|
||||
static String smartRound(double amount, int decimalPlace) {
|
||||
double a = double.parse(amount.toStringAsFixed(decimalPlace));
|
||||
double b = double.parse(amount.toStringAsFixed(0));
|
||||
if (a - b == 0) {
|
||||
return amount.toStringAsFixed(0);
|
||||
}
|
||||
return amount.toStringAsFixed(decimalPlace);
|
||||
}
|
||||
|
||||
static void createOrUpdateStripePaymentMethod(
|
||||
String paymentMethodId,
|
||||
String cardBrand,
|
||||
String paymentMethodType,
|
||||
String cardCountry,
|
||||
int cardExpMonth,
|
||||
int cardExpYear,
|
||||
String cardFunding,
|
||||
String cardLast4,
|
||||
) {
|
||||
HttpUtil.httpPost('v1/create-update-stripe-payment-method', (response) {
|
||||
if (response.statusCode == 200) {
|
||||
print('create or update customer stripe payment method success. ${response.data}');
|
||||
}
|
||||
},
|
||||
body: {
|
||||
'payment_method_id': paymentMethodId,
|
||||
'card_brand': cardBrand,
|
||||
'payment_method_type': paymentMethodType,
|
||||
'card_country': cardCountry,
|
||||
'card_exp_month': cardExpMonth,
|
||||
'card_exp_year': cardExpYear,
|
||||
'card_funding': cardFunding,
|
||||
'card_last4': cardLast4,
|
||||
},
|
||||
isFormData: true,
|
||||
).catchError((error) {
|
||||
print('Error: ${error}');
|
||||
});
|
||||
}
|
||||
|
||||
static showSubmitDialog(BuildContext context) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: WillPopScope(
|
||||
child: Container(
|
||||
width: 300.0,
|
||||
height: 150.0,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SpinKitThreeBounce(
|
||||
color: Colors.lightBlueAccent,
|
||||
size: 30.0,
|
||||
),
|
||||
Text(
|
||||
S.of(context).submitting,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
onWillPop: () async {
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).submitting_please_wait,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white
|
||||
);
|
||||
return false;
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static showLoadingDialog(BuildContext context, {String message}) {
|
||||
showDialog(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (BuildContext context) {
|
||||
return AlertDialog(
|
||||
content: WillPopScope(
|
||||
child: Container(
|
||||
width: 80.0,
|
||||
height: 80.0,
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
SpinKitThreeBounce(
|
||||
color: Colors.lightBlueAccent,
|
||||
size: 30.0,
|
||||
),
|
||||
Text(
|
||||
message != null ? message : S.of(context).recalculating,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
onWillPop: () async {
|
||||
Fluttertoast.showToast(
|
||||
msg: S.of(context).loading_please_wait,
|
||||
toastLength: Toast.LENGTH_SHORT,
|
||||
gravity: ToastGravity.CENTER,
|
||||
backgroundColor: Colors.red,
|
||||
textColor: Colors.white
|
||||
);
|
||||
return false;
|
||||
}
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
static getTitleFromBody(String body) {
|
||||
if (body.length <= 30) {
|
||||
return body;
|
||||
}
|
||||
return body.substring(0, 29);
|
||||
}
|
||||
|
||||
static void getMiniLink(String realLink, OnSuccess onSuccess, OnError onError) {
|
||||
HttpUtil.httpPost('get-minilink/', (response) {
|
||||
onSuccess(response);
|
||||
},
|
||||
body: {
|
||||
'link': realLink
|
||||
},
|
||||
isFormData: true,
|
||||
).catchError((error) {
|
||||
onError(error);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class RuntimeError extends Error{
|
||||
final int code;
|
||||
final String message;
|
||||
RuntimeError(this.message, {this.code});
|
||||
String toString() => "Runtime Error: $message";
|
||||
}
|
||||
113
lib/widgets/desktop/desktop_Index_carousel.dart
Normal file
113
lib/widgets/desktop/desktop_Index_carousel.dart
Normal file
@@ -0,0 +1,113 @@
|
||||
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../models/gallery.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class DesktopIndexCarousel extends StatefulWidget {
|
||||
final List<Gallery> galleries;
|
||||
|
||||
const DesktopIndexCarousel(this.galleries, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopIndexCarouselState();
|
||||
}
|
||||
}
|
||||
|
||||
class DesktopIndexCarouselState extends State<DesktopIndexCarousel> {
|
||||
int _current = 0;
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0),
|
||||
child: CarouselSlider(
|
||||
items: widget.galleries.map((i) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Container(
|
||||
width: mainSpace,
|
||||
// margin: EdgeInsets.symmetric(horizontal: 5.0),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
child: Util.showImage(
|
||||
'https:${i.image}',
|
||||
fit: BoxFit.fitWidth,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (i.linkUrl != null && i.linkUrl.isNotEmpty) {
|
||||
Util.openWebUrl(context, i.linkUrl);
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
options: CarouselOptions(
|
||||
height: mainSpace / 2.0,
|
||||
aspectRatio: 2/1,
|
||||
initialPage: 0,
|
||||
enableInfiniteScroll: true,
|
||||
autoPlay: true,
|
||||
autoPlayInterval: Duration(seconds: 5),
|
||||
autoPlayCurve: Curves.fastOutSlowIn,
|
||||
scrollDirection: Axis.horizontal,
|
||||
viewportFraction: 1.0,
|
||||
onPageChanged: (index, reason) {
|
||||
setState(() {
|
||||
_current = index;
|
||||
});
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 5,
|
||||
right: sideSpace + 10,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: widget.galleries.map((i) {
|
||||
int index = widget.galleries.indexOf(i);
|
||||
return Container(
|
||||
width: 8.0,
|
||||
height: 8.0,
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: _current == index
|
||||
? Color.fromRGBO(0, 0, 0, 0.9)
|
||||
: Color.fromRGBO(0, 0, 0, 0.4),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
60
lib/widgets/desktop/desktop_index_main_content_1.dart
Normal file
60
lib/widgets/desktop/desktop_index_main_content_1.dart
Normal file
@@ -0,0 +1,60 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
|
||||
class DesktopIndexMainContent1 extends StatefulWidget {
|
||||
final String message;
|
||||
const DesktopIndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopIndexMainContent1State();
|
||||
}
|
||||
}
|
||||
|
||||
class DesktopIndexMainContent1State extends State<DesktopIndexMainContent1> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Container(
|
||||
width: mainSpace,
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
padding: EdgeInsets.symmetric(vertical: 30.0, horizontal: 30.0),
|
||||
child: Container(
|
||||
child: Text(
|
||||
widget.message,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.lightGreen,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
247
lib/widgets/desktop/desktop_index_main_content_2.dart
Normal file
247
lib/widgets/desktop/desktop_index_main_content_2.dart
Normal file
@@ -0,0 +1,247 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class DesktopIndexMainContent2 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const DesktopIndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopIndexMainContent2State();
|
||||
}
|
||||
}
|
||||
|
||||
class DesktopIndexMainContent2State extends State<DesktopIndexMainContent2> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.content == null) {
|
||||
return Container();
|
||||
}
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
return Row(
|
||||
children: [
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
Container(
|
||||
width: mainSpace,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: mainSpace / 2,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['minipos']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: mainSpace / 2 - 100.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['point_of_sale_system_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'http:${widget.content['minipos_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
_buildMiniPosFeatures(mainSpace / 2),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: mainSpace / 2,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: mainSpace / 2 - 100.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'http:${widget.content['igoshow_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
_buildiGoShowFeatures(mainSpace / 2),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: sideSpace,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMiniPosFeatures(double width) {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['minipos_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['minipos_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
col.children.add(
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Text(
|
||||
S.of(context).learn_more,
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildiGoShowFeatures(double width) {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['igoshow_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['igoshow_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
col.children.add(
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Text(
|
||||
S.of(context).learn_more,
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
179
lib/widgets/desktop/desktop_index_main_content_3.dart
Normal file
179
lib/widgets/desktop/desktop_index_main_content_3.dart
Normal file
@@ -0,0 +1,179 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/text_link.dart';
|
||||
|
||||
class DesktopIndexMainContent3 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const DesktopIndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopIndexMainContent3State();
|
||||
}
|
||||
}
|
||||
|
||||
class DesktopIndexMainContent3State extends State<DesktopIndexMainContent3> {
|
||||
double sideSpace = 0;
|
||||
double mainSpace = 1200;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.content == null) {
|
||||
return Container();
|
||||
}
|
||||
if (MediaQuery.of(context).size.width <= 1200) {
|
||||
mainSpace = MediaQuery.of(context).size.width;
|
||||
sideSpace = 0;
|
||||
} else {
|
||||
mainSpace = 1200;
|
||||
sideSpace = (MediaQuery.of(context).size.width - 1200) / 2;
|
||||
}
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
margin: EdgeInsets.only(top: 20.0),
|
||||
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xff262626),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
child: Text(
|
||||
S.of(context).information,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white70,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
TextLink(S.of(context).service_policy, '/service_policy', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).return_policy, '/return_policy', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).privacy_policy, '/privacy_policy', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).license_agreement, '/license_agreement', paddingVertical: 5.0, paddingHorizontal: 10.0,)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 12.0),
|
||||
child: Text(
|
||||
S.of(context).support,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white70,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
TextLink(S.of(context).wiki, '/wiki', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).support_ticket, '/support_ticket', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).contact_us, '/contact_us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).about_us, '/about_us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).renew_license, '/renew_license', paddingVertical: 5.0, paddingHorizontal: 10.0,)
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 12.0),
|
||||
child: Text(
|
||||
S.of(context).developer_of,
|
||||
style: TextStyle(
|
||||
fontSize: 16.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white70,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe800,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe801,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe802,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe803,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe804,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe805,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.white24,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
99
lib/widgets/desktop/desktop_navigationbar.dart
Normal file
99
lib/widgets/desktop/desktop_navigationbar.dart
Normal file
@@ -0,0 +1,99 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/navigationbar_logo.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/text_link.dart';
|
||||
|
||||
class DesktopNavigationBar extends StatefulWidget {
|
||||
const DesktopNavigationBar({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DesktopNavigationBarState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DesktopNavigationBarState extends State<DesktopNavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String currentRoute = ModalRoute.of(context).settings.name;
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
color: Colors.blue,
|
||||
height: 80.0,
|
||||
),
|
||||
Container(
|
||||
height: 80.0,
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 5.0),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
NavigationBarLogo(),
|
||||
Container(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
SizedBox(width: 20.0,),
|
||||
TextLink(
|
||||
S.of(context).home,
|
||||
'/',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).download,
|
||||
'/download',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/download',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).tutorials,
|
||||
'/tutorials',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/tutorials',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).support,
|
||||
'/support',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/support',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).shop,
|
||||
'/shop',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/shop',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).blog,
|
||||
'/blog',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/blog',
|
||||
),
|
||||
SizedBox(width: 15.0,),
|
||||
TextLink(
|
||||
S.of(context).login,
|
||||
'/login',
|
||||
color: Colors.white,
|
||||
selected: currentRoute == '/login',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
51
lib/widgets/general/bottom_nav.dart
Normal file
51
lib/widgets/general/bottom_nav.dart
Normal file
@@ -0,0 +1,51 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class BottomNav extends StatefulWidget {
|
||||
const BottomNav({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return BottomNavState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class BottomNavState extends State<BottomNav> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
height: 50.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),
|
||||
decoration: BoxDecoration(
|
||||
color: Color(0xff232323),
|
||||
),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
Container(
|
||||
child: Text(
|
||||
'© 2007-${DateTime.now().year} wisetronic.com. All Rights Reserved.',
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: Colors.white60,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
'All logos shown are registered trademark, copyrighted and belong to their respective owners.',
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: Colors.white60,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
90
lib/widgets/general/download_item.dart
Normal file
90
lib/widgets/general/download_item.dart
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:universal_io/io.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class DownloadItem extends StatefulWidget {
|
||||
final dynamic desc;
|
||||
final double width;
|
||||
const DownloadItem(this.desc, {Key key, this.width}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return DownloadItemState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DownloadItemState extends State<DownloadItem> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
||||
return Container(
|
||||
padding: EdgeInsets.only(top: 10.0, bottom: 10.0, left: 10.0, right: 10.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Container(
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Container(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
child: Util.showImage(
|
||||
'https:${widget.desc['app_icon']}',
|
||||
width: 32.0,
|
||||
height: 32.0,
|
||||
fit: BoxFit.fill,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
'${widget.desc['name']}',
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 15.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${widget.desc['version']}',
|
||||
style: TextStyle(
|
||||
fontSize: 12.0,
|
||||
color: Colors.black38,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: getDownloadButton(),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
child: Text(
|
||||
'${widget.desc['description']}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget getDownloadButton() {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
21
lib/widgets/general/index_carousel.dart
Normal file
21
lib/widgets/general/index_carousel.dart
Normal file
@@ -0,0 +1,21 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/models/gallery.dart';
|
||||
import '../desktop/desktop_Index_carousel.dart';
|
||||
import '../mobile/mobile_index_carousel.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexCarousel extends StatelessWidget {
|
||||
final List<Gallery> galleries;
|
||||
const IndexCarousel(this.galleries, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexCarousel(galleries),
|
||||
tablet: DesktopIndexCarousel(galleries),
|
||||
desktop: DesktopIndexCarousel(galleries),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
20
lib/widgets/general/index_main_content_1.dart
Normal file
20
lib/widgets/general/index_main_content_1.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_index_main_content_1.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/mobile_index_main_content_1.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent1 extends StatelessWidget {
|
||||
final String message;
|
||||
const IndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent1(message),
|
||||
tablet: DesktopIndexMainContent1(message),
|
||||
desktop: DesktopIndexMainContent1(message),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
20
lib/widgets/general/index_main_content_2.dart
Normal file
20
lib/widgets/general/index_main_content_2.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../desktop/desktop_index_main_content_2.dart';
|
||||
import '../mobile/mobile_index_main_content_2.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent2 extends StatelessWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const IndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent2(content),
|
||||
tablet: DesktopIndexMainContent2(content),
|
||||
desktop: DesktopIndexMainContent2(content),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
20
lib/widgets/general/index_main_content_3.dart
Normal file
20
lib/widgets/general/index_main_content_3.dart
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import '../desktop/desktop_index_main_content_3.dart';
|
||||
import '../mobile/mobile_index_main_content_3.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class IndexMainContent3 extends StatelessWidget {
|
||||
final Map<String, dynamic> content;
|
||||
const IndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileIndexMainContent3(content),
|
||||
tablet: DesktopIndexMainContent3(content),
|
||||
desktop: DesktopIndexMainContent3(content),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
37
lib/widgets/general/navigationbar.dart
Normal file
37
lib/widgets/general/navigationbar.dart
Normal file
@@ -0,0 +1,37 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/widgets/desktop/desktop_navigationbar.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/mobile_navigationbar.dart';
|
||||
import 'package:responsive_builder/responsive_builder.dart';
|
||||
|
||||
class NavigationBar extends StatefulWidget implements PreferredSizeWidget {
|
||||
final Key key;
|
||||
final PreferredSizeWidget bottom;
|
||||
|
||||
NavigationBar({Key key, PreferredSizeWidget bottom})
|
||||
: key = key,
|
||||
preferredSize = Size.fromHeight(kToolbarHeight + (bottom?.preferredSize?.height ?? 0.0)),
|
||||
bottom = bottom;
|
||||
|
||||
@override
|
||||
final Size preferredSize;
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return NavigationBarState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NavigationBarState extends State<NavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ScreenTypeLayout(
|
||||
mobile: MobileNavigationBar(),
|
||||
tablet: DesktopNavigationBar(),
|
||||
desktop: DesktopNavigationBar(),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
25
lib/widgets/general/navigationbar_logo.dart
Normal file
25
lib/widgets/general/navigationbar_logo.dart
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class NavigationBarLogo extends StatelessWidget {
|
||||
const NavigationBarLogo({Key key}) : super(key: key);
|
||||
|
||||
static const IconData logoData = IconData(
|
||||
0xe800,
|
||||
fontFamily: 'wisetronic',
|
||||
fontPackage: null
|
||||
);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SizedBox(
|
||||
height: 48,
|
||||
width: 178,
|
||||
child: Icon(
|
||||
logoData,
|
||||
color: Colors.white,
|
||||
size: 48.0,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
58
lib/widgets/general/text_link.dart
Normal file
58
lib/widgets/general/text_link.dart
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/rendering.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class TextLink extends StatelessWidget {
|
||||
final String title;
|
||||
final String url;
|
||||
final Color color;
|
||||
final double paddingHorizontal;
|
||||
final double paddingVertical;
|
||||
final FontWeight fontWeight;
|
||||
final bool selected;
|
||||
TextLink(this.title, this.url, {
|
||||
this.color,
|
||||
this.paddingHorizontal,
|
||||
this.paddingVertical,
|
||||
this.fontWeight,
|
||||
this.selected
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MouseRegion(
|
||||
cursor: SystemMouseCursors.click,
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: paddingVertical ?? 0.0,
|
||||
horizontal: paddingHorizontal ?? 0.0
|
||||
),
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: color ?? Colors.blue,
|
||||
fontWeight: fontWeight ?? FontWeight.normal,
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
border: (selected != null && selected) ? Border(
|
||||
bottom: BorderSide(
|
||||
color: color ?? Colors.blue,
|
||||
width: 3.0,
|
||||
)
|
||||
) : null,
|
||||
),
|
||||
),
|
||||
onTap: () async {
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
throw 'Could not launch $url';
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
94
lib/widgets/mobile/mobile_index_carousel.dart
Normal file
94
lib/widgets/mobile/mobile_index_carousel.dart
Normal file
@@ -0,0 +1,94 @@
|
||||
|
||||
import 'package:carousel_slider/carousel_slider.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import '../../models/gallery.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileIndexCarousel extends StatefulWidget {
|
||||
final List<Gallery> galleries;
|
||||
|
||||
const MobileIndexCarousel(this.galleries, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileIndexCarouselState();
|
||||
}
|
||||
}
|
||||
|
||||
class MobileIndexCarouselState extends State<MobileIndexCarousel> {
|
||||
int _current = 0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.only(left: 0.0, right: 0.0, top: 0.0, bottom: 0.0),
|
||||
child: CarouselSlider(
|
||||
items: widget.galleries.map((i) {
|
||||
return Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
// margin: EdgeInsets.symmetric(horizontal: 5.0),
|
||||
child: GestureDetector(
|
||||
child: Container(
|
||||
child: Util.showImage(
|
||||
'https:${i.image}',
|
||||
fit: BoxFit.fitWidth,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
if (i.linkUrl != null && i.linkUrl.isNotEmpty) {
|
||||
Util.openWebUrl(context, i.linkUrl);
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
options: CarouselOptions(
|
||||
height: MediaQuery.of(context).size.width / 2.0,
|
||||
aspectRatio: 2/1,
|
||||
initialPage: 0,
|
||||
enableInfiniteScroll: true,
|
||||
autoPlay: true,
|
||||
autoPlayInterval: Duration(seconds: 5),
|
||||
autoPlayCurve: Curves.fastOutSlowIn,
|
||||
scrollDirection: Axis.horizontal,
|
||||
viewportFraction: 1.0,
|
||||
onPageChanged: (index, reason) {
|
||||
setState(() {
|
||||
_current = index;
|
||||
});
|
||||
}
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 5,
|
||||
right: 10,
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: widget.galleries.map((i) {
|
||||
int index = widget.galleries.indexOf(i);
|
||||
return Container(
|
||||
width: 8.0,
|
||||
height: 8.0,
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 2.0),
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: _current == index
|
||||
? Color.fromRGBO(0, 0, 0, 0.9)
|
||||
: Color.fromRGBO(0, 0, 0, 0.4),
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
40
lib/widgets/mobile/mobile_index_main_content_1.dart
Normal file
40
lib/widgets/mobile/mobile_index_main_content_1.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
|
||||
class MobileIndexMainContent1 extends StatefulWidget {
|
||||
final String message;
|
||||
|
||||
const MobileIndexMainContent1(this.message, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileIndexMainContent1State();
|
||||
}
|
||||
}
|
||||
|
||||
class MobileIndexMainContent1State extends State<MobileIndexMainContent1> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
padding: EdgeInsets.symmetric(vertical: 20.0, horizontal: 20.0),
|
||||
child: Container(
|
||||
child: Text(
|
||||
widget.message,
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.lightGreen,
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
119
lib/widgets/mobile/mobile_index_main_content_2.dart
Normal file
119
lib/widgets/mobile/mobile_index_main_content_2.dart
Normal file
@@ -0,0 +1,119 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileIndexMainContent2 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
|
||||
const MobileIndexMainContent2(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileIndexMainContent2State();
|
||||
}
|
||||
}
|
||||
|
||||
class MobileIndexMainContent2State extends State<MobileIndexMainContent2> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.content == null) {
|
||||
return Container();
|
||||
}
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['minipos']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['point_of_sale_system_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'http:${widget.content['minipos_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
_buildMiniPosFeatures(),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildMiniPosFeatures() {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['minipos_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['minipos_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
col.children.add(
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Text(
|
||||
S.of(context).learn_more,
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
122
lib/widgets/mobile/mobile_index_main_content_3.dart
Normal file
122
lib/widgets/mobile/mobile_index_main_content_3.dart
Normal file
@@ -0,0 +1,122 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import '../../utils/util_web.dart' if (dart.library.io) '../../utils/util_io.dart';
|
||||
|
||||
class MobileIndexMainContent3 extends StatefulWidget {
|
||||
final Map<String, dynamic> content;
|
||||
|
||||
const MobileIndexMainContent3(this.content, {Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileIndexMainContent3State();
|
||||
}
|
||||
}
|
||||
|
||||
class MobileIndexMainContent3State extends State<MobileIndexMainContent3> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (widget.content == null) {
|
||||
return Container();
|
||||
}
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
margin: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow']}',
|
||||
style: TextStyle(
|
||||
fontSize: 20.0,
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.blueGrey,
|
||||
),
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${widget.content['igoshow_solution']}',
|
||||
style: TextStyle(
|
||||
fontSize: 15.0,
|
||||
color: Colors.grey,
|
||||
),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10.0),
|
||||
child: Util.showImage(
|
||||
'http:${widget.content['igoshow_image']['image']}',
|
||||
fit: BoxFit.fitWidth
|
||||
),
|
||||
),
|
||||
_buildiGoShowFeatures(),
|
||||
Container(
|
||||
height: 20.0,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildiGoShowFeatures() {
|
||||
Column col = Column(
|
||||
children: [],
|
||||
);
|
||||
for (int i = 0; i < (widget.content['igoshow_features'] as List).length; i++) {
|
||||
col.children.add(Row(
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 8.0, horizontal: 5.0),
|
||||
child: Icon(
|
||||
Icons.circle,
|
||||
size: 10.0,
|
||||
color: Colors.black87,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width - 40.0,
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 5.0),
|
||||
child: Text(
|
||||
'${(widget.content['igoshow_features'] as List)[i]}',
|
||||
style: TextStyle(
|
||||
color: Colors.black54,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
));
|
||||
}
|
||||
col.children.add(
|
||||
GestureDetector(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 0.0),
|
||||
child: Text(
|
||||
S.of(context).learn_more,
|
||||
style: TextStyle(
|
||||
color: Colors.blue,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
return Container(
|
||||
padding: EdgeInsets.symmetric(vertical: 5.0, horizontal: 10.0),
|
||||
child: col,
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
233
lib/widgets/mobile/mobile_navigation_drawer.dart
Normal file
233
lib/widgets/mobile/mobile_navigation_drawer.dart
Normal file
@@ -0,0 +1,233 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/text_link.dart';
|
||||
import 'package:flutter_wisetronic/widgets/mobile/mobile_navigation_drawer_header.dart';
|
||||
|
||||
class MobileNavigationDrawer extends StatefulWidget {
|
||||
const MobileNavigationDrawer({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileNavigationDrawerState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MobileNavigationDrawerState extends State<MobileNavigationDrawer> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
String currentRoute = ModalRoute.of(context).settings.name;
|
||||
|
||||
return Container(
|
||||
width: 300.0,
|
||||
height: MediaQuery.of(context).size.height,
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
boxShadow: [
|
||||
BoxShadow(color: Colors.black12, blurRadius: 16.0),
|
||||
],
|
||||
),
|
||||
child: SingleChildScrollView(
|
||||
child: Column(
|
||||
children: [
|
||||
MobileNavigationDrawerHeader(),
|
||||
TextLink(
|
||||
S.of(context).home,
|
||||
'/',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).download,
|
||||
'/download',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/download',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).tutorials,
|
||||
'/tutorials',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/tutorials',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).support,
|
||||
'/support',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/support',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).shop,
|
||||
'/shop',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/shop',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).blog,
|
||||
'/blog',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/blog',
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).login,
|
||||
'/login',
|
||||
paddingVertical: 10.0,
|
||||
paddingHorizontal: 15.0,
|
||||
selected: currentRoute == '/login',
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 20.0),
|
||||
height: 0.5,
|
||||
color: Colors.green,
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
||||
child: Text(
|
||||
S.of(context).information,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black54,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).service_policy,
|
||||
'/service_policy',
|
||||
paddingVertical: 5.0,
|
||||
paddingHorizontal: 10.0,
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).return_policy,
|
||||
'/return_policy',
|
||||
paddingVertical: 5.0,
|
||||
paddingHorizontal: 10.0,
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).privacy_policy,
|
||||
'/privacy_policy',
|
||||
paddingVertical: 5.0,
|
||||
paddingHorizontal: 10.0,
|
||||
),
|
||||
TextLink(
|
||||
S.of(context).license_agreement,
|
||||
'/license_agreement',
|
||||
paddingVertical: 5.0,
|
||||
paddingHorizontal: 10.0,
|
||||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
||||
child: Text(
|
||||
S.of(context).support,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black54,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextLink(S.of(context).wiki, '/wiki', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).support_ticket, '/support_ticket', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).contact_us, '/contact_us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).about_us, '/about_us', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
TextLink(S.of(context).renew_license, '/renew_license', paddingVertical: 5.0, paddingHorizontal: 10.0,),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 20.0, bottom: 10.0),
|
||||
child: Text(
|
||||
S.of(context).developer_of,
|
||||
style: TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: Colors.black54,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
Wrap(
|
||||
children: [
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe800,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe801,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe802,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe803,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe804,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
Container(
|
||||
padding: EdgeInsets.all(10.0),
|
||||
child: Icon(
|
||||
IconData(
|
||||
0xe805,
|
||||
fontFamily: 'company',
|
||||
fontPackage: null
|
||||
),
|
||||
color: Colors.black26,
|
||||
size: 48.0,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
30
lib/widgets/mobile/mobile_navigation_drawer_header.dart
Normal file
30
lib/widgets/mobile/mobile_navigation_drawer_header.dart
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/generated/l10n.dart';
|
||||
|
||||
class MobileNavigationDrawerHeader extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
height: 40.0,
|
||||
padding: EdgeInsets.only(top: 10.0),
|
||||
color: Colors.green,
|
||||
alignment: Alignment.center,
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).navigation,
|
||||
style: TextStyle(
|
||||
fontSize: 18.0,
|
||||
fontWeight: FontWeight.w800,
|
||||
color: Colors.white,
|
||||
),
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
74
lib/widgets/mobile/mobile_navigationbar.dart
Normal file
74
lib/widgets/mobile/mobile_navigationbar.dart
Normal file
@@ -0,0 +1,74 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_wisetronic/events/eventbus.dart';
|
||||
import 'package:flutter_wisetronic/events/events.dart';
|
||||
import 'package:flutter_wisetronic/widgets/general/navigationbar_logo.dart';
|
||||
|
||||
class MobileNavigationBar extends StatefulWidget {
|
||||
const MobileNavigationBar({Key key}) : super(key: key);
|
||||
|
||||
@override
|
||||
State<StatefulWidget> createState() {
|
||||
return MobileNavigationBarState();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MobileNavigationBarState extends State<MobileNavigationBar> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0),
|
||||
height: 80.0,
|
||||
color: Colors.blue,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.menu),
|
||||
onPressed: () {
|
||||
eventBus.fire(OpenDrawer());
|
||||
},
|
||||
),
|
||||
Container(
|
||||
child: NavigationBarLogo(),
|
||||
padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 5.0),
|
||||
),
|
||||
Container()
|
||||
],
|
||||
),
|
||||
);
|
||||
// return Stack(
|
||||
// children: [
|
||||
// Container(
|
||||
// height: 80.0,
|
||||
// color: Colors.blue,
|
||||
// ),
|
||||
// Container(
|
||||
// padding: EdgeInsets.only(left: 10.0, right: 10.0),
|
||||
// height: 80.0,
|
||||
// child: Row(
|
||||
// mainAxisSize: MainAxisSize.max,
|
||||
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
// children: [
|
||||
// IconButton(
|
||||
// icon: Icon(Icons.menu),
|
||||
// onPressed: () {
|
||||
//
|
||||
// },
|
||||
// ),
|
||||
// Container(
|
||||
// child: NavigationBarLogo(),
|
||||
// padding: EdgeInsets.only(left: 10.0, right: 10.0, top: 5.0, bottom: 5.0),
|
||||
// ),
|
||||
// Container()
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user