Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Hoàng Văn Đạt
mypoint_flutter_app
Commits
a6797435
Commit
a6797435
authored
Nov 05, 2025
by
DatHV
Browse files
refactor print, log, request
parent
f0334970
Changes
117
Show whitespace changes
Inline
Side-by-side
lib/screen/membership/membership_screen.dart
View file @
a6797435
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'
;
...
...
lib/screen/membership/membership_viewmodel.dart
View file @
a6797435
...
...
@@ -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
;
}
}
...
...
lib/screen/mobile_card/product_mobile_card_viewmodel.dart
View file @
a6797435
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
>{};
...
...
lib/screen/news/news_list_viewmodel.dart
View file @
a6797435
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
lib/screen/notification/notification_detail_viewmodel.dart
View file @
a6797435
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
)
{
...
...
lib/screen/notification/notification_screen.dart
View file @
a6797435
...
...
@@ -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
,
...
...
lib/screen/notification/notification_viewmodel.dart
View file @
a6797435
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
{
...
...
lib/screen/onboarding/onboarding_screen.dart
View file @
a6797435
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
(
...
...
lib/screen/pageDetail/campaign_detail_screen.dart
View file @
a6797435
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:
()
{
p
rint
(
pageDetail
?.
directionalScreen
);
p
rint
(
pageDetail
?.
buttonClickActionType
);
p
rint
(
pageDetail
?.
buttonClickActionParam
);
debugP
rint
(
pageDetail
?.
directionalScreen
.
toString
()
);
debugP
rint
(
pageDetail
?.
buttonClickActionType
.
toString
()
);
debugP
rint
(
pageDetail
?.
buttonClickActionParam
.
toString
()
);
pageDetail
?.
directionalScreen
?.
begin
();
},
style:
ElevatedButton
.
styleFrom
(
...
...
lib/screen/pageDetail/campaign_detail_viewmodel.dart
View file @
a6797435
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
;
},
...
...
lib/screen/personal/personal_edit_screen.dart
View file @
a6797435
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:
()
{
p
rint
(
"Change avatar tapped"
);
debugP
rint
(
"Change avatar tapped"
);
},
child:
Container
(
padding:
const
EdgeInsets
.
all
(
4
),
...
...
lib/screen/popup_manager/popup_manager_screen.dart
View file @
a6797435
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
??
''
);
p
rint
(
debugP
rint
(
'Popup clicked:
${widget.model.directional?.clickActionType ?? ''}
-
${widget.model.directional?.clickActionParam ?? ''}
'
,
);
_timer
?.
cancel
();
...
...
lib/screen/register_campaign/register_form_input_screen.dart
View file @
a6797435
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
();
p
rint
(
"_gotoPaymentScreen metaData
$metaData
"
);
debugP
rint
(
"_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
)
{
p
rint
(
"Input:
${input.title}
, Value:
${input.value}
"
);
debugP
rint
(
"Input:
${input.title}
, Value:
${input.value}
"
);
}
final
isValid
=
inputs
.
every
((
input
)
{
if
(
input
.
require
==
true
)
{
...
...
lib/screen/splash/splash_screen.dart
View file @
a6797435
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
(
...
...
lib/screen/splash/splash_screen_viewmodel.dart
View file @
a6797435
...
...
@@ -64,28 +64,28 @@ class SplashScreenViewModel extends RestfulApiViewModel {
/// Get token from x-app-sdk (web only)
Future
<
String
?>
_getTokenFromSDK
()
async
{
if
(!
kIsWeb
)
{
p
rint
(
'🔍 SplashScreen - Not on web, skipping SDK token retrieval'
);
debugP
rint
(
'🔍 SplashScreen - Not on web, skipping SDK token retrieval'
);
return
null
;
}
try
{
p
rint
(
'🔍 SplashScreen - Attempting to get token from x-app-sdk...'
);
debugP
rint
(
'🔍 SplashScreen - Attempting to get token from x-app-sdk...'
);
await
webInitializeXAppSDK
().
timeout
(
_sdkTimeout
);
if
(!
webIsSDKInitialized
())
{
p
rint
(
'⚠️ SplashScreen - SDK not initialized, skipping'
);
debugP
rint
(
'⚠️ SplashScreen - SDK not initialized, skipping'
);
return
null
;
}
// Get token from SDK
final
token
=
await
webGetToken
().
timeout
(
_sdkTimeout
);
if
(
token
!=
null
&&
token
.
isNotEmpty
)
{
p
rint
(
'✅ SplashScreen - Token retrieved from x-app-sdk:
${token.substring(0, 8)}
...'
);
debugP
rint
(
'✅ SplashScreen - Token retrieved from x-app-sdk:
${token.substring(0, 8)}
...'
);
return
token
;
}
else
{
final
error
=
webGetLastError
();
p
rint
(
'❌ SplashScreen - Failed to get token from SDK:
$error
'
);
debugP
rint
(
'❌ SplashScreen - Failed to get token from SDK:
$error
'
);
return
null
;
}
}
catch
(
e
)
{
p
rint
(
'❌ SplashScreen - Error getting token from SDK:
$e
'
);
debugP
rint
(
'❌ SplashScreen - Error getting token from SDK:
$e
'
);
return
null
;
}
}
...
...
lib/screen/support/support_screen.dart
View file @
a6797435
...
...
@@ -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
{
...
...
lib/screen/support/support_screen_viewmodel.dart
View file @
a6797435
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
)
{
p
rint
(
"Lỗi load dữ liệu:
$e
"
);
debugP
rint
(
"Lỗi load dữ liệu:
$e
"
);
}
}
}
lib/screen/topup/topup_viewmodel.dart
View file @
a6797435
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
);
...
...
lib/screen/traffic_service/traffic_service_detail_screen.dart
View file @
a6797435
...
...
@@ -21,7 +21,7 @@ class _TrafficServiceDetailScreenState extends State<TrafficServiceDetailScreen>
@override
void
initState
()
{
super
.
initState
();
in
t
?
serviceId
;
Str
in
g
?
serviceId
;
TrafficServiceDetailModel
?
data
;
final
args
=
Get
.
arguments
;
if
(
args
is
Map
)
{
...
...
lib/screen/traffic_service/traffic_service_screen.dart
View file @
a6797435
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:
()
{
p
rint
(
'Tapped on item:
${item.licensePlate}
'
);
Get
.
toNamed
(
trafficServiceDetailScreen
,
arguments:
{
'serviceId'
:
item
.
itemId
});
debugP
rint
(
'Tapped on item:
${item.licensePlate}
'
);
Get
.
toNamed
(
trafficServiceDetailScreen
,
arguments:
{
'serviceId'
:
item
.
itemId
.
toString
()
});
},
leading:
SizedBox
(
width:
60
,
// <= giới hạn rõ
...
...
Prev
1
2
3
4
5
6
Next
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment