mirror of
https://gitlab.com/comunic/comunicmobile
synced 2024-11-22 21:09:21 +00:00
Create pick user dialog
This commit is contained in:
parent
1227ef283c
commit
804457c761
63
lib/ui/dialogs/pick_user_dialog.dart
Normal file
63
lib/ui/dialogs/pick_user_dialog.dart
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import 'package:comunic/models/user.dart';
|
||||||
|
import 'package:comunic/ui/widgets/dialogs/cancel_dialog_button.dart';
|
||||||
|
import 'package:comunic/ui/widgets/dialogs/confirm_dialog_button.dart';
|
||||||
|
import 'package:comunic/ui/widgets/pick_user_widget.dart';
|
||||||
|
import 'package:comunic/ui/widgets/safe_state.dart';
|
||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Pick user dialog
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
/// Ask the user to pick a user
|
||||||
|
///
|
||||||
|
/// Returns null if no user was selected
|
||||||
|
Future<int> showPickUserDialog(BuildContext context) async {
|
||||||
|
return await showDialog(context: context, builder: (c) => _PickUserDialog());
|
||||||
|
}
|
||||||
|
|
||||||
|
class _PickUserDialog extends StatefulWidget {
|
||||||
|
@override
|
||||||
|
__PickUserDialogState createState() => __PickUserDialogState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class __PickUserDialogState extends SafeState<_PickUserDialog> {
|
||||||
|
User _user;
|
||||||
|
|
||||||
|
bool get _isValid => _user != null;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return AlertDialog(
|
||||||
|
title: Text(tr("Choose a user")),
|
||||||
|
content: _buildContent(),
|
||||||
|
actions: <Widget>[
|
||||||
|
CancelDialogButton(),
|
||||||
|
ConfirmDialogButton(
|
||||||
|
value: _isValid ? _user.id : null,
|
||||||
|
enabled: _isValid,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildContent() {
|
||||||
|
final size = MediaQuery.of(context).size;
|
||||||
|
print(size);
|
||||||
|
return Container(
|
||||||
|
width: size.width,
|
||||||
|
height: size.height,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
PickUserWidget(
|
||||||
|
onSelectUser: (u) => setState(() => _user = u),
|
||||||
|
label: tr("Search user..."),
|
||||||
|
onValueChange: (u) => setState(() => _user = null),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import 'package:comunic/models/group.dart';
|
|||||||
import 'package:comunic/models/group_membership.dart';
|
import 'package:comunic/models/group_membership.dart';
|
||||||
import 'package:comunic/models/user.dart';
|
import 'package:comunic/models/user.dart';
|
||||||
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
|
import 'package:comunic/ui/dialogs/multi_choices_dialog.dart';
|
||||||
|
import 'package:comunic/ui/dialogs/pick_user_dialog.dart';
|
||||||
import 'package:comunic/ui/widgets/account_image_widget.dart';
|
import 'package:comunic/ui/widgets/account_image_widget.dart';
|
||||||
import 'package:comunic/ui/widgets/async_screen_widget.dart';
|
import 'package:comunic/ui/widgets/async_screen_widget.dart';
|
||||||
import 'package:comunic/ui/widgets/comunic_back_button_widget.dart';
|
import 'package:comunic/ui/widgets/comunic_back_button_widget.dart';
|
||||||
@ -61,8 +62,11 @@ class _GroupMembersScreenState extends State<GroupMembersScreen> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildBodyContent() {
|
Widget _buildBodyContent() {
|
||||||
return ListView(
|
return Stack(
|
||||||
children: _members.map(_buildGroupMemberTile).toList(),
|
children: [
|
||||||
|
ListView(children: _members.map(_buildGroupMemberTile).toList()),
|
||||||
|
_buildInvitationFAB()
|
||||||
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +79,29 @@ class _GroupMembersScreenState extends State<GroupMembersScreen> {
|
|||||||
onUpdated: () => _key.currentState.refresh(),
|
onUpdated: () => _key.currentState.refresh(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildInvitationFAB() {
|
||||||
|
return Positioned(
|
||||||
|
right: 20,
|
||||||
|
bottom: 20,
|
||||||
|
child: FloatingActionButton(
|
||||||
|
onPressed: _inviteMember,
|
||||||
|
child: Icon(Icons.add),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _inviteMember() async {
|
||||||
|
try {
|
||||||
|
final userID = await showPickUserDialog(context);
|
||||||
|
if (userID == null) return;
|
||||||
|
|
||||||
|
print("Invite user: $userID");
|
||||||
|
} catch (e, s) {
|
||||||
|
print("Could not invite a user! $e\n$s");
|
||||||
|
showSimpleSnack(context, tr("Could not invite a user!"));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<MultiChoiceEntry<GroupMembershipLevel>> get _membershipLevels => [
|
List<MultiChoiceEntry<GroupMembershipLevel>> get _membershipLevels => [
|
||||||
|
17
lib/ui/widgets/dialogs/cancel_dialog_button.dart
Normal file
17
lib/ui/widgets/dialogs/cancel_dialog_button.dart
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Render a cancel button for an alert dialog
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class CancelDialogButton extends StatelessWidget {
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialButton(
|
||||||
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
|
child: Text(tr("Cancel").toUpperCase()),
|
||||||
|
textColor: Colors.red,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
27
lib/ui/widgets/dialogs/confirm_dialog_button.dart
Normal file
27
lib/ui/widgets/dialogs/confirm_dialog_button.dart
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import 'package:comunic/utils/intl_utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
/// Confirm dialog button
|
||||||
|
///
|
||||||
|
/// @author Pierre HUBERT
|
||||||
|
|
||||||
|
class ConfirmDialogButton<T> extends StatelessWidget {
|
||||||
|
final bool enabled;
|
||||||
|
final T value;
|
||||||
|
|
||||||
|
const ConfirmDialogButton({
|
||||||
|
Key key,
|
||||||
|
this.enabled = true,
|
||||||
|
@required this.value,
|
||||||
|
}) : assert(enabled != null),
|
||||||
|
super(key: key);
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return MaterialButton(
|
||||||
|
onPressed: enabled ? () => Navigator.of(context).pop(value) : null,
|
||||||
|
child: Text(tr("Confirm").toUpperCase()),
|
||||||
|
textColor: Colors.green,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -15,19 +15,21 @@ typedef OnSelectUserCallback = void Function(User);
|
|||||||
|
|
||||||
class PickUserWidget extends StatefulWidget {
|
class PickUserWidget extends StatefulWidget {
|
||||||
final OnSelectUserCallback onSelectUser;
|
final OnSelectUserCallback onSelectUser;
|
||||||
|
final void Function(String) onValueChange;
|
||||||
final String label;
|
final String label;
|
||||||
final bool resetOnChoose;
|
final bool resetOnChoose;
|
||||||
final bool keepFocusOnChoose;
|
final bool keepFocusOnChoose;
|
||||||
final bool enabled;
|
final bool enabled;
|
||||||
|
|
||||||
const PickUserWidget(
|
const PickUserWidget({
|
||||||
{Key key,
|
Key key,
|
||||||
@required this.onSelectUser,
|
@required this.onSelectUser,
|
||||||
@required this.label,
|
@required this.label,
|
||||||
this.resetOnChoose = false,
|
this.resetOnChoose = false,
|
||||||
this.keepFocusOnChoose = false,
|
this.keepFocusOnChoose = false,
|
||||||
this.enabled = true})
|
this.onValueChange,
|
||||||
: assert(onSelectUser != null),
|
this.enabled = true,
|
||||||
|
}) : assert(onSelectUser != null),
|
||||||
assert(label != null),
|
assert(label != null),
|
||||||
assert(resetOnChoose != null),
|
assert(resetOnChoose != null),
|
||||||
assert(keepFocusOnChoose != null),
|
assert(keepFocusOnChoose != null),
|
||||||
@ -93,9 +95,9 @@ class _PickUserWidgetState extends State<PickUserWidget> {
|
|||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
itemCount: _suggestions == null ? 0 : _suggestions.length,
|
itemCount: _suggestions == null ? 0 : _suggestions.length,
|
||||||
itemBuilder: (c, i) => SimpleUserTile(
|
itemBuilder: (c, i) => SimpleUserTile(
|
||||||
user: _suggestions[i],
|
user: _suggestions[i],
|
||||||
onTap: _userTapped,
|
onTap: _userTapped,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -116,9 +118,11 @@ class _PickUserWidgetState extends State<PickUserWidget> {
|
|||||||
|
|
||||||
/// This method get called each time the input value is updated
|
/// This method get called each time the input value is updated
|
||||||
Future<void> _updateSuggestions() async {
|
Future<void> _updateSuggestions() async {
|
||||||
if (_controller.value.text.length == 0) return _removeOverlay();
|
if (widget.onValueChange != null) widget.onValueChange(_controller.text);
|
||||||
|
|
||||||
final results = await _searchHelper.searchUser(_controller.value.text);
|
if (_controller.text.length == 0) return _removeOverlay();
|
||||||
|
|
||||||
|
final results = await _searchHelper.searchUser(_controller.text);
|
||||||
|
|
||||||
if (results == null) return;
|
if (results == null) return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user