mirror of
https://github.com/cypherstack/stack_wallet.git
synced 2024-11-17 01:37:54 +00:00
various frost settings view ui tweaks and fixes
This commit is contained in:
parent
3bddec00f1
commit
a9449ace0d
4 changed files with 456 additions and 42 deletions
|
@ -1,8 +1,11 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/transaction_views/tx_v2/transaction_v2_details_view.dart';
|
||||
import 'package:stackwallet/pages_desktop_specific/my_stack_view/exit_to_my_stack_button.dart';
|
||||
import 'package:stackwallet/providers/db/main_db_provider.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
import 'package:stackwallet/wallets/isar/models/frost_wallet_info.dart';
|
||||
|
@ -11,6 +14,7 @@ import 'package:stackwallet/widgets/conditional_parent.dart';
|
|||
import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
|
||||
class FrostParticipantsView extends ConsumerWidget {
|
||||
const FrostParticipantsView({
|
||||
|
@ -84,31 +88,56 @@ class FrostParticipantsView extends ConsumerWidget {
|
|||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: Util.isDesktop
|
||||
? CrossAxisAlignment.start
|
||||
: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
for (int i = 0; i < frostInfo.participants.length; i++)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
vertical: 8,
|
||||
vertical: 5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
"Index $i",
|
||||
style: STextStyles.label(context),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
SelectableText(
|
||||
frostInfo.participants[i] == frostInfo.myName
|
||||
? "${frostInfo.participants[i]} (me)"
|
||||
: frostInfo.participants[i],
|
||||
style: STextStyles.itemSubtitle12(context),
|
||||
),
|
||||
],
|
||||
child: RoundedWhiteContainer(
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 26,
|
||||
height: 26,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldActiveBG,
|
||||
borderRadius: BorderRadius.circular(
|
||||
200,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
Assets.svg.user,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
frostInfo.participants[i] == frostInfo.myName
|
||||
? "${frostInfo.participants[i]} (me)"
|
||||
: frostInfo.participants[i],
|
||||
style: STextStyles.w500_14(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
IconCopyButton(
|
||||
data: frostInfo.participants[i],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import 'dart:math';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
@ -19,6 +21,7 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
|||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/rounded_white_container.dart';
|
||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||
|
||||
final class CompleteReshareConfigView extends ConsumerStatefulWidget {
|
||||
|
@ -45,9 +48,12 @@ class _CompleteReshareConfigViewState
|
|||
|
||||
final List<TextEditingController> controllers = [];
|
||||
|
||||
late final String myName;
|
||||
|
||||
int _participantsCount = 0;
|
||||
|
||||
bool _buttonLock = false;
|
||||
bool _includeMeInReshare = false;
|
||||
|
||||
Future<void> _onPressed() async {
|
||||
if (_buttonLock) {
|
||||
|
@ -74,10 +80,16 @@ class _CompleteReshareConfigViewState
|
|||
);
|
||||
}
|
||||
|
||||
final List<String> newParticipants =
|
||||
controllers.map((e) => e.text.trim()).toList();
|
||||
if (_includeMeInReshare) {
|
||||
newParticipants.insert(0, myName);
|
||||
}
|
||||
|
||||
final config = Frost.createResharerConfig(
|
||||
newThreshold: int.parse(_newThresholdController.text),
|
||||
resharers: widget.resharers,
|
||||
newParticipants: controllers.map((e) => e.text).toList(),
|
||||
newParticipants: newParticipants,
|
||||
);
|
||||
|
||||
final salt = Format.uint8listToString(
|
||||
|
@ -105,7 +117,7 @@ class _CompleteReshareConfigViewState
|
|||
});
|
||||
}
|
||||
|
||||
ref.read(pFrostResharingData).myName = frostInfo.myName;
|
||||
ref.read(pFrostResharingData).myName = myName;
|
||||
ref.read(pFrostResharingData).resharerConfig = config;
|
||||
|
||||
if (mounted) {
|
||||
|
@ -152,18 +164,29 @@ class _CompleteReshareConfigViewState
|
|||
return "At least two participants required";
|
||||
}
|
||||
|
||||
if (controllers.length != partsCount) {
|
||||
final newParticipants = controllers.map((e) => e.text.trim()).toList();
|
||||
|
||||
if (newParticipants.contains(myName)) {
|
||||
return "Using your own name should be done using the checkbox to include"
|
||||
" yourself";
|
||||
}
|
||||
|
||||
if (_includeMeInReshare) {
|
||||
newParticipants.add(myName);
|
||||
}
|
||||
|
||||
if (newParticipants.length != partsCount) {
|
||||
return "Participants count error";
|
||||
}
|
||||
|
||||
final hasEmptyParticipants = controllers
|
||||
.map((e) => e.text.isEmpty)
|
||||
final hasEmptyParticipants = newParticipants
|
||||
.map((e) => e.trim().isEmpty)
|
||||
.reduce((value, element) => value |= element);
|
||||
if (hasEmptyParticipants) {
|
||||
return "Participants must not be empty";
|
||||
}
|
||||
|
||||
if (controllers.length != controllers.map((e) => e.text).toSet().length) {
|
||||
if (newParticipants.length != newParticipants.toSet().length) {
|
||||
return "Duplicate participant name found";
|
||||
}
|
||||
|
||||
|
@ -171,8 +194,12 @@ class _CompleteReshareConfigViewState
|
|||
}
|
||||
|
||||
void _participantsCountChanged(String newValue) {
|
||||
final count = int.tryParse(newValue);
|
||||
int? count = int.tryParse(newValue);
|
||||
if (count != null) {
|
||||
if (_includeMeInReshare) {
|
||||
count = max(0, count - 1);
|
||||
}
|
||||
|
||||
if (count > _participantsCount) {
|
||||
for (int i = _participantsCount; i < count; i++) {
|
||||
controllers.add(TextEditingController());
|
||||
|
@ -192,6 +219,17 @@ class _CompleteReshareConfigViewState
|
|||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final frostInfo = ref
|
||||
.read(mainDBProvider)
|
||||
.isar
|
||||
.frostWalletInfo
|
||||
.getByWalletIdSync(widget.walletId)!;
|
||||
myName = frostInfo.myName;
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_newThresholdController.dispose();
|
||||
|
@ -231,7 +269,7 @@ class _CompleteReshareConfigViewState
|
|||
},
|
||||
),
|
||||
title: Text(
|
||||
"Modify Participants",
|
||||
"Edit group details",
|
||||
style: STextStyles.navBarTitle(context),
|
||||
),
|
||||
),
|
||||
|
@ -258,11 +296,62 @@ class _CompleteReshareConfigViewState
|
|||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
crossAxisAlignment: Util.isDesktop
|
||||
? CrossAxisAlignment.start
|
||||
: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 8,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_includeMeInReshare = !_includeMeInReshare;
|
||||
});
|
||||
_participantsCountChanged(_newParticipantsCountController.text);
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20,
|
||||
height: 26,
|
||||
child: Checkbox(
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
value: _includeMeInReshare,
|
||||
onChanged: (value) {
|
||||
setState(
|
||||
() => _includeMeInReshare = value == true,
|
||||
);
|
||||
_participantsCountChanged(
|
||||
_newParticipantsCountController.text);
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"I will be a signer in the new config",
|
||||
style: STextStyles.w500_14(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 20,
|
||||
),
|
||||
Text(
|
||||
"New threshold",
|
||||
style: STextStyles.label(context),
|
||||
style: STextStyles.w500_14(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
|
@ -271,13 +360,32 @@ class _CompleteReshareConfigViewState
|
|||
keyboardType: TextInputType.number,
|
||||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
controller: _newThresholdController,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter number of signatures",
|
||||
hintStyle: STextStyles.fieldLabel(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
child: Text(
|
||||
"Enter number of signatures required for fund management.",
|
||||
style: STextStyles.w500_12(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle2,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
Text(
|
||||
"Number of participants",
|
||||
style: STextStyles.label(context),
|
||||
"New number of participants",
|
||||
style: STextStyles.w500_14(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
|
@ -287,6 +395,23 @@ class _CompleteReshareConfigViewState
|
|||
inputFormatters: [FilteringTextInputFormatter.digitsOnly],
|
||||
controller: _newParticipantsCountController,
|
||||
onChanged: _participantsCountChanged,
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter number of participants",
|
||||
hintStyle: STextStyles.fieldLabel(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 6,
|
||||
),
|
||||
RoundedWhiteContainer(
|
||||
child: Text(
|
||||
"The number of participants must be equal to or less than the"
|
||||
" number of required signatures.",
|
||||
style: STextStyles.w500_12(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle2,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
|
@ -294,12 +419,26 @@ class _CompleteReshareConfigViewState
|
|||
if (controllers.isNotEmpty)
|
||||
Text(
|
||||
"Participants",
|
||||
style: STextStyles.label(context),
|
||||
style: STextStyles.w500_14(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
),
|
||||
),
|
||||
if (controllers.isNotEmpty)
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
if (controllers.isNotEmpty)
|
||||
RoundedWhiteContainer(
|
||||
child: Text(
|
||||
"Type each name in one word without spaces.",
|
||||
style: STextStyles.w500_12(context).copyWith(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textSubtitle2,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controllers.isNotEmpty)
|
||||
Column(
|
||||
children: [
|
||||
|
@ -310,6 +449,10 @@ class _CompleteReshareConfigViewState
|
|||
),
|
||||
child: TextField(
|
||||
controller: controllers[i],
|
||||
decoration: InputDecoration(
|
||||
hintText: "Enter name",
|
||||
hintStyle: STextStyles.fieldLabel(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:flutter_svg/flutter_svg.dart';
|
||||
import 'package:qr_flutter/qr_flutter.dart';
|
||||
import 'package:stackwallet/pages/settings_views/wallet_settings_view/frost_ms/resharing/involved/step_2/begin_resharing_view.dart';
|
||||
import 'package:stackwallet/pages/wallet_view/transaction_views/transaction_details_view.dart';
|
||||
|
@ -8,6 +9,7 @@ import 'package:stackwallet/providers/frost_wallet/frost_wallet_providers.dart';
|
|||
import 'package:stackwallet/providers/global/wallets_provider.dart';
|
||||
import 'package:stackwallet/services/frost.dart';
|
||||
import 'package:stackwallet/themes/stack_colors.dart';
|
||||
import 'package:stackwallet/utilities/assets.dart';
|
||||
import 'package:stackwallet/utilities/logger.dart';
|
||||
import 'package:stackwallet/utilities/text_styles.dart';
|
||||
import 'package:stackwallet/utilities/util.dart';
|
||||
|
@ -20,7 +22,10 @@ import 'package:stackwallet/widgets/custom_buttons/simple_copy_button.dart';
|
|||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/desktop/secondary_button.dart';
|
||||
import 'package:stackwallet/widgets/detail_item.dart';
|
||||
import 'package:stackwallet/widgets/dialogs/simple_mobile_dialog.dart';
|
||||
import 'package:stackwallet/widgets/frost_step_user_steps.dart';
|
||||
import 'package:stackwallet/widgets/stack_dialog.dart';
|
||||
|
||||
class DisplayReshareConfigView extends ConsumerStatefulWidget {
|
||||
|
@ -40,9 +45,19 @@ class DisplayReshareConfigView extends ConsumerStatefulWidget {
|
|||
|
||||
class _DisplayReshareConfigViewState
|
||||
extends ConsumerState<DisplayReshareConfigView> {
|
||||
static const info = [
|
||||
"Share this config with the signing group participants as well as any new "
|
||||
"participant.",
|
||||
"Wait for them to import the config.",
|
||||
"Verify that everyone has imported the config. If you try to continue "
|
||||
"before everyone is ready, the process will be canceled.",
|
||||
"Check the box and press “Start resharing”.",
|
||||
];
|
||||
|
||||
late final bool iAmInvolved;
|
||||
|
||||
bool _buttonLock = false;
|
||||
bool _userVerifyContinue = false;
|
||||
|
||||
Future<void> _onPressed() async {
|
||||
if (_buttonLock) {
|
||||
|
@ -88,6 +103,111 @@ class _DisplayReshareConfigViewState
|
|||
}
|
||||
}
|
||||
|
||||
void _showParticipantsDialog() {
|
||||
final participants =
|
||||
ref.read(pFrostResharingData).configData!.newParticipants;
|
||||
|
||||
showDialog<void>(
|
||||
context: context,
|
||||
builder: (_) => SimpleMobileDialog(
|
||||
showCloseButton: false,
|
||||
padding: EdgeInsets.zero,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
"Group participants",
|
||||
style: STextStyles.w600_20(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Text(
|
||||
"The names are case-sensitive and must be entered exactly.",
|
||||
style: STextStyles.w400_16(context).copyWith(
|
||||
color: Theme.of(context).extension<StackColors>()!.textDark3,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
for (final participant in participants)
|
||||
Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Container(
|
||||
width: double.infinity,
|
||||
height: 1.5,
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.background,
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Row(
|
||||
children: [
|
||||
Container(
|
||||
width: 26,
|
||||
height: 26,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context)
|
||||
.extension<StackColors>()!
|
||||
.textFieldActiveBG,
|
||||
borderRadius: BorderRadius.circular(
|
||||
200,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: SvgPicture.asset(
|
||||
Assets.svg.user,
|
||||
width: 16,
|
||||
height: 16,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
participant,
|
||||
style: STextStyles.w500_14(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 8,
|
||||
),
|
||||
IconCopyButton(
|
||||
data: participant,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 12,
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(
|
||||
height: 24,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: optimize this by creating watcher providers (similar to normal WalletInfo)
|
||||
|
@ -162,7 +282,13 @@ class _DisplayReshareConfigViewState
|
|||
),
|
||||
child: Column(
|
||||
children: [
|
||||
if (!Util.isDesktop) const Spacer(),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
const FrostStepUserSteps(
|
||||
userSteps: info,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
SizedBox(
|
||||
height: 220,
|
||||
child: Row(
|
||||
|
@ -197,13 +323,66 @@ class _DisplayReshareConfigViewState
|
|||
SizedBox(
|
||||
height: Util.isDesktop ? 64 : 16,
|
||||
),
|
||||
if (!Util.isDesktop)
|
||||
const Spacer(
|
||||
flex: 2,
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SecondaryButton(
|
||||
label: "Show group participants",
|
||||
onPressed: _showParticipantsDialog,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (iAmInvolved && !Util.isDesktop) const Spacer(),
|
||||
if (iAmInvolved)
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
if (iAmInvolved)
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_userVerifyContinue = !_userVerifyContinue;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20,
|
||||
height: 26,
|
||||
child: Checkbox(
|
||||
materialTapTargetSize:
|
||||
MaterialTapTargetSize.shrinkWrap,
|
||||
value: _userVerifyContinue,
|
||||
onChanged: (value) => setState(
|
||||
() => _userVerifyContinue = value == true,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"I have verified that everyone has imported the config",
|
||||
style: STextStyles.w500_14(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (iAmInvolved)
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
if (iAmInvolved)
|
||||
PrimaryButton(
|
||||
label: "Start resharing",
|
||||
enabled: _userVerifyContinue,
|
||||
onPressed: _onPressed,
|
||||
),
|
||||
],
|
||||
|
|
|
@ -21,6 +21,7 @@ import 'package:stackwallet/widgets/custom_buttons/app_bar_icon_button.dart';
|
|||
import 'package:stackwallet/widgets/desktop/desktop_app_bar.dart';
|
||||
import 'package:stackwallet/widgets/desktop/desktop_scaffold.dart';
|
||||
import 'package:stackwallet/widgets/desktop/primary_button.dart';
|
||||
import 'package:stackwallet/widgets/frost_step_user_steps.dart';
|
||||
import 'package:stackwallet/widgets/icon_widgets/clipboard_icon.dart';
|
||||
import 'package:stackwallet/widgets/icon_widgets/qrcode_icon.dart';
|
||||
import 'package:stackwallet/widgets/icon_widgets/x_icon.dart';
|
||||
|
@ -45,12 +46,22 @@ class ImportReshareConfigView extends ConsumerStatefulWidget {
|
|||
|
||||
class _ImportReshareConfigViewState
|
||||
extends ConsumerState<ImportReshareConfigView> {
|
||||
static const info = [
|
||||
"Scan the config QR code or paste the code provided by the group member who"
|
||||
" is initiating resharing.",
|
||||
"Wait for other participants to finish importing the config.",
|
||||
"Verify that everyone has filled out their forms before continuing. If you "
|
||||
"try to continue before everyone is ready, the process will be canceled.",
|
||||
"Check the box and press “Start resharing”.",
|
||||
];
|
||||
|
||||
late final TextEditingController configFieldController;
|
||||
late final FocusNode configFocusNode;
|
||||
|
||||
bool _configEmpty = true;
|
||||
|
||||
bool _buttonLock = false;
|
||||
bool _userVerifyContinue = false;
|
||||
|
||||
Future<void> _onPressed() async {
|
||||
if (_buttonLock) {
|
||||
|
@ -84,14 +95,14 @@ class _ImportReshareConfigViewState
|
|||
if (frostInfo.knownSalts.contains(salt)) {
|
||||
throw Exception("Duplicate config salt");
|
||||
} else {
|
||||
final salts = frostInfo.knownSalts;
|
||||
final salts = frostInfo.knownSalts.toList();
|
||||
salts.add(salt);
|
||||
final mainDB = ref.read(mainDBProvider);
|
||||
await mainDB.isar.writeTxn(() async {
|
||||
final info = frostInfo;
|
||||
await mainDB.isar.frostWalletInfo.delete(info.id);
|
||||
final id = frostInfo.id;
|
||||
await mainDB.isar.frostWalletInfo.delete(id);
|
||||
await mainDB.isar.frostWalletInfo.put(
|
||||
info.copyWith(knownSalts: salts),
|
||||
frostInfo.copyWith(knownSalts: salts),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
@ -201,6 +212,20 @@ class _ImportReshareConfigViewState
|
|||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
const FrostStepUserSteps(
|
||||
userSteps: info,
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Text(
|
||||
"Enter config",
|
||||
style: STextStyles.w500_14(context).copyWith(
|
||||
color:
|
||||
Theme.of(context).extension<StackColors>()!.textSubtitle1,
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 10,
|
||||
),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.circular(
|
||||
Constants.size.circularBorderRadius,
|
||||
|
@ -319,9 +344,47 @@ class _ImportReshareConfigViewState
|
|||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_userVerifyContinue = !_userVerifyContinue;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
color: Colors.transparent,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
SizedBox(
|
||||
width: 20,
|
||||
height: 26,
|
||||
child: Checkbox(
|
||||
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
|
||||
value: _userVerifyContinue,
|
||||
onChanged: (value) => setState(
|
||||
() => _userVerifyContinue = value == true,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 12,
|
||||
),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"I have verified that everyone has imported the config",
|
||||
style: STextStyles.w500_14(context),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(
|
||||
height: 16,
|
||||
),
|
||||
PrimaryButton(
|
||||
label: "Start resharing",
|
||||
enabled: !_configEmpty,
|
||||
enabled: !_configEmpty && _userVerifyContinue,
|
||||
onPressed: () async {
|
||||
if (FocusScope.of(context).hasFocus) {
|
||||
FocusScope.of(context).unfocus();
|
||||
|
|
Loading…
Reference in a new issue