Commit a7abbe4d authored by DatHV's avatar DatHV
Browse files

fix bug change profile when logout

parent 2cf5375a
...@@ -8,9 +8,11 @@ class Constants { ...@@ -8,9 +8,11 @@ class Constants {
static const timeoutSeconds = 30; static const timeoutSeconds = 30;
static const appStoreId = '1495923300'; static const appStoreId = '1495923300';
static double get extendTopPaddingNavigation { static double get extendTopPaddingNavigation {
print('extendTopPaddingNavigation: $kIsWeb');
return kIsWeb ? 24.0 : 0.0; return kIsWeb ? 24.0 : 0.0;
} }
static double get extendTopPaddingNavigationButton {
return kIsWeb ? 8.0 : 0.0;
}
} }
class ErrorCodes { class ErrorCodes {
......
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart'; import 'package:get/get_state_manager/src/rx_flutter/rx_obx_widget.dart';
import 'package:mypoint_flutter_app/shared/widgets/custom_empty_widget.dart'; import 'package:mypoint_flutter_app/shared/widgets/custom_empty_widget.dart';
import '../../shared/widgets/base_view/base_screen.dart'; import '../../shared/widgets/base_view/base_screen.dart';
...@@ -21,10 +23,17 @@ class _InterestCategoriesScreenState extends BaseState<InterestCategoriesScreen> ...@@ -21,10 +23,17 @@ class _InterestCategoriesScreenState extends BaseState<InterestCategoriesScreen>
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_viewModel.onShowAlertError = (message) { _viewModel.onShowAlertError = (message, onBack) {
if (message.isNotEmpty) { if (message.isEmpty) return;
showAlertError(content: message, headerImage: "assets/images/ic_pipi_05.png"); showAlertError(
} content: message,
headerImage: "assets/images/ic_pipi_05.png",
onConfirmed:
onBack ? () {
Get.back();
}
: null,
);
}; };
_viewModel.getInterestedCategories(); _viewModel.getInterestedCategories();
} }
......
...@@ -8,7 +8,7 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel { ...@@ -8,7 +8,7 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel {
final Rxn<InterestedCategoriesResponse> interestedCategories = Rxn<InterestedCategoriesResponse>(); final Rxn<InterestedCategoriesResponse> interestedCategories = Rxn<InterestedCategoriesResponse>();
Set<String> selectedIds = {}; Set<String> selectedIds = {};
void Function(String message)? onShowAlertError; void Function(String message, bool onBack)? onShowAlertError;
Future<void> getInterestedCategories() async { Future<void> getInterestedCategories() async {
await callApi<InterestedCategoriesResponse>( await callApi<InterestedCategoriesResponse>(
...@@ -25,7 +25,7 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel { ...@@ -25,7 +25,7 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel {
interestedCategories.value = data; interestedCategories.value = data;
}, },
onFailure: (msg, _, _) async { onFailure: (msg, _, _) async {
onShowAlertError?.call(msg); onShowAlertError?.call(msg, false);
}, },
); );
} }
...@@ -35,11 +35,11 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel { ...@@ -35,11 +35,11 @@ class InterestedCategoriesViewModel extends RestfulApiViewModel {
await callApi<EmptyCodable>( await callApi<EmptyCodable>(
request: () => client.submitCategorySubscribe(categories.join(',')), request: () => client.submitCategorySubscribe(categories.join(',')),
onSuccess: (data, _) { onSuccess: (data, _) {
onShowAlertError?.call("Cập nhật sở thích thành công"); onShowAlertError?.call("Cập nhật sở thích thành công", true);
_handleUnsubscribeCategories(categories); _handleUnsubscribeCategories(categories);
}, },
onFailure: (msg, _, _) async { onFailure: (msg, _, _) async {
onShowAlertError?.call(msg); onShowAlertError?.call(msg, false);
}, },
); );
} }
......
...@@ -33,7 +33,7 @@ class SplashScreenViewModel extends RestfulApiViewModel { ...@@ -33,7 +33,7 @@ class SplashScreenViewModel extends RestfulApiViewModel {
debugPrint('⚠️ SplashScreen - checkUpdateApp failed: $e'); debugPrint('⚠️ SplashScreen - checkUpdateApp failed: $e');
checkUpdateResponse?.call(null); checkUpdateResponse?.call(null);
} }
} }
Future<void> openLink() async { Future<void> openLink() async {
if (_updateLink.isEmpty) return; if (_updateLink.isEmpty) return;
...@@ -45,19 +45,17 @@ class SplashScreenViewModel extends RestfulApiViewModel { ...@@ -45,19 +45,17 @@ class SplashScreenViewModel extends RestfulApiViewModel {
Future<void> makeDataFollowInitApp() async { Future<void> makeDataFollowInitApp() async {
try { try {
if (kIsWeb) {
final token = await _getTokenFromSDK();
if (token.orEmpty.isNotEmpty) {
await DataPreference.instance.saveLoginToken(LoginTokenResponseModel(accessToken: token));
}
}
if (DataPreference.instance.logged) { if (DataPreference.instance.logged) {
await _loadProfileAndNavigate(); await _loadProfileAndNavigate();
return; } else {
}
final token = await _getTokenFromSDK();
if (token.orEmpty.isEmpty) {
directionWhenTokenInvalid(); directionWhenTokenInvalid();
return;
} }
await DataPreference.instance.saveLoginToken(LoginTokenResponseModel(accessToken: token));
await _loadProfileAndNavigate();
} on Object catch (e) { } on Object catch (e) {
debugPrint('❌ SplashScreen - makeDataFollowInitApp error: $e'); debugPrint('❌ SplashScreen - makeDataFollowInitApp error: $e');
DataPreference.instance.clearLoginToken(); DataPreference.instance.clearLoginToken();
...@@ -156,7 +154,7 @@ class SplashScreenViewModel extends RestfulApiViewModel { ...@@ -156,7 +154,7 @@ class SplashScreenViewModel extends RestfulApiViewModel {
void _goToMain() { void _goToMain() {
if (Get.currentRoute == mainScreen) return; if (Get.currentRoute == mainScreen) return;
if (Get.currentRoute == onboardingScreen) { if (kIsWeb || Get.currentRoute == onboardingScreen) {
Get.offNamed(mainScreen); Get.offNamed(mainScreen);
} else { } else {
Get.offAllNamed(mainScreen); Get.offAllNamed(mainScreen);
......
import 'dart:io'; import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:mypoint_flutter_app/shared/widgets/custom_toast_message.dart';
import 'package:share_plus/share_plus.dart'; import 'package:share_plus/share_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import 'package:webview_flutter/webview_flutter.dart'; import 'package:webview_flutter/webview_flutter.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
...@@ -33,6 +36,27 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert ...@@ -33,6 +36,27 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert
@override @override
void initState() { void initState() {
super.initState(); super.initState();
if (kIsWeb) {
_openUrlInBrowser();
} else {
_initializeWebView();
}
}
Future<void> _openUrlInBrowser() async {
Future.microtask(() async {
final uri = Uri.parse(widget.urlView);
if (await canLaunchUrl(uri)) {
await launchUrl(uri, mode: LaunchMode.externalApplication);
} else if (mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Không thể mở giấy chứng nhận')),
);
}
});
}
void _initializeWebView() {
AppLoading().show(); AppLoading().show();
_controller = WebViewController() _controller = WebViewController()
..loadRequest(Uri.parse(widget.urlView)) ..loadRequest(Uri.parse(widget.urlView))
...@@ -53,7 +77,7 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert ...@@ -53,7 +77,7 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert
Widget createBody() { Widget createBody() {
return Scaffold( return Scaffold(
appBar: CustomNavigationBar(title: "Giấy chứng nhận cứu hộ VNTRA"), appBar: CustomNavigationBar(title: "Giấy chứng nhận cứu hộ VNTRA"),
body: WebViewWidget(controller: _controller), body: kIsWeb ? _WebFallback(onRetry: _openUrlInBrowser) : WebViewWidget(controller: _controller),
bottomNavigationBar: _buildBottomButtonEditMode(), bottomNavigationBar: _buildBottomButtonEditMode(),
); );
} }
...@@ -86,29 +110,6 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert ...@@ -86,29 +110,6 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert
); );
} }
// Future<void> _savePdfToFiles() async {
// final url = widget.urlDownload;
// final licensePlate = widget.licensePlate;
// try {
// final response = await http.get(Uri.parse(url));
// if (response.statusCode == 200) {
// typed_data.Uint8List bytes = response.bodyBytes;
// final fileName = 'MyPoint-Cer-$licensePlate.pdf';
//
// await FileSaver.instance.saveFile(
// name: fileName,
// bytes: bytes,
// ext: 'pdf',
// mimeType: MimeType.pdf,
// );
// } else {
// print("Tải file thất bại");
// }
// } catch (e) {
// print("Lỗi: $e");
// }
// }
Future<void> _savePdfToFiles() async { Future<void> _savePdfToFiles() async {
final url = widget.urlDownload; final url = widget.urlDownload;
final licensePlate = widget.licensePlate; final licensePlate = widget.licensePlate;
...@@ -117,52 +118,46 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert ...@@ -117,52 +118,46 @@ class _TrafficServiceCertificateScreenState extends BaseState<TrafficServiceCert
if (response.statusCode == 200) { if (response.statusCode == 200) {
typed_data.Uint8List bytes = response.bodyBytes; typed_data.Uint8List bytes = response.bodyBytes;
final dir = await getTemporaryDirectory(); final dir = await getTemporaryDirectory();
final filePath = '${dir.path}/MyPoint-Cer-$licensePlate.pdf'; final filePath = '${dir.path}/MyPoint-Cer-$licensePlate-${DateTime.now().toString()}.pdf';
final file = File(filePath); final file = File(filePath);
await file.writeAsBytes(bytes); await file.writeAsBytes(bytes);
await Share.shareXFiles([XFile(filePath)], text: 'Giấy chứng nhận cứu hộ'); await Share.shareXFiles([XFile(filePath)], text: 'Giấy chứng nhận cứu hộ');
showToastMessage('Lưu file thành công');
} else { } else {
ScaffoldMessenger.of(context).showSnackBar( showToastMessage('Tải file thất bại');
const SnackBar(content: Text('Tải file thất bại')),
);
} }
} catch (e) { } catch (e) {
ScaffoldMessenger.of(context).showSnackBar( showToastMessage('Tải file thất bại');
SnackBar(content: Text('Lỗi: $e')),
);
} }
} }
}
Future<void> _savePdf() async { class _WebFallback extends StatelessWidget {
final url = widget.urlDownload; final VoidCallback onRetry;
final licensePlate = widget.licensePlate;
ScaffoldMessenger.of(context).showSnackBar( const _WebFallback({required this.onRetry});
const SnackBar(content: Text('Đang tải PDF...')),
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Padding(
padding: EdgeInsets.symmetric(horizontal: 24.0),
child: Text(
'Giấy chứng nhận đang được mở trong tab trình duyệt mới. '
'Nếu không tự mở, vui lòng chọn "Mở lại" hoặc sử dụng nút Lưu file.',
textAlign: TextAlign.center,
),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: onRetry,
child: const Text('Mở lại'),
),
],
),
); );
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final dir = await getApplicationDocumentsDirectory();
String baseName = 'MyPoint-Cer-$licensePlate.pdf';
String path = '${dir.path}/$baseName';
int count = 0;
while (File(path).existsSync()) {
path = '${dir.path}/MyPoint-Cer-$licensePlate-${count++}.pdf';
}
final file = File(path);
await file.writeAsBytes(response.bodyBytes);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Lưu file thành công:\n${file.path}')),
);
} else {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Tải file thất bại')),
);
}
} catch (e) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Lỗi: $e')),
);
}
} }
} }
\ No newline at end of file
...@@ -91,9 +91,9 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget ...@@ -91,9 +91,9 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
), ),
), ),
if (leftButtons.isNotEmpty) if (leftButtons.isNotEmpty)
Positioned(left: 12, child: Row(mainAxisSize: MainAxisSize.min, children: leftButtons)), Positioned(left: 12, top: Constants.extendTopPaddingNavigationButton, child: Row(mainAxisSize: MainAxisSize.min, children: leftButtons)),
if (rightButtons.isNotEmpty) if (rightButtons.isNotEmpty)
Positioned(right: 8, child: Row(mainAxisSize: MainAxisSize.min, children: rightButtons)), Positioned(right: 8, top: Constants.extendTopPaddingNavigationButton, child: Row(mainAxisSize: MainAxisSize.min, children: rightButtons)),
], ],
), ),
), ),
......
...@@ -122,9 +122,9 @@ class _CustomSearchNavigationBarState extends State<CustomSearchNavigationBar> { ...@@ -122,9 +122,9 @@ class _CustomSearchNavigationBarState extends State<CustomSearchNavigationBar> {
), ),
), ),
), ),
if (widget.showBackButton) Positioned(left: 12, child: CustomBackButton()), if (widget.showBackButton) Positioned(left: 12, top: Constants.extendTopPaddingNavigationButton, child: CustomBackButton()),
if (widget.rightButtons.isNotEmpty) if (widget.rightButtons.isNotEmpty)
Positioned(right: 12, child: Row(mainAxisSize: MainAxisSize.min, children: widget.rightButtons)), Positioned(right: 12, top: Constants.extendTopPaddingNavigationButton, child: Row(mainAxisSize: MainAxisSize.min, children: widget.rightButtons)),
], ],
), ),
), ),
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment