diff --git a/lib/helpers/conversations_helper.dart b/lib/helpers/conversations_helper.dart index 1b7c39d..04c6474 100644 --- a/lib/helpers/conversations_helper.dart +++ b/lib/helpers/conversations_helper.dart @@ -100,6 +100,15 @@ class ConversationsHelper { .removeElement((t) => t.id == settings.convID); } + /// Set a new conversation logo + /// + /// Throws in case of failure + static Future changeImage(int convID, BytesFile file) async => + await APIRequest.withLogin("conversations/change_image") + .addInt("convID", convID) + .addBytesFile("file", file) + .execWithFilesAndThrow(); + /// Delete a conversation specified by its [id] Future deleteConversation(int id) async => await APIRequest.withLogin("conversations/delete") diff --git a/lib/helpers/server_config_helper.dart b/lib/helpers/server_config_helper.dart index 6b8ee9f..e1e7cc8 100644 --- a/lib/helpers/server_config_helper.dart +++ b/lib/helpers/server_config_helper.dart @@ -64,6 +64,8 @@ class ServerConfigurationHelper { conversationsPolicy["max_message_image_height"], maxThumbnailWidth: conversationsPolicy["max_thumbnail_width"], maxThumbnailHeight: conversationsPolicy["max_thumbnail_height"], + maxLogoWidth: conversationsPolicy["max_logo_width"], + maxLogoHeight: conversationsPolicy["max_logo_height"], )); } diff --git a/lib/models/server_config.dart b/lib/models/server_config.dart index f2301f5..ea47a41 100644 --- a/lib/models/server_config.dart +++ b/lib/models/server_config.dart @@ -68,6 +68,8 @@ class ConversationsPolicy { final int maxMessageImageHeight; final int maxThumbnailWidth; final int maxThumbnailHeight; + final int maxLogoWidth; + final int maxLogoHeight; const ConversationsPolicy({ @required this.minMessageLen, @@ -80,6 +82,8 @@ class ConversationsPolicy { @required this.maxMessageImageHeight, @required this.maxThumbnailWidth, @required this.maxThumbnailHeight, + @required this.maxLogoWidth, + @required this.maxLogoHeight, }) : assert(minMessageLen != null), assert(maxMessageLen != null), assert(allowedFilesType != null), @@ -89,7 +93,9 @@ class ConversationsPolicy { assert(maxMessageImageWidth != null), assert(maxMessageImageHeight != null), assert(maxThumbnailWidth != null), - assert(maxThumbnailHeight != null); + assert(maxThumbnailHeight != null), + assert(maxLogoWidth != null), + assert(maxLogoHeight != null); } class ServerConfig { diff --git a/lib/ui/dialogs/pick_file_dialog.dart b/lib/ui/dialogs/pick_file_dialog.dart index cb7cd1c..d058021 100644 --- a/lib/ui/dialogs/pick_file_dialog.dart +++ b/lib/ui/dialogs/pick_file_dialog.dart @@ -173,7 +173,7 @@ Future showPickFileDialog({ if (file == null) return null; // Check file size - if (file.bytes.length > maxFileSize) { + if (maxFileSize != null && file.bytes.length > maxFileSize) { showSimpleSnack( context, tr("This file could not be sent: it is too big! (Max allowed size: %1%)", diff --git a/lib/ui/screens/update_conversation_screen.dart b/lib/ui/screens/update_conversation_screen.dart index d5c2ff0..e7d3346 100644 --- a/lib/ui/screens/update_conversation_screen.dart +++ b/lib/ui/screens/update_conversation_screen.dart @@ -1,4 +1,6 @@ +import 'package:cached_network_image/cached_network_image.dart'; import 'package:comunic/helpers/conversations_helper.dart'; +import 'package:comunic/helpers/server_config_helper.dart'; import 'package:comunic/helpers/users_helper.dart'; import 'package:comunic/lists/users_list.dart'; import 'package:comunic/models/conversation.dart'; @@ -6,6 +8,7 @@ import 'package:comunic/models/new_conversation.dart'; import 'package:comunic/models/new_conversation_settings.dart'; import 'package:comunic/models/user.dart'; import 'package:comunic/ui/dialogs/color_picker_dialog.dart'; +import 'package:comunic/ui/dialogs/pick_file_dialog.dart'; import 'package:comunic/ui/routes/main_route/main_route.dart'; import 'package:comunic/ui/tiles/simple_user_tile.dart'; import 'package:comunic/ui/widgets/async_screen_widget.dart'; @@ -46,6 +49,7 @@ class _UpdateConversationScreen extends State { Set _admins = Set(); bool _followConversation = true; bool _canEveryoneAddMembers = true; + String _image; String get _conversationColor => _colorController.text; @@ -87,6 +91,7 @@ class _UpdateConversationScreen extends State { _admins = _conversation.adminsID; _followConversation = _conversation.following; _canEveryoneAddMembers = _conversation.canEveryoneAddMembers; + _image = _conversation.logoURL; setState(() {}); } @@ -170,6 +175,9 @@ class _UpdateConversationScreen extends State { ], ), + // Conversation image + isUpdating ? _buildConversationImageWidget() : Container(), + // Add a member to the conversation PickUserWidget( resetOnChoose: true, @@ -314,4 +322,48 @@ class _UpdateConversationScreen extends State { snack(context, tr("Failed to update conversation settings!")); } } + + /// Conversation image management + Widget _buildConversationImageWidget() => Column( + children: [ + SizedBox(height: 10), + Text(tr("Conversation logo"), + style: TextStyle(fontWeight: FontWeight.bold)), + SizedBox(height: 5), + _image == null + ? Text("No logo defined yet.") + : CachedNetworkImage(imageUrl: _image), + SizedBox(height: 5), + isAdmin + ? OutlineButton( + onPressed: _uploadNewLogo, + child: Text(tr("Change logo")), + ) + : Container(), + SizedBox(height: 10), + ], + ); + + /// Upload new conversation logo + Future _uploadNewLogo() async { + try { + final newLogo = await showPickFileDialog( + context: context, + allowedMimeTypes: ["image/png", "image/jpeg", "image/gif"], + imageMaxWidth: srvConfig.conversationsPolicy.maxLogoWidth, + imageMaxHeight: srvConfig.conversationsPolicy.maxLogoHeight, + ); + + if (newLogo == null) return; + + await ConversationsHelper.changeImage(_conversation.id, newLogo); + + final newConvSettings = + await ConversationsHelper().getSingle(_conversation.id, force: true); + setState(() => _image = newConvSettings.logoURL); + } catch (e, s) { + logError(e, s); + snack(context, tr("Failed to change conversation logo !")); + } + } }