menu_account.dart 26 KB

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