Commit a6797435 authored by DatHV's avatar DatHV
Browse files

refactor print, log, request

parent f0334970
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart';
import '../../base/base_screen.dart';
......
......@@ -42,9 +42,7 @@ class MembershipViewModel extends RestfulApiViewModel {
orElse: () => levels!.first
);
} catch (e) {
if (kDebugMode) {
print('Failed to select level: $e');
}
debugPrint('Failed to select level: $e');
selectedLevel = levels!.isNotEmpty ? levels!.first : null;
}
}
......
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/screen/mobile_card/models/product_mobile_card_model.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../preference/point/point_manager.dart';
import 'models/mobile_service_redeem_data.dart';
......@@ -17,6 +18,19 @@ class ProductMobileCardViewModel extends RestfulApiViewModel {
return groupedSection[selectedBrandCode.value] ?? [];
}
ProductMobileCardModel? selectedProduct;
bool _productApiLoaded = false;
Future<void> _ensureProductApiLoaded() async {
if (_productApiLoaded) return;
await product_api.loadLibrary();
_productApiLoaded = true;
}
Future<BaseResponseModel<T>> _callProductApi<T>(Future<BaseResponseModel<T>> Function(dynamic api) fn) async {
await _ensureProductApiLoaded();
final api = product_api.ProductApi(client);
return fn(api);
}
int get payPoint {
return int.tryParse(selectedProduct?.prices?.firstOrNull?.payPoint ?? "0") ?? 0;
......@@ -33,7 +47,7 @@ class ProductMobileCardViewModel extends RestfulApiViewModel {
Future<void> redeemProductMobileCard() async {
await callApi<MobileServiceRedeemData>(
request: () => client.redeemMobileCard((selectedProduct?.id ?? 0).toString()),
request: () => _callProductApi((api) => api.redeemMobileCard((selectedProduct?.id ?? 0).toString())),
onSuccess: (data, _) async {
final itemId = data.itemId ?? "";
if (itemId.isEmpty) {
......@@ -50,7 +64,7 @@ class ProductMobileCardViewModel extends RestfulApiViewModel {
Future<void> _getMobileCardCode(String itemId) async {
await callApi<RedeemProductResponseModel>(
request: () => client.getMobileCardCode(itemId),
request: () => _callProductApi((api) => api.getMobileCardCode(itemId)),
onSuccess: (data, _) {
final item = data.item;
if (item != null) {
......@@ -67,7 +81,7 @@ class ProductMobileCardViewModel extends RestfulApiViewModel {
Future<void> getProductMobileCard() async {
await callApi<ProductMobileCardResponse>(
request: () => client.productMobileCardGetList(),
request: () => _callProductApi((api) => api.productMobileCardGetList()),
onSuccess: (data, _) {
final result = data.products ?? [];
final seen = <String>{};
......
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/networking/api/website_api.dart' deferred as website_api;
import '../../networking/restful_api_viewmodel.dart';
import '../faqs/faqs_model.dart';
......@@ -10,6 +10,14 @@ class NewsListViewModel extends RestfulApiViewModel {
var _canLoadMore = true;
int limit = 20;
bool _websiteApiLoaded = false;
Future<void> _ensureWebsiteApiLoaded() async {
if (_websiteApiLoaded) return;
await website_api.loadLibrary();
_websiteApiLoaded = true;
}
NewsListViewModel({this.folderUri = "TIN-TUC"});
@override
......@@ -22,13 +30,13 @@ class NewsListViewModel extends RestfulApiViewModel {
if (isLoading.value) return;
if (!isRefresh && !_canLoadMore) return;
isLoading(true);
final body = {
"folder_uri": folderUri,
"start": isRefresh ? 0 : newsList.length,
"limit": limit,
};
final body = {"folder_uri": folderUri, "start": isRefresh ? 0 : newsList.length, "limit": limit};
await callApi<FAQItemModelResponse>(
request: () => client.websiteFolderGetPageList(body),
request: () async {
await _ensureWebsiteApiLoaded();
final api = website_api.WebsiteApi(client);
return api.websiteFolderGetPageList(body);
},
onSuccess: (data, _) {
_canLoadMore = (data.items?.length ?? 0) == limit;
if (isRefresh) {
......@@ -39,7 +47,7 @@ class NewsListViewModel extends RestfulApiViewModel {
withLoading: false,
onComplete: () {
isLoading(false);
}
},
);
}
}
\ No newline at end of file
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/networking/api/notification_api.dart' deferred as notification_api;
import '../../configs/constants.dart';
import '../../networking/restful_api_viewmodel.dart';
import 'models/notification_detail_model.dart';
......@@ -8,6 +8,14 @@ class NotificationDetailViewModel extends RestfulApiViewModel {
var notification = Rxn<NotificationDetailModel>();
void Function(String message)? onShowAlertError;
bool _notificationApiLoaded = false;
Future<void> _ensureNotificationApiLoaded() async {
if (_notificationApiLoaded) return;
await notification_api.loadLibrary();
_notificationApiLoaded = true;
}
Future<void> fetchNotificationDetail({String? id, NotificationDetailModel? data}) async {
if (data != null) {
notification.value = data;
......@@ -15,7 +23,11 @@ class NotificationDetailViewModel extends RestfulApiViewModel {
}
if (id == null) return;
await callApi<NotificationDetailResponseModel>(
request: () => client.getNotificationDetail(id ?? ''),
request: () async {
await _ensureNotificationApiLoaded();
final api = notification_api.NotificationApi(client);
return api.getNotificationDetail(id ?? '');
},
onSuccess: (data, _) {
final notify = data.notification;
if (notify != null) {
......
......@@ -5,7 +5,6 @@ import '../../base/base_screen.dart';
import '../../base/basic_state.dart';
import '../../resources/base_color.dart';
import '../../widgets/alert/data_alert_model.dart';
import '../../widgets/back_button.dart';
import '../../widgets/custom_empty_widget.dart';
import '../../widgets/custom_navigation_bar.dart';
import '../../widgets/image_loader.dart';
......@@ -50,11 +49,7 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
rightButtons: [
CompositedTransformTarget(
link: _layerLink,
child: IconButton(
key: _infoKey,
icon: const Icon(Icons.settings),
onPressed: _toggleSetting,
),
child: IconButton(key: _infoKey, icon: const Icon(Icons.settings), onPressed: _toggleSetting),
),
],
),
......@@ -66,9 +61,7 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
_buildNotificationCategory(),
const Divider(height: 1),
if (items.isEmpty)
const Expanded(
child: EmptyWidget(),
)
const Expanded(child: EmptyWidget())
else
Expanded(
child: Container(
......@@ -110,7 +103,8 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
final size = renderBox?.size ?? Size.zero;
final double widthSize = 270;
_popupEntry = OverlayEntry(
builder: (context) => Stack(
builder:
(context) => Stack(
children: [
Positioned.fill(
child: GestureDetector(
......@@ -128,10 +122,7 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
child: Container(
width: widthSize,
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: Colors.grey.shade50,
borderRadius: BorderRadius.circular(16),
),
decoration: BoxDecoration(color: Colors.grey.shade50, borderRadius: BorderRadius.circular(16)),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
......@@ -144,11 +135,14 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
),
const Divider(height: 1, color: Colors.grey),
ListTile(
title: const Text('Xoá tất cả', style: TextStyle(color: Colors.red, fontWeight: FontWeight.w500)),
title: const Text(
'Xoá tất cả',
style: TextStyle(color: Colors.red, fontWeight: FontWeight.w500),
),
onTap: () {
_hidePopup();
_confirmDeleteAllNotifications();
}
},
),
],
),
......@@ -262,9 +256,15 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
color: Colors.red,
child: const Icon(Icons.delete, color: Colors.white),
),
onDismissed: (direction) {
_viewModel.handleRemoveNotification(item);
// _viewModel.notifications.remove(item);
onDismissed: (direction) async {
final notifications = _viewModel.notifications;
final index = notifications.indexOf(item);
if (index < 0) return;
notifications.removeAt(index);
final success = await _viewModel.deleteNotificationItem(item);
if (!success) {
notifications.insert(index, item);
}
},
child: GestureDetector(
onTap: () {
......@@ -279,7 +279,7 @@ class _NotificationScreenState extends BaseState<NotificationScreen> with BasicS
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: item.hasSeen ? Colors.white : Colors.pink.shade50,
borderRadius: BorderRadius.circular(12)
borderRadius: BorderRadius.circular(12),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
......
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/networking/api/notification_api.dart' deferred as notification_api;
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../preference/data_preference.dart';
......@@ -19,6 +19,20 @@ class NotificationViewModel extends RestfulApiViewModel {
void Function(String message)? onShowAlertError;
var _hasMoreData = true;
bool _notificationApiLoaded = false;
Future<void> _ensureNotificationApiLoaded() async {
if (_notificationApiLoaded) return;
await notification_api.loadLibrary();
_notificationApiLoaded = true;
}
Future<BaseResponseModel<T>> _callNotificationApi<T>(Future<BaseResponseModel<T>> Function(dynamic api) fn) async {
await _ensureNotificationApiLoaded();
final api = notification_api.NotificationApi(client);
return fn(api);
}
CategoryNotifyItemModel? get selectedCategory =>
categories.isNotEmpty ? categories.firstWhere((item) => item.isSelected ?? false) : null;
......@@ -30,7 +44,7 @@ class NotificationViewModel extends RestfulApiViewModel {
void _fetchCategories() async {
await callApi<List<CategoryNotifyItemModel>>(
request: () => client.getNotificationCategories(),
request: () => _callNotificationApi((api) => api.getNotificationCategories()),
onSuccess: (data, _) {
if (data.isNotEmpty) data[0].isSelected = true;
categories.assignAll(data);
......@@ -44,7 +58,9 @@ class NotificationViewModel extends RestfulApiViewModel {
void fetchNotifications({bool refresh = false}) async {
if (isLoading.value) return;
if (!refresh && !_hasMoreData) { return; }
if (!refresh && !_hasMoreData) {
return;
}
if (refresh) {
_notificationIndex = 0;
}
......@@ -57,7 +73,7 @@ class NotificationViewModel extends RestfulApiViewModel {
"noti_group_id": selectedCategory?.id ?? "",
};
await callApi<NotificationListDataModel>(
request: () => client.getNotifications(body),
request: () => _callNotificationApi((api) => api.getNotifications(body)),
onSuccess: (data, _) {
final items = data.items ?? [];
if (refresh) {
......@@ -87,7 +103,7 @@ class NotificationViewModel extends RestfulApiViewModel {
void notificationMarkAsSeen() {
callApi<EmptyCodable>(
request: () => client.notificationMarkAsSeen(),
request: () => _callNotificationApi((api) => api.notificationMarkAsSeen()),
onSuccess: (_, _) => _fetchCategories(),
onFailure: (msg, _, _) async {
onShowAlertError?.call(msg);
......@@ -97,7 +113,7 @@ class NotificationViewModel extends RestfulApiViewModel {
void deleteAllNotifications() {
callApi<EmptyCodable>(
request: () => client.deleteAllNotifications(),
request: () => _callNotificationApi((api) => api.deleteAllNotifications()),
onSuccess: (_, _) => _fetchCategories(),
onFailure: (msg, _, _) async {
onShowAlertError?.call(msg);
......@@ -105,31 +121,37 @@ class NotificationViewModel extends RestfulApiViewModel {
);
}
void handleRemoveNotification(NotificationItemModel item) {
if (item.notificationId == null) return;
callApi<EmptyCodable>(
request: () => client.deleteNotification(item.notificationId ?? ""),
Future<bool> deleteNotificationItem(NotificationItemModel item) async {
if (item.notificationId == null) return true;
var success = true;
await callApi<EmptyCodable>(
request: () => _callNotificationApi((api) => api.deleteNotification(item.notificationId ?? "")),
onSuccess: (_, _) {
notifications.remove(item);
if (notifications.length <= _pageLimit) {
fetchNotifications(refresh: false);
}
},
onFailure: (msg, _, _) async {
onShowAlertError?.call(msg);
success = false;
},
withLoading: false,
);
return success;
}
void handleClickNotification(NotificationItemModel item) {
callApi<NotificationDetailResponseModel>(
request: () => client.getNotificationDetail(item.notificationId ?? ""),
request: () => _callNotificationApi((api) => api.getNotificationDetail(item.notificationId ?? "")),
onSuccess: (data, _) {
final notification = data.notification;
if (notification == null) return;
final pushSuccess = notification.directionalScreen?.begin() ?? false;
if (!pushSuccess) {
Get.toNamed(notificationDetailScreen, arguments: {'notification': notification, 'notificationId': item.notificationId});
Get.toNamed(
notificationDetailScreen,
arguments: {'notification': notification, 'notificationId': item.notificationId},
);
}
},
onFailure: (msg, _, _) async {
......
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/shared/router_gage.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart';
import '../../base/base_screen.dart';
import '../../base/basic_state.dart';
import '../../resources/base_color.dart';
import '../faqs/faqs_screen.dart';
import '../otp/otp_screen.dart';
import '../otp/verify_otp_repository.dart';
import '../pageDetail/model/detail_page_rule_type.dart';
import 'model/check_phone_response_model.dart';
import 'onboarding_viewmodel.dart';
class OnboardingScreen extends BaseScreen {
......@@ -45,10 +43,14 @@ class _OnboardingScreenState extends BaseState<OnboardingScreen> with BasicState
children: [
Obx(
() => Positioned.fill(
child:
_viewModel.url.isNotEmpty
? Image.network(_viewModel.url, fit: BoxFit.cover)
: Image.asset("assets/images/bg_onboarding.png", fit: BoxFit.cover),
child: loadNetworkImage(
url: _viewModel.url,
fit: BoxFit.cover,
placeholderAsset: "assets/images/bg_onboarding.png",
),
// _viewModel.url.isNotEmpty
// ? Image.network(_viewModel.url, fit: BoxFit.cover)
// : Image.asset("assets/images/bg_onboarding.png", fit: BoxFit.cover),
),
),
SafeArea(
......
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/widgets/custom_empty_widget.dart';
import 'package:share_plus/share_plus.dart';
......@@ -163,9 +164,9 @@ class _CampaignDetailScreenState extends BaseState<CampaignDetailScreen> with Ba
SizedBox(height: 12),
ElevatedButton(
onPressed: () {
print(pageDetail?.directionalScreen);
print(pageDetail?.buttonClickActionType);
print(pageDetail?.buttonClickActionParam);
debugPrint(pageDetail?.directionalScreen.toString());
debugPrint(pageDetail?.buttonClickActionType.toString());
debugPrint(pageDetail?.buttonClickActionParam.toString());
pageDetail?.directionalScreen?.begin();
},
style: ElevatedButton.styleFrom(
......
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/configs/constants.dart';
import 'package:mypoint_flutter_app/networking/api/website_api.dart' deferred as website_api;
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import 'model/campaign_detail_model.dart';
import 'model/detail_page_rule_type.dart';
......@@ -11,6 +11,14 @@ class CampaignDetailViewModel extends RestfulApiViewModel {
var campaignDetail = Rxn<CampaignDetailResponseModel>();
void Function(String message)? onShowAlertError;
bool _websiteApiLoaded = false;
Future<void> _ensureWebsiteApiLoaded() async {
if (_websiteApiLoaded) return;
await website_api.loadLibrary();
_websiteApiLoaded = true;
}
Future<void> fetchData(DetailPageRuleType? type, String? pageId) async {
if ((pageId ?? "").isNotEmpty) {
await fetchWebsitePageGetDetail(pageId!);
......@@ -25,12 +33,13 @@ class CampaignDetailViewModel extends RestfulApiViewModel {
Future<void> fetchFAQItems() async {
await callApi<FAQItemModelResponse>(
request: () => client.websiteFolderGetPageList({"folder_uri": "ABOUT"}),
request: () async {
await _ensureWebsiteApiLoaded();
final api = website_api.WebsiteApi(client);
return api.websiteFolderGetPageList({"folder_uri": "ABOUT"});
},
onSuccess: (data, _) async {
final pageId = (data.items ?? [])
.firstWhereOrNull((item) => (item.pageId ?? "").isNotEmpty)
?.pageId ??
"";
final pageId = (data.items ?? []).firstWhereOrNull((item) => (item.pageId ?? "").isNotEmpty)?.pageId ?? "";
if (pageId.isEmpty) {
onShowAlertError?.call(Constants.commonError);
return;
......@@ -45,7 +54,11 @@ class CampaignDetailViewModel extends RestfulApiViewModel {
Future<void> fetchWebsitePage(DetailPageRuleType type) async {
await callApi<CampaignDetailResponseModel>(
request: () => client.websitePage(type),
request: () async {
await _ensureWebsiteApiLoaded();
final api = website_api.WebsiteApi(client);
return api.websitePage(type);
},
onSuccess: (data, _) {
campaignDetail.value = data;
},
......@@ -57,7 +70,11 @@ class CampaignDetailViewModel extends RestfulApiViewModel {
Future<void> fetchWebsitePageGetDetail(String pageId) async {
await callApi<CampaignDetailResponseModel>(
request: () => client.websitePageGetDetail(pageId),
request: () async {
await _ensureWebsiteApiLoaded();
final api = website_api.WebsiteApi(client);
return api.websitePageGetDetail(pageId);
},
onSuccess: (data, response) {
campaignDetail.value = data;
},
......
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
......@@ -126,7 +127,7 @@ class _PersonalEditScreenState extends BaseState<PersonalEditScreen> with BasicS
right: 4,
child: GestureDetector(
onTap: () {
print("Change avatar tapped");
debugPrint("Change avatar tapped");
},
child: Container(
padding: const EdgeInsets.all(4),
......
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:mypoint_flutter_app/screen/popup_manager/popup_manager_model.dart';
import 'package:mypoint_flutter_app/screen/popup_manager/popup_manager_viewmodel.dart';
......@@ -94,7 +95,7 @@ class _BasePopupViewState extends State<_BasePopupView> {
void _onContentTap() {
logPopupClick(popupId: widget.model.id ?? '');
print(
debugPrint(
'Popup clicked: ${widget.model.directional?.clickActionType ?? ''} - ${widget.model.directional?.clickActionParam ?? ''}',
);
_timer?.cancel();
......
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_widget_from_html/flutter_widget_from_html.dart';
import 'package:flutter_widget_from_html_core/flutter_widget_from_html_core.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart';
import '../../base/base_screen.dart';
......@@ -195,7 +196,7 @@ class _RegisterFormInputScreenState extends BaseState<RegisterFormInputScreen> w
void _gotoPaymentScreen() {
final metaData = (_viewModel.form.value?.submitParams ?? {}).toJsonString();
print("_gotoPaymentScreen metaData $metaData");
debugPrint("_gotoPaymentScreen metaData $metaData");
Get.toNamed(transactionDetailScreen, arguments: {"product": _product, "quantity": 1, "metaData": metaData});
}
......@@ -219,7 +220,7 @@ class _RegisterFormInputScreenState extends BaseState<RegisterFormInputScreen> w
final form = _viewModel.form.value?.formRegistration;
final inputs = form?.inputRequired ?? [];
for (var input in inputs) {
print("Input: ${input.title}, Value: ${input.value}");
debugPrint("Input: ${input.title}, Value: ${input.value}");
}
final isValid = inputs.every((input) {
if (input.require == true) {
......
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/screen/splash/splash_screen_viewmodel.dart';
import 'package:mypoint_flutter_app/shared/router_gage.dart';
import 'package:mypoint_flutter_app/widgets/alert/custom_alert_dialog.dart';
import '../../base/base_screen.dart';
import '../../base/basic_state.dart';
......@@ -32,8 +28,7 @@ class _SplashScreenState extends BaseState<SplashScreen> with BasicState {
_viewModel.makeDataFollowInitApp();
return;
}
var status = updateData?.status ?? UpdateStatus.none;
if (status == UpdateStatus.none) {
if (updateData.status == UpdateStatus.none) {
_viewModel.directionWhenTokenInvalid();
} else {
_showSuggestUpdateAlert(updateData);
......@@ -62,14 +57,6 @@ class _SplashScreenState extends BaseState<SplashScreen> with BasicState {
);
}
void _exitApp() {
if (Platform.isAndroid) {
SystemNavigator.pop();
} else {
exit(0);
}
}
void _showSuggestUpdateAlert(CheckUpdateResponseModel data) {
final buttons = data.status == UpdateStatus.force
? [AlertButton(
......
......@@ -64,28 +64,28 @@ class SplashScreenViewModel extends RestfulApiViewModel {
/// Get token from x-app-sdk (web only)
Future<String?> _getTokenFromSDK() async {
if (!kIsWeb) {
print('🔍 SplashScreen - Not on web, skipping SDK token retrieval');
debugPrint('🔍 SplashScreen - Not on web, skipping SDK token retrieval');
return null;
}
try {
print('🔍 SplashScreen - Attempting to get token from x-app-sdk...');
debugPrint('🔍 SplashScreen - Attempting to get token from x-app-sdk...');
await webInitializeXAppSDK().timeout(_sdkTimeout);
if (!webIsSDKInitialized()) {
print('⚠️ SplashScreen - SDK not initialized, skipping');
debugPrint('⚠️ SplashScreen - SDK not initialized, skipping');
return null;
}
// Get token from SDK
final token = await webGetToken().timeout(_sdkTimeout);
if (token != null && token.isNotEmpty) {
print('✅ SplashScreen - Token retrieved from x-app-sdk: ${token.substring(0, 8)}...');
debugPrint('✅ SplashScreen - Token retrieved from x-app-sdk: ${token.substring(0, 8)}...');
return token;
} else {
final error = webGetLastError();
print('❌ SplashScreen - Failed to get token from SDK: $error');
debugPrint('❌ SplashScreen - Failed to get token from SDK: $error');
return null;
}
} catch (e) {
print('❌ SplashScreen - Error getting token from SDK: $e');
debugPrint('❌ SplashScreen - Error getting token from SDK: $e');
return null;
}
}
......
......@@ -32,9 +32,7 @@ class _SupportScreenState extends State<SupportScreen> {
case SupportItemType.phone:
final phone = value.trim();
if (phone.isEmpty) {
if (kDebugMode) {
print('⚠️ SupportScreen: phone number is empty');
}
debugPrint('⚠️ SupportScreen: phone number is empty');
return;
}
if (kIsWeb) {
......@@ -44,9 +42,7 @@ class _SupportScreenState extends State<SupportScreen> {
await _launchTelUrl(phone);
}
} catch (e) {
if (kDebugMode) {
print('❌ webCallPhone failed: $e');
}
debugPrint('❌ webCallPhone failed: $e');
await _launchTelUrl(phone);
}
} else {
......
import 'dart:convert';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/screen/support/support_item_model.dart';
......@@ -20,7 +21,7 @@ class SupportViewModel extends GetxController {
supportItems.value = items.map((item) => SupportItemModel.fromJson(item)).toList();
} catch (e) {
print("Lỗi load dữ liệu: $e");
debugPrint("Lỗi load dữ liệu: $e");
}
}
}
import 'package:get/get.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart';
import 'package:mypoint_flutter_app/networking/api/product_api.dart' deferred as product_api;
import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/screen/topup/models/brand_network_model.dart';
import '../../base/base_response_model.dart';
import '../../networking/restful_api_viewmodel.dart';
import '../../preference/contact_storage_service.dart';
import '../voucher/models/product_brand_model.dart';
......@@ -17,6 +18,19 @@ class TopUpViewModel extends RestfulApiViewModel {
var selectedProduct = Rxn<ProductModel>();
final Map<String, List<ProductModel>> _allValue = {};
var phoneNumber = ''.obs;
bool _productApiLoaded = false;
Future<void> _ensureProductApiLoaded() async {
if (_productApiLoaded) return;
await product_api.loadLibrary();
_productApiLoaded = true;
}
Future<BaseResponseModel<T>> _callProductApi<T>(Future<BaseResponseModel<T>> Function(dynamic api) fn) async {
await _ensureProductApiLoaded();
final api = product_api.ProductApi(client);
return fn(api);
}
@override
void onInit() {
......@@ -42,7 +56,7 @@ class TopUpViewModel extends RestfulApiViewModel {
_getTopUpBrands() async {
await callApi<List<ProductBrandModel>>(
request: () => client.getTopUpBrands(ProductType.topupMobile),
request: () => _callProductApi((api) => api.getTopUpBrands(ProductType.topupMobile)),
onSuccess: (data, _) {
topUpBrands.assignAll(data);
checkMobileNetwork();
......@@ -53,7 +67,7 @@ class TopUpViewModel extends RestfulApiViewModel {
checkMobileNetwork() async {
await callApi<BrandNameCheckResponse>(
request: () => client.checkMobileNetwork(phoneNumber.value),
request: () => _callProductApi((api) => api.checkMobileNetwork(phoneNumber.value)),
onSuccess: (data, _) {
final brandCode = data?.brand ?? '';
var brand = topUpBrands.isNotEmpty
......@@ -107,7 +121,7 @@ class TopUpViewModel extends RestfulApiViewModel {
"brand_id": selectedBrand.value?.id ?? 0,
};
await callApi<List<ProductModel>>(
request: () => client.getProducts(body),
request: () => _callProductApi((api) => api.getProducts(body)),
onSuccess: (data, _) {
_allValue[code] = data;
products.assignAll(data);
......
......@@ -21,7 +21,7 @@ class _TrafficServiceDetailScreenState extends State<TrafficServiceDetailScreen>
@override
void initState() {
super.initState();
int? serviceId;
String? serviceId;
TrafficServiceDetailModel? data;
final args = Get.arguments;
if (args is Map) {
......
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:mypoint_flutter_app/extensions/datetime_extensions.dart';
......@@ -85,8 +86,8 @@ class _TrafficServiceScreenState extends State<TrafficServiceScreen> {
),
child: ListTile(
onTap: () {
print('Tapped on item: ${item.licensePlate}');
Get.toNamed(trafficServiceDetailScreen, arguments: {'serviceId': item.itemId});
debugPrint('Tapped on item: ${item.licensePlate}');
Get.toNamed(trafficServiceDetailScreen, arguments: {'serviceId': item.itemId.toString()});
},
leading: SizedBox(
width: 60, // <= giới hạn rõ
......
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