From b40fab98269be023f10bcdd773d2d3698fbdb9a3 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Tue, 16 Aug 2022 21:50:14 +0200 Subject: [PATCH 1/5] delete expired messages Signed-off-by: Marcel Hibbe --- .../talk/controllers/ChatController.kt | 23 +++++++++++++ .../talk/models/json/chat/ChatMessage.kt | 32 +++++++------------ .../talk/models/json/chat/ChatUtils.kt | 26 ++++++++------- .../models/json/conversations/Conversation.kt | 8 ++++- 4 files changed, 57 insertions(+), 32 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index 51746d841..ae05049f5 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -2216,6 +2216,8 @@ class ChatController(args: Bundle) : // since this is called asynchrously and UI might have been destroyed in the meantime Log.i(TAG, "UI destroyed - view binding already gone") } + + deleteExpiredMessages() } override fun onError(e: Throwable) { @@ -2256,6 +2258,8 @@ class ChatController(args: Bundle) : // since this is called asynchrously and UI might have been destroyed in the meantime Log.i(TAG, "UI destroyed - view binding already gone", e) } + + deleteExpiredMessages() } override fun onError(e: Throwable) { @@ -2270,6 +2274,24 @@ class ChatController(args: Bundle) : } } + private fun deleteExpiredMessages() { + if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")) { + val messagesToDelete: ArrayList = ArrayList() + val systemTime = System.currentTimeMillis() / ONE_SECOND_IN_MILLIS + + for (itemWrapper in adapter?.items!!) { + if (itemWrapper.item is ChatMessage) { + val chatMessage = itemWrapper.item as ChatMessage + if (chatMessage.expirationTimestamp != 0 && chatMessage.expirationTimestamp < systemTime) { + messagesToDelete.add(chatMessage) + } + } + } + adapter!!.delete(messagesToDelete) + adapter!!.notifyDataSetChanged() + } + } + private fun processMessages(response: Response<*>, isFromTheFuture: Boolean, timeout: Int) { val xChatLastGivenHeader: String? = response.headers().get("X-Chat-Last-Given") val xChatLastCommonRead = response.headers().get("X-Chat-Last-Common-Read")?.let { @@ -3252,5 +3274,6 @@ class ChatController(args: Bundle) : private const val RETRIES: Long = 3 private const val LOOKING_INTO_FUTURE_TIMEOUT = 30 private const val CHUNK_SIZE: Int = 10 + private const val ONE_SECOND_IN_MILLIS = 1000 } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt index 1d68ce625..8f7fd7814 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt @@ -112,6 +112,9 @@ data class ChatMessage( @JsonField(name = ["reactionsSelf"]) var reactionsSelf: ArrayList? = null, + @JsonField(name = ["expirationTimestamp"]) + var expirationTimestamp: Int = 0, + var isDownloadingVoiceMessage: Boolean = false, var resetVoiceMessage: Boolean = false, @@ -141,11 +144,7 @@ data class ChatMessage( fun hasFileAttachment(): Boolean { if (messageParameters != null && messageParameters!!.size > 0) { for ((_, individualHashMap) in messageParameters!!) { - if (MessageDigest.isEqual( - individualHashMap["type"]!!.toByteArray(), - "file".toByteArray() - ) - ) { + if (isHashMapEntryEqualTo(individualHashMap, "type", "file")) { return true } } @@ -156,11 +155,7 @@ data class ChatMessage( fun hasGeoLocation(): Boolean { if (messageParameters != null && messageParameters!!.size > 0) { for ((_, individualHashMap) in messageParameters!!) { - if (MessageDigest.isEqual( - individualHashMap["type"]!!.toByteArray(), - "geo-location".toByteArray() - ) - ) { + if (isHashMapEntryEqualTo(individualHashMap, "type", "geo-location")) { return true } } @@ -171,11 +166,7 @@ data class ChatMessage( fun isPoll(): Boolean { if (messageParameters != null && messageParameters!!.size > 0) { for ((_, individualHashMap) in messageParameters!!) { - if (MessageDigest.isEqual( - individualHashMap["type"]!!.toByteArray(), - "talk-poll".toByteArray() - ) - ) { + if (isHashMapEntryEqualTo(individualHashMap, "type", "talk-poll")) { return true } } @@ -183,14 +174,11 @@ data class ChatMessage( return false } + @Suppress("Detekt.NestedBlockDepth") override fun getImageUrl(): String? { if (messageParameters != null && messageParameters!!.size > 0) { for ((_, individualHashMap) in messageParameters!!) { - if (MessageDigest.isEqual( - individualHashMap["type"]!!.toByteArray(), - "file".toByteArray() - ) - ) { + if (isHashMapEntryEqualTo(individualHashMap, "type", "file")) { // FIX-ME: this selectedIndividualHashMap stuff needs to be analyzed and most likely be refactored! // it just feels wrong to fill this here inside getImageUrl() selectedIndividualHashMap = individualHashMap @@ -420,6 +408,10 @@ data class ChatMessage( return EnumSystemMessageTypeConverter().convertToString(systemMessageType) } + private fun isHashMapEntryEqualTo(map: HashMap, key: String, searchTerm: String): Boolean { + return map != null && MessageDigest.isEqual(map[key]!!.toByteArray(), searchTerm.toByteArray()) + } + val isVoiceMessage: Boolean get() = "voice-message" == messageType val isCommandMessage: Boolean diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatUtils.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatUtils.kt index c1251ae49..d6d1d6869 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatUtils.kt @@ -34,6 +34,7 @@ class ChatUtils { return message } + @Suppress("Detekt.ComplexMethod") private fun parse( messageParameters: HashMap>, message: String? @@ -41,19 +42,22 @@ class ChatUtils { var resultMessage = message for (key in messageParameters.keys) { val individualHashMap = messageParameters[key] - val type = individualHashMap?.get("type") - if (type == "user" || type == "guest" || type == "call") { - resultMessage = resultMessage?.replace("{$key}", "@" + individualHashMap["name"]) - } else if (type == "geo-location") { - resultMessage = individualHashMap.get("name") - } else if (individualHashMap?.containsKey("link") == true) { - resultMessage = if (type == "file") { - resultMessage?.replace("{$key}", individualHashMap["name"].toString()) + + if (individualHashMap != null) { + val type = individualHashMap["type"] + resultMessage = if (type == "user" || type == "guest" || type == "call") { + resultMessage?.replace("{$key}", "@" + individualHashMap["name"]) + } else if (type == "geo-location") { + individualHashMap["name"] + } else if (individualHashMap?.containsKey("link") == true) { + if (type == "file") { + resultMessage?.replace("{$key}", individualHashMap["name"].toString()) + } else { + individualHashMap["link"].toString() + } } else { - individualHashMap["link"].toString() + individualHashMap["name"]?.let { resultMessage?.replace("{$key}", it) } } - } else { - resultMessage = individualHashMap?.get("name")?.let { resultMessage?.replace("{$key}", it) } } } return resultMessage diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt index c351ba8f2..54e1559c7 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/Conversation.kt @@ -4,6 +4,8 @@ * @author Mario Danic * @author Tim Krüger * @author Andy Scherzinger + * @author Marcel Hibbe + * Copyright (C) 2022 Marcel Hibbe * Copyright (C) 2022 Andy Scherzinger * Copyright (C) 2021 Tim Krüger * Copyright (C) 2017 Mario Danic (mario@lovelyhq.com) @@ -122,7 +124,11 @@ data class Conversation( var notificationCalls: Int? = null, @JsonField(name = ["permissions"]) - var permissions: Int = 0 + var permissions: Int = 0, + + @JsonField(name = ["messageExpiration"]) + var messageExpiration: Int = 0 + ) : Parcelable { // This constructor is added to work with the 'com.bluelinelabs.logansquare.annotation.JsonObject' constructor() : this(null, null) From 77f69a676b402d53e380e7f2c8035efe2c6ee3b1 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Thu, 18 Aug 2022 09:34:43 +0200 Subject: [PATCH 2/5] add system messages for message expiration Signed-off-by: Marcel Hibbe --- .../java/com/nextcloud/talk/models/json/chat/ChatMessage.kt | 4 +++- .../json/converters/EnumSystemMessageTypeConverter.kt | 6 ++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt index 8f7fd7814..173c32c14 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/chat/ChatMessage.kt @@ -484,7 +484,9 @@ data class ChatMessage( REACTION_DELETED, REACTION_REVOKED, POLL_VOTED, - POLL_CLOSED + POLL_CLOSED, + MESSAGE_EXPIRATION_ENABLED, + MESSAGE_EXPIRATION_DISABLED, } companion object { diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt index cf691d9da..371e83338 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/EnumSystemMessageTypeConverter.kt @@ -60,6 +60,8 @@ import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MATTERB import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MATTERBRIDGE_CONFIG_ENABLED import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MATTERBRIDGE_CONFIG_REMOVED import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MESSAGE_DELETED +import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MESSAGE_EXPIRATION_DISABLED +import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MESSAGE_EXPIRATION_ENABLED import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MODERATOR_DEMOTED import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.MODERATOR_PROMOTED import com.nextcloud.talk.models.json.chat.ChatMessage.SystemMessageType.OBJECT_SHARED @@ -171,6 +173,8 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter REACTION_REVOKED "poll_voted" -> POLL_VOTED "poll_closed" -> POLL_CLOSED + "message_expiration_enabled" -> MESSAGE_EXPIRATION_ENABLED + "message_expiration_disabled" -> MESSAGE_EXPIRATION_DISABLED else -> DUMMY } } @@ -226,6 +230,8 @@ class EnumSystemMessageTypeConverter : StringBasedTypeConverter "reaction_revoked" POLL_VOTED -> "poll_voted" POLL_CLOSED -> "poll_closed" + MESSAGE_EXPIRATION_ENABLED -> "message_expiration_enabled" + MESSAGE_EXPIRATION_DISABLED -> "message_expiration_disabled" else -> "" } } From 4bdb78372e0ed8a3a8ba9c8a9025f9d084b38b97 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Thu, 18 Aug 2022 20:56:03 +0200 Subject: [PATCH 3/5] add expiring messages option in conversation info screen Signed-off-by: Marcel Hibbe --- .../java/com/nextcloud/talk/api/NcApi.java | 6 + .../talk/controllers/ChatController.kt | 12 +- .../controllers/ConversationInfoController.kt | 13 ++ .../com/nextcloud/talk/utils/ApiUtils.java | 6 +- .../DatabaseStorageModule.java | 153 ++++++++++++------ .../layout/controller_conversation_info.xml | 125 ++++++++------ app/src/main/res/values/arrays.xml | 20 +++ app/src/main/res/values/strings.xml | 14 ++ 8 files changed, 244 insertions(+), 105 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/api/NcApi.java b/app/src/main/java/com/nextcloud/talk/api/NcApi.java index 5a531f5c7..e4bcbfd67 100644 --- a/app/src/main/java/com/nextcloud/talk/api/NcApi.java +++ b/app/src/main/java/com/nextcloud/talk/api/NcApi.java @@ -550,4 +550,10 @@ public interface NcApi { @DELETE Observable closePoll(@Header("Authorization") String authorization, @Url String url); + + @FormUrlEncoded + @POST + Observable setMessageExpiration(@Header("Authorization") String authorization, + @Url String url, + @Field("seconds") Integer seconds); } diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt index ae05049f5..8ea577f05 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ChatController.kt @@ -2217,7 +2217,7 @@ class ChatController(args: Bundle) : Log.i(TAG, "UI destroyed - view binding already gone") } - deleteExpiredMessages() + processExpiredMessages() } override fun onError(e: Throwable) { @@ -2259,7 +2259,7 @@ class ChatController(args: Bundle) : Log.i(TAG, "UI destroyed - view binding already gone", e) } - deleteExpiredMessages() + processExpiredMessages() } override fun onError(e: Throwable) { @@ -2274,8 +2274,8 @@ class ChatController(args: Bundle) : } } - private fun deleteExpiredMessages() { - if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")) { + private fun processExpiredMessages() { + fun deleteExpiredMessages() { val messagesToDelete: ArrayList = ArrayList() val systemTime = System.currentTimeMillis() / ONE_SECOND_IN_MILLIS @@ -2290,6 +2290,10 @@ class ChatController(args: Bundle) : adapter!!.delete(messagesToDelete) adapter!!.notifyDataSetChanged() } + + if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")) { + deleteExpiredMessages() + } } private fun processMessages(response: Response<*>, isFromTheFuture: Boolean, timeout: Int) { diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index d1db00a1c..5e86e27d3 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -677,6 +677,7 @@ class ConversationInfoController(args: Bundle) : loadConversationAvatar() adjustNotificationLevelUI() + initExpiringMessageOption() binding.notificationSettingsView.notificationSettings.visibility = View.VISIBLE } @@ -697,6 +698,18 @@ class ConversationInfoController(args: Bundle) : }) } + private fun initExpiringMessageOption() { + if (conversation!!.isParticipantOwnerOrModerator && + CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration") + ) { + databaseStorageModule?.setMessageExpiration(conversation!!.messageExpiration) + binding.conversationInfoExpireMessages.setStorageModule(databaseStorageModule) + binding.conversationInfoExpireMessages.visibility = View.VISIBLE + } else { + binding.categoryConversationSettings.visibility = View.GONE + } + } + private fun adjustNotificationLevelUI() { if (conversation != null) { if ( diff --git a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java index ff28cf031..c79e3185c 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java +++ b/app/src/main/java/com/nextcloud/talk/utils/ApiUtils.java @@ -147,7 +147,7 @@ public class ApiUtils { return version; } if (version == APIv1 && - user.hasSpreedFeatureCapability( "mention-flag") && + user.hasSpreedFeatureCapability("mention-flag") && !user.hasSpreedFeatureCapability("conversation-v4")) { return version; } @@ -479,4 +479,8 @@ public class ApiUtils { return baseUrl + ocsApiVersion + spreedApiVersion + "/poll/" + roomToken; } + public static String getUrlForMessageExpiration(int version, String baseUrl, String token) { + return getUrlForRoom(version, baseUrl, token) + "/message-expiration"; + } + } diff --git a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java index 38ec20d5c..b38ee30c7 100644 --- a/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java +++ b/app/src/main/java/com/nextcloud/talk/utils/preferences/preferencestorage/DatabaseStorageModule.java @@ -60,6 +60,7 @@ public class DatabaseStorageModule implements StorageModule { @Inject NcApi ncApi; + private int messageExpiration; private final User conversationUser; private final String conversationToken; private final long accountIdentifier; @@ -78,7 +79,7 @@ public class DatabaseStorageModule implements StorageModule { @Override public void saveBoolean(String key, boolean value) { - if(key.equals("call_notifications")) { + if (key.equals("call_notifications")) { int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4}); ncApi.notificationCalls(ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()), @@ -89,27 +90,27 @@ public class DatabaseStorageModule implements StorageModule { .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Observer() { - @Override - public void onSubscribe(@NotNull Disposable d) { - // unused atm - } + @Override + public void onSubscribe(@NotNull Disposable d) { + // unused atm + } - @Override - public void onNext(@NotNull GenericOverall genericOverall) { - Log.d(TAG, "Toggled notification calls"); - } + @Override + public void onNext(@NotNull GenericOverall genericOverall) { + Log.d(TAG, "Toggled notification calls"); + } - @Override - public void onError(@NotNull Throwable e) { - Log.e(TAG, "Error when trying to toggle notification calls", e); - } + @Override + public void onError(@NotNull Throwable e) { + Log.e(TAG, "Error when trying to toggle notification calls", e); + } - @Override - public void onComplete() { - // unused atm - } - } - ); + @Override + public void onComplete() { + // unused atm + } + } + ); } if (!key.equals("conversation_lobby")) { @@ -124,9 +125,46 @@ public class DatabaseStorageModule implements StorageModule { @Override public void saveString(String key, String value) { - if (!key.equals("message_notification_level")) { - arbitraryStorageManager.storeStorageSetting(accountIdentifier, key, value, conversationToken); - } else { + if (key.equals("message_expire_key")) { + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{4}); + + String trimmedValue = value.replace("expire_", ""); + int valueInt = Integer.parseInt(trimmedValue); + + ncApi.setMessageExpiration( + ApiUtils.getCredentials( + conversationUser.getUsername(), + conversationUser.getToken()), + ApiUtils.getUrlForMessageExpiration( + apiVersion, + conversationUser.getBaseUrl(), + conversationToken), + valueInt) + .subscribeOn(Schedulers.io()) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe(new Observer() { + @Override + public void onSubscribe(@NotNull Disposable d) { + // unused atm + } + + @Override + public void onNext(@NotNull GenericOverall genericOverall) { + messageExpiration = valueInt; + } + + @Override + public void onError(@NotNull Throwable e) { + Log.e(TAG, "Error when trying to set message expiration", e); + } + + @Override + public void onComplete() { + // unused atm + } + }); + + } else if (key.equals("message_notification_level")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")) { if (!TextUtils.isEmpty(messageNotificationLevel) && !messageNotificationLevel.equals(value)) { int intValue; @@ -144,40 +182,42 @@ public class DatabaseStorageModule implements StorageModule { intValue = 0; } - int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[] {ApiUtils.APIv4, 1}); + int apiVersion = ApiUtils.getConversationApiVersion(conversationUser, new int[]{ApiUtils.APIv4, 1}); ncApi.setNotificationLevel(ApiUtils.getCredentials(conversationUser.getUsername(), conversationUser.getToken()), - ApiUtils.getUrlForRoomNotificationLevel(apiVersion, - conversationUser.getBaseUrl(), - conversationToken), - intValue) - .subscribeOn(Schedulers.io()) - .subscribe(new Observer() { - @Override - public void onSubscribe(Disposable d) { - // unused atm - } + ApiUtils.getUrlForRoomNotificationLevel(apiVersion, + conversationUser.getBaseUrl(), + conversationToken), + intValue) + .subscribeOn(Schedulers.io()) + .subscribe(new Observer() { + @Override + public void onSubscribe(Disposable d) { + // unused atm + } - @Override - public void onNext(GenericOverall genericOverall) { - messageNotificationLevel = value; - } + @Override + public void onNext(GenericOverall genericOverall) { + messageNotificationLevel = value; + } - @Override - public void onError(Throwable e) { - // unused atm - } + @Override + public void onError(Throwable e) { + // unused atm + } - @Override - public void onComplete() { - // unused atm - } - }); + @Override + public void onComplete() { + // unused atm + } + }); } else { messageNotificationLevel = value; } } + } else { + arbitraryStorageManager.storeStorageSetting(accountIdentifier, key, value, conversationToken); } } @@ -205,7 +245,22 @@ public class DatabaseStorageModule implements StorageModule { @Override public String getString(String key, String defaultVal) { - if (key.equals("message_notification_level")) { + if (key.equals("message_expire_key")) { + switch (messageExpiration) { + case 2419200: + return "expire_2419200"; + case 604800: + return "expire_604800"; + case 86400: + return "expire_86400"; + case 28800: + return "expire_28800"; + case 3600: + return "expire_3600"; + default: + return "expire_0"; + } + } else if (key.equals("message_notification_level")) { return messageNotificationLevel; } else { return arbitraryStorageManager @@ -243,4 +298,8 @@ public class DatabaseStorageModule implements StorageModule { public void onRestoreInstanceState(Bundle savedState) { // unused atm } + + public void setMessageExpiration(int messageExpiration) { + this.messageExpiration = messageExpiration; + } } diff --git a/app/src/main/res/layout/controller_conversation_info.xml b/app/src/main/res/layout/controller_conversation_info.xml index 42944cdd3..3f924d4ba 100644 --- a/app/src/main/res/layout/controller_conversation_info.xml +++ b/app/src/main/res/layout/controller_conversation_info.xml @@ -3,6 +3,8 @@ ~ ~ @author Mario Danic ~ @author Andy Scherzinger + ~ @author Marcel Hibbe + ~ Copyright (C) 2022 Marcel Hibbe ~ Copyright (C) 2021 Andy Scherzinger ~ Copyright (C) 2017-2018 Mario Danic ~ @@ -45,9 +47,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content"> - + android:layout_height="wrap_content" + android:orientation="vertical"> + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 39bd83373..914ed67e3 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -3,6 +3,8 @@ ~ Nextcloud Talk application ~ ~ @author Mario Danic + ~ @author Marcel Hibbe + ~ Copyright (C) 2022 Marcel Hibbe ~ Copyright (C) 2017 Mario Danic ~ ~ This program is free software: you can redistribute it and/or modify @@ -39,6 +41,24 @@ always + + @string/nc_expire_message_off + @string/nc_expire_message_four_weeks + @string/nc_expire_message_one_week + @string/nc_expire_message_one_day + @string/nc_expire_message_eight_hours + @string/nc_expire_message_one_hour + + + + expire_0 + expire_2419200 + expire_604800 + expire_86400 + expire_28800 + expire_3600 + + @string/nc_screen_lock_timeout_30 @string/nc_screen_lock_timeout_60 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1322cb462..2c8f1fc79 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -3,6 +3,8 @@ ~ ~ @author Mario Danic ~ @author Andy Scherzinger + ~ @author Marcel Hibbe + ~ Copyright (C) 2022 Marcel Hibbe ~ Copyright (C) 2021 Andy Scherzinger ~ Copyright (C) 2017-2018 Mario Danic ~ @@ -564,4 +566,16 @@ Call without notification Set avatar from camera + Conversation settings + + + Expire chat messages + Off + 4 weeks + 1 week + 1 day + 8 hours + 1 hour + + From e43fe4774e7a3b553888e2ddf7185c3c09de19fc Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 24 Aug 2022 11:45:58 +0200 Subject: [PATCH 4/5] show explanation for expire messages Signed-off-by: Marcel Hibbe --- .../talk/controllers/ConversationInfoController.kt | 1 + .../main/res/layout/controller_conversation_info.xml | 11 +++++++++++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 13 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index 5e86e27d3..891e90156 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -705,6 +705,7 @@ class ConversationInfoController(args: Bundle) : databaseStorageModule?.setMessageExpiration(conversation!!.messageExpiration) binding.conversationInfoExpireMessages.setStorageModule(databaseStorageModule) binding.conversationInfoExpireMessages.visibility = View.VISIBLE + binding.conversationInfoExpireMessagesExplanation.visibility = View.VISIBLE } else { binding.categoryConversationSettings.visibility = View.GONE } diff --git a/app/src/main/res/layout/controller_conversation_info.xml b/app/src/main/res/layout/controller_conversation_info.xml index 3f924d4ba..cbd69562b 100644 --- a/app/src/main/res/layout/controller_conversation_info.xml +++ b/app/src/main/res/layout/controller_conversation_info.xml @@ -192,6 +192,17 @@ apc:mp_title="@string/nc_expire_messages"> + + + 1 day 8 hours 1 hour + Expire chat messages after a certain time. Files shared into the chat will only be unshared from the conversation but are not deleted for the owner. From 4b88effb72e41063f4216fa91eba0defbf3de03e Mon Sep 17 00:00:00 2001 From: Marcel Hibbe Date: Wed, 24 Aug 2022 11:50:28 +0200 Subject: [PATCH 5/5] add theming for categoryConversationSettings Signed-off-by: Marcel Hibbe --- .../com/nextcloud/talk/controllers/ConversationInfoController.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt index 891e90156..80866b882 100644 --- a/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt +++ b/app/src/main/java/com/nextcloud/talk/controllers/ConversationInfoController.kt @@ -204,6 +204,7 @@ class ConversationInfoController(args: Bundle) : participantsListCategory, ownOptions, categorySharedItems, + categoryConversationSettings, binding.webinarInfoView.conversationInfoWebinar, binding.notificationSettingsView.notificationSettingsCategory ).forEach(viewThemeUtils::colorPreferenceCategory)