Commit f714cdcc authored by DatHV's avatar DatHV
Browse files

update logic, flutter refactor

parent cc202df4
...@@ -4,14 +4,11 @@ import 'package:mypoint_flutter_app/preference/data_preference.dart'; ...@@ -4,14 +4,11 @@ import 'package:mypoint_flutter_app/preference/data_preference.dart';
import 'package:mypoint_flutter_app/screen/personal/personal_edit_item_model.dart'; import 'package:mypoint_flutter_app/screen/personal/personal_edit_item_model.dart';
import 'package:mypoint_flutter_app/screen/personal/personal_edit_viewmodel.dart'; import 'package:mypoint_flutter_app/screen/personal/personal_edit_viewmodel.dart';
import 'package:mypoint_flutter_app/screen/personal/personal_gender.dart'; import 'package:mypoint_flutter_app/screen/personal/personal_gender.dart';
import 'package:mypoint_flutter_app/widgets/custom_app_bar.dart';
import '../../base/base_screen.dart'; import '../../base/base_screen.dart';
import '../../base/basic_state.dart'; import '../../base/basic_state.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
import '../../shared/router_gage.dart';
import '../../widgets/alert/data_alert_model.dart'; import '../../widgets/alert/data_alert_model.dart';
import '../../widgets/bottom_sheet_helper.dart'; import '../../widgets/custom_navigation_bar.dart';
import '../../widgets/time_picker_widget.dart';
class PersonalEditScreen extends BaseScreen { class PersonalEditScreen extends BaseScreen {
const PersonalEditScreen({super.key}); const PersonalEditScreen({super.key});
...@@ -52,7 +49,7 @@ class _PersonalEditScreenState extends BaseState<PersonalEditScreen> with BasicS ...@@ -52,7 +49,7 @@ class _PersonalEditScreenState extends BaseState<PersonalEditScreen> with BasicS
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
behavior: HitTestBehavior.translucent, behavior: HitTestBehavior.translucent,
child: Scaffold( child: Scaffold(
appBar: CustomAppBar.back(title: "Chỉnh sửa thông tin cá nhân"), appBar: CustomNavigationBar(title: "Chỉnh sửa thông tin cá nhân"),
body: Obx(() { body: Obx(() {
List<PersonalEditItemModel> items; List<PersonalEditItemModel> items;
final editDataModel = viewModel.editDataModel.value; final editDataModel = viewModel.editDataModel.value;
......
...@@ -30,17 +30,6 @@ class _PersonalScreenState extends BaseState<PersonalScreen> with BasicState, Po ...@@ -30,17 +30,6 @@ class _PersonalScreenState extends BaseState<PersonalScreen> with BasicState, Po
super.initState(); super.initState();
_loadAppInfo(); _loadAppInfo();
_headerHomeVM.freshData(); _headerHomeVM.freshData();
// WidgetsBinding.instance.addPostFrameCallback((_) async {
// if (!mounted) return;
// await PopupManagerViewModel.instance.ensureLoaded();
// final popup = PopupManagerViewModel.instance.getForScreen(DirectionalScreenName.personal.rawValue);
// final id = popup?.id ?? '';
// if (id.isEmpty || popup == null) return;
// await showPopupManagerScreen(
// context,
// modelPopup: popup,
// );
// });
runPopupCheck(DirectionalScreenName.personal); runPopupCheck(DirectionalScreenName.personal);
} }
......
import 'package:flutter/material.dart';
import '../../widgets/custom_navigation_bar.dart';
class PointHistoryScreen extends StatefulWidget {
const PointHistoryScreen({super.key});
@override
State<PointHistoryScreen> createState() => _PointHistoryScreenState();
}
class _PointHistoryScreenState extends State<PointHistoryScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: CustomNavigationBar(title: "Lịch sử điểm"),
body: SafeArea(
child: Center(child: Text('Point History Screen')),
),
);
}
}
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
import 'package:mypoint_flutter_app/directional/directional_screen.dart';
part 'form_input_description_model.g.dart'; part 'form_input_description_model.g.dart';
@JsonSerializable() @JsonSerializable()
...@@ -10,6 +11,13 @@ class FormInputDescriptionModel { ...@@ -10,6 +11,13 @@ class FormInputDescriptionModel {
@JsonKey(name: 'click_action_param') @JsonKey(name: 'click_action_param')
final String? clickActionParam; final String? clickActionParam;
DirectionalScreen? get directional {
return DirectionalScreen.build(
clickActionType: clickActionType,
clickActionParam: clickActionParam,
);
}
FormInputDescriptionModel({ FormInputDescriptionModel({
this.title, this.title,
this.checkbox, this.checkbox,
......
...@@ -4,7 +4,7 @@ import 'package:get/get.dart'; ...@@ -4,7 +4,7 @@ import 'package:get/get.dart';
import 'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart'; import 'package:mypoint_flutter_app/screen/register_campaign/register_form_input_viewmodel.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
import '../../shared/router_gage.dart'; import '../../shared/router_gage.dart';
import '../../widgets/custom_app_bar.dart'; import '../../widgets/custom_navigation_bar.dart';
import '../voucher/models/product_model.dart'; import '../voucher/models/product_model.dart';
import 'input_form_cell.dart'; import 'input_form_cell.dart';
import 'model/registration_form_package_model.dart'; import 'model/registration_form_package_model.dart';
...@@ -51,10 +51,11 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> { ...@@ -51,10 +51,11 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
return GestureDetector( return GestureDetector(
onTap: () => FocusScope.of(context).unfocus(), onTap: () => FocusScope.of(context).unfocus(),
child: Scaffold( child: Scaffold(
appBar: CustomAppBar.back(title: _title), appBar: CustomNavigationBar(title: _title),
body: Obx(() { body: Obx(() {
final form = _isConfirmScreen ? _viewModel.form.value?.formConfirm : _viewModel.form.value?.formRegistration; final form = _isConfirmScreen ? _viewModel.form.value?.formConfirm : _viewModel.form.value?.formRegistration;
final inputItem = _viewModel.form.value?.formRegistration?.inputRequired; final inputItem = _viewModel.form.value?.formRegistration?.inputRequired;
_validateForm();
if (form == null) { if (form == null) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
} }
...@@ -101,7 +102,13 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> { ...@@ -101,7 +102,13 @@ class _RegisterFormInputScreenState extends State<RegisterFormInputScreen> {
}, },
), ),
), ),
Expanded(child: HtmlWidget(form!.footerDescription!.title!)), Expanded(child:
GestureDetector(
onTap: () {
form.footerDescription?.directional?.begin();
},
child: HtmlWidget(form!.footerDescription!.title!)),
),
], ],
), ),
), ),
......
...@@ -4,6 +4,7 @@ import 'package:intl/intl.dart'; ...@@ -4,6 +4,7 @@ import 'package:intl/intl.dart';
import 'package:mypoint_flutter_app/screen/topup/topup_viewmodel.dart'; import 'package:mypoint_flutter_app/screen/topup/topup_viewmodel.dart';
import 'package:mypoint_flutter_app/widgets/custom_navigation_bar.dart'; import 'package:mypoint_flutter_app/widgets/custom_navigation_bar.dart';
import 'package:mypoint_flutter_app/widgets/image_loader.dart'; import 'package:mypoint_flutter_app/widgets/image_loader.dart';
import '../../extensions/debouncer.dart';
import '../../preference/data_preference.dart'; import '../../preference/data_preference.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
import '../../shared/router_gage.dart'; import '../../shared/router_gage.dart';
...@@ -20,6 +21,7 @@ class PhoneTopUpScreen extends StatefulWidget { ...@@ -20,6 +21,7 @@ class PhoneTopUpScreen extends StatefulWidget {
class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> { class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
final TopUpViewModel _viewModel = Get.put(TopUpViewModel()); final TopUpViewModel _viewModel = Get.put(TopUpViewModel());
late final TextEditingController _phoneController; late final TextEditingController _phoneController;
final _deb = Debouncer(ms: 500);
@override @override
void initState() { void initState() {
...@@ -84,7 +86,7 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> { ...@@ -84,7 +86,7 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
keyboardType: TextInputType.phone, keyboardType: TextInputType.phone,
onChanged: (value) { onChanged: (value) {
_viewModel.phoneNumber.value = value; _viewModel.phoneNumber.value = value;
_viewModel.checkMobileNetwork(); _deb.run(() => _viewModel.checkMobileNetwork());
}, },
), ),
), ),
...@@ -326,12 +328,12 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> { ...@@ -326,12 +328,12 @@ class _PhoneTopUpScreenState extends State<PhoneTopUpScreen> {
), ),
const Spacer(), const Spacer(),
ElevatedButton( ElevatedButton(
onPressed: () { onPressed: _viewModel.validatePhoneNumber() ? () {
Get.toNamed( Get.toNamed(
transactionDetailScreen, transactionDetailScreen,
arguments: {"product": product, "quantity": 1, "targetPhoneNumber": _viewModel.phoneNumber.value}, arguments: {"product": product, "quantity": 1, "targetPhoneNumber": _viewModel.phoneNumber.value},
); );
}, } : null,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
backgroundColor: BaseColor.primary500, backgroundColor: BaseColor.primary500,
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)),
......
...@@ -35,22 +35,29 @@ class TopUpViewModel extends RestfulApiViewModel { ...@@ -35,22 +35,29 @@ class TopUpViewModel extends RestfulApiViewModel {
} }
} }
bool validatePhoneNumber() {
final phone = phoneNumber.value.replaceAll(RegExp(r'\s+'), '');
final regex = RegExp(r'^(0|\+84)(3[2-9]|5[6|8|9]|7[0|6-9]|8[1-5]|9[0-4|6-9])[0-9]{7}$');
return regex.hasMatch(phone);
}
firstLoadTopUpData() async { firstLoadTopUpData() async {
showLoading(); _getTopUpBrands();
await getTopUpBrands();
await checkMobileNetwork();
hideLoading();
} }
getTopUpBrands() { _getTopUpBrands() {
showLoading();
client.getTopUpBrands(ProductType.topupMobile).then((response) { client.getTopUpBrands(ProductType.topupMobile).then((response) {
topUpBrands.value = response.data ?? []; topUpBrands.value = response.data ?? [];
hideLoading();
checkMobileNetwork();
}).catchError((error) { }).catchError((error) {
print('Error fetching brands topup: $error'); hideLoading();
}); });
} }
checkMobileNetwork() { checkMobileNetwork() {
showLoading();
client.checkMobileNetwork(phoneNumber.value).then((response) { client.checkMobileNetwork(phoneNumber.value).then((response) {
final brandCode = response.data?.brand ?? ''; final brandCode = response.data?.brand ?? '';
final brand = topUpBrands.isNotEmpty final brand = topUpBrands.isNotEmpty
...@@ -60,12 +67,14 @@ class TopUpViewModel extends RestfulApiViewModel { ...@@ -60,12 +67,14 @@ class TopUpViewModel extends RestfulApiViewModel {
) )
: null; : null;
selectedBrand.value = brand; selectedBrand.value = brand;
hideLoading();
getTelcoDetail(); getTelcoDetail();
}).catchError((error) { }).catchError((error) {
final first = topUpBrands.value.firstOrNull; final first = topUpBrands.value.firstOrNull;
if (first != null) { if (first != null) {
selectedBrand.value = first; selectedBrand.value = first;
} }
hideLoading();
getTelcoDetail(); getTelcoDetail();
print('Error checking mobile network: $error'); print('Error checking mobile network: $error');
}); });
...@@ -75,7 +84,6 @@ class TopUpViewModel extends RestfulApiViewModel { ...@@ -75,7 +84,6 @@ class TopUpViewModel extends RestfulApiViewModel {
final code = selectedBrand.value?.code; final code = selectedBrand.value?.code;
final id = selectedBrand.value?.id; final id = selectedBrand.value?.id;
if (code == null || id == null) return; if (code == null || id == null) return;
void makeSelected(List<ProductModel> list) { void makeSelected(List<ProductModel> list) {
bool didSelect = false; bool didSelect = false;
if (selected != null && selected.isNotEmpty) { if (selected != null && selected.isNotEmpty) {
...@@ -116,8 +124,8 @@ class TopUpViewModel extends RestfulApiViewModel { ...@@ -116,8 +124,8 @@ class TopUpViewModel extends RestfulApiViewModel {
final data = result.data ?? []; final data = result.data ?? [];
_allValue[code] = data; _allValue[code] = data;
products.value = result.data ?? []; products.value = result.data ?? [];
makeSelected(data);
hideLoading(); hideLoading();
makeSelected(data);
} catch (error) { } catch (error) {
print("Error fetching all products: $error"); print("Error fetching all products: $error");
hideLoading(); hideLoading();
......
...@@ -5,7 +5,7 @@ import 'package:intl/intl.dart'; ...@@ -5,7 +5,7 @@ import 'package:intl/intl.dart';
import '../../base/base_screen.dart'; import '../../base/base_screen.dart';
import '../../base/basic_state.dart'; import '../../base/basic_state.dart';
import '../../resources/base_color.dart'; import '../../resources/base_color.dart';
import '../../widgets/custom_app_bar.dart'; import '../../widgets/custom_navigation_bar.dart';
import '../../widgets/image_loader.dart'; import '../../widgets/image_loader.dart';
import '../voucher/models/product_model.dart'; import '../voucher/models/product_model.dart';
import 'model/payment_bank_account_info_model.dart'; import 'model/payment_bank_account_info_model.dart';
...@@ -60,7 +60,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w ...@@ -60,7 +60,7 @@ class _TransactionDetailScreenState extends BaseState<TransactionDetailScreen> w
Widget createBody() { Widget createBody() {
return Scaffold( return Scaffold(
backgroundColor: Colors.grey.shade50, backgroundColor: Colors.grey.shade50,
appBar: CustomAppBar.back(title: "Thông tin thanh toán"), appBar: CustomNavigationBar(title: "Thông tin thanh toán"),
body: Obx(() { body: Obx(() {
if (_viewModel.isLoading.value) { if (_viewModel.isLoading.value) {
return const Center(child: CircularProgressIndicator()); return const Center(child: CircularProgressIndicator());
......
...@@ -48,7 +48,7 @@ class VoucherDetailViewModel extends RestfulApiViewModel { ...@@ -48,7 +48,7 @@ class VoucherDetailViewModel extends RestfulApiViewModel {
liked.value = (response.data?.id ?? 0) != 0; liked.value = (response.data?.id ?? 0) != 0;
} }
} catch (error) { } catch (error) {
onShowAlertError?.call("Error toggling favorite: $error"); onShowAlertError?.call(Constants.commonError);
} }
} }
......
import 'package:json_annotation/json_annotation.dart'; import 'package:json_annotation/json_annotation.dart';
part 'like_product_reponse_model.g.dart'; part 'like_product_response_model.g.dart';
@JsonSerializable() @JsonSerializable()
class LikeProductReponseModel { class LikeProductResponseModel {
@JsonKey(name: 'like_id') @JsonKey(name: 'like_id')
final int? id; final int? id;
LikeProductReponseModel({ LikeProductResponseModel({
this.id, this.id,
}); });
factory LikeProductReponseModel.fromJson(Map<String, dynamic> json) => _$LikeProductReponseModelFromJson(json); factory LikeProductResponseModel.fromJson(Map<String, dynamic> json) => _$LikeProductResponseModelFromJson(json);
Map<String, dynamic> toJson() => _$LikeProductReponseModelToJson(this); Map<String, dynamic> toJson() => _$LikeProductResponseModelToJson(this);
} }
// GENERATED CODE - DO NOT MODIFY BY HAND // GENERATED CODE - DO NOT MODIFY BY HAND
part of 'like_product_reponse_model.dart'; part of 'like_product_response_model.dart';
// ************************************************************************** // **************************************************************************
// JsonSerializableGenerator // JsonSerializableGenerator
// ************************************************************************** // **************************************************************************
LikeProductReponseModel _$LikeProductReponseModelFromJson( LikeProductResponseModel _$LikeProductResponseModelFromJson(
Map<String, dynamic> json, Map<String, dynamic> json,
) => LikeProductReponseModel(id: (json['like_id'] as num?)?.toInt()); ) => LikeProductResponseModel(id: (json['like_id'] as num?)?.toInt());
Map<String, dynamic> _$LikeProductReponseModelToJson( Map<String, dynamic> _$LikeProductResponseModelToJson(
LikeProductReponseModel instance, LikeProductResponseModel instance,
) => <String, dynamic>{'like_id': instance.id}; ) => <String, dynamic>{'like_id': instance.id};
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import '../../../shared/router_gage.dart'; import '../../../shared/router_gage.dart';
import '../../../widgets/custom_app_bar.dart';
import '../../../widgets/custom_empty_widget.dart'; import '../../../widgets/custom_empty_widget.dart';
import '../../../widgets/custom_navigation_bar.dart';
import '../../../widgets/image_loader.dart'; import '../../../widgets/image_loader.dart';
import '../../home/models/my_product_model.dart'; import '../../home/models/my_product_model.dart';
import 'my_product_list_viewmodel.dart'; import 'my_product_list_viewmodel.dart';
...@@ -28,14 +28,17 @@ class _MyVoucherListScreenState extends State<MyVoucherListScreen> { ...@@ -28,14 +28,17 @@ class _MyVoucherListScreenState extends State<MyVoucherListScreen> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final screenWidth = MediaQuery.of(context).size.width; final screenWidth = MediaQuery.of(context).size.width;
return Scaffold( return Scaffold(
appBar: CustomAppBar.back(title: 'Ưu đãi của tôi'), appBar: CustomNavigationBar(title: 'Ưu đãi của tôi'),
body: Obx( body: Obx(
() => Column( () => Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Row( Padding(
mainAxisAlignment: MainAxisAlignment.spaceAround, padding: const EdgeInsets.all(8.0),
children: [_buildTab('Đang có', 0), _buildTab('Đã sử dụng', 1), _buildTab('Hết hạn', 2)], child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [_buildTab('Đang có', 0), _buildTab('Đã sử dụng', 1), _buildTab('Hết hạn', 2)],
),
), ),
const Divider(height: 1), const Divider(height: 1),
if (_viewModel.myProducts.isEmpty) if (_viewModel.myProducts.isEmpty)
......
...@@ -37,7 +37,6 @@ class _VoucherTabScreenState extends State<VoucherTabScreen> with PopupOnInit { ...@@ -37,7 +37,6 @@ class _VoucherTabScreenState extends State<VoucherTabScreen> with PopupOnInit {
appBar: CustomNavigationBar( appBar: CustomNavigationBar(
title: "Ưu đãi", title: "Ưu đãi",
leftButtons: [], leftButtons: [],
backgroundImage: _headerHomeVM.headerData.background ?? "assets/images/bg_header_navi.png",
rightButtons: [ rightButtons: [
IconButton( IconButton(
icon: const Icon(Icons.search, color: Colors.white), icon: const Icon(Icons.search, color: Colors.white),
......
...@@ -28,6 +28,7 @@ import '../screen/onboarding/onboarding_screen.dart'; ...@@ -28,6 +28,7 @@ import '../screen/onboarding/onboarding_screen.dart';
import '../screen/order_menu/order_menu_screen.dart'; import '../screen/order_menu/order_menu_screen.dart';
import '../screen/pageDetail/campaign_detail_screen.dart'; import '../screen/pageDetail/campaign_detail_screen.dart';
import '../screen/personal/personal_edit_screen.dart'; import '../screen/personal/personal_edit_screen.dart';
import '../screen/point_history/point_history_screen.dart';
import '../screen/quiz_campaign/quiz_campaign_screen.dart'; import '../screen/quiz_campaign/quiz_campaign_screen.dart';
import '../screen/register_campaign/register_form_input_screen.dart'; import '../screen/register_campaign/register_form_input_screen.dart';
import '../screen/setting/setting_screen.dart'; import '../screen/setting/setting_screen.dart';
...@@ -94,6 +95,7 @@ const deviceManagerScreen = '/deviceManagerScreen'; ...@@ -94,6 +95,7 @@ const deviceManagerScreen = '/deviceManagerScreen';
const interestCategoriesScreen = '/interestCategoriesScreen'; const interestCategoriesScreen = '/interestCategoriesScreen';
const myMobileCardListScreen = '/myMobileCardListScreen'; const myMobileCardListScreen = '/myMobileCardListScreen';
const bankAccountManagerScreen = '/bankAccountManagerScreen'; const bankAccountManagerScreen = '/bankAccountManagerScreen';
const pointHistoryScreen = '/pointHistoryScreen';
class RouterPage { class RouterPage {
static List<GetPage> pages() { static List<GetPage> pages() {
...@@ -157,6 +159,7 @@ class RouterPage { ...@@ -157,6 +159,7 @@ class RouterPage {
GetPage(name: myMobileCardListScreen, page: () => MyMobileCardListScreen()), GetPage(name: myMobileCardListScreen, page: () => MyMobileCardListScreen()),
GetPage(name: interestCategoriesScreen, page: () => InterestCategoriesScreen()), GetPage(name: interestCategoriesScreen, page: () => InterestCategoriesScreen()),
GetPage(name: bankAccountManagerScreen, page: () => BankAccountManagerScreen()), GetPage(name: bankAccountManagerScreen, page: () => BankAccountManagerScreen()),
GetPage(name: pointHistoryScreen, page: () => PointHistoryScreen()),
]; ];
} }
} }
\ No newline at end of file
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart';
import '../screen/home/header_home_viewmodel.dart';
import 'back_button.dart'; import 'back_button.dart';
import 'image_loader.dart'; import 'image_loader.dart';
...@@ -7,68 +9,73 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget ...@@ -7,68 +9,73 @@ class CustomNavigationBar extends StatelessWidget implements PreferredSizeWidget
final String? backgroundImage; final String? backgroundImage;
final List<Widget> leftButtons; final List<Widget> leftButtons;
final List<Widget> rightButtons; final List<Widget> rightButtons;
final _defaultBgImage = 'assets/images/bg_header_navi.png';
const CustomNavigationBar({ const CustomNavigationBar({
super.key, super.key,
required this.title, required this.title,
this.backgroundImage = "assets/images/bg_header_navi.png", this.backgroundImage,
this.leftButtons = const [CustomBackButton()], this.leftButtons = const [CustomBackButton()],
this.rightButtons = const [], this.rightButtons = const [],
}); });
@override @override
Size get preferredSize => const Size.fromHeight(kToolbarHeight); Size get preferredSize => const Size.fromHeight(kToolbarHeight);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top; if (backgroundImage != null && backgroundImage!.isNotEmpty) {
final bool isHttp = return _buildAppBar(backgroundImage!, context);
backgroundImage != null && (backgroundImage!.startsWith('http://') || backgroundImage!.startsWith('https://')); }
final theme = Get.find<HeaderThemeController>();
return Obx(() {
final bg = theme.background.value ?? _defaultBgImage;
return _buildAppBar(bg, context);
});
}
Widget _buildAppBar(String bgImage, BuildContext context) {
final double statusBarHeight = MediaQuery.of(context).padding.top;
final bool isHttp = bgImage.startsWith('http://') || bgImage.startsWith('https://');
return Container( return Container(
height: statusBarHeight + kToolbarHeight, height: statusBarHeight + kToolbarHeight,
decoration: BoxDecoration( decoration: BoxDecoration(
// image: backgroundImage != null color: bgImage.isEmpty ? Colors.white : null,
// ? DecorationImage( ),
// image: AssetImage(backgroundImage!), child: Stack(
// fit: BoxFit.cover, fit: StackFit.expand,
// ) children: [
// : null, if (bgImage.isNotEmpty)
color: backgroundImage == null ? Colors.white : null, isHttp
), ? loadNetworkImage(
child: Stack( url: bgImage,
fit: StackFit.expand, fit: BoxFit.cover,
children: [ placeholderAsset: _defaultBgImage,
if (backgroundImage != null) )
isHttp : Image.asset(_defaultBgImage, fit: BoxFit.cover),
? loadNetworkImage( SafeArea(
url: backgroundImage, bottom: false,
fit: BoxFit.cover, child: Stack(
placeholderAsset: 'assets/images/bg_header_navi.png', alignment: Alignment.center,
) children: [
: Image.asset(backgroundImage!, fit: BoxFit.cover), Text(
SafeArea( title,
bottom: false, maxLines: 1,
child: Stack( style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white),
alignment: Alignment.center, textAlign: TextAlign.center,
children: [ ),
Text( // Buttons bên trái
title, if (leftButtons.isNotEmpty)
maxLines: 1, Positioned(left: 12, child: Row(mainAxisSize: MainAxisSize.min, children: leftButtons)),
style: const TextStyle(fontSize: 18, fontWeight: FontWeight.w800, color: Colors.white), // Buttons bên phải
textAlign: TextAlign.center, if (rightButtons != null)
), Positioned(right: 12, child: Row(mainAxisSize: MainAxisSize.min, children: rightButtons!)),
// Back button bên trái ],
// if (showBackButton) Positioned(left: 12, child: CustomBackButton()), ),
if (leftButtons.isNotEmpty)
Positioned(left: 12, child: Row(mainAxisSize: MainAxisSize.min, children: leftButtons)),
// Buttons bên phải
if (rightButtons != null)
Positioned(right: 12, child: Row(mainAxisSize: MainAxisSize.min, children: rightButtons!)),
],
), ),
), ],
], ),
), );
);
} }
} }
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment