diff --git a/lib/helpers/groups_helper.dart b/lib/helpers/groups_helper.dart index dd7b645..b98ceda 100644 --- a/lib/helpers/groups_helper.dart +++ b/lib/helpers/groups_helper.dart @@ -1,9 +1,11 @@ import 'dart:typed_data'; +import 'package:comunic/helpers/conversations_helper.dart'; import 'package:comunic/lists/group_members_list.dart'; import 'package:comunic/lists/groups_list.dart'; import 'package:comunic/models/advanced_group_info.dart'; import 'package:comunic/models/api_request.dart'; +import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/group.dart'; import 'package:comunic/models/group_membership.dart'; import 'package:comunic/models/new_group_conversation.dart'; @@ -345,6 +347,20 @@ class GroupsHelper { .addString("name", conv.name) .execWithThrow(); + /// Set new conversation visibility level + /// + /// Throws in case of failure + static Future setConversationVisibility( + int convID, GroupMembershipLevel newLevel) async => + await APIRequest.withLogin("groups/set_conversation_visibility") + .addInt("conv_id", convID) + .addString( + "min_membership_level", + APIGroupsMembershipLevelsMap.entries + .firstWhere((e) => e.value == newLevel) + .key) + .execWithThrow(); + /// Turn an API entry into a group object Group _getGroupFromAPI(Map map) { return Group( @@ -381,6 +397,10 @@ class GroupsHelper { url: nullToEmpty(map["url"]), likes: map["number_likes"], userLike: map["is_liking"], + conversations: map["conversations"] + .map((s) => ConversationsHelper.apiToConversation(s)) + .cast() + .toList(), ); /// Create [GroupMembership] object from API entry diff --git a/lib/models/advanced_group_info.dart b/lib/models/advanced_group_info.dart index 5b9e897..f2eb9c2 100644 --- a/lib/models/advanced_group_info.dart +++ b/lib/models/advanced_group_info.dart @@ -35,6 +35,7 @@ class AdvancedGroupInfo extends Group implements LikeElement { @required this.url, @required this.likes, @required this.userLike, + @required this.conversations, }) : super( id: id, name: name, diff --git a/lib/models/conversation.dart b/lib/models/conversation.dart index d33f569..ba4d70e 100644 --- a/lib/models/conversation.dart +++ b/lib/models/conversation.dart @@ -77,6 +77,8 @@ class Conversation extends SerializableElement { /// Check out whether a conversation is managed or not bool get isManaged => groupID != null; + bool get hasLogo => logoURL != null; + Conversation.fromJson(Map map) : id = map["id"], name = map["name"], diff --git a/lib/ui/screens/group_settings_screen.dart b/lib/ui/screens/group_settings_screen.dart index f5ba96d..18ca71c 100644 --- a/lib/ui/screens/group_settings_screen.dart +++ b/lib/ui/screens/group_settings_screen.dart @@ -1,8 +1,10 @@ import 'dart:typed_data'; +import 'package:cached_network_image/cached_network_image.dart'; import 'package:comunic/helpers/groups_helper.dart'; import 'package:comunic/helpers/server_config_helper.dart'; import 'package:comunic/models/advanced_group_info.dart'; +import 'package:comunic/models/conversation.dart'; import 'package:comunic/models/group.dart'; import 'package:comunic/models/new_group_conversation.dart'; import 'package:comunic/ui/dialogs/input_user_password_dialog.dart'; @@ -284,12 +286,34 @@ class _GroupSettingsScreenState extends SafeState { SettingsSection _buildConversationsArea() => SettingsSection( title: tr("Group conversations"), - tiles: [ - SettingsTile( - title: tr("Create a new conversation"), - onPressed: _createNewGroupConversation, - ), - ], + tiles: _groupSettings.conversations + .map( + (e) { + SettingsTile tile = + MultiChoicesSettingsTile( + title: e.name, + choices: _conversationMinMembershipLevel, + currentValue: e.groupMinMembershipLevel, + leading: e.hasLogo + ? CachedNetworkImage( + imageUrl: e.logoURL, + width: 30, + ) + : Icon(Icons.group, size: 30), + onChanged: (c) => _changeConversationVisibility(e, c), + ); + + return tile; + }, + ) + .toList() + .cast() + ..add( + SettingsTile( + title: tr("Create a new conversation"), + onPressed: _createNewGroupConversation, + ), + ), ); void _createNewGroupConversation(BuildContext context) async { @@ -329,6 +353,18 @@ class _GroupSettingsScreenState extends SafeState { } } + void _changeConversationVisibility( + Conversation conv, GroupMembershipLevel newLevel) async { + try { + await GroupsHelper.setConversationVisibility(conv.id, newLevel); + + _key.currentState.refresh(); + } catch (e, s) { + logError(e, s); + snack(context, tr("Failed to change conversation visibility level!")); + } + } + Widget _buildGroupLogoArea() { return SettingsSection( title: tr("Group logo"), diff --git a/lib/ui/widgets/settings/multi_choices_settings_tile.dart b/lib/ui/widgets/settings/multi_choices_settings_tile.dart index ab81ab0..0e6119a 100644 --- a/lib/ui/widgets/settings/multi_choices_settings_tile.dart +++ b/lib/ui/widgets/settings/multi_choices_settings_tile.dart @@ -11,6 +11,8 @@ class MultiChoicesSettingsTile extends SettingsTile { final List> choices; final T currentValue; final Function(T) onChanged; + final Widget leading; + final Widget trailing; const MultiChoicesSettingsTile({ Key key, @@ -18,6 +20,8 @@ class MultiChoicesSettingsTile extends SettingsTile { @required this.choices, @required this.currentValue, @required this.onChanged, + this.leading, + this.trailing, }) : assert(title != null), assert(choices != null), assert(currentValue != null), @@ -26,6 +30,8 @@ class MultiChoicesSettingsTile extends SettingsTile { @override Widget build(BuildContext context) { return SettingsTile( + leading: leading, + trailing: trailing, title: title, subtitle: choices.firstWhere((f) => f.id == currentValue).title, onPressed: (_) => _changeValue(context),