Skip to content

Commit

Permalink
ui: new_group_page: add conditional policy tile
Browse files Browse the repository at this point in the history
  • Loading branch information
dufkan committed May 2, 2024
1 parent a864bbf commit f3cb771
Show file tree
Hide file tree
Showing 3 changed files with 159 additions and 147 deletions.
4 changes: 2 additions & 2 deletions lib/ui/home_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -901,8 +901,8 @@ class _HomePageViewState extends State<HomePageView> {
if (res == null) return;

try {
await context.read<HomeState>().addGroup(
res.name, res.members, res.threshold, res.protocol, res.keyType);
await context.read<HomeState>().addGroup(res.name, res.members,
res.threshold, res.protocol, res.keyType, res.note);
} catch (e) {
showErrorDialog(
title: 'Group request failed',
Expand Down
4 changes: 2 additions & 2 deletions lib/ui/home_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ class HomeState with ChangeNotifier {
}

Future<void> addGroup(String name, List<Device> members, int threshold,
Protocol protocol, KeyType keyType) =>
_groupRepository.group(name, members, threshold, protocol, keyType);
Protocol protocol, KeyType keyType, String? note) =>
_groupRepository.group(name, members, threshold, protocol, keyType, note);

Future<void> sign(XFile file, Group group) async {
await _fileRepository.sign(file.name, await file.readAsBytes(), group.id);
Expand Down
298 changes: 155 additions & 143 deletions lib/ui/new_group_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ class _NewGroupPageState extends State<NewGroupPage> {
int _threshold = _minThreshold;
final List<Device> _members = [];
final _nameController = TextEditingController();
final _policyController = TextEditingController();
String? _nameErr, _memberErr;
KeyType _keyType = KeyType.signPdf;
Protocol _protocol = KeyType.signPdf.supportedProtocols.first;
Expand Down Expand Up @@ -105,6 +106,8 @@ class _NewGroupPageState extends State<NewGroupPage> {
});
}

bool _hasBot() => _members.any((member) => member.kind == DeviceKind.bot);

void _selectPeer(String route) async {
// TODO: pass the current selection to the search page?
final devices = await Navigator.pushNamed(context, route);
Expand All @@ -125,16 +128,9 @@ class _NewGroupPageState extends State<NewGroupPage> {
if (_nameErr != null || _memberErr != null) return;

Navigator.pop(
context,
Group(
const [],
_nameController.text,
_members,
_threshold,
_protocol,
_keyType,
),
);
context,
Group(const [], _nameController.text, _members, _threshold, _protocol,
_keyType, _hasBot() ? _policyController.text : null));
}

@override
Expand All @@ -144,6 +140,154 @@ class _NewGroupPageState extends State<NewGroupPage> {
backgroundColor: Theme.of(context).colorScheme.errorContainer)
: null;

var elements = List<Widget>.empty(growable: true);
elements.add(OptionTile(
title: 'Name',
children: [
TextField(
controller: _nameController,
decoration: InputDecoration(
// labelText: 'Name',
border: const OutlineInputBorder(),
errorText: _nameErr,
),
maxLength: 32,
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp('[${RegExp.escape(asciiPunctuationChars)}]'),
)
],
),
],
));
elements.add(OptionTile(
title: 'Members',
children: [
Row(
children: [
Expanded(
child: FilledButton.tonalIcon(
icon: const Icon(Icons.search),
label: const Text('Search'),
style: membersButtonStyle,
onPressed: () => _selectPeer(Routes.newGroupSearch),
),
),
const SizedBox(width: 8),
if (Platform.isAndroid || Platform.isIOS)
Expanded(
child: FilledButton.tonalIcon(
icon: const Icon(Icons.qr_code),
label: const Text('Scan'),
style: membersButtonStyle,
onPressed: () => _selectPeer(Routes.newGroupQr),
),
),
],
),
const SizedBox(height: 8),
Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: _memberChips.toList(),
),
],
));
elements.add(OptionTile(
title: 'Threshold',
children: [
Row(
children: [
const Icon(Icons.person),
Expanded(
child: Slider(
value: min(_threshold, _members.length).toDouble(),
min: 0,
max: _members.length.toDouble(),
divisions: max(1, _members.length),
label: '$_threshold',
onChanged: _members.length > _minThreshold
? (value) => setState(() {
_setThreshold(value.round());
})
: null,
),
),
const Icon(Icons.people),
],
),
],
));
elements.add(OptionTile(
title: 'Purpose',
children: [
SegmentedButton<KeyType>(
selected: {_keyType},
onSelectionChanged: (value) {
setState(() {
_protocol = value.first.supportedProtocols.first;
_keyType = value.first;
});
},
segments: const [
ButtonSegment<KeyType>(
value: KeyType.signPdf,
label: Text('Sign PDF'),
),
ButtonSegment<KeyType>(
value: KeyType.signChallenge,
label: Text('Challenge'),
),
ButtonSegment<KeyType>(
value: KeyType.decrypt,
label: Text('Decrypt'),
)
],
),
],
));
// check if _members contains a device with DeviceKind.bot
if (_hasBot()) {
elements.add(OptionTile(
title: 'Policy',
children: [
TextField(
controller: _policyController,
decoration: InputDecoration(
border: const OutlineInputBorder(),
),
maxLines: null,
),
],
));
}
elements.add(ExpansionTile(
title: const Text('Advanced options'),
collapsedTextColor:
Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.5),
expandedCrossAxisAlignment: CrossAxisAlignment.stretch,
children: [
OptionTile(
title: 'Protocol',
children: [
SegmentedButton<Protocol>(
selected: {_protocol},
onSelectionChanged: (value) {
setState(() => _protocol = value.first);
},
segments: [
for (var protocol in _keyType.supportedProtocols)
ButtonSegment<Protocol>(
value: protocol,
label: Text(protocol.name.toUpperCase()),
),
],
),
],
)
],
));

