menu_account.dart 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. import 'package:app_settings/app_settings.dart';
  2. import 'package:auto_route/auto_route.dart';
  3. import 'package:easy_localization/easy_localization.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:page_transition/page_transition.dart';
  6. import 'package:provider/provider.dart';
  7. import 'package:qr_flutter/qr_flutter.dart';
  8. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  9. import 'package:telnow_mobile_new/src/layouts/functions/account.dart';
  10. import 'package:telnow_mobile_new/src/layouts/mobile/password.dart';
  11. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  12. import 'package:telnow_mobile_new/src/utils/U.dart';
  13. import 'package:telnow_mobile_new/src/utils/provider.dart';
  14. import 'package:permission_handler/permission_handler.dart';
  15. import '../../utils/C.dart';
  16. class MobAccountPage extends StatefulWidget {
  17. const MobAccountPage({super.key});
  18. @override
  19. State<MobAccountPage> createState() => _MobAccountPageState();
  20. }
  21. class _MobAccountPageState extends State<MobAccountPage> {
  22. final AccountFunction accFunc = AccountFunction();
  23. bool isDeniedNotifPermission = false;
  24. bool serDis = false;
  25. bool dnd = false;
  26. bool autoTranslate = false;
  27. List lang = [];
  28. bool _timeLimit = false;
  29. var codeOflang = {};
  30. @override
  31. void initState() {
  32. Provider.of<UserModule>(context, listen: false).reset();
  33. accFunc.getUser(context);
  34. setToggle();
  35. checkPermission(0);
  36. // TODO: implement initState
  37. super.initState();
  38. }
  39. checkPermission(seconds){
  40. Future.delayed(Duration(seconds: seconds)).then((value)async {
  41. bool denied = await Permission.notification.isDenied;
  42. if(!U.getNotifPermission() && !denied) U.setNotifPermissionDismissed(false);
  43. U.setNotifPermission(!denied);
  44. setState(() => isDeniedNotifPermission = denied);
  45. });
  46. }
  47. setToggle() async{
  48. var license = await U.getLicense();
  49. if(await U.isCompatibleWith(VersionKey.multiBahasa)){
  50. lang = license['_validLang'] ?? [];
  51. } else {
  52. lang = license['languages'] != null ? license['languages'].split(',') : [];
  53. }
  54. setState(() {
  55. dnd = Provider.of<UserModule>(context, listen: false).dndStatus();
  56. serDis = U.servantDisplay();
  57. autoTranslate = U.autoTranslate();
  58. });
  59. }
  60. @override
  61. Widget build(BuildContext context) {
  62. codeOflang = {
  63. "id": 'bahasa'.tr(),
  64. "en": 'english'.tr(),
  65. "ja": 'japanese'.tr(),
  66. "zh": 'chinese'.tr(),
  67. "ko": 'korean'.tr(),
  68. "ar": 'arabic'.tr(),
  69. "de": 'german'.tr(),
  70. "fr": 'french'.tr(),
  71. "hi": 'hindi'.tr(),
  72. "nl": 'dutch'.tr()
  73. };
  74. return Provider.of<UserModule>(context).user().isNotEmpty ? Scaffold(
  75. backgroundColor: backgroundColor,
  76. appBar: AppBar(
  77. elevation: 0,
  78. bottomOpacity: 0,
  79. backgroundColor: backgroundColor,
  80. titleSpacing: 16,
  81. title: Text('account'.tr(), style: TextStyle(color: textColor, fontSize: 17, fontWeight: FontWeight.w500), overflow: TextOverflow.ellipsis),
  82. ),
  83. body: Column(
  84. children: [
  85. divider(),
  86. Expanded(
  87. child: Container(
  88. alignment: Alignment.topCenter,
  89. width: U.bodyWidth(context),
  90. child: SingleChildScrollView(
  91. child: Column(
  92. crossAxisAlignment: CrossAxisAlignment.start,
  93. children: [
  94. Container(
  95. padding: EdgeInsets.all(16),
  96. child: Row(
  97. children: [
  98. CircleAvatar(
  99. child: Text(Provider.of<UserModule>(context).user()['name'][0].toString().toUpperCase(), style: TextStyle(color: Colors.white)),
  100. backgroundColor: primaryColor,
  101. radius: 25,
  102. ),
  103. SizedBox(width: 16),
  104. Expanded(child: Text(Provider.of<UserModule>(context).user()['name'], style: TextStyle(fontSize: 16, fontWeight: FontWeight.w500, color: textColor), maxLines: 2, overflow: TextOverflow.ellipsis))
  105. ],
  106. ),
  107. ),
  108. separator(),
  109. Container(
  110. padding: EdgeInsets.all(16),
  111. child: Column(
  112. crossAxisAlignment: CrossAxisAlignment.start,
  113. children: [
  114. Text('info_label'.tr(), style: TextStyle(color: textColor, fontSize: 16, fontWeight: FontWeight.w500)),
  115. SizedBox(height: 20),
  116. textHorizontal('userId'.tr(), Provider.of<UserModule>(context).user()['relatedTo'] ?? Provider.of<UserModule>(context).user()['userId'], size: 16, opacity: 0.75),
  117. SizedBox(height: 12),
  118. textHorizontal('location'.tr(), Provider.of<UserModule>(context).user()['location'] ?? '-', size: 16, opacity: 0.75),
  119. SizedBox(height: 12),
  120. textHorizontal('servantGroup'.tr(), Provider.of<UserModule>(context).user()['requestTypeListDescriptionMobile'] != null ? Provider.of<UserModule>(context).user()['requestTypeListDescriptionMobile'].toLowerCase() == 'semua' ? 'all'.tr() : Provider.of<UserModule>(context).user()['requestTypeListDescriptionMobile'] : '-', size: 16, opacity: 0.75),
  121. ],
  122. ),
  123. ),
  124. Provider.of<UserModule>(context).houseKeeping()?separator():Container(),
  125. Provider.of<UserModule>(context).houseKeeping()?Container(
  126. padding: EdgeInsets.all(16),
  127. child: Column(
  128. crossAxisAlignment: CrossAxisAlignment.start,
  129. children: [
  130. Text('doNotDisturb'.tr(), style: TextStyle(color: textColor, fontSize: 16, fontWeight: FontWeight.w500)),
  131. SizedBox(height: 20),
  132. Row(
  133. children: [
  134. Expanded(child: Text('set_dnd_status'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16))),
  135. Text(dnd?'active_dnd'.tr():'inactive_dnd'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  136. SizedBox(width: 5),
  137. GestureDetector(
  138. child: Container(
  139. decoration: BoxDecoration(border: Border.all(color: Provider.of<UserModule>(context).user()['checkedIn']?primaryColor:Colors.black38, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(50))),
  140. child: Row(
  141. children: [
  142. !dnd?Container(
  143. width: 20, height: 20, decoration: BoxDecoration(color: Provider.of<UserModule>(context).user()['checkedIn']?primaryColor:Colors.black38, borderRadius: BorderRadius.all(Radius.circular(20))),
  144. ):Container(width: 20, height: 20),
  145. dnd?Container(
  146. width: 20, height: 20, decoration: BoxDecoration(color: Provider.of<UserModule>(context).user()['checkedIn']?primaryColor:Colors.black38, borderRadius: BorderRadius.all(Radius.circular(20))),
  147. ):Container(width: 20, height: 20),
  148. ],
  149. ),
  150. ),
  151. onTap: Provider.of<UserModule>(context).user()['checkedIn']?(){
  152. dialogConfirm(context: context, title: 'set_dnd_status'.tr(), text: dnd?'msg_change_inactive'.tr():'msg_change_active'.tr(), actionYes: ()async{
  153. bool res = await accFunc.setDndStatus(context, dnd);
  154. if(res){
  155. setState(() => dnd = !dnd);
  156. }
  157. });
  158. }:null,
  159. ),
  160. ],
  161. )
  162. ],
  163. ),
  164. ):Container(),
  165. !Provider.of<UserModule>(context).user()['_profile']['isRoom']?separator():Container(),
  166. !Provider.of<UserModule>(context).user()['_profile']['isRoom']?Container(
  167. padding: EdgeInsets.all(16),
  168. child: Column(
  169. crossAxisAlignment: CrossAxisAlignment.start,
  170. children: [
  171. Text('display_menu'.tr(), style: TextStyle(color: textColor, fontSize: 16, fontWeight: FontWeight.w500)),
  172. SizedBox(height: 20),
  173. Row(
  174. children: [
  175. Expanded(child: Text(serDis?'ser_group'.tr():'req_group'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16))),
  176. SizedBox(width: 5),
  177. GestureDetector(
  178. child: Container(
  179. decoration: BoxDecoration(border: Border.all(color: primaryColor, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(50))),
  180. child: Row(
  181. children: [
  182. !serDis?Container(
  183. width: 20, height: 20, decoration: BoxDecoration(color: primaryColor, borderRadius: BorderRadius.all(Radius.circular(20))),
  184. ):Container(width: 20, height: 20),
  185. serDis?Container(
  186. width: 20, height: 20, decoration: BoxDecoration(color: primaryColor, borderRadius: BorderRadius.all(Radius.circular(20))),
  187. ):Container(width: 20, height: 20),
  188. ],
  189. ),
  190. ),
  191. onTap: (){
  192. setState(() {
  193. if(serDis){
  194. U.setServantDisplay(false);
  195. serDis = false;
  196. }
  197. else{
  198. U.setServantDisplay(true);
  199. serDis = true;
  200. }
  201. });
  202. },
  203. ),
  204. ],
  205. )
  206. ],
  207. ),
  208. ):Container(),
  209. separator(),
  210. Container(
  211. padding: EdgeInsets.fromLTRB(16, 16, 16, 0),
  212. child: Column(
  213. crossAxisAlignment: CrossAxisAlignment.start,
  214. children: [
  215. Text('setting'.tr(), style: TextStyle(color: textColor, fontSize: 16, fontWeight: FontWeight.w500)),
  216. SizedBox(height: 6),
  217. GestureDetector(
  218. child: Container(
  219. color: Colors.white,
  220. padding: EdgeInsets.symmetric(vertical: 16),
  221. child: Row(
  222. children: [
  223. U.iconsax('bold/global', color: textColor.withValues(alpha: 0.75)),
  224. SizedBox(width: 16),
  225. Expanded(child: Text('language'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16), overflow: TextOverflow.ellipsis)),
  226. Text(codeOflang[context.locale.toString()]!, style: TextStyle(color: textColor)),
  227. SizedBox(width: 12),
  228. U.iconsax('arrow-right-3', size: 16, color: textColor.withValues(alpha: 0.75)),
  229. ],
  230. ),
  231. ),
  232. onTap: ()=>changeLang(context, Provider.of<UserModule>(context, listen: false).user()),
  233. ),
  234. divider(),
  235. Container(
  236. color: Colors.white,
  237. padding: EdgeInsets.symmetric(vertical: 16),
  238. child: Row(
  239. children: [
  240. Icon(Icons.g_translate_rounded, color: textColor.withValues(alpha: 0.75)),
  241. SizedBox(width: 16),
  242. Expanded(child: Text('auto_translate'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16), overflow: TextOverflow.ellipsis)),
  243. Text(autoTranslate?'ON':'OFF', style: TextStyle(color: textColor)),
  244. SizedBox(width: 5),
  245. GestureDetector(
  246. child: Container(
  247. decoration: BoxDecoration(border: Border.all(color: autoTranslate?primaryColor:Colors.black38, width: 1.5), borderRadius: BorderRadius.all(Radius.circular(50))),
  248. child: Row(
  249. children: [
  250. !autoTranslate?Container(
  251. width: 20, height: 20, decoration: BoxDecoration(color: Colors.black38, borderRadius: BorderRadius.all(Radius.circular(20))),
  252. ):Container(width: 20, height: 20),
  253. autoTranslate?Container(
  254. width: 20, height: 20, decoration: BoxDecoration(color: primaryColor, borderRadius: BorderRadius.all(Radius.circular(20))),
  255. ):Container(width: 20, height: 20),
  256. ],
  257. ),
  258. ),
  259. onTap: (){
  260. setState(() {
  261. if(autoTranslate){
  262. U.setAutoTranslate(false);
  263. autoTranslate = false;
  264. }
  265. else{
  266. U.setAutoTranslate(true);
  267. autoTranslate = true;
  268. }
  269. });
  270. },
  271. ),
  272. ],
  273. ),
  274. ),
  275. divider(),
  276. GestureDetector(
  277. child: Container(
  278. color: Colors.white,
  279. padding: EdgeInsets.symmetric(vertical: 16),
  280. child: Row(
  281. children: [
  282. U.iconsax('bold/key', color: textColor.withValues(alpha: 0.75)),
  283. SizedBox(width: 16),
  284. Text('password'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16)),
  285. Expanded(child: Text('settingPasswordText'.tr(), style: TextStyle(color: textColor), overflow: TextOverflow.ellipsis, textAlign: TextAlign.end)),
  286. SizedBox(width: 12),
  287. U.iconsax('arrow-right-3', size: 16, color: textColor.withValues(alpha: 0.75)),
  288. ],
  289. ),
  290. ),
  291. onTap: ()=>Navigator.push(context, PageTransition(type: PageTransitionType.rightToLeft, child: MobPasswordPage(user: Provider.of<UserModule>(context, listen: false).user()))).then((value) {
  292. value??false;
  293. if (value) showSuccess(context, 'messagePassChanged'.tr());
  294. }),
  295. ),
  296. divider(),
  297. GestureDetector(
  298. child: Container(
  299. color: Colors.white,
  300. padding: EdgeInsets.symmetric(vertical: 16),
  301. child: Row(
  302. children: [
  303. U.iconsax('bold/logout', color: textColor.withValues(alpha: 0.75)),
  304. SizedBox(width: 16),
  305. Expanded(child: Text('logout'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16), overflow: TextOverflow.ellipsis)),
  306. U.iconsax('arrow-right-3', size: 16, color: textColor.withValues(alpha: 0.75)),
  307. ],
  308. ),
  309. ),
  310. onTap: (){
  311. showDialog(
  312. context: context,
  313. builder: (BuildContext context) {
  314. return AlertDialog(
  315. title: Text("logout".tr()),
  316. content: Text("textLogout".tr()),
  317. actions: <Widget>[
  318. TextButton(
  319. child: Text("buttonNo".tr()),
  320. onPressed: () {
  321. Navigator.of(context).pop();
  322. },
  323. ),
  324. TextButton(
  325. onPressed: () => accFunc.logoutAction(context),
  326. child: Text("buttonYes".tr())),
  327. ],
  328. );
  329. },
  330. );
  331. },
  332. ),
  333. ],
  334. ),
  335. ),
  336. separator(),
  337. GestureDetector(
  338. child: Container(
  339. color: Colors.white,
  340. margin: EdgeInsets.symmetric(horizontal: 16),
  341. padding: EdgeInsets.symmetric(vertical: 16),
  342. child: Row(
  343. children: [
  344. U.iconsax('bold/scan', color: textColor.withValues(alpha: 0.75)),
  345. SizedBox(width: 16),
  346. Expanded(child: Text('scan_qr'.tr(), style: TextStyle(color: textColor.withValues(alpha: 0.75), fontSize: 16), overflow: TextOverflow.ellipsis)),
  347. U.iconsax('arrow-right-3', size: 16, color: textColor.withValues(alpha: 0.75)),
  348. ],
  349. ),
  350. ),
  351. onTap: (){
  352. var size = MediaQuery.of(context).size.width - (MediaQuery.of(context).size.width/3);
  353. var pid = U.getPidFromUrl(context.router.currentUrl);
  354. var qr_data = 'https://telnow.telmessenger.com/#/app/${pid}%23${U.getBaseUrl()}';
  355. showDialog(
  356. context: context,
  357. builder: (BuildContext context) {
  358. return AlertDialog(
  359. title: Text("show_qr".tr(), style: TextStyle(fontSize: 16, color: Colors.black), textAlign: TextAlign.center),
  360. content: Column(
  361. mainAxisSize: MainAxisSize.min,
  362. crossAxisAlignment: CrossAxisAlignment.center,
  363. children: [
  364. SizedBox(
  365. width: size,
  366. height: size,
  367. child: QrImageView(
  368. data: qr_data,
  369. version: QrVersions.auto,
  370. gapless: true,
  371. ),
  372. ),
  373. SizedBox(height: 15),
  374. Text("show_qr_desc".tr(), style: TextStyle(fontSize: 14, color: Colors.black), textAlign: TextAlign.center)
  375. ],
  376. ),
  377. );
  378. },
  379. );
  380. },
  381. ),
  382. separator(),
  383. isDeniedNotifPermission ? Container(
  384. padding: EdgeInsets.all(16),
  385. child: GestureDetector(
  386. child: Column(
  387. crossAxisAlignment: CrossAxisAlignment.start,
  388. children: [
  389. Text("not_allow_permission".tr()),
  390. SizedBox(height: 8,),
  391. Text("tap_here".tr(), style: TextStyle(color: Color(0xFF198AF2)),),
  392. ],
  393. ),
  394. onTap: () => AppSettings.openAppSettings(type: AppSettingsType.notification).then((value) async {
  395. // print("after open setting");
  396. // checkPermission(2);
  397. }),
  398. ),
  399. ) : Container(),
  400. isDeniedNotifPermission ? Container() : separator(),
  401. Padding(
  402. padding: const EdgeInsets.symmetric(vertical: 24),
  403. child: Center(child: Column(
  404. children: [
  405. Text("${"version".tr()} ${ApiAuthProvider().displayVersion}"),
  406. Text("Build ${ApiAuthProvider().buildNumber}", style: TextStyle(fontSize: 13),),
  407. ],
  408. )),
  409. )
  410. ],
  411. ),
  412. ),
  413. ),
  414. )
  415. ],
  416. ),
  417. ) : Provider.of<UserModule>(context).resetData() ? RefreshPage(() {
  418. Provider.of<UserModule>(context, listen: false).setResetData(false);
  419. accFunc.getUser(context);
  420. }) : _timeLimit ? showButton(context) : loadingTemplate(() {if(mounted) setState(()=>_timeLimit=true);},);
  421. }
  422. changeLang(context, user) {
  423. showModalBottomSheet(
  424. context: context,
  425. backgroundColor: Colors.white,
  426. builder: (BuildContext context) {
  427. return Column(
  428. mainAxisSize: MainAxisSize.min,
  429. children: <Widget>[
  430. Padding(
  431. padding: EdgeInsets.symmetric(vertical: 16),
  432. child: Center(
  433. child: Text('chooseLanguage'.tr(), style: TextStyle(color: textColor)),
  434. ),
  435. ),
  436. divider(),
  437. SizedBox(height: 16),
  438. listOfLang(user),
  439. SizedBox(height: 16)
  440. ],
  441. );
  442. }
  443. );
  444. }
  445. listOfLang(user){
  446. return SafeArea(
  447. child: Column(
  448. crossAxisAlignment: CrossAxisAlignment.start,
  449. children: [
  450. ListTile(
  451. title: Text('bahasa'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  452. trailing: Icon(context.locale.toString()=='id'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  453. onTap: context.locale.toString() != 'id' ? () async {
  454. accFunc.switchLang(context, 'id', user);
  455. Navigator.of(context).pop();
  456. } : null,
  457. ),
  458. ListTile(
  459. title: Text('english'.tr(), style: TextStyle(color: textColor, fontSize: 14)),
  460. trailing: Icon(context.locale.toString()=='en'?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  461. onTap: context.locale.toString() != 'en' ? () async {
  462. accFunc.switchLang(context, 'en', user);
  463. Navigator.of(context).pop();
  464. } : null,
  465. ),
  466. //TODO: kene
  467. lang.length - 1 > 1 ? ListTile(
  468. title: Text(codeOflang[lang[2]], style: TextStyle(color: textColor, fontSize: 14)),
  469. trailing: Icon(context.locale.toString()==lang[2]?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  470. onTap: context.locale.toString() != lang[2] ? () async {
  471. accFunc.switchLang(context, 1, user);
  472. Navigator.of(context).pop();
  473. } : null,
  474. ) : Container(),
  475. lang.length - 1 > 2 ? ListTile(
  476. title: Text(codeOflang[lang[3]], style: TextStyle(color: textColor, fontSize: 14)),
  477. trailing: Icon(context.locale.toString()==lang[3]?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  478. onTap: context.locale.toString() != lang[3] ? () async {
  479. accFunc.switchLang(context, 2, user);
  480. Navigator.of(context).pop();
  481. } : null,
  482. ) : Container(),
  483. lang.length - 1 > 3 ? ListTile(
  484. title: Text(codeOflang[lang[4]], style: TextStyle(color: textColor, fontSize: 14)),
  485. trailing: Icon(context.locale.toString()==lang[4]?Icons.radio_button_checked:Icons.radio_button_off, color: primaryColor, size: 18),
  486. onTap: context.locale.toString() != lang[4] ? () async {
  487. accFunc.switchLang(context, 3, user);
  488. Navigator.of(context).pop();
  489. } : null,
  490. ) : Container(),
  491. ],
  492. ),
  493. );
  494. }
  495. }