template.dart 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:io';
  4. import 'dart:ui';
  5. import 'package:another_flushbar/flushbar.dart';
  6. import 'package:auto_route/auto_route.dart';
  7. import 'package:cached_network_image/cached_network_image.dart';
  8. import 'package:dotted_line/dotted_line.dart';
  9. import 'package:easy_localization/easy_localization.dart';
  10. import 'package:flutter/foundation.dart';
  11. import 'package:flutter/material.dart';
  12. import 'package:flutter_cache_manager/flutter_cache_manager.dart';
  13. import 'package:loading_indicator/loading_indicator.dart';
  14. import 'package:lottie/lottie.dart';
  15. import 'package:page_transition/page_transition.dart';
  16. import 'package:photo_view/photo_view.dart';
  17. import 'package:photo_view/photo_view_gallery.dart';
  18. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  19. import 'package:telnow_mobile_new/src/api/jwt_token.dart';
  20. import 'package:telnow_mobile_new/src/injector/injector.dart';
  21. import 'package:telnow_mobile_new/src/layouts/auth/qr.dart';
  22. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  23. import 'package:telnow_mobile_new/src/utils/U.dart';
  24. import 'package:telnow_mobile_new/src/utils/cache_manager.dart';
  25. import 'package:uuid/uuid.dart';
  26. PreferredSizeWidget appBarTemplate({required BuildContext context, required String title, String icon = 'arrow-left', List<Widget>? action, exc = false}){
  27. return AppBar(
  28. elevation: 0,
  29. bottomOpacity: 0,
  30. backgroundColor: backgroundColor,
  31. leading: GestureDetector(
  32. child: U.iconsax(icon, color: textColor),
  33. onTap: ()=>Navigator.of(context).pop(exc),
  34. ),
  35. titleSpacing: 0,
  36. title: Text(title, style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis),
  37. actions: action,
  38. );
  39. }
  40. Widget buttonTemplate({double width = double.infinity, double height = 51, required String text, required action(), backgroundColor = primaryColor, textColor = Colors.white, borderColor = primaryColor}){
  41. return SizedBox(
  42. width: width,
  43. height: height,
  44. child: ElevatedButton(
  45. style: ButtonStyle(
  46. elevation: MaterialStateProperty.all<double>(0),
  47. backgroundColor: MaterialStateProperty.all<Color>(backgroundColor),
  48. shape: MaterialStateProperty.all<RoundedRectangleBorder>(RoundedRectangleBorder(borderRadius: BorderRadius.circular(12))),
  49. side: MaterialStateProperty.all<BorderSide>(BorderSide(color: borderColor))
  50. ),
  51. onPressed: ()=>action(),
  52. child: Text(text, style: TextStyle(fontSize: 16, color: textColor, fontWeight: FontWeight.w500)),
  53. ),
  54. );
  55. }
  56. Widget textVertical(String title, String subtitle){
  57. return Column(
  58. crossAxisAlignment: CrossAxisAlignment.start,
  59. children: [
  60. Text(title, style: TextStyle(color: textColor)),
  61. SizedBox(height: 5),
  62. Text(subtitle, style: TextStyle(color: textColor, fontSize: 12, fontWeight: FontWeight.w300)),
  63. ],
  64. );
  65. }
  66. Widget textHorizontal(String title, String subtitle, {double size = 14, double opacity = 1}){
  67. return Row(
  68. crossAxisAlignment: CrossAxisAlignment.start,
  69. children: [
  70. Text(title, style: TextStyle(color: textColor.withValues(alpha: opacity), fontSize: size)),
  71. Expanded(
  72. child: Text(subtitle, style: TextStyle(color: textColor, fontSize: size), maxLines: 3, overflow: TextOverflow.ellipsis, textAlign: TextAlign.right),
  73. ),
  74. ],
  75. );
  76. }
  77. Widget divider({opacity = 0.15}){
  78. return Divider(height: 1, thickness: 1, color: textColor.withValues(alpha: opacity));
  79. }
  80. Widget dashed({double top = 8, double bottom = 8, double left = 0, double right = 0, Color color = textColor, double width = double.infinity}){
  81. return Padding(padding: EdgeInsets.only(top: top, bottom: bottom, left: left, right: right), child: DottedLine(dashColor: color, lineLength: width, dashLength: 5, dashGapLength: 5, lineThickness: 0.15, dashRadius: 1));
  82. }
  83. Widget separator(){
  84. return Container(
  85. color: Color(0xffF3F3F3),
  86. width: double.infinity, height: 8,
  87. );
  88. }
  89. //------------------------------------------------------------------------------
  90. Widget categoryContainer({required BuildContext context, required String iconUrl}){
  91. double size = U.bodyWidth(context)/6;
  92. String ext = iconUrl.split(".").last;
  93. return Container(
  94. padding: EdgeInsets.all(5),
  95. child: Image(image: CachedNetworkImageProvider(iconUrl+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(iconUrl+'?bridge-cache=true'))), width: size, height: size),
  96. decoration: BoxDecoration(
  97. color: Colors.white,
  98. borderRadius: BorderRadius.all(Radius.circular(20)),
  99. border: Border.all(width: 0.2, color: Colors.black12),
  100. boxShadow: [BoxShadow(color: Colors.grey.withValues(alpha: 0.3), blurRadius: 2, offset: Offset(0, 2))]
  101. ),
  102. );
  103. }
  104. Widget shimmerTopMenu(BuildContext context){
  105. double size = (U.bodyWidth(context)/6)+10;
  106. return Row(
  107. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  108. children: List.generate(4, (index){
  109. return Container(
  110. width: size, height: size,
  111. decoration: BoxDecoration(
  112. color: Colors.black26,
  113. borderRadius: BorderRadius.all(Radius.circular(20)),
  114. ),
  115. );
  116. // return Shimmer.fromColors(
  117. // baseColor: Colors.grey[400]!,
  118. // highlightColor: Colors.white,
  119. // child: Container(
  120. // width: size, height: size,
  121. // decoration: BoxDecoration(
  122. // color: Colors.white,
  123. // borderRadius: BorderRadius.all(Radius.circular(20)),
  124. // ),
  125. // ),
  126. // );
  127. }),
  128. );
  129. }
  130. //------------------------------------------------------------------------------
  131. Widget requestTiles({required String image, required String title, required String subtitle, bool border = false, double vertical = 16}){
  132. return Container(
  133. margin: EdgeInsets.symmetric(vertical: vertical),
  134. padding: EdgeInsets.only(right: border?16:0),
  135. child: Row(
  136. children: [
  137. imageTiles(imageUrl: image),
  138. SizedBox(width: 16),
  139. Expanded(
  140. child: Column(
  141. crossAxisAlignment: CrossAxisAlignment.start,
  142. children: [
  143. Text(title, style: TextStyle(color: textColor, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis),
  144. dashed(),
  145. Text(subtitle, style: TextStyle(color: textColor, fontSize: 13, fontWeight: FontWeight.w300), maxLines: 2, overflow: TextOverflow.ellipsis)
  146. ],
  147. ),
  148. )
  149. ],
  150. ),
  151. decoration: BoxDecoration(
  152. color: Colors.white,
  153. border: border?Border.all(color: textColor.withValues(alpha: 0.15)):null,
  154. borderRadius: border?BorderRadius.all(Radius.circular(12)):null
  155. ),
  156. );
  157. }
  158. Widget imageTiles({required String imageUrl, double width = 100, double height = 80, double radius = 12}){
  159. return imageUrl != "null" ? Container(
  160. padding: EdgeInsets.fromLTRB(1, 0, 1, 0),
  161. decoration: BoxDecoration(
  162. color: textColor.withValues(alpha: 0.1),
  163. borderRadius: BorderRadius.all(Radius.circular(radius)),
  164. ),
  165. child: Container(
  166. width: width, height: height,
  167. decoration: BoxDecoration(
  168. color: textColor.withValues(alpha: 0.1),
  169. borderRadius: BorderRadius.all(Radius.circular(radius)),
  170. image: DecorationImage(
  171. image: CachedNetworkImageProvider(imageUrl+'?bridge-cache=true', cacheManager: CacheManager(CacheMan.config(imageUrl+'?bridge-cache=true'))),
  172. fit: BoxFit.cover,
  173. ),
  174. ),
  175. ),
  176. ): Container(
  177. height: height,
  178. width: width,
  179. child: Center(child: Text("noImage".tr(), style: TextStyle(fontStyle: FontStyle.italic, fontSize: width<100?10:14, color: Colors.black38), maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center,)),
  180. decoration: BoxDecoration(
  181. color: Colors.black12,
  182. borderRadius: BorderRadius.all(Radius.circular(12.0))
  183. ),
  184. );
  185. }
  186. Widget loginFieldTemplate({required String value, placeholder = '', required action(value), required submit(value), isPassword = false}){
  187. TextEditingController controller = TextEditingController()..text = value;
  188. bool hidePass = true;
  189. return SizedBox(
  190. width: double.infinity,
  191. child: StatefulBuilder(
  192. builder: (context, fieldState) => TextFormField(
  193. controller: controller,
  194. style: TextStyle(fontSize: 16, color: Colors.white),
  195. keyboardType: TextInputType.text,
  196. obscureText: isPassword?hidePass:false,
  197. cursorColor: Colors.white,
  198. decoration: InputDecoration(
  199. hintText: placeholder,
  200. hintStyle: TextStyle(fontSize: 16, color: Colors.white.withValues(alpha: 0.6)),
  201. filled: true,
  202. fillColor: Colors.white.withValues(alpha: 0.25),
  203. hoverColor: Colors.white.withValues(alpha: 0.26),
  204. contentPadding: EdgeInsets.all(16),
  205. border: InputBorder.none,
  206. suffixIconConstraints: BoxConstraints(maxHeight: 40, maxWidth: 40, minHeight: 40, minWidth: 40),
  207. suffixIcon: isPassword?GestureDetector(child: U.iconsax(hidePass?'eye':'eye-slash', color: Colors.white.withValues(alpha: 0.6)), onTap: ()=>fieldState(()=>hidePass=!hidePass)):null,
  208. enabledBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.white)),
  209. focusedBorder: OutlineInputBorder(borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.white)),
  210. isDense: true
  211. ),
  212. onChanged: (val)=>action(val.toString()),
  213. onFieldSubmitted: (val)=>submit(val.toString()),
  214. ),
  215. ),
  216. );
  217. }
  218. Widget loadingTemplate(){
  219. return Center(
  220. child: Container(
  221. height: 36,
  222. child: LoadingIndicator(
  223. indicatorType: Indicator.ballPulseRise,
  224. colors: U.defaultRainbowColors(),
  225. strokeWidth: 2,
  226. backgroundColor: Colors.black.withValues(alpha: 0),
  227. pathBackgroundColor: Colors.black,
  228. ),
  229. ),
  230. );
  231. }
  232. Widget infoContainer(String text){
  233. return Container(
  234. width: double.infinity,
  235. padding: EdgeInsets.all(12),
  236. child: Text(text, style: TextStyle(color: textColor), textAlign: TextAlign.center),
  237. decoration: BoxDecoration(
  238. color: secondaryColor.withValues(alpha: 0.1),
  239. border: Border.all(color: secondaryColor),
  240. borderRadius: BorderRadius.all(Radius.circular(12))
  241. ),
  242. );
  243. }
  244. class PhotoPreview extends StatelessWidget {
  245. final title;
  246. final imageUrl;
  247. final bool isUrl;
  248. final bool isNetwork;
  249. PhotoPreview(this.title, this.imageUrl, this.isUrl, {this.isNetwork = false});
  250. @override
  251. Widget build(BuildContext context) {
  252. return Scaffold(
  253. backgroundColor: Colors.black,
  254. appBar: AppBar(
  255. elevation: 0,
  256. bottomOpacity: 0,
  257. titleSpacing: 0,
  258. title: Text(title, style: TextStyle(color: Colors.white, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis),
  259. backgroundColor: Colors.black.withValues(alpha: 0.4),
  260. leading: GestureDetector(
  261. child: U.iconsax('arrow-left', color: Colors.white),
  262. onTap: () => Navigator.of(context).pop(),
  263. ),
  264. ),
  265. body: Container(
  266. width: MediaQuery.of(context).size.width,
  267. height: MediaQuery.of(context).size.height,
  268. child: PhotoView(
  269. maxScale: 5.0,
  270. minScale: 0.3,
  271. imageProvider: (isUrl ? NetworkImage(imageUrl) : isNetwork ? MemoryImage(imageUrl) : FileImage(imageUrl)) as ImageProvider<Object>?,
  272. )),
  273. );
  274. }
  275. }
  276. class PhotoPreviewGallery extends StatelessWidget {
  277. final String title;
  278. final List imageList;
  279. final int startIndex;
  280. final bool isUrl;
  281. final String column;
  282. const PhotoPreviewGallery({required this.title, required this.imageList, required this.startIndex, this.isUrl = true, this.column = 'image', super.key});
  283. @override
  284. Widget build(BuildContext context) {
  285. return Scaffold(
  286. backgroundColor: Colors.black,
  287. appBar: AppBar(
  288. title: Text(title, style: TextStyle(fontSize: 18)),
  289. backgroundColor: Colors.black.withValues(alpha: 0.4),
  290. titleSpacing: 0,
  291. leading: new IconButton(
  292. icon: new Icon(Icons.arrow_back_rounded),
  293. onPressed: () => Navigator.of(context).pop(),
  294. ),
  295. ),
  296. body: Container(
  297. width: MediaQuery.of(context).size.width,
  298. height: MediaQuery.of(context).size.height,
  299. child: PhotoViewGallery.builder(
  300. itemCount: imageList.length,
  301. pageController: PageController(initialPage: startIndex),
  302. builder: (context, index) {
  303. var uuid = Uuid().v1().replaceAll('-', '');
  304. return PhotoViewGalleryPageOptions(
  305. imageProvider: (isUrl?NetworkImage(imageList[index][column]+'?uuid='+uuid):imageList[index] is File?FileImage(imageList[index]):MemoryImage(imageList[index])) as ImageProvider<Object>?,
  306. maxScale: 5.0, minScale: 0.3,
  307. );
  308. },
  309. )
  310. ),
  311. );
  312. }
  313. }
  314. //------------------------------------------------------------------------------
  315. class MyClipper extends CustomClipper<Path> {
  316. final isNip;
  317. MyClipper(this.isNip);
  318. @override
  319. Path getClip(Size size) {
  320. var path = Path();
  321. double factor = 6.0;
  322. path.lineTo(0, size.height - factor);
  323. path.quadraticBezierTo(0, size.height, factor, size.height);
  324. if (isNip) {
  325. path.lineTo(size.width - (factor * 2), size.height);
  326. path.quadraticBezierTo(size.width - factor, size.height, size.width - factor, size.height - factor);
  327. path.lineTo(size.width - factor, factor);
  328. } else {
  329. path.lineTo(size.width - factor, size.height);
  330. path.quadraticBezierTo(size.width, size.height, size.width, size.height - factor);
  331. path.lineTo(size.width, factor);
  332. path.quadraticBezierTo(size.width, 0, size.width - factor, 0);
  333. }
  334. path.lineTo(size.width, 0);
  335. path.lineTo(factor, 0);
  336. path.quadraticBezierTo(0, 0, 0, factor);
  337. return path;
  338. }
  339. @override
  340. bool shouldReclip(CustomClipper oldClipper) => true;
  341. }
  342. class YourClipper extends CustomClipper<Path> {
  343. final isNip;
  344. YourClipper(this.isNip);
  345. @override
  346. Path getClip(Size size) {
  347. var path = Path();
  348. double factor = 6.0;
  349. if (isNip) {
  350. path.lineTo(factor, factor);
  351. path.lineTo(factor, size.height - factor);
  352. path.quadraticBezierTo(factor, size.height, factor * 2, size.height);
  353. } else {
  354. path.lineTo(0, size.height - factor);
  355. path.quadraticBezierTo(0, size.height, factor, size.height);
  356. }
  357. path.lineTo(size.width - factor, size.height);
  358. path.quadraticBezierTo(size.width, size.height, size.width, size.height - factor);
  359. path.lineTo(size.width, factor);
  360. path.quadraticBezierTo(size.width, 0, size.width - factor, 0);
  361. if (!isNip) {
  362. path.lineTo(factor, 0);
  363. path.quadraticBezierTo(0, 0, 0, factor);
  364. }
  365. return path;
  366. }
  367. @override
  368. bool shouldReclip(CustomClipper oldClipper) => true;
  369. }
  370. isBase64(value) {
  371. try {
  372. base64Decode(value);
  373. return true;
  374. } catch (e) {
  375. return false;
  376. }
  377. }
  378. //------------------------------------------------------------------------------
  379. class Debouncer {
  380. final int? milliseconds;
  381. VoidCallback? action;
  382. Timer? _timer;
  383. Debouncer({this.milliseconds});
  384. run(VoidCallback action) {
  385. if (null != _timer) {
  386. _timer?.cancel();
  387. }
  388. _timer = Timer(Duration(milliseconds: milliseconds!), action);
  389. }
  390. }
  391. navigateTo(BuildContext context, child){
  392. return Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: child));
  393. }
  394. navigateToThen(BuildContext context, child, act){
  395. return Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: child)).then((v) => act());
  396. }
  397. navigateBack(BuildContext context, {exc = false}){
  398. return Navigator.of(context).pop(exc);
  399. }
  400. void showError(BuildContext context, message) {
  401. Flushbar(
  402. message: message,
  403. icon: Icon(
  404. Icons.info_outline,
  405. size: 28.0,
  406. color: Colors.red,
  407. ),
  408. duration: Duration(seconds: 5),
  409. flushbarPosition: FlushbarPosition.BOTTOM,
  410. margin: EdgeInsets.all(8),
  411. borderRadius: BorderRadius.all(Radius.circular(8)),
  412. )..show(context);
  413. }
  414. void showSuccess(context, message) {
  415. Flushbar(
  416. message: message,
  417. icon: Icon(
  418. Icons.info_outline,
  419. size: 28.0,
  420. color: Colors.green,
  421. ),
  422. duration: Duration(seconds: 5),
  423. flushbarPosition: FlushbarPosition.BOTTOM,
  424. margin: EdgeInsets.all(8),
  425. borderRadius: BorderRadius.all(Radius.circular(8)),
  426. )..show(context);
  427. }
  428. String convertDate(date, locale) {
  429. if (date == "-" || date.isEmpty) {
  430. return date;
  431. }
  432. final dateToCheck = DateTime.parse(date);
  433. final now = DateTime.now();
  434. final today = DateTime(now.year, now.month, now.day);
  435. final yesterday = DateTime(now.year, now.month, now.day - 1);
  436. final aDate = DateTime(dateToCheck.year, dateToCheck.month, dateToCheck.day);
  437. if (aDate == today) {
  438. return 'today'.tr()+' '+DateFormat('HH:mm', locale).format(DateTime.parse(date));
  439. } else if (aDate == yesterday) {
  440. return 'yesterday'.tr()+' '+DateFormat('HH:mm', locale).format(DateTime.parse(date));
  441. } else {
  442. return DateFormat('dd MMM HH:mm', locale).format(DateTime.parse(date));
  443. }
  444. }
  445. //------------------------------------------------------------------------------
  446. class RefreshPage extends StatelessWidget {
  447. final VoidCallback onRefresh;
  448. RefreshPage(this.onRefresh);
  449. @override
  450. Widget build(BuildContext context) {
  451. return Container(
  452. padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 2.5),
  453. height: MediaQuery.of(context).size.height,
  454. child: Center(
  455. child: GestureDetector(
  456. child: Column(
  457. children: [
  458. Icon(Icons.refresh_rounded, size: 50, color: Colors.grey),
  459. Text('refresh'.tr(), style: TextStyle(color: Colors.grey))
  460. ],
  461. ),
  462. onTap: () => onRefresh(),
  463. ),
  464. ),
  465. );
  466. }
  467. }
  468. //------------------------------------------------------------------------------
  469. final JwtToken token = JwtToken();
  470. final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
  471. class NoDataPage extends StatelessWidget {
  472. @override
  473. Widget build(BuildContext context) {
  474. print(ApiAuthProvider().getServiceAsset('TNSendRequest.json'));
  475. return Center(
  476. child: Column(
  477. mainAxisSize: MainAxisSize.min,
  478. children: <Widget>[
  479. kIsWeb && !isCanvasKit ? Container(
  480. width: 150, margin: EdgeInsets.only(top: 20, bottom: 10), padding: EdgeInsets.all(10),
  481. child: Image(image: AssetImage('assets/image/error/EmptyData.png'))
  482. ) : Lottie.asset('assets/image/lottie/Nodata.json', width: 250, height: 250, fit: BoxFit.fill),
  483. Padding(
  484. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  485. child: Text('notFound'.tr(),
  486. style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
  487. textAlign: TextAlign.center),
  488. ),
  489. Padding(
  490. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  491. child: Text('notFound2'.tr(),
  492. style: TextStyle(fontSize: 14), textAlign: TextAlign.center),
  493. )
  494. ],
  495. ),
  496. );
  497. }
  498. }
  499. handlingError(context, type) {
  500. var data = [
  501. {
  502. 'image': 'NoInternet.png',
  503. 'title': 'noInternetTitle'.tr(),
  504. 'description': 'noInternetDesc'.tr()
  505. },
  506. {
  507. 'image': 'ErrorServer.png',
  508. 'title': 'errorServerTitle'.tr(),
  509. 'description': 'errorServerDesc'.tr()
  510. },
  511. {
  512. 'image': 'ErrorConnection.png',
  513. 'title': 'errorConnectTitle'.tr(),
  514. 'description': 'errorConnectDesc'.tr()
  515. },
  516. {
  517. 'image': 'ErrorAuth.png',
  518. 'title': 'invalidAccountTitle'.tr(),
  519. 'description': 'invalidAccountDesc'.tr()
  520. },
  521. {
  522. 'image': 'ErrorAuth.png',
  523. 'title': 'expAccountTitle'.tr(),
  524. 'description': 'expAccountDesc'.tr()
  525. }
  526. ];
  527. showModalBottomSheet<void>(
  528. context: context,
  529. backgroundColor: Colors.white,
  530. isDismissible: false,
  531. enableDrag: false,
  532. builder: (BuildContext context) {
  533. return SingleChildScrollView(
  534. child: Column(
  535. mainAxisSize: MainAxisSize.min,
  536. children: <Widget>[
  537. Container(
  538. padding: const EdgeInsets.fromLTRB(15, 10, 15, 0),
  539. alignment: Alignment.centerRight,
  540. child: GestureDetector(
  541. child: Icon(Icons.clear),
  542. onTap: () => Navigator.of(context).pop(),
  543. ),
  544. ),
  545. Container(
  546. width: 200,
  547. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  548. child: Image(
  549. image: AssetImage('assets/image/error/' + data[type]['image']!))),
  550. Padding(
  551. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  552. child: Text(data[type]['title']!,
  553. style: TextStyle(fontSize: 14, fontWeight: FontWeight.bold),
  554. textAlign: TextAlign.center),
  555. ),
  556. Padding(
  557. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  558. child: Text(data[type]['description']!,
  559. style: TextStyle(fontSize: 14),
  560. textAlign: TextAlign.center),
  561. ),
  562. type == 3 || type == 4
  563. ? Padding(
  564. padding: const EdgeInsets.fromLTRB(15, 0, 15, 10),
  565. child: SizedBox(
  566. width: double.infinity,
  567. height: 45,
  568. child: TextButton(
  569. style: ButtonStyle(
  570. backgroundColor:
  571. MaterialStateProperty.all<Color>(primaryColor),
  572. shape: MaterialStateProperty.all<
  573. RoundedRectangleBorder>(
  574. RoundedRectangleBorder(
  575. borderRadius: BorderRadius.circular(5),
  576. ))),
  577. child: new Text('logout'.tr().toUpperCase(),
  578. style: TextStyle(color: Colors.white),
  579. textAlign: TextAlign.center),
  580. onPressed: () {
  581. if (type == 4) {
  582. _sharedPreferencesManager.clearKey(
  583. SharedPreferencesManager.keyAccessCode);
  584. _sharedPreferencesManager.clearKey(
  585. SharedPreferencesManager.keySerialCode);
  586. _sharedPreferencesManager.clearKey(
  587. SharedPreferencesManager.keyAccessToken);
  588. _sharedPreferencesManager.clearKey(
  589. SharedPreferencesManager.keyRefreshToken);
  590. _sharedPreferencesManager.clearKey(
  591. SharedPreferencesManager.keyUsername);
  592. _sharedPreferencesManager.clearKey(
  593. SharedPreferencesManager.keyIsLogin);
  594. _sharedPreferencesManager.clearKey(
  595. SharedPreferencesManager.keyScoope);
  596. _sharedPreferencesManager.clearKey(
  597. SharedPreferencesManager.debugString);
  598. _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyHistoryMark);
  599. Navigator.pushAndRemoveUntil(
  600. context,
  601. MaterialPageRoute(
  602. builder: (context) => NewQrPage()),
  603. ModalRoute.withName("/home"));
  604. } else {
  605. var pid = U.getPidFromUrl(context.router.currentUrl);
  606. token.logout();
  607. context.router.removeLast();
  608. context.navigateToPath("/app/$pid/login");
  609. // print(pid);
  610. // context.router.removeLast();
  611. // context.navigateToPath('/app/$pid/login');
  612. }
  613. },
  614. )),
  615. )
  616. : Container(height: 1, width: 1)
  617. ],
  618. ),
  619. );
  620. });
  621. }
  622. // ignore: must_be_immutable
  623. class NoImageFound extends StatelessWidget {
  624. bool show = true;
  625. NoImageFound(this.show);
  626. @override
  627. Widget build(BuildContext context) {
  628. return Container(
  629. width: MediaQuery.of(context).size.width - 150,
  630. height: MediaQuery.of(context).size.height / 4,
  631. child: Stack(
  632. fit: StackFit.expand,
  633. children: [
  634. Image.asset('assets/image/general/QrCode.jpg', fit: BoxFit.cover),
  635. ClipRRect(
  636. // Clip it cleanly.
  637. child: BackdropFilter(
  638. filter: ImageFilter.blur(sigmaX: 10, sigmaY: 10),
  639. child: Container(
  640. color: Colors.grey.withValues(alpha: 0.5),
  641. alignment: Alignment.center,
  642. child: show
  643. ? Container(
  644. padding: const EdgeInsets.all(10),
  645. child: Text('notFoundImg'.tr(),
  646. style: TextStyle(fontSize: 12)),
  647. decoration: BoxDecoration(
  648. color: Colors.white24,
  649. borderRadius:
  650. BorderRadius.all(Radius.circular(50))),
  651. )
  652. : Center(
  653. child: CircularProgressIndicator(),
  654. ),
  655. ),
  656. ),
  657. ),
  658. ],
  659. ),
  660. );
  661. }
  662. }
  663. dialogConfirm({required BuildContext context, required String title, required String text, required Function actionYes}){
  664. showDialog(
  665. context: context,
  666. builder: (BuildContext context) {
  667. return AlertDialog(
  668. title: Text(title),
  669. content: Text(text),
  670. actions: <Widget>[
  671. TextButton(
  672. child: Text("buttonNo".tr()),
  673. onPressed: () {
  674. Navigator.of(context).pop();
  675. },
  676. ),
  677. TextButton(
  678. onPressed: (){
  679. Navigator.of(context).pop();
  680. actionYes();
  681. },
  682. child: Text("buttonYes".tr())),
  683. ],
  684. );
  685. },
  686. );
  687. }
  688. showLoading(BuildContext context, {String? text, String? lottie}){
  689. showDialog(
  690. context: context,
  691. barrierDismissible: false,
  692. barrierColor: lottie!=null?Colors.white:null,
  693. builder: (BuildContext context) {
  694. return WillPopScope(
  695. onWillPop: ()=>Future.value(false),
  696. child: Center(
  697. child: Column(
  698. mainAxisSize: MainAxisSize.min,
  699. children: [
  700. lottie != null ? Lottie.asset('assets/image/lottie/$lottie', width: 250, height: 250, fit: BoxFit.fill) : CircularProgressIndicator(color: primaryColor),
  701. SizedBox(height: 5),
  702. Text(text??'inProcess'.tr(), style: TextStyle(color: lottie!=null?Colors.black:Colors.white))
  703. ],
  704. ),
  705. ),
  706. );
  707. },
  708. );
  709. }
  710. closeLoading(BuildContext context){
  711. Navigator.of(context, rootNavigator: true).pop();
  712. }