return Scaffold(
appBar: AppBar(
title: const Text('New Group'),
Expand All @@ -158,139 +302,7 @@ class _NewGroupPageState extends State<NewGroupPage> {
],
),
body: ListView(
children: [
OptionTile(
title: 'Name',
children: [
TextField(
controller: _nameController,
decoration: InputDecoration(
// labelText: 'Name',
border: const OutlineInputBorder(),
errorText: _nameErr,
),
maxLength: 32,
inputFormatters: [
FilteringTextInputFormatter.deny(
RegExp('[${RegExp.escape(asciiPunctuationChars)}]'),
)
],
),
],
),
OptionTile(
title: 'Members',
children: [
Row(
children: [
Expanded(
child: FilledButton.tonalIcon(
icon: const Icon(Icons.search),
label: const Text('Search'),
style: membersButtonStyle,
onPressed: () => _selectPeer(Routes.newGroupSearch),
),
),
const SizedBox(width: 8),
if (Platform.isAndroid || Platform.isIOS)
Expanded(
child: FilledButton.tonalIcon(
icon: const Icon(Icons.qr_code),
label: const Text('Scan'),
style: membersButtonStyle,
onPressed: () => _selectPeer(Routes.newGroupQr),
),
),
],
),
const SizedBox(height: 8),
Wrap(
spacing: 8.0,
runSpacing: 4.0,
children: _memberChips.toList(),
),
],
),
OptionTile(
title: 'Threshold',
children: [
Row(
children: [
const Icon(Icons.person),
Expanded(
child: Slider(
value: min(_threshold, _members.length).toDouble(),
min: 0,
max: _members.length.toDouble(),
divisions: max(1, _members.length),
label: '$_threshold',
onChanged: _members.length > _minThreshold
? (value) => setState(() {
_setThreshold(value.round());
})
: null,
),
),
const Icon(Icons.people),
],
),
],
),
OptionTile(
title: 'Purpose',
children: [
SegmentedButton<KeyType>(
selected: {_keyType},
onSelectionChanged: (value) {
setState(() {
_protocol = value.first.supportedProtocols.first;
_keyType = value.first;
});
},
segments: const [
ButtonSegment<KeyType>(
value: KeyType.signPdf,
label: Text('Sign PDF'),
),
ButtonSegment<KeyType>(
value: KeyType.signChallenge,
label: Text('Challenge'),
),
ButtonSegment<KeyType>(
value: KeyType.decrypt,
label: Text('Decrypt'),
)
],
),
],
),
ExpansionTile(
title: const Text('Advanced options'),
collapsedTextColor:
Theme.of(context).textTheme.bodyLarge?.color?.withOpacity(0.5),
expandedCrossAxisAlignment: CrossAxisAlignment.stretch,
children: [
OptionTile(
title: 'Protocol',
children: [
SegmentedButton<Protocol>(
selected: {_protocol},
onSelectionChanged: (value) {
setState(() => _protocol = value.first);
},
segments: [
for (var protocol in _keyType.supportedProtocols)
ButtonSegment<Protocol>(
value: protocol,
label: Text(protocol.name.toUpperCase()),
),
],
),
],
)
],
),
],
children: elements,
),
);
}
Expand Down

0 comments on commit f3cb771

Please sign in to comment.