feat: login password invisiable pwd
This commit is contained in:
parent
9361c8a9df
commit
322368339f
|
@ -3,7 +3,6 @@ import 'package:get/get.dart';
|
||||||
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
||||||
import 'package:sk_base_mobile/apis/api.dart';
|
import 'package:sk_base_mobile/apis/api.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/config.dart';
|
|
||||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||||
import 'package:sk_base_mobile/constants/constants.dart';
|
import 'package:sk_base_mobile/constants/constants.dart';
|
||||||
import 'package:sk_base_mobile/models/user_info.model.dart';
|
import 'package:sk_base_mobile/models/user_info.model.dart';
|
||||||
|
@ -30,14 +29,6 @@ class HrManagePage extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
// return Column(
|
|
||||||
// children: [
|
|
||||||
// Expanded(
|
|
||||||
// child: Material(
|
|
||||||
// child: EditUserInfo(),
|
|
||||||
// ))
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
// 取消焦点
|
// 取消焦点
|
||||||
|
@ -125,7 +116,7 @@ class HrManagePage extends StatelessWidget {
|
||||||
doSearch('');
|
doSearch('');
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
hint: '查询员工',
|
hint: '查询员工 姓名、手机号、邮箱',
|
||||||
isDense: true,
|
isDense: true,
|
||||||
contentPadding:
|
contentPadding:
|
||||||
EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)),
|
EdgeInsets.symmetric(vertical: ScreenAdaper.height(10)),
|
||||||
|
@ -134,23 +125,27 @@ class HrManagePage extends StatelessWidget {
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: ScreenAdaper.width(10),
|
width: ScreenAdaper.width(10),
|
||||||
),
|
),
|
||||||
SkInk(
|
buildFilterBtn()
|
||||||
border: Border.all(color: AppTheme.grey.withOpacity(0.8)),
|
|
||||||
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
|
|
||||||
onTap: () {},
|
|
||||||
child: SizedBox(
|
|
||||||
width: ScreenAdaper.height(65),
|
|
||||||
height: ScreenAdaper.height(65),
|
|
||||||
child: Icon(
|
|
||||||
Icons.filter_list_sharp,
|
|
||||||
size: ScreenAdaper.height(50),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
]),
|
]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget buildFilterBtn() {
|
||||||
|
return SkInk(
|
||||||
|
border: Border.all(color: AppTheme.grey.withOpacity(0.8)),
|
||||||
|
borderRadius: BorderRadius.circular(ScreenAdaper.sp(15)),
|
||||||
|
onTap: () {},
|
||||||
|
child: SizedBox(
|
||||||
|
width: ScreenAdaper.height(65),
|
||||||
|
height: ScreenAdaper.height(65),
|
||||||
|
child: Icon(
|
||||||
|
Icons.filter_list_sharp,
|
||||||
|
size: ScreenAdaper.height(50),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget buildUserCard(int index) {
|
Widget buildUserCard(int index) {
|
||||||
return SkInk(
|
return SkInk(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
|
@ -6,9 +6,7 @@ import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/constants/enum.dart';
|
import 'package:sk_base_mobile/constants/enum.dart';
|
||||||
import 'package:sk_base_mobile/db_helper/db_help.dart';
|
import 'package:sk_base_mobile/db_helper/db_help.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory_inout/components/inventory_inout_info.dart';
|
import 'package:sk_base_mobile/screens/inventory_inout/components/inventory_inout_info.dart';
|
||||||
import 'package:sk_base_mobile/screens/landing/landing_controller.dart';
|
|
||||||
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
|
import 'package:sk_base_mobile/screens/new_inventory_inout/new_inventory_inout.dart';
|
||||||
import 'package:sk_base_mobile/services/app_info.service.dart';
|
|
||||||
import 'package:sk_base_mobile/util/date.util.dart';
|
import 'package:sk_base_mobile/util/date.util.dart';
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
import 'package:sk_base_mobile/util/modal.util.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
|
|
@ -1,16 +1,11 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/apis/api.dart';
|
|
||||||
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
|
import 'package:sk_base_mobile/models/app_bottom_nav_item.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory/inventory.dart';
|
import 'package:sk_base_mobile/screens/inventory/inventory.dart';
|
||||||
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout.dart';
|
import 'package:sk_base_mobile/screens/inventory_inout/inventory_inout.dart';
|
||||||
import 'package:sk_base_mobile/screens/mine/mine.dart';
|
import 'package:sk_base_mobile/screens/mine/mine.dart';
|
||||||
import 'package:sk_base_mobile/screens/workbench/workbench.dart';
|
import 'package:sk_base_mobile/screens/workbench/workbench.dart';
|
||||||
import 'package:sk_base_mobile/services/app_info.service.dart';
|
import 'package:sk_base_mobile/services/app_info.service.dart';
|
||||||
import 'package:sk_base_mobile/util/device.util.dart';
|
|
||||||
import 'package:sk_base_mobile/util/modal.util.dart';
|
|
||||||
|
|
||||||
import '../../constants/constants.dart';
|
|
||||||
|
|
||||||
class LandingController extends GetxController {
|
class LandingController extends GetxController {
|
||||||
RxInt currentIndex = 0.obs;
|
RxInt currentIndex = 0.obs;
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/apis/api.dart';
|
|
||||||
import 'package:sk_base_mobile/util/device.util.dart';
|
|
||||||
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
import 'package:sk_base_mobile/util/snack_bar.util.dart';
|
||||||
import '../../constants/constants.dart';
|
|
||||||
import '../../store/auth.store.dart';
|
import '../../store/auth.store.dart';
|
||||||
// import 'package:sentry/sentry.dart';
|
// import 'package:sentry/sentry.dart';
|
||||||
|
|
||||||
|
@ -14,6 +11,7 @@ class LoginController extends GetxController {
|
||||||
String username = '';
|
String username = '';
|
||||||
String password = '';
|
String password = '';
|
||||||
bool loading = false;
|
bool loading = false;
|
||||||
|
RxBool obscureText = true.obs;
|
||||||
Future<void> doLogin() async {
|
Future<void> doLogin() async {
|
||||||
if (username.isEmpty || password.isEmpty) {
|
if (username.isEmpty || password.isEmpty) {
|
||||||
SnackBarUtil().warning('请填写用户名和密码');
|
SnackBarUtil().warning('请填写用户名和密码');
|
||||||
|
|
|
@ -94,6 +94,7 @@ class LoginScreen extends StatelessWidget {
|
||||||
final children = [
|
final children = [
|
||||||
buildUserNameInput(),
|
buildUserNameInput(),
|
||||||
Divider(
|
Divider(
|
||||||
|
height: 1,
|
||||||
thickness: ScreenAdaper.height(2),
|
thickness: ScreenAdaper.height(2),
|
||||||
),
|
),
|
||||||
buildPasswordInput(),
|
buildPasswordInput(),
|
||||||
|
@ -177,7 +178,7 @@ class LoginScreen extends StatelessWidget {
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
prefixIcon: Icon(
|
prefixIcon: Icon(
|
||||||
Icons.person_2_outlined,
|
Icons.person_2_outlined,
|
||||||
size: ScreenAdaper.height(40),
|
size: ScreenAdaper.height(45),
|
||||||
),
|
),
|
||||||
hintText: '用户名',
|
hintText: '用户名',
|
||||||
hintStyle: TextStyle(fontSize: ScreenAdaper.height(25)),
|
hintStyle: TextStyle(fontSize: ScreenAdaper.height(25)),
|
||||||
|
@ -186,7 +187,7 @@ class LoginScreen extends StatelessWidget {
|
||||||
onFieldSubmitted: (value) {
|
onFieldSubmitted: (value) {
|
||||||
_controller.passwordFocusNode.requestFocus();
|
_controller.passwordFocusNode.requestFocus();
|
||||||
},
|
},
|
||||||
style: TextStyle(fontSize: ScreenAdaper.height(25)),
|
style: TextStyle(fontSize: ScreenAdaper.height(30)),
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
_controller.username = value;
|
_controller.username = value;
|
||||||
},
|
},
|
||||||
|
@ -194,26 +195,38 @@ class LoginScreen extends StatelessWidget {
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildPasswordInput() {
|
Widget buildPasswordInput() {
|
||||||
return TextFormField(
|
return Obx(() => TextFormField(
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
prefixIcon: Icon(
|
prefixIcon: Icon(
|
||||||
Icons.lock_outlined,
|
Icons.lock_outlined,
|
||||||
size: ScreenAdaper.height(40),
|
size: ScreenAdaper.height(45),
|
||||||
),
|
),
|
||||||
errorStyle: TextStyle(fontSize: ScreenAdaper.height(20)),
|
suffixIcon: GestureDetector(
|
||||||
hintText: '密码',
|
onTap: () {
|
||||||
border: InputBorder.none,
|
_controller.obscureText.value =
|
||||||
focusedBorder: InputBorder.none),
|
!_controller.obscureText.value;
|
||||||
obscureText: true,
|
},
|
||||||
focusNode: _controller.passwordFocusNode,
|
child: Icon(
|
||||||
onFieldSubmitted: (value) {
|
!_controller.obscureText.value
|
||||||
_controller.doLogin();
|
? Icons.visibility
|
||||||
},
|
: Icons.visibility_off,
|
||||||
style: TextStyle(fontSize: ScreenAdaper.height(25)),
|
size: ScreenAdaper.height(45),
|
||||||
onChanged: (value) {
|
),
|
||||||
_controller.password = value;
|
),
|
||||||
},
|
errorStyle: TextStyle(fontSize: ScreenAdaper.height(20)),
|
||||||
);
|
hintText: '密码',
|
||||||
|
border: InputBorder.none,
|
||||||
|
focusedBorder: InputBorder.none),
|
||||||
|
obscureText: _controller.obscureText.value,
|
||||||
|
focusNode: _controller.passwordFocusNode,
|
||||||
|
onFieldSubmitted: (value) {
|
||||||
|
_controller.doLogin();
|
||||||
|
},
|
||||||
|
style: TextStyle(fontSize: ScreenAdaper.height(30)),
|
||||||
|
onChanged: (value) {
|
||||||
|
_controller.password = value;
|
||||||
|
},
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget buildForgotPassword() {
|
Widget buildForgotPassword() {
|
||||||
|
|
|
@ -3,7 +3,6 @@ import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
import 'package:sk_base_mobile/constants/bg_color.dart';
|
||||||
import 'package:sk_base_mobile/services/app_info.service.dart';
|
import 'package:sk_base_mobile/services/app_info.service.dart';
|
||||||
import 'package:sk_base_mobile/store/auth.store.dart';
|
import 'package:sk_base_mobile/store/auth.store.dart';
|
||||||
import 'package:sk_base_mobile/util/device.util.dart';
|
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
|
|
||||||
class MineSettingsPage extends StatelessWidget {
|
class MineSettingsPage extends StatelessWidget {
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import 'package:collection/collection.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/widgets/core/sk_ink.dart';
|
import 'package:sk_base_mobile/widgets/core/sk_ink.dart';
|
||||||
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
|
||||||
import 'package:sk_base_mobile/widgets/loading_indicator.dart';
|
import 'package:sk_base_mobile/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
class CascadeItem<T, Z> {
|
class CascadeItem<T, Z> {
|
||||||
|
@ -28,7 +26,8 @@ class SkCascadePicker<T, Z> extends StatelessWidget {
|
||||||
final Function(List<CascadeItem<T, Z>>)? onConfirm;
|
final Function(List<CascadeItem<T, Z>>)? onConfirm;
|
||||||
|
|
||||||
SkCascadePicker(
|
SkCascadePicker(
|
||||||
{required Future<List<CascadeItem<T, Z>>> Function() getData,
|
{super.key,
|
||||||
|
required Future<List<CascadeItem<T, Z>>> Function() getData,
|
||||||
required List<CascadeItem<T, Z>> Function(SkCascadePickerController<T, Z>)
|
required List<CascadeItem<T, Z>> Function(SkCascadePickerController<T, Z>)
|
||||||
initialPageData,
|
initialPageData,
|
||||||
required NextPageCallback<T, Z> nextPageData,
|
required NextPageCallback<T, Z> nextPageData,
|
||||||
|
@ -209,7 +208,7 @@ class SkCascadePicker<T, Z> extends StatelessWidget {
|
||||||
height: tabHeight,
|
height: tabHeight,
|
||||||
color: tabColor,
|
color: tabColor,
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: Container(
|
child: SizedBox(
|
||||||
// constraints: BoxConstraints(
|
// constraints: BoxConstraints(
|
||||||
// maxWidth: MediaQuery.of(Get.context!).size.width /
|
// maxWidth: MediaQuery.of(Get.context!).size.width /
|
||||||
// cascadeController.pagesData.length -
|
// cascadeController.pagesData.length -
|
||||||
|
@ -244,7 +243,7 @@ class SkCascadePicker<T, Z> extends StatelessWidget {
|
||||||
}
|
}
|
||||||
cascadeController.isAnimateTextHide = false;
|
cascadeController.isAnimateTextHide = false;
|
||||||
if (i < cascadeController.pagesData.length - 1) {
|
if (i < cascadeController.pagesData.length - 1) {
|
||||||
widgets.add(Container(
|
widgets.add(SizedBox(
|
||||||
// color: Colors.red,
|
// color: Colors.red,
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.arrow_right,
|
Icons.arrow_right,
|
||||||
|
@ -269,13 +268,12 @@ class SkCascadePicker<T, Z> extends StatelessWidget {
|
||||||
item == cascadeController.selectedTabs[page]
|
item == cascadeController.selectedTabs[page]
|
||||||
? Padding(
|
? Padding(
|
||||||
padding: const EdgeInsets.all(5.0),
|
padding: const EdgeInsets.all(5.0),
|
||||||
child: selectedIcon == null
|
child: selectedIcon ??
|
||||||
? Icon(Icons.chevron_right,
|
Icon(Icons.chevron_right,
|
||||||
size: ScreenAdaper.height(40),
|
size: ScreenAdaper.height(40),
|
||||||
color: activeColor)
|
color: activeColor),
|
||||||
: selectedIcon,
|
|
||||||
)
|
)
|
||||||
: SizedBox(),
|
: const SizedBox(),
|
||||||
Text(item.label,
|
Text(item.label,
|
||||||
style: item == cascadeController.selectedTabs[page]
|
style: item == cascadeController.selectedTabs[page]
|
||||||
? (itemTitleStyle ??
|
? (itemTitleStyle ??
|
||||||
|
@ -500,7 +498,7 @@ class SkCascadePickerController<T, Z> extends GetxController
|
||||||
animateController.forward();
|
animateController.forward();
|
||||||
if (movePage) {
|
if (movePage) {
|
||||||
pageController.animateToPage(page,
|
pageController.animateToPage(page,
|
||||||
curve: Curves.linear, duration: Duration(milliseconds: 500));
|
curve: Curves.linear, duration: const Duration(milliseconds: 500));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -516,7 +514,7 @@ class SkCascadePickerController<T, Z> extends GetxController
|
||||||
/// pageData: 下一页的数据
|
/// pageData: 下一页的数据
|
||||||
/// currentPage: 当前是第几页,
|
/// currentPage: 当前是第几页,
|
||||||
/// selectIndex: 当前页选中第几项
|
/// selectIndex: 当前页选中第几项
|
||||||
typedef void NextPageCallback<T, Z>(
|
typedef NextPageCallback<T, Z> = void Function(
|
||||||
Function(List<CascadeItem<T, Z>>) pageData,
|
Function(List<CascadeItem<T, Z>>) pageData,
|
||||||
int currentPage,
|
int currentPage,
|
||||||
int selectIndex,
|
int selectIndex,
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/constants/bg_color.dart';
|
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
|
||||||
|
|
||||||
class SkInk extends StatelessWidget {
|
class SkInk extends StatelessWidget {
|
||||||
final Widget? child;
|
final Widget? child;
|
||||||
|
@ -35,7 +33,7 @@ class SkInk extends StatelessWidget {
|
||||||
padding: padding,
|
padding: padding,
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
border: border,
|
border: border,
|
||||||
color: color,
|
color: color ?? AppTheme.nearlyWhite,
|
||||||
gradient: gradient,
|
gradient: gradient,
|
||||||
borderRadius: borderRadius,
|
borderRadius: borderRadius,
|
||||||
),
|
),
|
||||||
|
|
|
@ -8,7 +8,7 @@ import 'package:sk_base_mobile/widgets/loading_indicator.dart';
|
||||||
|
|
||||||
class SkMutiPickerDialog<T> extends StatelessWidget {
|
class SkMutiPickerDialog<T> extends StatelessWidget {
|
||||||
final SkMutiPickerDialogController controller;
|
final SkMutiPickerDialogController controller;
|
||||||
Function(List<PickerItem> data)? onSelected;
|
final Function(List<PickerItem> data)? onSelected;
|
||||||
SkMutiPickerDialog(
|
SkMutiPickerDialog(
|
||||||
{super.key,
|
{super.key,
|
||||||
required Future<List<PickerItem<T>>> Function() getData,
|
required Future<List<PickerItem<T>>> Function() getData,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/widgets/form_item/sk_form_item.dart';
|
import 'package:sk_base_mobile/widgets/form_item/sk_form_item.dart';
|
||||||
import 'package:sk_base_mobile/widgets/form_item/sk_base_field.dart';
|
import 'package:sk_base_mobile/widgets/form_item/sk_base_field.dart';
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:sk_base_mobile/store/auth.store.dart';
|
import 'package:sk_base_mobile/store/auth.store.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
|
||||||
import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart';
|
import 'package:sk_base_mobile/widgets/fade_in_cache_image.dart';
|
||||||
|
|
||||||
import '../util/util.dart';
|
import '../util/util.dart';
|
||||||
|
|
|
@ -1,16 +1,13 @@
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:sk_base_mobile/app_theme.dart';
|
import 'package:sk_base_mobile/app_theme.dart';
|
||||||
import 'package:sk_base_mobile/services/app_info.service.dart';
|
|
||||||
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
import 'package:sk_base_mobile/util/screen_adaper_util.dart';
|
||||||
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
import 'package:sk_base_mobile/widgets/gradient_button.dart';
|
||||||
|
|
||||||
class UpgradeConfirm extends StatelessWidget {
|
class UpgradeConfirm extends StatelessWidget {
|
||||||
void Function()? onConfirm;
|
final void Function()? onConfirm;
|
||||||
bool forceUpgrade;
|
final bool forceUpgrade;
|
||||||
UpgradeConfirm({super.key, this.onConfirm, this.forceUpgrade = true});
|
const UpgradeConfirm({super.key, this.onConfirm, this.forceUpgrade = true});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|
Loading…
Reference in New Issue