U.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. import 'package:easy_localization/easy_localization.dart';
  2. import 'package:firebase_messaging/firebase_messaging.dart';
  3. import 'package:flutter/foundation.dart';
  4. import 'package:flutter/material.dart';
  5. import 'package:flutter_randomcolor/flutter_randomcolor.dart';
  6. import 'package:flutter_svg/svg.dart';
  7. import 'package:telnow_mobile_new/src/api/api_auth_repository.dart';
  8. import 'package:telnow_mobile_new/src/model/token/token.dart';
  9. import 'dart:convert';
  10. import 'package:flutter_local_notifications/flutter_local_notifications.dart';
  11. import 'package:fluttertoast/fluttertoast.dart';
  12. import 'package:telnow_mobile_new/src/api/api_auth_provider.dart';
  13. import 'package:telnow_mobile_new/src/api/jwt_token.dart';
  14. import 'package:telnow_mobile_new/src/injector/injector.dart';
  15. import 'package:telnow_mobile_new/src/model/refreshtoken/refresh_token_body.dart';
  16. import 'package:telnow_mobile_new/src/layouts/components/template.dart';
  17. import 'package:telnow_mobile_new/src/storage/sharedpreferences/shared_preferences_manager.dart';
  18. import 'package:synchronized/synchronized.dart';
  19. import 'cache_manager.dart';
  20. const Color backgroundColor = Colors.white;
  21. const Color primaryColor = Color(0xff078C84);
  22. const Color secondaryColor = Color(0xffCC6029);
  23. const Color textColor = Color(0xff292D32);
  24. const Color disabledColor = Color(0xff989696);
  25. class U {
  26. static final String passphrase = "telmessenger-key";
  27. static final SharedPreferencesManager _sharedPreferencesManager = locator<SharedPreferencesManager>();
  28. static dynamic _license;
  29. static dynamic _userData;
  30. static String rawPid = '';
  31. static String _url = '';
  32. static bool _hasChangedPassword = true;
  33. static bool _loadAfterRequest = false;
  34. static bool? _connected;
  35. static bool _notifPermission = false;
  36. static bool _notifPermissionDismissed = false;
  37. // static final ApiAuthProvider _apiAuthProvider = ApiAuthProvider();
  38. static final Codec<String, String> stringToBase64Url = utf8.fuse(base64Url);
  39. static final JwtToken token = JwtToken();
  40. static final _lockAuth = Lock();
  41. static int _authLastMs = 0;
  42. static Token? _lastReqToken;
  43. static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
  44. static const AndroidNotificationChannel channel = AndroidNotificationChannel(
  45. 'notification_channel', // id
  46. 'Normal Notification', // title
  47. description: 'This channel is used for normal notifications.', // description
  48. importance: Importance.high,
  49. enableLights: true,
  50. playSound: true,
  51. sound: RawResourceAndroidNotificationSound('notification_alarm'),
  52. );
  53. // =
  54. // FlutterLocalNotificationsPlugin();
  55. static Future<Token?> _tryRefreshAuth(RefreshTokenBody refreshTokenBody,
  56. {int n = 0}) async {
  57. ApiAuthRepository apiAuthRepository = ApiAuthRepository();
  58. try {
  59. Token token = await apiAuthRepository.postRefreshAuth(refreshTokenBody);
  60. await _sharedPreferencesManager.putString(
  61. SharedPreferencesManager.keyAccessToken, token.accessToken!);
  62. await _sharedPreferencesManager.putString(
  63. SharedPreferencesManager.keyRefreshToken, token.refreshToken!);
  64. return Future.value(token);
  65. } catch (error) {
  66. if (n < 3) {
  67. return _tryRefreshAuth(refreshTokenBody, n: n++);
  68. } else {
  69. await _sharedPreferencesManager.putString(
  70. SharedPreferencesManager.keyAccessToken, '');
  71. await _sharedPreferencesManager.putString(
  72. SharedPreferencesManager.keyRefreshToken, '');
  73. Future.error(error);
  74. }
  75. }
  76. }
  77. static Future waitForRefreshAuth() async {
  78. return _lockAuth.synchronized(() async {
  79. // print("wait refresh token OK");
  80. });
  81. }
  82. static Future<Token?> refreshAuth(RefreshTokenBody refreshTokenBody) async {
  83. // print("refresh token");
  84. return _lockAuth.synchronized(() async {
  85. // print("refresh token start");
  86. var nw = DateTime.now().millisecondsSinceEpoch;
  87. if (_authLastMs == 0 || nw - _authLastMs >= 5000) {
  88. // print("refresh token request");
  89. ApiAuthRepository apiAuthRepository = ApiAuthRepository();
  90. var token = await _tryRefreshAuth(refreshTokenBody);
  91. _authLastMs = DateTime.now().millisecondsSinceEpoch;
  92. _lastReqToken = token;
  93. }
  94. // print("refresh token finish");
  95. return _lastReqToken;
  96. });
  97. // if (token != null) {
  98. // _authLastMs = DateTime.now().millisecondsSinceEpoch;
  99. // _lastReqToken = token;
  100. // }
  101. // print("refresh token finish");
  102. // return Future.value(_lastReqToken);
  103. }
  104. static Future <String?> getFcmToken() async {
  105. // print("minta fcm nya");
  106. if (_sharedPreferencesManager.getString(SharedPreferencesManager.keyFcmToken) != "" && _sharedPreferencesManager.getString(SharedPreferencesManager.keyFcmToken) != null) {
  107. // print("return shared aja");
  108. return _sharedPreferencesManager.getString(SharedPreferencesManager.keyFcmToken);
  109. } else {
  110. try {
  111. var token = await FirebaseMessaging.instance.getToken();
  112. if (token != null) {
  113. _sharedPreferencesManager.putString(SharedPreferencesManager.keyFcmToken, token);
  114. // print("token from U: $token");
  115. return token;
  116. }
  117. } catch(e) {
  118. print(e.toString());
  119. return null;
  120. }
  121. }
  122. return null;
  123. }
  124. static void clearUserData() {
  125. _userData = null;
  126. }
  127. static void clearLicenseData() {
  128. _license = null;
  129. }
  130. static void setNotifPermission(value) {
  131. _notifPermission = value;
  132. }
  133. static getNotifPermission(){
  134. return _notifPermission;
  135. }
  136. static void setNotifPermissionDismissed(value) {
  137. _notifPermissionDismissed = value;
  138. }
  139. static getNotifPermissionDismissed(){
  140. return _notifPermissionDismissed;
  141. }
  142. static void savePreferences(token) async {
  143. // print('save preferences!');
  144. await _sharedPreferencesManager.putString(SharedPreferencesManager.keyAccessToken, token.accessToken);
  145. await _sharedPreferencesManager.putString(SharedPreferencesManager.keyRefreshToken, token.refreshToken);
  146. await _sharedPreferencesManager.putInt(SharedPreferencesManager.keyCountRefreshToken, 0);
  147. }
  148. static Future<bool> clearPreferences() async {
  149. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessToken);
  150. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyRefreshToken);
  151. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyUsername);
  152. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyIsLogin);
  153. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyScoope);
  154. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.debugString);
  155. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyMenuDisplay);
  156. return true;
  157. }
  158. static setChangedPassword(val) async {
  159. _hasChangedPassword = val;
  160. }
  161. static bool getChangedPassword() {
  162. return _hasChangedPassword;
  163. }
  164. static setInternetStatus(val) async {
  165. _connected = val;
  166. }
  167. static bool getInternetStatus() {
  168. return _connected??true;
  169. }
  170. static setLoadAfterRequest(val) async {
  171. _loadAfterRequest = val;
  172. }
  173. static bool getLoadAfterRequest() {
  174. return _loadAfterRequest;
  175. }
  176. static Future<dynamic> getUserData(context) async {
  177. if (_userData == null) {
  178. try {
  179. _userData = await token.getUserData(context);
  180. } catch (error) {
  181. print(error.toString());
  182. U.showDebugToast(error.toString());
  183. return Future.error(error);
  184. }
  185. }
  186. return Future.value(_userData);
  187. }
  188. static Future<dynamic> reloadLicense() async {
  189. _license = null;
  190. return getLicense();
  191. }
  192. static Future<dynamic>? getLicense({showErr = true}) async {
  193. if (_license == null) {
  194. try {
  195. var dt = await ApiAuthProvider().getJsonDataNoAuth('/api/license');
  196. _license = dt;
  197. } catch (error) {
  198. if(showErr){
  199. Fluttertoast.showToast(msg: 'invalid_bridge'.tr());
  200. }
  201. // print(error.toString());
  202. // U.showDebugToast(error.toString());
  203. return Future.error(error);
  204. }
  205. }
  206. return Future.value(_license);
  207. }
  208. static bool? isDebug() {
  209. return _sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsDebug);
  210. }
  211. static bool? isLoggedIn() {
  212. return _sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsLogin) != null ? _sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsLogin) : false;
  213. }
  214. static int? getVersion() {
  215. return _sharedPreferencesManager.getInt(SharedPreferencesManager.version);
  216. }
  217. static String? getAccessCode() {
  218. return _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessCode) == null || _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessCode) == '' ? null :
  219. _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessCode)!.contains("=") ?
  220. Uri.encodeComponent(_sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessCode)!) :
  221. _sharedPreferencesManager.getString(SharedPreferencesManager.keyAccessCode);
  222. }
  223. static String? getBaseUrl() {
  224. return _sharedPreferencesManager.getString(SharedPreferencesManager.keyBaseUrl);
  225. }
  226. static bool servantDisplay() {
  227. if(_sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyMenuDisplay)!){
  228. return _sharedPreferencesManager.getBool(SharedPreferencesManager.keyMenuDisplay)!;
  229. }
  230. return false;
  231. }
  232. static void setServantDisplay(bool servant) async {
  233. await _sharedPreferencesManager.putBool(SharedPreferencesManager.keyMenuDisplay, servant);
  234. }
  235. static bool autoTranslate() {
  236. if(_sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyAutoTranslate)!){
  237. return _sharedPreferencesManager.getBool(SharedPreferencesManager.keyAutoTranslate)!;
  238. }
  239. return false;
  240. }
  241. static void setAutoTranslate(bool translate) async {
  242. await _sharedPreferencesManager.putBool(SharedPreferencesManager.keyAutoTranslate, translate);
  243. }
  244. static void clearAccessCode() async {
  245. // print("accCode cleared!!");
  246. await _sharedPreferencesManager.clearKey(SharedPreferencesManager.keyAccessCode);
  247. return;
  248. }
  249. static String? getSerialCode() {
  250. return _sharedPreferencesManager.getString(SharedPreferencesManager.keySerialCode);
  251. }
  252. static int _serverVersion = 0;
  253. static getServerVersion() async{
  254. String url = '/api/license';
  255. try {
  256. var dt = await ApiAuthProvider().getJsonDataNoAuth(url);
  257. _serverVersion = dt['serverVersion'];
  258. CacheMan.writeData(url, _serverVersion);
  259. } catch (error) {
  260. var val = await CacheMan.readData(url);
  261. if (val != null) {
  262. _serverVersion = val['data'];
  263. }
  264. print("U checkServerVersion error: ${error.toString()}");
  265. }
  266. print('checking current server version: $_serverVersion');
  267. }
  268. static newServerVersion(int version){
  269. return version <= _serverVersion;
  270. }
  271. static int retServerVersion(){
  272. return _serverVersion;
  273. }
  274. static Map _otherLabelList = {};
  275. static getOtherLabelList(BuildContext context) async{
  276. if(newServerVersion(1725245109)){
  277. var res = await ApiAuthProvider().getData('/api/systemSettings/search/additional', {'key': 'request-for-other'}, context);
  278. if(res != null){
  279. _otherLabelList = res;
  280. }
  281. }
  282. }
  283. static otherLabelList(){
  284. return _otherLabelList;
  285. }
  286. static void showDebugToast(String msg) {
  287. if (_sharedPreferencesManager.getBool(SharedPreferencesManager.keyIsDebug)!) {
  288. Fluttertoast.showToast(
  289. msg: "Debug:" + msg,
  290. toastLength: Toast.LENGTH_SHORT,
  291. gravity: ToastGravity.BOTTOM,
  292. timeInSecForIosWeb: 1,
  293. backgroundColor: Colors.red,
  294. textColor: Colors.white,
  295. fontSize: 16.0);
  296. }
  297. }
  298. static double bodyWidth(context) {
  299. var width = MediaQuery.of(context).size.width;
  300. var height = MediaQuery.of(context).size.height;
  301. var portrait = !(width * 3 / 4 > height);
  302. var bodyWidth = portrait ? width : width / 2;
  303. if (bodyWidth < 500) {
  304. if (width < 500) {
  305. bodyWidth = width;
  306. } else {
  307. bodyWidth = 500;
  308. }
  309. }
  310. return bodyWidth;
  311. }
  312. static bool webView(BuildContext context){
  313. if(kIsWeb && MediaQuery.of(context).size.width >= 1000){
  314. return true;
  315. }
  316. return false;
  317. }
  318. static String rewriteUrl(String encrypted){
  319. var targetString = encrypted;
  320. if(encrypted.contains('/')){
  321. targetString = encrypted.split("/").first;
  322. }
  323. var baseUrl = decodeBase64Url(targetString);
  324. if(!baseUrl.contains('https://') && !baseUrl.contains('http://')){
  325. if(baseUrl.contains('://')){
  326. baseUrl = 'https://'+(baseUrl.split('://')[1]);
  327. }
  328. else{
  329. baseUrl = 'https://'+baseUrl;
  330. }
  331. }
  332. if(baseUrl.substring(baseUrl.length - 1) != '/'){
  333. baseUrl = baseUrl+'/';
  334. }
  335. // print(baseUrl);
  336. return encodeBase64Url(baseUrl);
  337. }
  338. static String encodeBase64Url(String encrypted){
  339. try {
  340. return stringToBase64Url.encode(encrypted);
  341. } catch (error) {
  342. throw error;
  343. }
  344. }
  345. static String decodeBase64Url(String encrypted){
  346. try {
  347. return stringToBase64Url.decode(encrypted);
  348. } catch (error) {
  349. throw error;
  350. }
  351. }
  352. static String getUrl() {
  353. return _url;
  354. }
  355. static void setUrl(String url) async {
  356. _url = url;
  357. return;
  358. }
  359. static void clearUrl() {
  360. _url = "";
  361. }
  362. static String getPidFromUrl(String url){
  363. // print("U => url : $url");
  364. if (url.contains("/loginme")) {
  365. url = url.split("/loginme").first;
  366. }
  367. if (!url.contains("=")) {
  368. url = Uri.decodeComponent(url);
  369. }
  370. url = url.replaceAll('/app/', '');
  371. // if(url.contains('#')){
  372. // return Uri.encodeComponent(url);
  373. // }
  374. return Uri.encodeComponent(url.split('/').first);
  375. }
  376. static List<Color> defaultRainbowColors() {
  377. return [
  378. Colors.red,
  379. Colors.orange,
  380. Colors.yellow,
  381. Colors.green,
  382. Colors.blue,
  383. Colors.indigo,
  384. Colors.purple,
  385. ];
  386. }
  387. static Widget iconsax(String name, {Color color = Colors.black, double size = 24}){
  388. return SvgPicture.asset(
  389. 'assets/iconsax/${name}.svg',
  390. colorFilter: ColorFilter.mode(color, BlendMode.srcIn),
  391. width: size, height: size,
  392. fit: BoxFit.scaleDown
  393. );
  394. }
  395. static Options options = Options(format: Format.hex, luminosity: Luminosity.dark, colorType: [ColorType.red, ColorType.green, ColorType.blue, ColorType.orange]);
  396. static Map<String, dynamic> colorList = {};
  397. static int getColor(String name){
  398. try {
  399. if(!colorList.containsKey(name)){
  400. var color;
  401. do{
  402. color = int.parse(RandomColor.getColor(options).replaceAll('#', '0xff'));
  403. }while(colorList.containsValue(color));
  404. colorList[name] = color;
  405. }
  406. return colorList[name];
  407. } catch (e) {
  408. return 0xff000000;
  409. }
  410. }
  411. static String langColumn(BuildContext context, String text){
  412. var code = context.locale.toString();
  413. return code == 'id' ? text : '$text${code[0].toUpperCase()}${code.substring(1).toLowerCase()}';
  414. }
  415. static bool hidePayload = false;
  416. static void setHidePayload(value) {
  417. hidePayload = value;
  418. }
  419. static checkPendingRequest(BuildContext context)async{
  420. List list = _sharedPreferencesManager.isKeyExists(SharedPreferencesManager.keyPendingData)!?jsonDecode(_sharedPreferencesManager.getString(SharedPreferencesManager.keyPendingData)!):[];
  421. List uniqueId = [];
  422. if(list.length > 0){
  423. showLoading(context);
  424. for(var element in list){
  425. var data = element['data'];
  426. if(element['others']){
  427. data['req'][0]['uniqueId'] = element['uniqueId'];
  428. data['req'][0]['images'] = element['imageList'];
  429. var res = await ApiAuthProvider().postData('/api/receptionists/send/request', null, data, context);
  430. if (res != null) {
  431. uniqueId.add(res['uniqueId']);
  432. print('success send pending request others');
  433. }
  434. }
  435. else{
  436. data['uniqueId'] = element['uniqueId'];
  437. data['images'] = element['imageList'];
  438. var res = await ApiAuthProvider().postData('/api/requestHistories/search/request/' + element['type'] + '/' + element['id'].toString() + '/' + element['noteFormat'] + '/submit', null, data, context);
  439. if (res != null) {
  440. uniqueId.add(res['uniqueId']);
  441. print('success send pending request');
  442. }
  443. }
  444. }
  445. uniqueId.forEach((id) {
  446. list.removeWhere((li) => li['uniqueId'] == id);
  447. });
  448. await _sharedPreferencesManager.putString(SharedPreferencesManager.keyPendingData, jsonEncode(list));
  449. closeLoading(context);
  450. }
  451. }
  452. }
  453. //@optionalTypeArgs
  454. // abstract class State<T extends StatefulWidget>
  455. @optionalTypeArgs
  456. abstract class SaveState<T extends StatefulWidget> extends State<T> {
  457. bool _disposed = false;
  458. @override
  459. void dispose() {
  460. _disposed = true;
  461. super.dispose();
  462. }
  463. @override
  464. void setState(VoidCallback fn) {
  465. if (!mounted || _disposed) {
  466. return;
  467. }
  468. super.setState(fn);
  469. }
  470. }