1
0
mirror of https://gitlab.com/comunic/comunicmobile synced 2024-11-22 12:59:21 +00:00

Can remove members from conversation

This commit is contained in:
Pierre HUBERT 2021-03-13 10:48:59 +01:00
parent ba60fa9e37
commit 5d0ead5889
3 changed files with 71 additions and 29 deletions

View File

@ -49,6 +49,15 @@ class ConversationsHelper {
return response.getObject()["conversationID"]; return response.getObject()["conversationID"];
} }
/// Remove a member from a conversation.
///
/// Throws in case of failure
static Future<void> removeMember(int convID, int userID) async =>
await APIRequest.withLogin("conversations/removeMember")
.addInt("convID", convID)
.addInt("userID", userID)
.execWithThrow();
/// Update an existing conversation /// Update an existing conversation
/// ///
/// Throws in case of failure /// Throws in case of failure

View File

@ -10,6 +10,7 @@ import 'package:comunic/ui/tiles/simple_user_tile.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';
import 'package:comunic/ui/widgets/pick_user_widget.dart'; import 'package:comunic/ui/widgets/pick_user_widget.dart';
import 'package:comunic/utils/account_utils.dart';
import 'package:comunic/utils/color_utils.dart'; import 'package:comunic/utils/color_utils.dart';
import 'package:comunic/utils/dart_color.dart'; import 'package:comunic/utils/dart_color.dart';
import 'package:comunic/utils/intl_utils.dart'; import 'package:comunic/utils/intl_utils.dart';
@ -21,7 +22,7 @@ import 'package:flutter/material.dart';
/// ///
/// @author Pierre HUBERT /// @author Pierre HUBERT
enum _MembersMenuChoices { REMOVE } enum _MembersMenuChoices { TOGGLE_ADMIN_STATUS, REMOVE }
class UpdateConversationScreen extends StatefulWidget { class UpdateConversationScreen extends StatefulWidget {
final convID; final convID;
@ -67,13 +68,17 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
get _isValid => _members.length > 0; get _isValid => _members.length > 0;
Future<void> _init() async { Future<void> _init() async {
if (!isUpdating) return; if (!isUpdating) {
_admins.add(userID());
return;
}
_conversation = _conversation =
await ConversationsHelper().getSingle(widget.convID, force: true); await ConversationsHelper().getSingle(widget.convID, force: true);
_nameController.text = _conversation.name ?? ""; _nameController.text = _conversation.name ?? "";
_colorController.text = _colorController.text =
_conversationColor == null ? "" : "#${_conversation.color}"; _conversationColor == null ? "" : "#${colorToHex(_conversation.color)}";
_members = await UsersHelper().getList(_conversation.membersID); _members = await UsersHelper().getList(_conversation.membersID);
_admins = _conversation.adminsID; _admins = _conversation.adminsID;
_followConversation = _conversation.following; _followConversation = _conversation.following;
@ -172,29 +177,7 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
//Conversation members //Conversation members
Column( Column(
children: _members children: _members.map((f) => _buildMemberTile(f)).toList(),
.map((f) => SimpleUserTile(
user: f,
trailing: _canAddMembers
? PopupMenuButton<_MembersMenuChoices>(
captureInheritedThemes: false,
onSelected: (choice) =>
_membersMenuItemSelected(f, choice),
itemBuilder: (c) =>
<PopupMenuEntry<_MembersMenuChoices>>[
PopupMenuItem(
child: Text(tr("Remove")),
value: _MembersMenuChoices.REMOVE,
enabled: isAdmin ||
(_canEveryoneAddMembers &&
!_conversation.membersID
.contains(f.id)),
)
],
)
: null,
))
.toList(),
), ),
], ],
), ),
@ -202,6 +185,29 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
); );
} }
Widget _buildMemberTile(User user) => SimpleUserTile(
user: user,
subtitle: _admins.contains(user.id) ? tr("Admin") : tr("Member"),
trailing: _canAddMembers
? PopupMenuButton<_MembersMenuChoices>(
captureInheritedThemes: false,
onSelected: (choice) => _membersMenuItemSelected(user, choice),
itemBuilder: (c) => <PopupMenuEntry<_MembersMenuChoices>>[
PopupMenuItem(
child: Text(tr("Toggle admin status")),
value: _MembersMenuChoices.TOGGLE_ADMIN_STATUS,
enabled: isUpdating && isAdmin && user.id != userID(),
),
PopupMenuItem(
child: Text(tr("Remove")),
value: _MembersMenuChoices.REMOVE,
enabled: isAdmin && user.id != userID(),
),
],
)
: null,
);
void _pickColor() async { void _pickColor() async {
final color = await showColorPickerDialog(context, _color); final color = await showColorPickerDialog(context, _color);
setState(() => setState(() =>
@ -212,10 +218,30 @@ class _UpdateConversationScreen extends State<UpdateConversationScreen> {
void _membersMenuItemSelected(User user, _MembersMenuChoices choice) { void _membersMenuItemSelected(User user, _MembersMenuChoices choice) {
if (choice == null) return; if (choice == null) return;
if (choice == _MembersMenuChoices.REMOVE) switch (choice) {
case _MembersMenuChoices.REMOVE:
_removeMember(user);
break;
case _MembersMenuChoices.TOGGLE_ADMIN_STATUS:
// TODO: Handle this case.
break;
}
}
void _removeMember(User user) async {
try {
if (isUpdating)
await ConversationsHelper.removeMember(_conversation.id, user.id);
setState(() { setState(() {
_members.removeWhere((u) => u.id == user.id); _members.removeWhere((u) => u.id == user.id);
_admins.remove(user.id);
}); });
} catch (e, s) {
logError(e, s);
snack(context, tr("Failed to remove member!"));
}
} }
/// Submit the conversation /// Submit the conversation

View File

@ -14,9 +14,15 @@ class SimpleUserTile extends StatelessWidget {
final User user; final User user;
final OnUserTap onTap; final OnUserTap onTap;
final Widget trailing; final Widget trailing;
final String subtitle;
const SimpleUserTile({Key key, this.user, this.onTap, this.trailing}) const SimpleUserTile({
: assert(user != null), Key key,
this.user,
this.onTap,
this.trailing,
this.subtitle,
}) : assert(user != null),
super(key: key); super(key: key);
@override @override
@ -27,6 +33,7 @@ class SimpleUserTile extends StatelessWidget {
user: user, user: user,
), ),
title: Text(user.fullName), title: Text(user.fullName),
subtitle: subtitle == null ? null : Text(subtitle),
trailing: trailing, trailing: trailing,
); );
} }