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
6b980613
Commit
6b980613
authored
Nov 14, 2025
by
DatHV
Browse files
update project structure
parent
bfff9e47
Changes
507
Hide whitespace changes
Inline
Side-by-side
lib/
screen
/history_point_cashback/history_point_cashback_screen.dart
→
lib/
features
/history_point_cashback/history_point_cashback_screen.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/
core/utils/
extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/
shared/
widgets/image_loader.dart'
;
import
'../../
..
/widgets/custom_empty_widget.dart'
;
import
'../../
shared
/widgets/custom_empty_widget.dart'
;
import
'../../widgets/custom_navigation_bar.dart'
;
import
'../../
shared/
widgets/custom_navigation_bar.dart'
;
import
'history_point_cashback_viewmodel.dart'
;
import
'history_point_cashback_viewmodel.dart'
;
import
'models/history_point_cashback_model.dart'
;
import
'models/history_point_cashback_model.dart'
;
...
@@ -26,7 +26,6 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
...
@@ -26,7 +26,6 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
screenWidth
=
MediaQuery
.
of
(
context
).
size
.
width
;
return
Scaffold
(
return
Scaffold
(
appBar:
CustomNavigationBar
(
title:
"Lịch sử hoàn điểm"
),
appBar:
CustomNavigationBar
(
title:
"Lịch sử hoàn điểm"
),
body:
Column
(
body:
Column
(
...
@@ -62,12 +61,13 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
...
@@ -62,12 +61,13 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
),
),
),
),
),
),
if
(
_viewModel
.
orders
.
isEmpty
)
Expanded
(
Expanded
(
child:
EmptyWidget
(
size:
Size
(
screenWidth
/
2
,
screenWidth
/
2
)))
child:
Obx
(
else
()
{
Obx
(
if
(
_viewModel
.
orders
.
isEmpty
)
{
()
=>
Expanded
(
return
EmptyWidget
(
isLoading:
_viewModel
.
isLoading
.
value
);
child:
RefreshIndicator
(
}
return
RefreshIndicator
(
onRefresh:
()
async
{
onRefresh:
()
async
{
_viewModel
.
freshData
(
isRefresh:
true
);
_viewModel
.
freshData
(
isRefresh:
true
);
},
},
...
@@ -85,9 +85,10 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
...
@@ -85,9 +85,10 @@ class _HistoryPointCashBackScreenState extends State<HistoryPointCashBackScreen>
return
_buildVoucherItem
(
order
);
return
_buildVoucherItem
(
order
);
},
},
),
),
)
,
)
;
)
,
}
,
),
),
),
],
],
),
),
);
);
...
...
lib/
screen
/history_point_cashback/history_point_cashback_viewmodel.dart
→
lib/
features
/history_point_cashback/history_point_cashback_viewmodel.dart
View file @
6b980613
import
'package:get/get_rx/src/rx_types/rx_types.dart'
;
import
'package:get/get_rx/src/rx_types/rx_types.dart'
;
import
'package:mypoint_flutter_app/extensions/collection_extension.dart'
;
import
'package:mypoint_flutter_app/
core/utils/
extensions/collection_extension.dart'
;
import
'package:mypoint_flutter_app/network
ing
/restful_api_client_all_request.dart'
;
import
'package:mypoint_flutter_app/
core/
network/restful_api_client_all_request.dart'
;
import
'../../network
ing
/restful_api_viewmodel.dart'
;
import
'../../
core/
network/restful_api_viewmodel.dart'
;
import
'models/history_point_cashback_model.dart'
;
import
'models/history_point_cashback_model.dart'
;
class
HistoryPointCashBackViewModel
extends
RestfulApiViewModel
{
class
HistoryPointCashBackViewModel
extends
RestfulApiViewModel
{
...
...
lib/
screen
/history_point_cashback/models/history_point_cashback_model.dart
→
lib/
features
/history_point_cashback/models/history_point_cashback_model.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/extensions/datetime_extensions.dart'
;
import
'package:mypoint_flutter_app/core/utils/extensions/datetime_extensions.dart'
;
import
'../../../extensions/date_format.dart'
;
class
HistoryPointCashBackResponse
{
class
HistoryPointCashBackResponse
{
final
double
points
;
final
double
points
;
...
...
lib/
screen
/home/custom_widget/achievement_carousel_widget.dart
→
lib/
features
/home/custom_widget/achievement_carousel_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../widgets/image_loader.dart'
;
import
'../../../
shared/
widgets/image_loader.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../model
s
/achievement_model.dart'
;
import
'../
../achievement/
model/achievement_model.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
class
AchievementCarousel
extends
StatelessWidget
{
class
AchievementCarousel
extends
StatelessWidget
{
...
@@ -33,7 +33,7 @@ class AchievementCarousel extends StatelessWidget {
...
@@ -33,7 +33,7 @@ class AchievementCarousel extends StatelessWidget {
scrollDirection:
Axis
.
horizontal
,
scrollDirection:
Axis
.
horizontal
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
itemCount:
items
.
length
,
itemCount:
items
.
length
,
separatorBuilder:
(
_
,
_
_
)
=>
const
SizedBox
(
width:
12
),
separatorBuilder:
(
_
,
_
)
=>
const
SizedBox
(
width:
12
),
itemBuilder:
(
context
,
index
)
=>
AchievementCard
(
itemBuilder:
(
context
,
index
)
=>
AchievementCard
(
achievement:
items
[
index
],
achievement:
items
[
index
],
onTap:
()
=>
onTap
?.
call
(
items
[
index
]),
onTap:
()
=>
onTap
?.
call
(
items
[
index
]),
...
...
lib/
screen
/home/custom_widget/affiliate_brand_grid_widget.dart
→
lib/
features
/home/custom_widget/affiliate_brand_grid_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/extensions/string_extension.dart'
;
import
'package:mypoint_flutter_app/
core/utils/
extensions/string_extension.dart'
;
import
'../../affiliate/model/affiliate_brand_model.dart'
;
import
'../../affiliate/model/affiliate_brand_model.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
...
@@ -11,7 +11,7 @@ class AffiliateBrandGridWidget extends StatelessWidget {
...
@@ -11,7 +11,7 @@ class AffiliateBrandGridWidget extends StatelessWidget {
const
AffiliateBrandGridWidget
({
super
.
key
,
required
this
.
affiliateBrands
,
this
.
sectionConfig
,
this
.
onTap
});
const
AffiliateBrandGridWidget
({
super
.
key
,
required
this
.
affiliateBrands
,
this
.
sectionConfig
,
this
.
onTap
});
_handleTapRightButton
()
{
void
_handleTapRightButton
()
{
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
}
}
...
@@ -74,7 +74,7 @@ class AffiliateBrandGridWidget extends StatelessWidget {
...
@@ -74,7 +74,7 @@ class AffiliateBrandGridWidget extends StatelessWidget {
child:
Image
.
network
(
child:
Image
.
network
(
brand
.
logo
??
''
,
brand
.
logo
??
''
,
fit:
BoxFit
.
contain
,
fit:
BoxFit
.
contain
,
errorBuilder:
(
_
,
_
_
,
__
_
)
=>
const
Icon
(
Icons
.
broken_image
),
errorBuilder:
(
_
,
_
,
_
)
=>
const
Icon
(
Icons
.
broken_image
),
),
),
),
),
),
),
...
...
lib/
screen
/home/custom_widget/banner_carousel_widget.dart
→
lib/
features
/home/custom_widget/banner_carousel_widget.dart
View file @
6b980613
...
@@ -22,12 +22,16 @@ class _BannerCarouselState extends State<BannerCarousel> {
...
@@ -22,12 +22,16 @@ class _BannerCarouselState extends State<BannerCarousel> {
Timer
?
_autoPlayTimer
;
Timer
?
_autoPlayTimer
;
final
bool
_isDragging
=
false
;
final
bool
_isDragging
=
false
;
bool
_isUserScrolling
=
false
;
bool
_isUserScrolling
=
false
;
double
?
_firstBannerAspectRatio
;
// height / width
String
?
_aspectRatioSourceUrl
;
static
const
double
_defaultAspectRatio
=
535
/
1125
;
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
_controller
=
InfiniteScrollController
(
initialItem:
0
);
_controller
=
InfiniteScrollController
(
initialItem:
0
);
_startAutoPlay
();
_startAutoPlay
();
_resolveFirstBannerAspectRatio
();
}
}
void
_startAutoPlay
()
{
void
_startAutoPlay
()
{
...
@@ -55,13 +59,57 @@ class _BannerCarouselState extends State<BannerCarousel> {
...
@@ -55,13 +59,57 @@ class _BannerCarouselState extends State<BannerCarousel> {
super
.
dispose
();
super
.
dispose
();
}
}
_handleTapRightButton
()
{
@override
void
didUpdateWidget
(
covariant
BannerCarousel
oldWidget
)
{
super
.
didUpdateWidget
(
oldWidget
);
final
oldUrl
=
oldWidget
.
banners
.
isNotEmpty
?
oldWidget
.
banners
.
first
.
itemImage
:
null
;
final
newUrl
=
widget
.
banners
.
isNotEmpty
?
widget
.
banners
.
first
.
itemImage
:
null
;
if
(
oldUrl
!=
newUrl
)
{
_firstBannerAspectRatio
=
null
;
_aspectRatioSourceUrl
=
null
;
_resolveFirstBannerAspectRatio
();
}
}
void
_resolveFirstBannerAspectRatio
()
{
if
(
widget
.
banners
.
isEmpty
)
return
;
final
url
=
widget
.
banners
.
first
.
itemImage
;
if
((
url
??
''
).
isEmpty
||
url
==
_aspectRatioSourceUrl
)
{
return
;
}
_aspectRatioSourceUrl
=
url
;
final
provider
=
NetworkImage
(
url
!);
final
stream
=
provider
.
resolve
(
const
ImageConfiguration
());
late
ImageStreamListener
listener
;
listener
=
ImageStreamListener
(
(
info
,
_
)
{
final
ratio
=
info
.
image
.
height
/
info
.
image
.
width
;
if
(
mounted
)
{
setState
(()
{
_firstBannerAspectRatio
=
ratio
;
});
}
stream
.
removeListener
(
listener
);
},
onError:
(
_
,
_
)
{
stream
.
removeListener
(
listener
);
},
);
stream
.
addListener
(
listener
);
}
void
_handleTapRightButton
()
{
widget
.
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
widget
.
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
}
}
double
_currentBannerAspectRatio
()
{
return
_firstBannerAspectRatio
??
_defaultAspectRatio
;
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
final
width
=
MediaQuery
.
of
(
context
).
size
.
width
*
0.9
;
final
width
=
MediaQuery
.
of
(
context
).
size
.
width
*
0.9
;
final
height
=
width
*
_currentBannerAspectRatio
()
+
16
;
return
Column
(
return
Column
(
children:
[
children:
[
if
((
widget
.
sectionConfig
?.
name
??
""
).
isNotEmpty
)
if
((
widget
.
sectionConfig
?.
name
??
""
).
isNotEmpty
)
...
@@ -69,66 +117,74 @@ class _BannerCarouselState extends State<BannerCarousel> {
...
@@ -69,66 +117,74 @@ class _BannerCarouselState extends State<BannerCarousel> {
title:
widget
.
sectionConfig
?.
name
??
""
,
title:
widget
.
sectionConfig
?.
name
??
""
,
onViewAll:
widget
.
sectionConfig
?.
buttonViewAll
?.
directionalScreen
!=
null
?
_handleTapRightButton
:
null
,
onViewAll:
widget
.
sectionConfig
?.
buttonViewAll
?.
directionalScreen
!=
null
?
_handleTapRightButton
:
null
,
),
),
GestureDetector
(
if
(
widget
.
banners
.
isNotEmpty
)
onPanDown:
(
_
)
=>
_pauseAutoPlayTemporarily
(),
GestureDetector
(
child:
SizedBox
(
onPanDown:
(
_
)
=>
_pauseAutoPlayTemporarily
(),
height:
width
*
135
/
343
+
16
,
child:
SizedBox
(
child:
Stack
(
// height: width * 135 / 343 + 16,
alignment:
Alignment
.
bottomCenter
,
height:
height
,
children:
[
child:
Stack
(
InfiniteCarousel
.
builder
(
alignment:
Alignment
.
bottomCenter
,
itemCount:
widget
.
banners
.
length
,
children:
[
itemExtent:
width
,
InfiniteCarousel
.
builder
(
scrollBehavior:
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
),
itemCount:
widget
.
banners
.
length
,
loop:
true
,
itemExtent:
width
,
center:
true
,
scrollBehavior:
ScrollConfiguration
.
of
(
context
).
copyWith
(
scrollbars:
false
),
anchor:
0.0
,
loop:
true
,
velocityFactor:
0.1
,
// ✅ fix lỗi: snap từng page
center:
true
,
controller:
_controller
,
anchor:
0.0
,
onIndexChanged:
(
index
)
=>
setState
(()
=>
_currentIndex
=
index
%
widget
.
banners
.
length
),
velocityFactor:
0.1
,
itemBuilder:
(
context
,
itemIndex
,
realIndex
)
{
controller:
_controller
,
return
GestureDetector
(
onIndexChanged:
(
index
)
=>
setState
(()
=>
_currentIndex
=
index
%
widget
.
banners
.
length
),
onTap:
()
=>
widget
.
onTap
?.
call
(
widget
.
banners
[
itemIndex
%
widget
.
banners
.
length
]),
itemBuilder:
(
context
,
itemIndex
,
realIndex
)
{
child:
Padding
(
final
bannerIndex
=
itemIndex
%
widget
.
banners
.
length
;
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
4.0
,
vertical:
8.0
),
final
ratio
=
_currentBannerAspectRatio
();
child:
ClipRRect
(
return
GestureDetector
(
borderRadius:
BorderRadius
.
circular
(
12
),
onTap:
()
=>
widget
.
onTap
?.
call
(
widget
.
banners
[
bannerIndex
]),
child:
Image
.
network
(
child:
Padding
(
widget
.
banners
[
itemIndex
%
widget
.
banners
.
length
].
itemImage
??
""
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
4.0
,
vertical:
8.0
),
fit:
BoxFit
.
cover
,
child:
AspectRatio
(
width:
double
.
infinity
,
aspectRatio:
ratio
<=
0
?
1125
/
535
:
1
/
ratio
,
child:
ClipRRect
(
borderRadius:
BorderRadius
.
circular
(
12
),
child:
Image
.
network
(
widget
.
banners
[
bannerIndex
].
itemImage
??
""
,
fit:
BoxFit
.
cover
,
width:
double
.
infinity
,
),
),
),
),
),
),
),
);
);
},
},
),
),
Positioned
(
Positioned
(
bottom:
12
,
bottom:
12
,
child:
Row
(
child:
Row
(
mainAxisAlignment:
MainAxisAlignment
.
center
,
mainAxisAlignment:
MainAxisAlignment
.
center
,
children:
children:
widget
.
banners
.
asMap
().
entries
.
map
((
entry
)
{
widget
.
banners
.
asMap
().
entries
.
map
((
entry
)
{
return
GestureDetector
(
return
GestureDetector
(
onTap:
onTap:
()
=>
()
=>
_controller
.
animateToItem
(
entry
.
key
,
duration:
const
Duration
(
milliseconds:
500
)),
_controller
.
animateToItem
(
entry
.
key
,
duration:
const
Duration
(
milliseconds:
500
)),
child:
Container
(
child:
Container
(
width:
8.0
,
width:
8.0
,
height:
8.0
,
height:
8.0
,
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
4.0
),
margin:
const
EdgeInsets
.
symmetric
(
horizontal:
4.0
),
decoration:
BoxDecoration
(
decoration:
BoxDecoration
(
shape:
BoxShape
.
circle
,
shape:
BoxShape
.
circle
,
color:
_currentIndex
==
entry
.
key
?
Colors
.
white
:
Colors
.
white
.
withOpacity
(
0.4
),
color:
_currentIndex
==
entry
.
key
?
Colors
.
white
:
Colors
.
white
.
withOpacity
(
0.4
),
),
),
),
)
,
)
;
);
}).
toList
(),
}).
toList
(
),
),
),
),
)
,
]
,
]
,
)
,
),
),
),
),
),
],
],
);
);
}
}
...
...
lib/
screen
/home/custom_widget/brand_grid_widget.dart
→
lib/
features
/home/custom_widget/brand_grid_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/extensions/string_extension.dart'
;
import
'package:mypoint_flutter_app/shared/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/brand_model.dart'
;
import
'../
../affiliate_brand_detail/
models/brand_model.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
class
BrandGridWidget
extends
StatelessWidget
{
class
BrandGridWidget
extends
StatelessWidget
{
...
...
lib/
screen
/home/custom_widget/flash_sale_carousel_widget.dart
→
lib/
features
/home/custom_widget/flash_sale_carousel_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/
core/utils/
extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/
shared/
widgets/image_loader.dart'
;
import
'../../voucher/models/product_model.dart'
;
import
'../../voucher/models/product_model.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'flash_sale_header_widget.dart'
;
import
'flash_sale_header_widget.dart'
;
...
...
lib/
screen
/home/custom_widget/flash_sale_header_widget.dart
→
lib/
features
/home/custom_widget/flash_sale_header_widget.dart
View file @
6b980613
...
@@ -80,7 +80,6 @@ class _FlashSaleHeaderState extends State<FlashSaleHeader> {
...
@@ -80,7 +80,6 @@ class _FlashSaleHeaderState extends State<FlashSaleHeader> {
}
}
Widget
_buildCountdownSection
(
Duration
duration
)
{
Widget
_buildCountdownSection
(
Duration
duration
)
{
final
bool
isCounting
=
duration
.
inSeconds
>
0
;
final
label
=
(
widget
.
flashSale
?.
desTime
??
'Kết thúc trong'
);
final
label
=
(
widget
.
flashSale
?.
desTime
??
'Kết thúc trong'
);
return
Row
(
return
Row
(
mainAxisSize:
MainAxisSize
.
min
,
mainAxisSize:
MainAxisSize
.
min
,
...
...
lib/
screen
/home/custom_widget/header_home_widget.dart
→
lib/
features
/home/custom_widget/header_home_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/core/utils/extensions/num_extension.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/shared/widgets/image_loader.dart'
;
import
'../../../preference/data_preference.dart'
;
import
'../../../shared/preferences/data_preference.dart'
;
import
'../../../preference/point/header_home_model.dart'
;
import
'../../../shared/preferences/point/point_manager.dart'
;
import
'../../../preference/point/point_manager.dart'
;
import
'../../../shared/router_gage.dart'
;
import
'../../../shared/router_gage.dart'
;
import
'../models/notification_unread_model.dart'
;
import
'../models/header_home_model.dart'
;
import
'../../notification/models/notification_unread_model.dart'
;
class
HomeGreetingHeader
extends
StatelessWidget
{
class
HomeGreetingHeader
extends
StatelessWidget
{
final
double
?
heightContent
;
final
double
?
heightContent
;
...
...
lib/
screen
/home/custom_widget/hover_view_widget.dart
→
lib/
features
/home/custom_widget/hover_view_widget.dart
View file @
6b980613
import
'dart:async'
;
import
'dart:async'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/
shared/
widgets/image_loader.dart'
;
class
HoverView
extends
StatefulWidget
{
class
HoverView
extends
StatefulWidget
{
final
String
imagePath
;
final
String
imagePath
;
...
@@ -31,7 +30,7 @@ class HoverView extends StatefulWidget {
...
@@ -31,7 +30,7 @@ class HoverView extends StatefulWidget {
class
_HoverViewState
extends
State
<
HoverView
>
{
class
_HoverViewState
extends
State
<
HoverView
>
{
Offset
_position
=
const
Offset
(
0
,
0
);
Offset
_position
=
const
Offset
(
0
,
0
);
bool
_isDragging
=
false
;
bool
_isDragging
=
false
;
bool
_showCloseButton
=
fals
e
;
//
bool _showCloseButton =
tru
e;
Size
_screenSize
=
Size
.
zero
;
Size
_screenSize
=
Size
.
zero
;
bool
_isInitialized
=
false
;
bool
_isInitialized
=
false
;
final
_remainingSeconds
=
0
.
obs
;
final
_remainingSeconds
=
0
.
obs
;
...
@@ -89,7 +88,7 @@ class _HoverViewState extends State<HoverView> {
...
@@ -89,7 +88,7 @@ class _HoverViewState extends State<HoverView> {
void
_onPanStart
(
DragStartDetails
details
)
{
void
_onPanStart
(
DragStartDetails
details
)
{
setState
(()
{
setState
(()
{
_isDragging
=
true
;
_isDragging
=
true
;
_showCloseButton
=
true
;
//
_showCloseButton = true;
});
});
}
}
...
@@ -148,7 +147,7 @@ class _HoverViewState extends State<HoverView> {
...
@@ -148,7 +147,7 @@ class _HoverViewState extends State<HoverView> {
// Animate to nearest corner using setState
// Animate to nearest corner using setState
setState
(()
{
setState
(()
{
_position
=
nearestCorner
;
_position
=
nearestCorner
;
_showCloseButton
=
false
;
//
_showCloseButton = false;
});
});
}
}
...
@@ -158,6 +157,9 @@ class _HoverViewState extends State<HoverView> {
...
@@ -158,6 +157,9 @@ class _HoverViewState extends State<HoverView> {
}
}
}
}
void
_onLongPress
()
{
}
void
_onClose
()
{
void
_onClose
()
{
if
(
widget
.
onClose
!=
null
)
{
if
(
widget
.
onClose
!=
null
)
{
widget
.
onClose
!();
widget
.
onClose
!();
...
@@ -196,11 +198,7 @@ class _HoverViewState extends State<HoverView> {
...
@@ -196,11 +198,7 @@ class _HoverViewState extends State<HoverView> {
onPanUpdate:
_onPanUpdate
,
onPanUpdate:
_onPanUpdate
,
onPanEnd:
_onPanEnd
,
onPanEnd:
_onPanEnd
,
onTap:
_onTap
,
onTap:
_onTap
,
onLongPress:
()
{
onLongPress:
_onLongPress
,
setState
(()
{
_showCloseButton
=
!
_showCloseButton
;
});
},
child:
Stack
(
child:
Stack
(
clipBehavior:
Clip
.
none
,
clipBehavior:
Clip
.
none
,
children:
[
children:
[
...
@@ -208,7 +206,7 @@ class _HoverViewState extends State<HoverView> {
...
@@ -208,7 +206,7 @@ class _HoverViewState extends State<HoverView> {
Column
(
Column
(
children:
[
children:
[
AnimatedScale
(
AnimatedScale
(
scale:
_isDragging
?
1.
1
:
1.0
,
scale:
_isDragging
?
1.
2
:
1.0
,
duration:
const
Duration
(
milliseconds:
200
),
duration:
const
Duration
(
milliseconds:
200
),
child:
SizedBox
(
child:
SizedBox
(
width:
widget
.
size
,
width:
widget
.
size
,
...
@@ -237,7 +235,7 @@ class _HoverViewState extends State<HoverView> {
...
@@ -237,7 +235,7 @@ class _HoverViewState extends State<HoverView> {
],
],
),
),
// Close button
// Close button
if
(
_showCloseButton
)
//
if (_showCloseButton)
Positioned
(
Positioned
(
top:
-
8
,
top:
-
8
,
right:
-
8
,
right:
-
8
,
...
...
lib/
screen
/home/custom_widget/main_service_grid_widget.dart
→
lib/
features
/home/custom_widget/main_service_grid_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'../../../widgets/image_loader.dart'
;
import
'../../../
shared/
widgets/image_loader.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_service_model.dart'
;
import
'../models/main_service_model.dart'
;
...
...
lib/
screen
/home/custom_widget/my_product_carousel_widget.dart
→
lib/
features
/home/custom_widget/my_product_carousel_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/
shared/
widgets/image_loader.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/my_product_model.dart'
;
import
'../
../voucher/
models/my_product_model.dart'
;
class
MyProductCarouselWidget
extends
StatelessWidget
{
class
MyProductCarouselWidget
extends
StatelessWidget
{
final
List
<
MyProductModel
>
items
;
final
List
<
MyProductModel
>
items
;
...
@@ -33,7 +33,7 @@ class MyProductCarouselWidget extends StatelessWidget {
...
@@ -33,7 +33,7 @@ class MyProductCarouselWidget extends StatelessWidget {
scrollDirection:
Axis
.
horizontal
,
scrollDirection:
Axis
.
horizontal
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
itemCount:
items
.
length
,
itemCount:
items
.
length
,
separatorBuilder:
(
_
,
_
_
)
=>
const
SizedBox
(
width:
12
),
separatorBuilder:
(
_
,
_
)
=>
const
SizedBox
(
width:
12
),
itemBuilder:
(
context
,
index
)
=>
_buildItem
(
context
,
items
[
index
],
widthItem
),
itemBuilder:
(
context
,
index
)
=>
_buildItem
(
context
,
items
[
index
],
widthItem
),
),
),
),
),
...
@@ -88,7 +88,7 @@ class MyProductCarouselWidget extends StatelessWidget {
...
@@ -88,7 +88,7 @@ class MyProductCarouselWidget extends StatelessWidget {
overflow:
TextOverflow
.
ellipsis
,
overflow:
TextOverflow
.
ellipsis
,
),
),
const
SizedBox
(
height:
2
),
const
SizedBox
(
height:
2
),
Text
(
'HSD:
${product.expire
?? ''
}
'
,
style:
const
TextStyle
(
fontSize:
13
,
color:
Colors
.
black54
)),
Text
(
'HSD:
${product.expire}
'
,
style:
const
TextStyle
(
fontSize:
13
,
color:
Colors
.
black54
)),
],
],
),
),
),
),
...
...
lib/
screen
/home/custom_widget/news_carousel_widget.dart
→
lib/
features
/home/custom_widget/news_carousel_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/shared/widgets/image_loader.dart'
;
import
'../../faqs/faqs_model.dart'
;
import
'../../faqs/faqs_model.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
...
@@ -32,7 +31,7 @@ class NewsCarouselWidget extends StatelessWidget {
...
@@ -32,7 +31,7 @@ class NewsCarouselWidget extends StatelessWidget {
scrollDirection:
Axis
.
horizontal
,
scrollDirection:
Axis
.
horizontal
,
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
padding:
const
EdgeInsets
.
symmetric
(
horizontal:
16
),
itemCount:
items
.
length
,
itemCount:
items
.
length
,
separatorBuilder:
(
_
,
_
_
)
=>
const
SizedBox
(
width:
12
),
separatorBuilder:
(
_
,
_
)
=>
const
SizedBox
(
width:
12
),
itemBuilder:
(
context
,
index
)
=>
_buildItem
(
context
,
items
[
index
]),
itemBuilder:
(
context
,
index
)
=>
_buildItem
(
context
,
items
[
index
]),
),
),
),
),
...
...
lib/
screen
/home/custom_widget/product_grid_widget.dart
→
lib/
features
/home/custom_widget/product_grid_widget.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:mypoint_flutter_app/widgets/image_loader.dart'
;
import
'package:mypoint_flutter_app/
shared/
widgets/image_loader.dart'
;
import
'../../../widgets/custom_point_text_tag.dart'
;
import
'../../../
shared/
widgets/custom_point_text_tag.dart'
;
import
'../../voucher/models/product_model.dart'
;
import
'../../voucher/models/product_model.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../../voucher/sub_widget/voucher_section_title.dart'
;
import
'../models/main_section_config_model.dart'
;
import
'../models/main_section_config_model.dart'
;
...
@@ -13,7 +13,7 @@ class ProductGrid extends StatelessWidget {
...
@@ -13,7 +13,7 @@ class ProductGrid extends StatelessWidget {
const
ProductGrid
({
super
.
key
,
required
this
.
products
,
this
.
sectionConfig
,
this
.
onTap
});
const
ProductGrid
({
super
.
key
,
required
this
.
products
,
this
.
sectionConfig
,
this
.
onTap
});
_handleTapRightButton
()
{
void
_handleTapRightButton
()
{
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
sectionConfig
?.
buttonViewAll
?.
directionalScreen
?.
begin
();
}
}
...
...
lib/
screen
/home/header_home_viewmodel.dart
→
lib/
features
/home/header_home_viewmodel.dart
View file @
6b980613
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/networking/api/notification_api.dart'
import
'package:mypoint_flutter_app/core/network/api/notification_api.dart'
deferred
as
notification_api
;
deferred
as
notification_api
;
import
'package:mypoint_flutter_app/core/network/restful_api_client_all_request.dart'
;
import
'package:mypoint_flutter_app/networking/restful_api_client_all_request.dart'
;
import
'package:mypoint_flutter_app/shared/preferences/data_preference.dart'
;
import
'package:mypoint_flutter_app/preference/data_preference.dart'
;
import
'../../core/network/restful_api_viewmodel.dart'
;
import
'../../networking/restful_api_viewmodel.dart'
;
import
'../../shared/preferences/point/point_manager.dart'
;
import
'../../preference/point/point_manager.dart'
;
import
'models/header_home_model.dart'
;
import
'../../preference/point/header_home_model.dart'
;
import
'../notification/models/notification_unread_model.dart'
;
import
'models/notification_unread_model.dart'
;
class
HeaderHomeRepository
extends
RestfulApiViewModel
{
class
HeaderHomeRepository
extends
RestfulApiViewModel
{
HeaderHomeRepository
.
_
();
HeaderHomeRepository
.
_
();
...
...
lib/
screen
/home/home_screen.dart
→
lib/
features
/home/home_screen.dart
View file @
6b980613
import
'package:flutter/material.dart'
;
import
'package:flutter/material.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/preference/point/point_manager.dart'
;
import
'package:mypoint_flutter_app/features/home/custom_widget/header_home_widget.dart'
;
import
'package:mypoint_flutter_app/screen/home/custom_widget/header_home_widget.dart'
;
import
'package:mypoint_flutter_app/features/home/custom_widget/product_grid_widget.dart'
;
import
'package:mypoint_flutter_app/screen/home/custom_widget/product_grid_widget.dart'
;
import
'package:mypoint_flutter_app/features/pipi/pipi_detail_screen.dart'
;
import
'package:mypoint_flutter_app/screen/pipi/pipi_detail_screen.dart'
;
import
'package:mypoint_flutter_app/features/voucher/models/product_model.dart'
;
import
'package:mypoint_flutter_app/screen/voucher/models/product_model.dart'
;
import
'package:mypoint_flutter_app/shared/router_gage.dart'
;
import
'package:mypoint_flutter_app/shared/router_gage.dart'
;
import
'../../directional/directional_action_type.dart'
;
import
'../../shared/widgets/base_view/base_screen.dart'
;
import
'../../widgets/custom_empty_widget.dart'
;
import
'../../shared/widgets/base_view/basic_state.dart'
;
import
'../../app/routing/directional_action_type.dart'
;
import
'../../shared/widgets/custom_empty_widget.dart'
;
import
'../popup_manager/popup_runner_helper.dart'
;
import
'../popup_manager/popup_runner_helper.dart'
;
import
'custom_widget/achievement_carousel_widget.dart'
;
import
'custom_widget/achievement_carousel_widget.dart'
;
import
'custom_widget/affiliate_brand_grid_widget.dart'
;
import
'custom_widget/affiliate_brand_grid_widget.dart'
;
...
@@ -21,25 +22,29 @@ import 'custom_widget/news_carousel_widget.dart';
...
@@ -21,25 +22,29 @@ import 'custom_widget/news_carousel_widget.dart';
import
'header_home_viewmodel.dart'
;
import
'header_home_viewmodel.dart'
;
import
'home_tab_viewmodel.dart'
;
import
'home_tab_viewmodel.dart'
;
import
'models/header_section_type.dart'
;
import
'models/header_section_type.dart'
;
import
'models/hover_data_model.dart'
;
import
'models/main_section_config_model.dart'
;
import
'models/main_section_config_model.dart'
;
class
HomeScreen
extends
StatefulWidget
{
class
HomeScreen
extends
BaseScreen
{
const
HomeScreen
({
super
.
key
});
const
HomeScreen
({
super
.
key
});
@override
@override
State
<
HomeScreen
>
createState
()
=>
_HomeScreenState
();
State
<
HomeScreen
>
createState
()
=>
_HomeScreenState
();
}
}
class
_HomeScreenState
extends
State
<
HomeScreen
>
with
PopupOnInit
{
class
_HomeScreenState
extends
Base
State
<
HomeScreen
>
with
PopupOnInit
,
BasicState
{
final
HomeTabViewModel
_viewModel
=
Get
.
put
(
HomeTabViewModel
());
final
HomeTabViewModel
_viewModel
=
Get
.
put
(
HomeTabViewModel
());
final
_headerHomeVM
=
Get
.
find
<
HeaderHomeViewModel
>();
final
_headerHomeVM
=
Get
.
find
<
HeaderHomeViewModel
>();
final
RxBool
_showHover
=
true
.
obs
;
final
RxBool
_showHover
=
false
.
obs
;
late
final
Worker
_hoverDataWorker
;
bool
_isRefreshingFlashSale
=
false
;
bool
_isRefreshingFlashSale
=
false
;
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
UserPointManager
().
fetchUserPoint
();
debugPrint
(
'HomeScreen initState'
);
// UserPointManager().fetchUserPoint();
_hoverDataWorker
=
ever
<
HoverDataModel
?>(
_viewModel
.
hoverData
,
_onHoverDataChanged
);
_headerHomeVM
.
freshData
();
_headerHomeVM
.
freshData
();
runPopupCheck
(
DirectionalScreenName
.
home
);
runPopupCheck
(
DirectionalScreenName
.
home
);
}
}
...
@@ -70,7 +75,12 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
...
@@ -70,7 +75,12 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
List
<
Widget
>
_buildSectionContent
()
{
List
<
Widget
>
_buildSectionContent
()
{
final
sections
=
_viewModel
.
sectionLayouts
.
map
(
_buildSection
).
whereType
<
Widget
>().
toList
();
final
sections
=
_viewModel
.
sectionLayouts
.
map
(
_buildSection
).
whereType
<
Widget
>().
toList
();
if
(
sections
.
isEmpty
)
{
if
(
sections
.
isEmpty
)
{
return
const
[
Padding
(
padding:
EdgeInsets
.
symmetric
(
vertical:
40
),
child:
EmptyWidget
())];
return
[
Padding
(
padding:
const
EdgeInsets
.
symmetric
(
vertical:
40
),
child:
EmptyWidget
(
isLoading:
_viewModel
.
isLoading
.
value
),
),
];
}
}
return
sections
;
return
sections
;
}
}
...
@@ -153,7 +163,7 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
...
@@ -153,7 +163,7 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
}
}
@override
@override
Widget
build
(
BuildContext
context
)
{
Widget
createBody
(
)
{
final
paddingBottom
=
MediaQuery
.
of
(
context
).
padding
.
bottom
+
20
;
final
paddingBottom
=
MediaQuery
.
of
(
context
).
padding
.
bottom
+
20
;
final
width
=
MediaQuery
.
of
(
context
).
size
.
width
;
final
width
=
MediaQuery
.
of
(
context
).
size
.
width
;
final
heightHeader
=
width
*
86
/
375
+
112
;
final
heightHeader
=
width
*
86
/
375
+
112
;
...
@@ -203,14 +213,66 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
...
@@ -203,14 +213,66 @@ class _HomeScreenState extends State<HomeScreen> with PopupOnInit {
}
}
void
_handleCloseHoverView
()
{
void
_handleCloseHoverView
()
{
setState
(()
{
_handleCloseHoverViewInternal
();
}
void
_handleCloseHoverViewInternal
({
bool
dismissedByUser
=
true
})
{
if
(
dismissedByUser
)
{
_viewModel
.
hoverDismissed
=
true
;
}
if
(
mounted
)
{
_showHover
.
value
=
false
;
_showHover
.
value
=
false
;
}
);
}
}
}
Future
<
void
>
_onRefresh
()
async
{
Future
<
void
>
_onRefresh
()
async
{
_resetHoverViewState
();
await
_viewModel
.
getSectionLayoutHome
(
showLoading:
false
);
await
_viewModel
.
getSectionLayoutHome
(
showLoading:
false
);
await
_viewModel
.
loadDataPiPiHome
();
await
_viewModel
.
loadDataPiPiHome
();
await
_headerHomeVM
.
freshData
();
await
_headerHomeVM
.
freshData
();
}
}
@override
void
onDispose
()
{
_hoverDataWorker
.
dispose
();
_pauseCountdown
();
super
.
onDispose
();
}
@override
void
onRouteWillDisappear
()
{
super
.
onRouteWillDisappear
();
_pauseCountdown
();
}
@override
void
onRouteDidAppear
()
{
super
.
onRouteDidAppear
();
if
(
_viewModel
.
hoverDismissed
)
return
;
_viewModel
.
loadDataPiPiHome
();
}
void
_pauseCountdown
()
{
_handleCloseHoverViewInternal
(
dismissedByUser:
false
);
}
void
_resetHoverViewState
()
{
_viewModel
.
hoverDismissed
=
false
;
_updateHoverVisibility
();
}
void
_updateHoverVisibility
()
{
if
(
_viewModel
.
hoverDismissed
||
!
mounted
)
return
;
_showHover
.
value
=
_shouldShowHover
(
_viewModel
.
hoverData
.
value
);
}
void
_onHoverDataChanged
(
HoverDataModel
?
data
)
{
if
(
_viewModel
.
hoverDismissed
||
!
mounted
)
return
;
_showHover
.
value
=
_shouldShowHover
(
data
);
}
bool
_shouldShowHover
(
HoverDataModel
?
data
)
{
if
(
data
==
null
)
return
false
;
return
data
.
icon
?.
isNotEmpty
==
true
;
}
}
}
lib/
screen
/home/home_tab_viewmodel.dart
→
lib/
features
/home/home_tab_viewmodel.dart
View file @
6b980613
...
@@ -2,20 +2,20 @@ import 'dart:convert';
...
@@ -2,20 +2,20 @@ import 'dart:convert';
import
'package:flutter/foundation.dart'
;
import
'package:flutter/foundation.dart'
;
import
'package:flutter/services.dart'
;
import
'package:flutter/services.dart'
;
import
'package:get/get.dart'
;
import
'package:get/get.dart'
;
import
'package:mypoint_flutter_app/network
ing
/restful_api_client_all_request.dart'
;
import
'package:mypoint_flutter_app/
core/
network/restful_api_client_all_request.dart'
;
import
'../../network
ing
/restful_api_viewmodel.dart'
;
import
'../../
core/
network/restful_api_viewmodel.dart'
;
import
'../affiliate/model/affiliate_brand_model.dart'
;
import
'../affiliate/model/affiliate_brand_model.dart'
;
import
'../faqs/faqs_model.dart'
;
import
'../faqs/faqs_model.dart'
;
import
'../voucher/models/product_model.dart'
;
import
'../voucher/models/product_model.dart'
;
import
'model
s
/achievement_model.dart'
;
import
'
../achievement/
model/achievement_model.dart'
;
import
'models/banner_model.dart'
;
import
'models/banner_model.dart'
;
import
'models/brand_model.dart'
;
import
'
../affiliate_brand_detail/
models/brand_model.dart'
;
import
'models/flash_sale_model.dart'
;
import
'
../flash_sale/
models/flash_sale_model.dart'
;
import
'models/header_section_type.dart'
;
import
'models/header_section_type.dart'
;
import
'models/hover_data_model.dart'
;
import
'models/hover_data_model.dart'
;
import
'models/main_section_config_model.dart'
;
import
'models/main_section_config_model.dart'
;
import
'models/main_service_model.dart'
;
import
'models/main_service_model.dart'
;
import
'models/my_product_model.dart'
;
import
'
../voucher/
models/my_product_model.dart'
;
class
HomeTabViewModel
extends
RestfulApiViewModel
{
class
HomeTabViewModel
extends
RestfulApiViewModel
{
final
RxList
<
ProductModel
>
products
=
<
ProductModel
>[].
obs
;
final
RxList
<
ProductModel
>
products
=
<
ProductModel
>[].
obs
;
...
@@ -29,6 +29,7 @@ class HomeTabViewModel extends RestfulApiViewModel {
...
@@ -29,6 +29,7 @@ class HomeTabViewModel extends RestfulApiViewModel {
final
RxList
<
MainSectionConfigModel
>
sectionLayouts
=
<
MainSectionConfigModel
>[].
obs
;
final
RxList
<
MainSectionConfigModel
>
sectionLayouts
=
<
MainSectionConfigModel
>[].
obs
;
final
Rxn
<
FlashSaleModel
>
flashSaleData
=
Rxn
<
FlashSaleModel
>();
final
Rxn
<
FlashSaleModel
>
flashSaleData
=
Rxn
<
FlashSaleModel
>();
final
Rxn
<
HoverDataModel
>
hoverData
=
Rxn
<
HoverDataModel
>();
final
Rxn
<
HoverDataModel
>
hoverData
=
Rxn
<
HoverDataModel
>();
bool
hoverDismissed
=
false
;
late
final
Map
<
HeaderSectionType
,
Future
<
void
>
Function
(
MainSectionConfigModel
)>
_sectionLoaders
;
late
final
Map
<
HeaderSectionType
,
Future
<
void
>
Function
(
MainSectionConfigModel
)>
_sectionLoaders
;
...
@@ -47,7 +48,6 @@ class HomeTabViewModel extends RestfulApiViewModel {
...
@@ -47,7 +48,6 @@ class HomeTabViewModel extends RestfulApiViewModel {
HeaderSectionType
.
myProduct
:
_loadMyProducts
,
HeaderSectionType
.
myProduct
:
_loadMyProducts
,
};
};
getSectionLayoutHome
();
getSectionLayoutHome
();
loadDataPiPiHome
();
}
}
MainSectionConfigModel
?
getMainSectionConfigModel
(
HeaderSectionType
type
)
{
MainSectionConfigModel
?
getMainSectionConfigModel
(
HeaderSectionType
type
)
{
...
...
lib/
screen
/home/models/banner_model.dart
→
lib/
features
/home/models/banner_model.dart
View file @
6b980613
import
'package:json_annotation/json_annotation.dart'
;
import
'package:json_annotation/json_annotation.dart'
;
import
'package:mypoint_flutter_app/
direc
tion
al
/directional_screen.dart'
;
import
'package:mypoint_flutter_app/
shared/naviga
tion/directional_screen.dart'
;
part
'banner_model.g.dart'
;
part
'banner_model.g.dart'
;
@JsonSerializable
()
@JsonSerializable
()
...
...
lib/
screen
/home/models/banner_model.g.dart
→
lib/
features
/home/models/banner_model.g.dart
View file @
6b980613
File moved
Prev
1
…
7
8
9
10
11
12
13
14
15
…
26
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