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
6c72edcb
Commit
6c72edcb
authored
Oct 14, 2025
by
DatHV
Browse files
update logic direction
parent
97763d9b
Changes
24
Hide whitespace changes
Inline
Side-by-side
lib/screen/voucher/voucher_list/voucher_list_viewmodel.dart
View file @
6c72edcb
import
'dart:async'
;
import
'dart:async'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'
;
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
'../../../networking/restful_api_viewmodel.dart'
;
import
'../../../widgets/alert/popup_data_model.dart'
;
import
'../models/product_model.dart'
;
import
'../models/product_model.dart'
;
import
'../models/product_type.dart'
;
import
'../models/product_type.dart'
;
...
@@ -20,6 +22,9 @@ class VoucherListViewModel extends RestfulApiViewModel {
...
@@ -20,6 +22,9 @@ class VoucherListViewModel extends RestfulApiViewModel {
String
_searchQuery
=
''
;
String
_searchQuery
=
''
;
String
get
searchQuery
=>
_searchQuery
;
String
get
searchQuery
=>
_searchQuery
;
var
totalResult
=
0
.
obs
;
var
totalResult
=
0
.
obs
;
/// Đánh dấu đã hoàn tất lần tải đầu tiên (có dữ liệu) để UI có thể bắt đầu countdown
final
firstLoadDone
=
false
.
obs
;
void
Function
(
BaseResponseModel
<
SubmitViewVoucherCompletedResponse
>
response
)?
submitCampaignViewVoucherResponse
;
@override
@override
void
onInit
()
{
void
onInit
()
{
...
@@ -79,6 +84,8 @@ class VoucherListViewModel extends RestfulApiViewModel {
...
@@ -79,6 +84,8 @@ class VoucherListViewModel extends RestfulApiViewModel {
hideLoading
();
hideLoading
();
isLoading
.
value
=
false
;
isLoading
.
value
=
false
;
isLoadMore
.
value
=
false
;
isLoadMore
.
value
=
false
;
// Khi lần đầu có dữ liệu, đánh dấu để UI start countdown
if
(
products
.
isNotEmpty
)
firstLoadDone
.
value
=
true
;
}
}
}
}
...
@@ -120,6 +127,15 @@ class VoucherListViewModel extends RestfulApiViewModel {
...
@@ -120,6 +127,15 @@ class VoucherListViewModel extends RestfulApiViewModel {
hideLoading
();
hideLoading
();
isLoading
.
value
=
false
;
isLoading
.
value
=
false
;
isLoadMore
.
value
=
false
;
isLoadMore
.
value
=
false
;
// Khi lần đầu có dữ liệu, đánh dấu để UI start countdown
if
(
products
.
isNotEmpty
)
firstLoadDone
.
value
=
true
;
}
}
}
}
void
submitCampaignViewVoucherComplete
()
async
{
showProgressIndicator
();
final
response
=
await
client
.
submitCampaignViewVoucherComplete
();
hideProgressIndicator
();
submitCampaignViewVoucherResponse
?.
call
(
response
);
}
}
}
lib/screen/webview/web_view_screen.dart
View file @
6c72edcb
...
@@ -160,89 +160,6 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
...
@@ -160,89 +160,6 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
}
}
}
}
Widget
_buildWebViewForWeb
()
{
if
(!
kIsWeb
)
return
const
SizedBox
.
shrink
();
return
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
child:
Column
(
children:
[
// Header với URL
Container
(
padding:
const
EdgeInsets
.
all
(
16
),
color:
Colors
.
grey
[
100
],
child:
Row
(
children:
[
Icon
(
Icons
.
language
,
color:
Colors
.
blue
),
const
SizedBox
(
width:
8
),
Expanded
(
child:
Text
(
input
.
url
,
style:
const
TextStyle
(
fontSize:
14
),
overflow:
TextOverflow
.
ellipsis
,
),
),
const
SizedBox
(
width:
8
),
ElevatedButton
.
icon
(
onPressed:
()
=>
_openUrlInBrowser
(),
icon:
const
Icon
(
Icons
.
open_in_new
,
size:
16
),
label:
const
Text
(
'Mở tab mới'
),
style:
ElevatedButton
.
styleFrom
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
12
,
vertical:
8
),
),
),
],
),
),
// iframe area
Expanded
(
child:
Container
(
width:
double
.
infinity
,
height:
double
.
infinity
,
decoration:
BoxDecoration
(
border:
Border
.
all
(
color:
Colors
.
grey
[
300
]!),
),
child:
Center
(
child:
Column
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
[
Icon
(
Icons
.
web
,
size:
64
,
color:
Colors
.
grey
[
400
]),
const
SizedBox
(
height:
16
),
Text
(
'WebView không hỗ trợ trực tiếp trên web'
,
style:
Theme
.
of
(
context
).
textTheme
.
headlineSmall
?.
copyWith
(
color:
Colors
.
grey
[
600
],
),
textAlign:
TextAlign
.
center
,
),
const
SizedBox
(
height:
8
),
Text
(
'Vui lòng click "Mở tab mới" để xem nội dung'
,
style:
Theme
.
of
(
context
).
textTheme
.
bodyMedium
?.
copyWith
(
color:
Colors
.
grey
[
500
],
),
textAlign:
TextAlign
.
center
,
),
const
SizedBox
(
height:
24
),
ElevatedButton
.
icon
(
onPressed:
()
=>
_openUrlInBrowser
(),
icon:
const
Icon
(
Icons
.
open_in_new
),
label:
const
Text
(
'Mở trong tab mới'
),
style:
ElevatedButton
.
styleFrom
(
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
24
,
vertical:
12
),
),
),
],
),
),
),
),
],
),
);
}
Future
<
void
>
_openUrlInBrowser
()
async
{
Future
<
void
>
_openUrlInBrowser
()
async
{
try
{
try
{
final
uri
=
Uri
.
parse
(
formatUrl
(
input
.
url
));
final
uri
=
Uri
.
parse
(
formatUrl
(
input
.
url
));
...
@@ -267,7 +184,7 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
...
@@ -267,7 +184,7 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
return
NavigationDecision
.
prevent
;
return
NavigationDecision
.
prevent
;
}
}
if
(
url
.
startsWith
(
'itms-apps://'
))
{
if
(
url
.
startsWith
(
'itms-apps://'
))
{
open
AppStore
(
url
);
open
StringUrlExternally
(
url
);
return
NavigationDecision
.
prevent
;
return
NavigationDecision
.
prevent
;
}
}
if
(
url
.
startsWith
(
'sms:'
))
{
if
(
url
.
startsWith
(
'sms:'
))
{
...
@@ -277,4 +194,87 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
...
@@ -277,4 +194,87 @@ class _BaseWebViewScreenState extends BaseState<BaseWebViewScreen> with BasicSta
}
}
return
NavigationDecision
.
navigate
;
return
NavigationDecision
.
navigate
;
}
}
// Widget _buildWebViewForWeb() {
// if (!kIsWeb) return const SizedBox.shrink();
//
// return Container(
// width: double.infinity,
// height: double.infinity,
// child: Column(
// children: [
// // Header với URL
// Container(
// padding: const EdgeInsets.all(16),
// color: Colors.grey[100],
// child: Row(
// children: [
// Icon(Icons.language, color: Colors.blue),
// const SizedBox(width: 8),
// Expanded(
// child: Text(
// input.url,
// style: const TextStyle(fontSize: 14),
// overflow: TextOverflow.ellipsis,
// ),
// ),
// const SizedBox(width: 8),
// ElevatedButton.icon(
// onPressed: () => _openUrlInBrowser(),
// icon: const Icon(Icons.open_in_new, size: 16),
// label: const Text('Mở tab mới'),
// style: ElevatedButton.styleFrom(
// padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
// ),
// ),
// ],
// ),
// ),
// // iframe area
// Expanded(
// child: Container(
// width: double.infinity,
// height: double.infinity,
// decoration: BoxDecoration(
// border: Border.all(color: Colors.grey[300]!),
// ),
// child: Center(
// child: Column(
// mainAxisAlignment: MainAxisAlignment.center,
// children: [
// Icon(Icons.web, size: 64, color: Colors.grey[400]),
// const SizedBox(height: 16),
// Text(
// 'WebView không hỗ trợ trực tiếp trên web',
// style: Theme.of(context).textTheme.headlineSmall?.copyWith(
// color: Colors.grey[600],
// ),
// textAlign: TextAlign.center,
// ),
// const SizedBox(height: 8),
// Text(
// 'Vui lòng click "Mở tab mới" để xem nội dung',
// style: Theme.of(context).textTheme.bodyMedium?.copyWith(
// color: Colors.grey[500],
// ),
// textAlign: TextAlign.center,
// ),
// const SizedBox(height: 24),
// ElevatedButton.icon(
// onPressed: () => _openUrlInBrowser(),
// icon: const Icon(Icons.open_in_new),
// label: const Text('Mở trong tab mới'),
// style: ElevatedButton.styleFrom(
// padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// ],
// ),
// );
// }
}
}
lib/widgets/alert/popup_data_model.dart
View file @
6c72edcb
...
@@ -38,5 +38,18 @@ class PopupDataModel {
...
@@ -38,5 +38,18 @@ class PopupDataModel {
});
});
factory
PopupDataModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$PopupDataModelFromJson
(
json
);
factory
PopupDataModel
.
fromJson
(
Map
<
String
,
dynamic
>
json
)
=>
_$PopupDataModelFromJson
(
json
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$PopupDataModelToJson
(
this
);
Map
<
String
,
dynamic
>
toJson
()
=>
_$PopupDataModelToJson
(
this
);
static
PopupDataModel
?
error
(
String
mgs
)
{
return
PopupDataModel
(
urlHeaderImg:
null
,
title:
null
,
description:
mgs
,
value:
null
,
buttonConfirm:
null
,
buttonCancel:
null
,
localHeaderImg:
'assets/images/ic_pipi_03.png'
,
);
}
}
}
\ No newline at end of file
pubspec.yaml
View file @
6c72edcb
...
@@ -67,12 +67,12 @@ dependencies:
...
@@ -67,12 +67,12 @@ dependencies:
encrypt
:
^5.0.1
encrypt
:
^5.0.1
connectivity_plus
:
connectivity_plus
:
flutter_launcher_icons
:
^0.14.4
flutter_launcher_icons
:
^0.14.4
game_miniapp
:
path
:
../mini_app/game_miniapp
firebase_core
:
^4.1.0
firebase_core
:
^4.1.0
firebase_messaging
:
^16.0.1
firebase_messaging
:
^16.0.1
flutter_local_notifications
:
^19.4.2
flutter_local_notifications
:
^19.4.2
uni_links
:
^0.5.1
auto_size_text
:
^3.0.0
auto_size_text
:
^3.0.0
in_app_review
:
^2.0.8
dev_dependencies
:
dev_dependencies
:
flutter_test
:
flutter_test
:
sdk
:
flutter
sdk
:
flutter
...
...
Prev
1
2
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