From b96ee903980074dd9a89f9ff488626e9d46dbdab Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Tue, 1 Apr 2025 13:02:26 +0200 Subject: [PATCH 01/22] add object type event to handle event conversations Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../talk/models/json/conversations/ConversationEnums.kt | 3 ++- .../models/json/converters/ConversationObjectTypeConverter.kt | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/models/json/conversations/ConversationEnums.kt b/app/src/main/java/com/nextcloud/talk/models/json/conversations/ConversationEnums.kt index 15be0a664..44dd302b5 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/conversations/ConversationEnums.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/conversations/ConversationEnums.kt @@ -43,6 +43,7 @@ class ConversationEnums { DEFAULT, SHARE_PASSWORD, FILE, - ROOM + ROOM, + EVENT } } diff --git a/app/src/main/java/com/nextcloud/talk/models/json/converters/ConversationObjectTypeConverter.kt b/app/src/main/java/com/nextcloud/talk/models/json/converters/ConversationObjectTypeConverter.kt index 65ffb639a..817f1b089 100644 --- a/app/src/main/java/com/nextcloud/talk/models/json/converters/ConversationObjectTypeConverter.kt +++ b/app/src/main/java/com/nextcloud/talk/models/json/converters/ConversationObjectTypeConverter.kt @@ -15,6 +15,7 @@ class ConversationObjectTypeConverter : StringBasedTypeConverter<ConversationEnu "share:password" -> ConversationEnums.ObjectType.SHARE_PASSWORD "room" -> ConversationEnums.ObjectType.ROOM "file" -> ConversationEnums.ObjectType.FILE + "event" -> ConversationEnums.ObjectType.EVENT else -> ConversationEnums.ObjectType.DEFAULT } } @@ -28,6 +29,7 @@ class ConversationObjectTypeConverter : StringBasedTypeConverter<ConversationEnu ConversationEnums.ObjectType.SHARE_PASSWORD -> "share:password" ConversationEnums.ObjectType.ROOM -> "room" ConversationEnums.ObjectType.FILE -> "file" + ConversationEnums.ObjectType.EVENT -> "event" else -> "" } } From 83b8915787b10eb7c715e0e1e0117af1365c1789 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 7 Apr 2025 09:01:03 +0200 Subject: [PATCH 02/22] add icon for event conversations Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 25 ++++++++++++---- .../talk/models/domain/ConversationModel.kt | 1 + .../models/json/conversations/Conversation.kt | 3 ++ app/src/main/res/drawable/calendar_clock.xml | 16 ++++++++++ app/src/main/res/menu/menu_conversation.xml | 30 +++++++++++++++---- app/src/main/res/values/strings.xml | 1 + 6 files changed, 65 insertions(+), 11 deletions(-) create mode 100644 app/src/main/res/drawable/calendar_clock.xml diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 5c10b4ec4..f9ccb39ec 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -324,6 +324,7 @@ class ChatActivity : private var conversationVoiceCallMenuItem: MenuItem? = null private var conversationVideoMenuItem: MenuItem? = null + private var eventConversationMenuItem: MenuItem? = null var webSocketInstance: WebSocketInstance? = null var signalingMessageSender: SignalingMessageSender? = null @@ -568,6 +569,7 @@ class ChatActivity : invalidateOptionsMenu() checkShowCallButtons() + isEventConversation() checkLobbyState() updateRoomTimerHandler() } else { @@ -601,6 +603,7 @@ class ChatActivity : setupSwipeToReply() setActionBarTitle() checkShowCallButtons() + isEventConversation() checkLobbyState() if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && currentConversation?.status == "dnd" @@ -1889,6 +1892,17 @@ class ChatActivity : } } + private fun isEventConversation() { + if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { + if (eventConversationMenuItem != null) { + eventConversationMenuItem?.icon?.alpha = FULLY_OPAQUE_INT + eventConversationMenuItem?.isEnabled = true + } + } else { + eventConversationMenuItem?.isEnabled = false + } + } + private fun isReadOnlyConversation(): Boolean = currentConversation?.conversationReadOnlyState != null && currentConversation?.conversationReadOnlyState == @@ -2855,6 +2869,11 @@ class ChatActivity : loadAvatarForStatusBar() setActionBarTitle() } + if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { + eventConversationMenuItem = menu.findItem(R.id.conversation_event_icon) + } else { + menu.removeItem(R.id.conversation_event_icon) + } return true } @@ -2871,12 +2890,6 @@ class ChatActivity : searchItem.isVisible = CapabilitiesUtil.isUnifiedSearchAvailable(spreedCapabilities) && currentConversation!!.remoteServer.isNullOrEmpty() - if (currentConversation!!.remoteServer != null || - !CapabilitiesUtil.isSharedItemsAvailable(spreedCapabilities) - ) { - menu.removeItem(R.id.shared_items) - } - if (CapabilitiesUtil.isAbleToCall(spreedCapabilities)) { conversationVoiceCallMenuItem = menu.findItem(R.id.conversation_voice_call) conversationVideoMenuItem = menu.findItem(R.id.conversation_video_call) diff --git a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt index e6a036564..ebdca4951 100644 --- a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt +++ b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt @@ -33,6 +33,7 @@ class ConversationModel( var unreadMention: Boolean = false, var lastMessage: ChatMessageJson? = null, var objectType: ConversationEnums.ObjectType, + var objectId: String = "", var notificationLevel: ConversationEnums.NotificationLevel, var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState, var lobbyState: ConversationEnums.LobbyState, 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 6ef2bd50e..f16db4a78 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 @@ -79,6 +79,9 @@ data class Conversation( @JsonField(name = ["objectType"], typeConverter = ConversationObjectTypeConverter::class) var objectType: ConversationEnums.ObjectType = ConversationEnums.ObjectType.DEFAULT, + @JsonField(name = ["objectId"]) + var objectId: String = "", + @JsonField(name = ["notificationLevel"], typeConverter = EnumNotificationLevelConverter::class) var notificationLevel: ConversationEnums.NotificationLevel = ConversationEnums.NotificationLevel.DEFAULT, diff --git a/app/src/main/res/drawable/calendar_clock.xml b/app/src/main/res/drawable/calendar_clock.xml new file mode 100644 index 000000000..fddc4d044 --- /dev/null +++ b/app/src/main/res/drawable/calendar_clock.xml @@ -0,0 +1,16 @@ +<!-- + ~ Nextcloud Talk - Android Client + ~ + ~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kch@gmail.com> + ~ SPDX-License-Identifier: GPL-3.0-or-later + --> + +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24" + android:viewportHeight="24"> + <path + android:fillColor="#FF000000" + android:pathData="M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0,0 1,16 9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0,0 1,21 5V11.1C22.24,12.36 23,14.09 23,16A7,7 0,0 1,16 23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0,0 0,11.15 16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0,0 0,20.85 16C20.85,13.32 18.68,11.15 16,11.15Z"/> +</vector> diff --git a/app/src/main/res/menu/menu_conversation.xml b/app/src/main/res/menu/menu_conversation.xml index bb7799dd5..b930a803b 100644 --- a/app/src/main/res/menu/menu_conversation.xml +++ b/app/src/main/res/menu/menu_conversation.xml @@ -8,36 +8,56 @@ <menu xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + <item + android:id="@+id/conversation_event_icon" + android:icon="@drawable/calendar_clock" + android:orderInCategory="0" + android:title="@string/nc_event_conversation_menu" + app:showAsAction="ifRoom"> + + <menu> + <item + android:id="@+id/action_option_one" + android:title="Scheduled event" /> + + <item + android:id="@+id/action_option_two" + android:title="@string/nc_delete_call" + android:icon = "@drawable/ic_delete"/> + </menu> + + </item> + <item android:id="@+id/conversation_voice_call" android:icon="@drawable/ic_call_white_24dp" - android:orderInCategory="0" + android:orderInCategory="1" android:title="@string/nc_conversation_menu_voice_call" app:showAsAction="ifRoom" /> <item android:id="@+id/conversation_video_call" android:icon="@drawable/ic_videocam_white_24px" - android:orderInCategory="1" + android:orderInCategory="2" android:title="@string/nc_conversation_menu_video_call" app:showAsAction="ifRoom" /> <item android:id="@+id/conversation_search" android:icon="@drawable/ic_search_white_24dp" - android:orderInCategory="2" + android:orderInCategory="3" android:title="@string/nc_search" app:showAsAction="ifRoom" /> <item android:id="@+id/conversation_info" - android:orderInCategory="3" + android:orderInCategory="4" android:title="@string/nc_conversation_menu_conversation_info" app:showAsAction="never" /> <item android:id="@+id/shared_items" - android:orderInCategory="4" + android:orderInCategory="5" android:title="@string/nc_shared_items" app:showAsAction="never" /> </menu> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 1440edc32..6d9226c99 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -403,6 +403,7 @@ How to translate with transifex: <string name="nc_date_header_today">Today</string> <string name="nc_conversation_menu_voice_call">Voice call</string> <string name="nc_conversation_menu_video_call">Video call</string> + <string name="nc_event_conversation_menu">Event conversation menu</string> <string name="nc_conversation_menu_conversation_info">Conversation info</string> <string name="nc_new_messages">Unread messages</string> <string name="nc_sent_a_gif" formatted="true">%1$s sent a GIF.</string> From fd47146729e30ab27aef81341efbc4e8da6e34ab Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Tue, 8 Apr 2025 17:14:30 +0200 Subject: [PATCH 03/22] UI changes and hiding events Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../13.json | 12 +- .../com/nextcloud/talk/chat/ChatActivity.kt | 148 +++++++++++++++++- .../ConversationInfoEditActivity.kt | 6 + .../OfflineFirstConversationsRepository.kt | 12 +- .../database/mappers/ConversationMapUtils.kt | 3 + .../data/database/model/ConversationEntity.kt | 1 + .../talk/models/domain/ConversationModel.kt | 1 + .../main/res/layout/item_event_schedule.xml | 40 +++++ app/src/main/res/menu/menu_conversation.xml | 13 +- app/src/main/res/values/strings.xml | 1 + 10 files changed, 216 insertions(+), 21 deletions(-) create mode 100644 app/src/main/res/layout/item_event_schedule.xml diff --git a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json index 2e2345001..100acd968 100644 --- a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json +++ b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 13, - "identityHash": "a521f027909f69f4c7d1855f84a2e67f", + "identityHash": "506abc931eb3b657cafe6ad1b25f635d", "entities": [ { "tableName": "User", @@ -138,7 +138,7 @@ }, { "tableName": "Conversations", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `objectId` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", "fields": [ { "fieldPath": "internalId", @@ -320,6 +320,12 @@ "affinity": "TEXT", "notNull": true }, + { + "fieldPath": "objectId", + "columnName": "objectId", + "affinity": "TEXT", + "notNull": true + }, { "fieldPath": "participantType", "columnName": "participantType", @@ -743,7 +749,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a521f027909f69f4c7d1855f84a2e67f')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '506abc931eb3b657cafe6ad1b25f635d')" ] } } \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index f9ccb39ec..3ca69bf19 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -38,12 +38,14 @@ import android.view.Gravity import android.view.Menu import android.view.MenuItem import android.view.View +import android.view.ViewGroup import android.view.animation.AccelerateDecelerateInterpolator import android.widget.AbsListView import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import android.widget.PopupMenu +import android.widget.PopupWindow import android.widget.TextView import android.widget.Toast import androidx.activity.OnBackPressedCallback @@ -51,6 +53,7 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.PickVisualMediaRequest import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AlertDialog import androidx.appcompat.view.ContextThemeWrapper import androidx.cardview.widget.CardView import androidx.compose.runtime.mutableStateOf @@ -82,6 +85,7 @@ import coil.request.CachePolicy import coil.request.ImageRequest import coil.target.Target import coil.transform.CircleCropTransformation +import com.google.android.material.dialog.MaterialAlertDialogBuilder import com.google.android.material.snackbar.Snackbar import com.nextcloud.android.common.ui.color.ColorUtil import com.nextcloud.android.common.ui.theme.utils.ColorRole @@ -127,6 +131,7 @@ import com.nextcloud.talk.databinding.ActivityChatBinding import com.nextcloud.talk.events.UserMentionClickEvent import com.nextcloud.talk.events.WebSocketCommunicationEvent import com.nextcloud.talk.extensions.loadAvatarOrImagePreview +import com.nextcloud.talk.jobs.DeleteConversationWorker import com.nextcloud.talk.jobs.DownloadFileToCacheWorker import com.nextcloud.talk.jobs.ShareOperationWorker import com.nextcloud.talk.jobs.UploadAndShareFilesWorker @@ -210,11 +215,14 @@ import java.io.File import java.io.IOException import java.net.HttpURLConnection import java.text.SimpleDateFormat +import java.time.Instant +import java.time.ZoneId +import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter import java.util.Date import java.util.Locale import java.util.concurrent.ExecutionException import javax.inject.Inject -import kotlin.collections.set import kotlin.math.roundToInt import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia @@ -1892,7 +1900,7 @@ class ChatActivity : } } - private fun isEventConversation() { + private fun isEventConversation() { if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { if (eventConversationMenuItem != null) { eventConversationMenuItem?.icon?.alpha = FULLY_OPAQUE_INT @@ -2870,10 +2878,11 @@ class ChatActivity : setActionBarTitle() } if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { - eventConversationMenuItem = menu.findItem(R.id.conversation_event_icon) + eventConversationMenuItem = menu.findItem(R.id.conversation_event) } else { - menu.removeItem(R.id.conversation_event_icon) + menu.removeItem(R.id.conversation_event) } + return true } @@ -2922,7 +2931,6 @@ class ChatActivity : menu.removeItem(R.id.conversation_voice_call) } } - return true } @@ -2953,9 +2961,139 @@ class ChatActivity : true } + R.id.conversation_event -> { + val anchorView = findViewById<View>(R.id.conversation_event) + showPopupWindow(anchorView) + true + } + else -> super.onOptionsItemSelected(item) } + private fun showPopupWindow(anchorView: View) { + val popupView = layoutInflater.inflate(R.layout.item_event_schedule, null) + + val titleTextView = popupView.findViewById<TextView>(R.id.event_scheduled) + val subtitleTextView = popupView.findViewById<TextView>(R.id.meetingTime) + val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation) + + val popupWindow = PopupWindow( + popupView, + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + true + ) + + popupWindow.isOutsideTouchable = true + popupWindow.isFocusable = true + popupWindow.showAsDropDown(anchorView, 0, -anchorView.height) + + val meetingStatus = showEventSchedule() + + titleTextView.text = "Scheduled" + subtitleTextView.text = meetingStatus + + if (meetingStatus == "Meeting Ended" && currentConversation?.canDeleteConversation == true) { + deleteConversation.visibility = View.VISIBLE + + deleteConversation.setOnClickListener { + val dialogBuilder = MaterialAlertDialogBuilder(it.context) + .setIcon( + viewThemeUtils.dialog + .colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp) + ) + .setTitle(R.string.nc_delete_call) + .setMessage(R.string.nc_delete_conversation_more) + .setPositiveButton(R.string.nc_delete) { _, _ -> + currentConversation?.let { conversation -> + deleteConversation(conversation) + } + } + .setNegativeButton(R.string.nc_cancel) { _, _ -> + } + + viewThemeUtils.dialog + .colorMaterialAlertDialogBackground(it.context, dialogBuilder) + val dialog = dialogBuilder.show() + viewThemeUtils.platform.colorTextButtons( + dialog.getButton(AlertDialog.BUTTON_POSITIVE), + dialog.getButton(AlertDialog.BUTTON_NEGATIVE) + ) + } + } else { + deleteConversation.visibility = View.GONE + } + } + + private fun deleteConversation(conversation: ConversationModel) { + val data = Data.Builder() + data.putLong( + KEY_INTERNAL_USER_ID, + conversationUser?.id!! + ) + data.putString(KEY_ROOM_TOKEN, conversation.token) + + val deleteConversationWorker = + OneTimeWorkRequest.Builder(DeleteConversationWorker::class.java).setInputData(data.build()).build() + WorkManager.getInstance().enqueue(deleteConversationWorker) + + WorkManager.getInstance(context).getWorkInfoByIdLiveData(deleteConversationWorker.id) + .observeForever { workInfo: WorkInfo? -> + if (workInfo != null) { + when (workInfo.state) { + WorkInfo.State.SUCCEEDED -> { + val successMessage = String.format( + context.resources.getString(R.string.deleted_conversation), + conversation.displayName + ) + Snackbar.make(binding.root, successMessage, Snackbar.LENGTH_LONG).show() + finish() + } + + WorkInfo.State.FAILED -> { + val errorMessage = context.resources.getString(R.string.nc_common_error_sorry) + Snackbar.make(binding.root, errorMessage, Snackbar.LENGTH_LONG).show() + } + + else -> { + } + } + } + } + } + + private fun showEventSchedule(): String { + val objectId = currentConversation?.objectId ?: "" + val status = getMeetingSchedule(objectId) + return status + } + + private fun getMeetingSchedule(objectId: String): String { + val timestamps = objectId.split("#") + if (timestamps.size != 2) return "Invalid Time" + + val startEpoch = timestamps[0].toLong() + val endEpoch = timestamps[1].toLong() + + val startDateTime = Instant.ofEpochSecond(startEpoch).atZone(ZoneId.systemDefault()) + val endDateTime = Instant.ofEpochSecond(endEpoch).atZone(ZoneId.systemDefault()) + val now = ZonedDateTime.now(ZoneId.systemDefault()) + + return when { + now.isBefore(startDateTime) -> { + val isToday = startDateTime.toLocalDate().isEqual(now.toLocalDate()) + val isTomorrow = startDateTime.toLocalDate().isEqual(now.toLocalDate().plusDays(1)) + when { + isToday -> "Today at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}" + isTomorrow -> "Tomorrow at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}" + else -> startDateTime.format(DateTimeFormatter.ofPattern("MMM d, yyyy, HH:mm")) + } + } + now.isAfter(endDateTime) -> "Meeting Ended" + else -> "Ongoing" + } + } + private fun showSharedItems() { val intent = Intent(this, SharedItemsActivity::class.java) intent.putExtra(KEY_CONVERSATION_NAME, currentConversation?.displayName) diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt index ae333d955..1436a19f7 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt @@ -185,6 +185,11 @@ class ConversationInfoEditActivity : BaseActivity() { binding.conversationDescription.isEnabled = false } + if (conversation?.objectType == ConversationEnums.ObjectType.EVENT) { + binding.conversationName.isEnabled = false + binding.conversationDescription.isEnabled = false + } + loadConversationAvatar() } @@ -266,6 +271,7 @@ class ConversationInfoEditActivity : BaseActivity() { override fun onPrepareOptionsMenu(menu: Menu): Boolean { super.onPrepareOptionsMenu(menu) + return true } diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt index c4b941962..6be702186 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt @@ -18,6 +18,7 @@ import com.nextcloud.talk.data.database.model.ConversationEntity import com.nextcloud.talk.data.network.NetworkMonitor import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel +import com.nextcloud.talk.models.json.conversations.ConversationEnums import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import io.reactivex.Observer @@ -121,7 +122,15 @@ class OfflineFirstConversationsRepository @Inject constructor( .observeOn(AndroidSchedulers.mainThread()) .blockingSingle() - conversationsFromSync = conversationsList.map { + val currentTime = System.currentTimeMillis() / 1000 + + val conversationListWithoutEvents = conversationsList.filterNot { conversation -> + + conversation.objectType == ConversationEnums.ObjectType.EVENT && + conversation.objectId.split("#")[0].toLong() - currentTime > + AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS + } + conversationsFromSync = conversationListWithoutEvents.map { it.asEntity(user.id!!) } @@ -156,5 +165,6 @@ class OfflineFirstConversationsRepository @Inject constructor( companion object { val TAG = OfflineFirstConversationsRepository::class.simpleName + private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400 } } diff --git a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt index 90acf6117..23151b7a4 100644 --- a/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt +++ b/app/src/main/java/com/nextcloud/talk/data/database/mappers/ConversationMapUtils.kt @@ -34,6 +34,7 @@ fun ConversationModel.asEntity() = unreadMention = unreadMention, lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) }, objectType = objectType, + objectId = objectId, notificationLevel = notificationLevel, conversationReadOnlyState = conversationReadOnlyState, lobbyState = lobbyState, @@ -85,6 +86,7 @@ fun ConversationEntity.asModel() = lastMessage = lastMessage?.let { LoganSquare.parse(lastMessage, ChatMessageJson::class.java) }, objectType = objectType, + objectId = objectId, notificationLevel = notificationLevel, conversationReadOnlyState = conversationReadOnlyState, lobbyState = lobbyState, @@ -135,6 +137,7 @@ fun Conversation.asEntity(accountId: Long) = unreadMention = unreadMention, lastMessage = lastMessage?.let { LoganSquare.serialize(lastMessage) }, objectType = objectType, + objectId = objectId, notificationLevel = notificationLevel, conversationReadOnlyState = conversationReadOnlyState, lobbyState = lobbyState, diff --git a/app/src/main/java/com/nextcloud/talk/data/database/model/ConversationEntity.kt b/app/src/main/java/com/nextcloud/talk/data/database/model/ConversationEntity.kt index 4f4652264..106c7e7a8 100644 --- a/app/src/main/java/com/nextcloud/talk/data/database/model/ConversationEntity.kt +++ b/app/src/main/java/com/nextcloud/talk/data/database/model/ConversationEntity.kt @@ -78,6 +78,7 @@ data class ConversationEntity( @ColumnInfo(name = "notificationCalls") var notificationCalls: Int = 0, @ColumnInfo(name = "notificationLevel") var notificationLevel: ConversationEnums.NotificationLevel, @ColumnInfo(name = "objectType") var objectType: ConversationEnums.ObjectType, + @ColumnInfo(name = "objectId") var objectId: String, @ColumnInfo(name = "participantType") var participantType: Participant.ParticipantType, @ColumnInfo(name = "permissions") var permissions: Int = 0, @ColumnInfo(name = "readOnly") var conversationReadOnlyState: ConversationEnums.ConversationReadOnlyState, diff --git a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt index ebdca4951..d9c30ee22 100644 --- a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt +++ b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt @@ -89,6 +89,7 @@ class ConversationModel( unreadMention = conversation.unreadMention, lastMessage = conversation.lastMessage, objectType = conversation.objectType.let { ConversationEnums.ObjectType.valueOf(it.name) }, + objectId = conversation.objectId, notificationLevel = conversation.notificationLevel.let { ConversationEnums.NotificationLevel.valueOf( it.name diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml new file mode 100644 index 000000000..e97b7ba6e --- /dev/null +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?><!-- + ~ Nextcloud Talk - Android Client + ~ + ~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kota@gmail.com> + ~ SPDX-License-Identifier: GPL-3.0-or-later + --> + + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:padding="32dp" + android:background="@color/bg_bottom_sheet"> + + <TextView + android:id="@+id/event_scheduled" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Scheduled" + android:textStyle="bold" + android:textSize="16sp" /> + + <TextView + android:id="@+id/meetingTime" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="?android:attr/textColorSecondary" + android:textSize="14sp" + android:text="Meeting at 8:00 pm"/> + + <TextView + android:id="@+id/delete_conversation" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="Delete Conversation" + android:textColor="@android:color/holo_red_dark" + android:visibility = "gone" + android:paddingTop="16dp"/> +</LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_conversation.xml b/app/src/main/res/menu/menu_conversation.xml index b930a803b..ffcd29932 100644 --- a/app/src/main/res/menu/menu_conversation.xml +++ b/app/src/main/res/menu/menu_conversation.xml @@ -9,23 +9,12 @@ xmlns:app="http://schemas.android.com/apk/res-auto"> <item - android:id="@+id/conversation_event_icon" + android:id="@+id/conversation_event" android:icon="@drawable/calendar_clock" android:orderInCategory="0" android:title="@string/nc_event_conversation_menu" app:showAsAction="ifRoom"> - <menu> - <item - android:id="@+id/action_option_one" - android:title="Scheduled event" /> - - <item - android:id="@+id/action_option_two" - android:title="@string/nc_delete_call" - android:icon = "@drawable/ic_delete"/> - </menu> - </item> <item diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6d9226c99..ce2af5983 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -242,6 +242,7 @@ How to translate with transifex: <string name="nc_rename">Rename conversation</string> <string name="nc_rename_confirm">Rename</string> <string name="nc_delete_call">Delete conversation</string> + <string name="nc_event_schedule">Schedule</string> <string name="nc_delete">Delete</string> <string name="nc_delete_all">Delete all</string> <string name="nc_delete_conversation_more">If you delete the conversation, it will also be deleted for all other participants.</string> From a18e192d28ae470f61aea40ee166018cd25471bb Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 13:34:14 +0200 Subject: [PATCH 04/22] fix search Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../ConversationsListActivity.kt | 26 ++++++++++++++++--- .../OfflineFirstConversationsRepository.kt | 12 +-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 3e5f87ce5..96faf1877 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -519,9 +519,15 @@ class ConversationsListActivity : // Update Conversations conversationItems.clear() conversationItemsWithHeader.clear() + searchableConversationItems.clear() + for (conversation in list) { - addToConversationItems(conversation) + if (!FutureEvent(conversation)) { + addToConversationItems(conversation) + } + addToSearchableConversationItems(conversation) } + sortConversations(conversationItems) sortConversations(conversationItemsWithHeader) @@ -550,6 +556,21 @@ class ConversationsListActivity : return false } + private fun FutureEvent(conversation: ConversationModel): Boolean { + return conversation.objectType == ConversationEnums.ObjectType.EVENT && + (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / 1000)) > AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS + } + + private fun addToSearchableConversationItems(conversation: ConversationModel) { + val headerTitle = resources!!.getString(R.string.conversations) + val headerItem = callHeaderItems.getOrPut(headerTitle) { + GenericTextHeaderItem(headerTitle, viewThemeUtils) + } + + val conversationItem = ConversationItem(conversation, currentUser!!, this, headerItem, viewThemeUtils) + searchableConversationItems.add(conversationItem) + } + fun filterConversation() { val accountId = UserIdUtils.getIdForUser(currentUser) filterState[FilterConversationFragment.UNREAD] = ( @@ -1069,8 +1090,6 @@ class ConversationsListActivity : } private fun fetchOpenConversations(apiVersion: Int) { - searchableConversationItems.clear() - searchableConversationItems.addAll(conversationItemsWithHeader) if (hasSpreedFeatureCapability( currentUser!!.capabilities!!.spreedCapability!!, SpreedFeatures.LISTABLE_ROOMS @@ -2114,5 +2133,6 @@ class ConversationsListActivity : const val NOTIFICATION_WARNING_DATE_NOT_SET = 0L const val OFFSET_HEIGHT_DIVIDER: Int = 3 const val ROOM_TYPE_ONE_ONE = "1" + private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400 } } diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt index 6be702186..c4b941962 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/data/network/OfflineFirstConversationsRepository.kt @@ -18,7 +18,6 @@ import com.nextcloud.talk.data.database.model.ConversationEntity import com.nextcloud.talk.data.network.NetworkMonitor import com.nextcloud.talk.data.user.model.User import com.nextcloud.talk.models.domain.ConversationModel -import com.nextcloud.talk.models.json.conversations.ConversationEnums import com.nextcloud.talk.utils.CapabilitiesUtil.isUserStatusAvailable import com.nextcloud.talk.utils.database.user.CurrentUserProviderNew import io.reactivex.Observer @@ -122,15 +121,7 @@ class OfflineFirstConversationsRepository @Inject constructor( .observeOn(AndroidSchedulers.mainThread()) .blockingSingle() - val currentTime = System.currentTimeMillis() / 1000 - - val conversationListWithoutEvents = conversationsList.filterNot { conversation -> - - conversation.objectType == ConversationEnums.ObjectType.EVENT && - conversation.objectId.split("#")[0].toLong() - currentTime > - AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS - } - conversationsFromSync = conversationListWithoutEvents.map { + conversationsFromSync = conversationsList.map { it.asEntity(user.id!!) } @@ -165,6 +156,5 @@ class OfflineFirstConversationsRepository @Inject constructor( companion object { val TAG = OfflineFirstConversationsRepository::class.simpleName - private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400 } } From 562faaaa441593389a003ab2d92d587aea990b45 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 13:36:13 +0200 Subject: [PATCH 05/22] ktlintFormat Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../talk/conversationlist/ConversationsListActivity.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 96faf1877..2da84234d 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -522,7 +522,7 @@ class ConversationsListActivity : searchableConversationItems.clear() for (conversation in list) { - if (!FutureEvent(conversation)) { + if (!futureEvent(conversation)) { addToConversationItems(conversation) } addToSearchableConversationItems(conversation) @@ -556,9 +556,10 @@ class ConversationsListActivity : return false } - private fun FutureEvent(conversation: ConversationModel): Boolean { + private fun futureEvent(conversation: ConversationModel): Boolean { return conversation.objectType == ConversationEnums.ObjectType.EVENT && - (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / 1000)) > AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS + (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / 1000)) > + AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS } private fun addToSearchableConversationItems(conversation: ConversationModel) { From 8e599a567db94bbad4dcc58d53b4932966076aba Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 15:52:00 +0200 Subject: [PATCH 06/22] handle invalid objectId Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../talk/conversationlist/ConversationsListActivity.kt | 3 +++ app/src/main/res/layout/item_event_schedule.xml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 2da84234d..fc6fd749a 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -557,6 +557,9 @@ class ConversationsListActivity : } private fun futureEvent(conversation: ConversationModel): Boolean { + if(!conversation.objectId.contains("#")){ + return false + } return conversation.objectType == ConversationEnums.ObjectType.EVENT && (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / 1000)) > AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index e97b7ba6e..4c8b7cab5 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -10,7 +10,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="32dp" + android:padding="8dp" android:background="@color/bg_bottom_sheet"> <TextView From 351b532e6af1c3ebe74ace3b7eedf44bc937c99e Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 16:34:44 +0200 Subject: [PATCH 07/22] background color for popup menu Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../conversationinfoedit/ConversationInfoEditActivity.kt | 9 +++++---- app/src/main/res/layout/item_event_schedule.xml | 4 ++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt index 1436a19f7..0b92df4d7 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt @@ -271,14 +271,15 @@ class ConversationInfoEditActivity : BaseActivity() { override fun onPrepareOptionsMenu(menu: Menu): Boolean { super.onPrepareOptionsMenu(menu) - return true } override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == R.id.save) { - saveConversationNameAndDescription() - } + if (item.itemId == R.id.save) { + if (conversation?.objectType != ConversationEnums.ObjectType.EVENT) { + saveConversationNameAndDescription() + } + } return true } diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index 4c8b7cab5..ebf47520c 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -10,8 +10,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="vertical" - android:padding="8dp" - android:background="@color/bg_bottom_sheet"> + android:padding="16dp" + android:background="@color/dialog_background"> <TextView android:id="@+id/event_scheduled" From b128c5a8ea4114f8b43c29f41125ae0f8a73a778 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 17:15:24 +0200 Subject: [PATCH 08/22] use string resources Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 45 +++++++++++-------- .../ConversationInfoEditActivity.kt | 8 ++-- .../ConversationsListActivity.kt | 5 ++- .../main/res/layout/item_event_schedule.xml | 7 +-- app/src/main/res/values/strings.xml | 5 +++ 5 files changed, 43 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 3ca69bf19..1e4f21b27 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -2989,11 +2989,11 @@ class ChatActivity : popupWindow.showAsDropDown(anchorView, 0, -anchorView.height) val meetingStatus = showEventSchedule() - - titleTextView.text = "Scheduled" subtitleTextView.text = meetingStatus - if (meetingStatus == "Meeting Ended" && currentConversation?.canDeleteConversation == true) { + if (meetingStatus == context.resources.getString(R.string.nc_meeting_ended) && + currentConversation?.canDeleteConversation == true + ) { deleteConversation.visibility = View.VISIBLE deleteConversation.setOnClickListener { @@ -3063,34 +3063,41 @@ class ChatActivity : } private fun showEventSchedule(): String { - val objectId = currentConversation?.objectId ?: "" - val status = getMeetingSchedule(objectId) + val meetingTimeStamp = currentConversation?.objectId ?: "" + val status = getMeetingSchedule(meetingTimeStamp) return status } - private fun getMeetingSchedule(objectId: String): String { - val timestamps = objectId.split("#") - if (timestamps.size != 2) return "Invalid Time" + private fun getMeetingSchedule(meetingTimeStamp: String): String { + val timestamps = meetingTimeStamp.split("#") + if (timestamps.size != 2) return context.resources.getString(R.string.nc_invalid_time) - val startEpoch = timestamps[0].toLong() - val endEpoch = timestamps[1].toLong() + val startEpoch = timestamps[ZERO_INDEX].toLong() + val endEpoch = timestamps[ONE_INDEX].toLong() val startDateTime = Instant.ofEpochSecond(startEpoch).atZone(ZoneId.systemDefault()) val endDateTime = Instant.ofEpochSecond(endEpoch).atZone(ZoneId.systemDefault()) - val now = ZonedDateTime.now(ZoneId.systemDefault()) + val currentTime = ZonedDateTime.now(ZoneId.systemDefault()) return when { - now.isBefore(startDateTime) -> { - val isToday = startDateTime.toLocalDate().isEqual(now.toLocalDate()) - val isTomorrow = startDateTime.toLocalDate().isEqual(now.toLocalDate().plusDays(1)) + currentTime.isBefore(startDateTime) -> { + val isToday = startDateTime.toLocalDate().isEqual(currentTime.toLocalDate()) + val isTomorrow = startDateTime.toLocalDate().isEqual(currentTime.toLocalDate().plusDays(1)) when { - isToday -> "Today at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}" - isTomorrow -> "Tomorrow at ${startDateTime.format(DateTimeFormatter.ofPattern("HH:mm"))}" + isToday -> String.format( + context.resources.getString(R.string.nc_today_meeting), + startDateTime.format(DateTimeFormatter.ofPattern("HH:mm")) + ) + + isTomorrow -> String.format( + context.resources.getString(R.string.nc_tomorrow_meeting), + startDateTime.format(DateTimeFormatter.ofPattern("HH:mm")) + ) else -> startDateTime.format(DateTimeFormatter.ofPattern("MMM d, yyyy, HH:mm")) } } - now.isAfter(endDateTime) -> "Meeting Ended" - else -> "Ongoing" + currentTime.isAfter(endDateTime) -> context.resources.getString(R.string.nc_meeting_ended) + else -> context.resources.getString(R.string.nc_ongoing_meeting) } } @@ -3951,5 +3958,7 @@ class ChatActivity : const val VOICE_MESSAGE_PLAY_ADD_THRESHOLD = 0.1 const val VOICE_MESSAGE_MARK_PLAYED_FACTOR = 20 const val OUT_OF_OFFICE_ALPHA = 76 + const val ZERO_INDEX = 0 + const val ONE_INDEX = 1 } } diff --git a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt index 0b92df4d7..47e007a06 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationinfoedit/ConversationInfoEditActivity.kt @@ -275,11 +275,11 @@ class ConversationInfoEditActivity : BaseActivity() { } override fun onOptionsItemSelected(item: MenuItem): Boolean { - if (item.itemId == R.id.save) { - if (conversation?.objectType != ConversationEnums.ObjectType.EVENT) { - saveConversationNameAndDescription() - } + if (item.itemId == R.id.save) { + if (conversation?.objectType != ConversationEnums.ObjectType.EVENT) { + saveConversationNameAndDescription() } + } return true } diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index fc6fd749a..3fecd21de 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -557,11 +557,11 @@ class ConversationsListActivity : } private fun futureEvent(conversation: ConversationModel): Boolean { - if(!conversation.objectId.contains("#")){ + if (!conversation.objectId.contains("#")) { return false } return conversation.objectType == ConversationEnums.ObjectType.EVENT && - (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / 1000)) > + (conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / LONG_1000)) > AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS } @@ -2138,5 +2138,6 @@ class ConversationsListActivity : const val OFFSET_HEIGHT_DIVIDER: Int = 3 const val ROOM_TYPE_ONE_ONE = "1" private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400 + const val LONG_1000: Long = 1000 } } diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index ebf47520c..cf2a439c1 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -9,6 +9,7 @@ <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content" android:layout_height="wrap_content" + xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:padding="16dp" android:background="@color/dialog_background"> @@ -17,7 +18,7 @@ android:id="@+id/event_scheduled" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Scheduled" + android:text="@string/nc_event_schedule" android:textStyle="bold" android:textSize="16sp" /> @@ -27,13 +28,13 @@ android:layout_height="wrap_content" android:textColor="?android:attr/textColorSecondary" android:textSize="14sp" - android:text="Meeting at 8:00 pm"/> + tools:text="Meeting at 8:00 pm"/> <TextView android:id="@+id/delete_conversation" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:text="Delete Conversation" + android:text="@string/nc_delete_call" android:textColor="@android:color/holo_red_dark" android:visibility = "gone" android:paddingTop="16dp"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ce2af5983..7645e2d2a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -245,6 +245,11 @@ How to translate with transifex: <string name="nc_event_schedule">Schedule</string> <string name="nc_delete">Delete</string> <string name="nc_delete_all">Delete all</string> + <string name="nc_ongoing_meeting">Ongoing meeting</string> + <string name="nc_meeting_ended">Meeting ended</string> + <string name="nc_invalid_time">Invalid time</string> + <string name="nc_today_meeting">Today at %1$s</string> + <string name="nc_tomorrow_meeting">Tomorrow at %1$s</string> <string name="nc_delete_conversation_more">If you delete the conversation, it will also be deleted for all other participants.</string> <string name="nc_new_conversation">New conversation</string> From 44065ae9464e4d92e9dbb40da02d22a9c18a76ec Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 9 Apr 2025 18:48:11 +0200 Subject: [PATCH 09/22] archive conversation Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 27 +++++++++++++++++++ .../main/res/layout/item_event_schedule.xml | 8 ++++++ app/src/main/res/values/strings.xml | 1 + 3 files changed, 36 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 1e4f21b27..8951c6f0c 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -225,6 +225,8 @@ import java.util.concurrent.ExecutionException import javax.inject.Inject import kotlin.math.roundToInt import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia +import com.nextcloud.talk.conversationinfo.viewmodel.ConversationInfoViewModel +import com.nextcloud.talk.models.json.participants.Participant @AutoInjector(NextcloudTalkApplication::class) class ChatActivity : @@ -262,6 +264,8 @@ class ChatActivity : lateinit var networkMonitor: NetworkMonitor lateinit var chatViewModel: ChatViewModel + + lateinit var conversationInfoViewModel: ConversationInfoViewModel lateinit var messageInputViewModel: MessageInputViewModel private val startSelectContactForResult = registerForActivityResult( @@ -427,6 +431,8 @@ class ChatActivity : chatViewModel = ViewModelProvider(this, viewModelFactory)[ChatViewModel::class.java] + conversationInfoViewModel = ViewModelProvider(this, viewModelFactory)[ConversationInfoViewModel::class.java] + val urlForChatting = ApiUtils.getUrlForChat(chatApiVersion, conversationUser?.baseUrl, roomToken) val credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser!!.token) chatViewModel.initData( @@ -2976,6 +2982,7 @@ class ChatActivity : val titleTextView = popupView.findViewById<TextView>(R.id.event_scheduled) val subtitleTextView = popupView.findViewById<TextView>(R.id.meetingTime) val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation) + val archiveConversation = popupView.findViewById<TextView>(R.id.archive_conversation) val popupWindow = PopupWindow( popupView, @@ -3019,10 +3026,30 @@ class ChatActivity : dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_NEGATIVE) ) + popupWindow.dismiss() } } else { deleteConversation.visibility = View.GONE } + + if (meetingStatus == context.resources.getString(R.string.nc_meeting_ended) && + ( + Participant.ParticipantType.MODERATOR == currentConversation?.participantType || + Participant.ParticipantType.OWNER == currentConversation?.participantType + ) && + currentConversation?.hasArchived == false + ) { + archiveConversation.visibility = View.VISIBLE + archiveConversation.setOnClickListener { + this.lifecycleScope.launch { + conversationInfoViewModel.archiveConversation(conversationUser!!, currentConversation?.token!!) + Snackbar.make(binding.root, R.string.conversation_archived, Snackbar.LENGTH_LONG).show() + } + popupWindow.dismiss() + } + } else { + archiveConversation.visibility = View.GONE + } } private fun deleteConversation(conversation: ConversationModel) { diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index cf2a439c1..addb2536c 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -38,4 +38,12 @@ android:textColor="@android:color/holo_red_dark" android:visibility = "gone" android:paddingTop="16dp"/> + + <TextView + android:id="@+id/archive_conversation" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/archive_conversation" + android:visibility = "gone" + android:paddingTop="16dp"/> </LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7645e2d2a..6fbcb4280 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -850,4 +850,5 @@ How to translate with transifex: <string name="no_conversations_archived">No archived conversations</string> <string name="archived_conversation">Archived %1$s</string> <string name="unarchived_conversation">Unarchived %1$s</string> + <string name="conversation_archived">Conversation is archived</string> </resources> From cf27a489e7158c5efb656f2699b1623afb79f51f Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 14 Apr 2025 12:08:21 +0200 Subject: [PATCH 10/22] use calendar icon instead of calendar clock icon Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 67 ++++++++++++++----- .../drawable/baseline_calendar_today_24.xml | 19 ++++++ app/src/main/res/drawable/calendar_clock.xml | 16 ----- .../main/res/layout/item_event_schedule.xml | 8 +++ app/src/main/res/menu/menu_conversation.xml | 2 +- 5 files changed, 78 insertions(+), 34 deletions(-) create mode 100644 app/src/main/res/drawable/baseline_calendar_today_24.xml delete mode 100644 app/src/main/res/drawable/calendar_clock.xml diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 8951c6f0c..62d67e4f2 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -582,8 +582,8 @@ class ChatActivity : participantPermissions = ParticipantPermissions(spreedCapabilities, currentConversation!!) invalidateOptionsMenu() - checkShowCallButtons() isEventConversation() + checkShowCallButtons() checkLobbyState() updateRoomTimerHandler() } else { @@ -616,8 +616,8 @@ class ChatActivity : loadAvatarForStatusBar() setupSwipeToReply() setActionBarTitle() - checkShowCallButtons() isEventConversation() + checkShowCallButtons() checkLobbyState() if (currentConversation?.type == ConversationEnums.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL && currentConversation?.status == "dnd" @@ -2877,17 +2877,19 @@ class ChatActivity : super.onCreateOptionsMenu(menu) menuInflater.inflate(R.menu.menu_conversation, menu) + if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { + eventConversationMenuItem = menu.findItem(R.id.conversation_event) + } else { + menu.removeItem(R.id.conversation_event) + } + if (conversationUser?.userId == "?") { menu.removeItem(R.id.conversation_info) } else { loadAvatarForStatusBar() setActionBarTitle() } - if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT) { - eventConversationMenuItem = menu.findItem(R.id.conversation_event) - } else { - menu.removeItem(R.id.conversation_event) - } + return true } @@ -2983,6 +2985,7 @@ class ChatActivity : val subtitleTextView = popupView.findViewById<TextView>(R.id.meetingTime) val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation) val archiveConversation = popupView.findViewById<TextView>(R.id.archive_conversation) + val unarchiveConversation = popupView.findViewById<TextView>(R.id.unarchive_conversation) val popupWindow = PopupWindow( popupView, @@ -3033,22 +3036,52 @@ class ChatActivity : } if (meetingStatus == context.resources.getString(R.string.nc_meeting_ended) && - ( - Participant.ParticipantType.MODERATOR == currentConversation?.participantType || + (Participant.ParticipantType.MODERATOR == currentConversation?.participantType || Participant.ParticipantType.OWNER == currentConversation?.participantType - ) && - currentConversation?.hasArchived == false + ) ) { - archiveConversation.visibility = View.VISIBLE - archiveConversation.setOnClickListener { - this.lifecycleScope.launch { - conversationInfoViewModel.archiveConversation(conversationUser!!, currentConversation?.token!!) - Snackbar.make(binding.root, R.string.conversation_archived, Snackbar.LENGTH_LONG).show() + if (currentConversation?.hasArchived == false) { + unarchiveConversation.visibility = View.GONE + archiveConversation.visibility = View.VISIBLE + archiveConversation.setOnClickListener { + this.lifecycleScope.launch { + conversationInfoViewModel.archiveConversation(conversationUser!!, currentConversation?.token!!) + Snackbar.make( + binding.root, + String.format( + context.resources.getString(R.string.archived_conversation), + currentConversation?.displayName + ), + Snackbar.LENGTH_LONG + ).show() + } + popupWindow.dismiss() } - popupWindow.dismiss() + } else { + unarchiveConversation.visibility = View.VISIBLE + archiveConversation.visibility = View.GONE + unarchiveConversation.setOnClickListener { + this.lifecycleScope.launch { + conversationInfoViewModel.unarchiveConversation( + conversationUser!!, + currentConversation?.token!! + ) + Snackbar.make( + binding.root, + String.format( + context.resources.getString(R.string.unarchived_conversation), + currentConversation?.displayName + ), + Snackbar.LENGTH_LONG + ).show() + } + popupWindow.dismiss() + } + } } else { archiveConversation.visibility = View.GONE + unarchiveConversation.visibility = View.GONE } } diff --git a/app/src/main/res/drawable/baseline_calendar_today_24.xml b/app/src/main/res/drawable/baseline_calendar_today_24.xml new file mode 100644 index 000000000..5a569b829 --- /dev/null +++ b/app/src/main/res/drawable/baseline_calendar_today_24.xml @@ -0,0 +1,19 @@ +<!-- + ~ Nextcloud Talk - Android Client + ~ + ~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kch@gmail.com> + ~ SPDX-License-Identifier: GPL-3.0-or-later + --> + +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:height="20dp" + android:tint="#000000" + android:viewportHeight="24" + android:viewportWidth="24" + android:width="20dp"> + + <path android:fillColor="@android:color/white" + android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z"/> + +</vector> diff --git a/app/src/main/res/drawable/calendar_clock.xml b/app/src/main/res/drawable/calendar_clock.xml deleted file mode 100644 index fddc4d044..000000000 --- a/app/src/main/res/drawable/calendar_clock.xml +++ /dev/null @@ -1,16 +0,0 @@ -<!-- - ~ Nextcloud Talk - Android Client - ~ - ~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kch@gmail.com> - ~ SPDX-License-Identifier: GPL-3.0-or-later - --> - -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:fillColor="#FF000000" - android:pathData="M15,13H16.5V15.82L18.94,17.23L18.19,18.53L15,16.69V13M19,8H5V19H9.67C9.24,18.09 9,17.07 9,16A7,7 0,0 1,16 9C17.07,9 18.09,9.24 19,9.67V8M5,21C3.89,21 3,20.1 3,19V5C3,3.89 3.89,3 5,3H6V1H8V3H16V1H18V3H19A2,2 0,0 1,21 5V11.1C22.24,12.36 23,14.09 23,16A7,7 0,0 1,16 23C14.09,23 12.36,22.24 11.1,21H5M16,11.15A4.85,4.85 0,0 0,11.15 16C11.15,18.68 13.32,20.85 16,20.85A4.85,4.85 0,0 0,20.85 16C20.85,13.32 18.68,11.15 16,11.15Z"/> -</vector> diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index addb2536c..502fd1122 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -46,4 +46,12 @@ android:text="@string/archive_conversation" android:visibility = "gone" android:paddingTop="16dp"/> + + <TextView + android:id="@+id/unarchive_conversation" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/unarchive_conversation" + android:visibility = "gone" + android:paddingTop="16dp"/> </LinearLayout> \ No newline at end of file diff --git a/app/src/main/res/menu/menu_conversation.xml b/app/src/main/res/menu/menu_conversation.xml index ffcd29932..c7830b0dc 100644 --- a/app/src/main/res/menu/menu_conversation.xml +++ b/app/src/main/res/menu/menu_conversation.xml @@ -10,7 +10,7 @@ <item android:id="@+id/conversation_event" - android:icon="@drawable/calendar_clock" + android:icon="@drawable/baseline_calendar_today_24" android:orderInCategory="0" android:title="@string/nc_event_conversation_menu" app:showAsAction="ifRoom"> From 40ffa582e30a78ef91eec0bf39c063259dc8fa04 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 14 Apr 2025 13:40:16 +0200 Subject: [PATCH 11/22] fix detekt Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/chat/ChatActivity.kt | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt index 62d67e4f2..20382f661 100644 --- a/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/chat/ChatActivity.kt @@ -2890,7 +2890,6 @@ class ChatActivity : setActionBarTitle() } - return true } @@ -2983,9 +2982,6 @@ class ChatActivity : val titleTextView = popupView.findViewById<TextView>(R.id.event_scheduled) val subtitleTextView = popupView.findViewById<TextView>(R.id.meetingTime) - val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation) - val archiveConversation = popupView.findViewById<TextView>(R.id.archive_conversation) - val unarchiveConversation = popupView.findViewById<TextView>(R.id.unarchive_conversation) val popupWindow = PopupWindow( popupView, @@ -3001,6 +2997,12 @@ class ChatActivity : val meetingStatus = showEventSchedule() subtitleTextView.text = meetingStatus + deleteEventConversation(meetingStatus, popupWindow, popupView) + archiveEventConversation(meetingStatus, popupWindow, popupView) + } + + private fun deleteEventConversation(meetingStatus: String, popupWindow: PopupWindow, popupView: View) { + val deleteConversation = popupView.findViewById<TextView>(R.id.delete_conversation) if (meetingStatus == context.resources.getString(R.string.nc_meeting_ended) && currentConversation?.canDeleteConversation == true ) { @@ -3034,9 +3036,14 @@ class ChatActivity : } else { deleteConversation.visibility = View.GONE } + } + private fun archiveEventConversation(meetingStatus: String, popupWindow: PopupWindow, popupView: View) { + val archiveConversation = popupView.findViewById<TextView>(R.id.archive_conversation) + val unarchiveConversation = popupView.findViewById<TextView>(R.id.unarchive_conversation) if (meetingStatus == context.resources.getString(R.string.nc_meeting_ended) && - (Participant.ParticipantType.MODERATOR == currentConversation?.participantType || + ( + Participant.ParticipantType.MODERATOR == currentConversation?.participantType || Participant.ParticipantType.OWNER == currentConversation?.participantType ) ) { @@ -3077,7 +3084,6 @@ class ChatActivity : } popupWindow.dismiss() } - } } else { archiveConversation.visibility = View.GONE From d2bb9b6223ca2e5e27d918bc1e6efaa4520f80c0 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 14 Apr 2025 15:04:20 +0200 Subject: [PATCH 12/22] fix detekt + add objectId in tests Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../com/nextcloud/talk/data/database/dao/ChatBlocksDaoTest.kt | 1 + .../com/nextcloud/talk/data/database/dao/ChatMessagesDaoTest.kt | 1 + .../java/com/nextcloud/talk/models/domain/ConversationModel.kt | 1 + 3 files changed, 3 insertions(+) diff --git a/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatBlocksDaoTest.kt b/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatBlocksDaoTest.kt index 6b2b06ecf..8e077f863 100644 --- a/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatBlocksDaoTest.kt +++ b/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatBlocksDaoTest.kt @@ -215,6 +215,7 @@ class ChatBlocksDaoTest { lobbyState = ConversationEnums.LobbyState.LOBBY_STATE_MODERATORS_ONLY, lobbyTimer = 0, objectType = ConversationEnums.ObjectType.FILE, + objectId = "", statusIcon = null, description = "", displayName = "", diff --git a/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatMessagesDaoTest.kt b/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatMessagesDaoTest.kt index 7b3f6876d..a6f8386e7 100644 --- a/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatMessagesDaoTest.kt +++ b/app/src/androidTest/java/com/nextcloud/talk/data/database/dao/ChatMessagesDaoTest.kt @@ -211,6 +211,7 @@ class ChatMessagesDaoTest { lobbyState = ConversationEnums.LobbyState.LOBBY_STATE_MODERATORS_ONLY, lobbyTimer = 0, objectType = ConversationEnums.ObjectType.FILE, + objectId = "", statusIcon = null, description = "", displayName = "", diff --git a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt index d9c30ee22..5e1f845d3 100644 --- a/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt +++ b/app/src/main/java/com/nextcloud/talk/models/domain/ConversationModel.kt @@ -67,6 +67,7 @@ class ConversationModel( ) { companion object { + @Suppress("LongMethod") fun mapToConversationModel(conversation: Conversation, user: User): ConversationModel { return ConversationModel( internalId = user.id!!.toString() + "@" + conversation.token, From 3d8dee966a40ad078914fbc8c328253cff27c7b3 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 12 May 2025 17:06:40 +0200 Subject: [PATCH 13/22] shows events older than 16 hours + padding for menu items Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../conversationlist/ConversationsListActivity.kt | 2 +- app/src/main/res/layout/item_event_schedule.xml | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 3fecd21de..71b0f2035 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -2137,7 +2137,7 @@ class ConversationsListActivity : const val NOTIFICATION_WARNING_DATE_NOT_SET = 0L const val OFFSET_HEIGHT_DIVIDER: Int = 3 const val ROOM_TYPE_ONE_ONE = "1" - private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 86400 + private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 57600 const val LONG_1000: Long = 1000 } } diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index 502fd1122..6a9016758 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -20,14 +20,14 @@ android:layout_height="wrap_content" android:text="@string/nc_event_schedule" android:textStyle="bold" - android:textSize="16sp" /> + android:textSize="18sp" /> <TextView android:id="@+id/meetingTime" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textColor="?android:attr/textColorSecondary" - android:textSize="14sp" + android:textSize="16sp" tools:text="Meeting at 8:00 pm"/> <TextView @@ -37,7 +37,8 @@ android:text="@string/nc_delete_call" android:textColor="@android:color/holo_red_dark" android:visibility = "gone" - android:paddingTop="16dp"/> + android:textSize="18sp" + android:paddingTop="24dp"/> <TextView android:id="@+id/archive_conversation" @@ -45,7 +46,8 @@ android:layout_height="wrap_content" android:text="@string/archive_conversation" android:visibility = "gone" - android:paddingTop="16dp"/> + android:textSize="18sp" + android:paddingTop="24dp"/> <TextView android:id="@+id/unarchive_conversation" @@ -53,5 +55,6 @@ android:layout_height="wrap_content" android:text="@string/unarchive_conversation" android:visibility = "gone" - android:paddingTop="16dp"/> + android:textSize="18sp" + android:paddingTop="24dp"/> </LinearLayout> \ No newline at end of file From 853f173740967eb657125c8d37fb76f0b6fd3627 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Mon, 12 May 2025 17:54:20 +0200 Subject: [PATCH 14/22] database migrations Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../14.json | 719 ++++++++++++++++++ .../talk/data/source/local/Migrations.kt | 20 + .../talk/data/source/local/TalkDatabase.kt | 7 +- 3 files changed, 743 insertions(+), 3 deletions(-) create mode 100644 app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/14.json diff --git a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/14.json b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/14.json new file mode 100644 index 000000000..cc73f1e94 --- /dev/null +++ b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/14.json @@ -0,0 +1,719 @@ +{ + "formatVersion": 1, + "database": { + "version": 14, + "identityHash": "506abc931eb3b657cafe6ad1b25f635d", + "entities": [ + { + "tableName": "User", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `userId` TEXT, `username` TEXT, `baseUrl` TEXT, `token` TEXT, `displayName` TEXT, `pushConfigurationState` TEXT, `capabilities` TEXT, `serverVersion` TEXT DEFAULT '', `clientCertificate` TEXT, `externalSignalingServer` TEXT, `current` INTEGER NOT NULL, `scheduledForDeletion` INTEGER NOT NULL)", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "userId", + "columnName": "userId", + "affinity": "TEXT" + }, + { + "fieldPath": "username", + "columnName": "username", + "affinity": "TEXT" + }, + { + "fieldPath": "baseUrl", + "columnName": "baseUrl", + "affinity": "TEXT" + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT" + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT" + }, + { + "fieldPath": "pushConfigurationState", + "columnName": "pushConfigurationState", + "affinity": "TEXT" + }, + { + "fieldPath": "capabilities", + "columnName": "capabilities", + "affinity": "TEXT" + }, + { + "fieldPath": "serverVersion", + "columnName": "serverVersion", + "affinity": "TEXT", + "defaultValue": "''" + }, + { + "fieldPath": "clientCertificate", + "columnName": "clientCertificate", + "affinity": "TEXT" + }, + { + "fieldPath": "externalSignalingServer", + "columnName": "externalSignalingServer", + "affinity": "TEXT" + }, + { + "fieldPath": "current", + "columnName": "current", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "scheduledForDeletion", + "columnName": "scheduledForDeletion", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + } + }, + { + "tableName": "ArbitraryStorage", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`accountIdentifier` INTEGER NOT NULL, `key` TEXT NOT NULL, `object` TEXT, `value` TEXT, PRIMARY KEY(`accountIdentifier`, `key`))", + "fields": [ + { + "fieldPath": "accountIdentifier", + "columnName": "accountIdentifier", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "key", + "columnName": "key", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "storageObject", + "columnName": "object", + "affinity": "TEXT" + }, + { + "fieldPath": "value", + "columnName": "value", + "affinity": "TEXT" + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "accountIdentifier", + "key" + ] + } + }, + { + "tableName": "Conversations", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `objectId` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "internalId", + "columnName": "internalId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "displayName", + "columnName": "displayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actorId", + "columnName": "actorId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actorType", + "columnName": "actorType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "avatarVersion", + "columnName": "avatarVersion", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "callFlag", + "columnName": "callFlag", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "callRecording", + "columnName": "callRecording", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "callStartTime", + "columnName": "callStartTime", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canDeleteConversation", + "columnName": "canDeleteConversation", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canLeaveConversation", + "columnName": "canLeaveConversation", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "canStartCall", + "columnName": "canStartCall", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "description", + "columnName": "description", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "hasCall", + "columnName": "hasCall", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasPassword", + "columnName": "hasPassword", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasCustomAvatar", + "columnName": "isCustomAvatar", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "favorite", + "columnName": "isFavorite", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastActivity", + "columnName": "lastActivity", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastCommonReadMessage", + "columnName": "lastCommonReadMessage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastMessage", + "columnName": "lastMessage", + "affinity": "TEXT" + }, + { + "fieldPath": "lastPing", + "columnName": "lastPing", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastReadMessage", + "columnName": "lastReadMessage", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lobbyState", + "columnName": "lobbyState", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "lobbyTimer", + "columnName": "lobbyTimer", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "messageExpiration", + "columnName": "messageExpiration", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "name", + "columnName": "name", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "notificationCalls", + "columnName": "notificationCalls", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "notificationLevel", + "columnName": "notificationLevel", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "objectType", + "columnName": "objectType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "objectId", + "columnName": "objectId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "participantType", + "columnName": "participantType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "permissions", + "columnName": "permissions", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "conversationReadOnlyState", + "columnName": "readOnly", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "recordingConsentRequired", + "columnName": "recordingConsent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "remoteServer", + "columnName": "remoteServer", + "affinity": "TEXT" + }, + { + "fieldPath": "remoteToken", + "columnName": "remoteToken", + "affinity": "TEXT" + }, + { + "fieldPath": "sessionId", + "columnName": "sessionId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "status", + "columnName": "status", + "affinity": "TEXT" + }, + { + "fieldPath": "statusClearAt", + "columnName": "statusClearAt", + "affinity": "INTEGER" + }, + { + "fieldPath": "statusIcon", + "columnName": "statusIcon", + "affinity": "TEXT" + }, + { + "fieldPath": "statusMessage", + "columnName": "statusMessage", + "affinity": "TEXT" + }, + { + "fieldPath": "type", + "columnName": "type", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "unreadMention", + "columnName": "unreadMention", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadMentionDirect", + "columnName": "unreadMentionDirect", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "unreadMessages", + "columnName": "unreadMessages", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasArchived", + "columnName": "hasArchived", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "internalId" + ] + }, + "indices": [ + { + "name": "index_Conversations_accountId", + "unique": false, + "columnNames": [ + "accountId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_Conversations_accountId` ON `${TABLE_NAME}` (`accountId`)" + } + ], + "foreignKeys": [ + { + "table": "User", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "accountId" + ], + "referencedColumns": [ + "id" + ] + } + ] + }, + { + "tableName": "ChatMessages", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `id` INTEGER NOT NULL, `internalConversationId` TEXT NOT NULL, `actorDisplayName` TEXT NOT NULL, `message` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `deleted` INTEGER NOT NULL, `expirationTimestamp` INTEGER NOT NULL, `isReplyable` INTEGER NOT NULL, `isTemporary` INTEGER NOT NULL, `lastEditActorDisplayName` TEXT, `lastEditActorId` TEXT, `lastEditActorType` TEXT, `lastEditTimestamp` INTEGER, `markdown` INTEGER, `messageParameters` TEXT, `messageType` TEXT NOT NULL, `parent` INTEGER, `reactions` TEXT, `reactionsSelf` TEXT, `referenceId` TEXT, `sendingFailed` INTEGER NOT NULL, `silent` INTEGER NOT NULL, `systemMessage` TEXT NOT NULL, `timestamp` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`internalConversationId`) REFERENCES `Conversations`(`internalId`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "internalId", + "columnName": "internalId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "internalConversationId", + "columnName": "internalConversationId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actorDisplayName", + "columnName": "actorDisplayName", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "message", + "columnName": "message", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actorId", + "columnName": "actorId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "actorType", + "columnName": "actorType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "deleted", + "columnName": "deleted", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "expirationTimestamp", + "columnName": "expirationTimestamp", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "replyable", + "columnName": "isReplyable", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "isTemporary", + "columnName": "isTemporary", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "lastEditActorDisplayName", + "columnName": "lastEditActorDisplayName", + "affinity": "TEXT" + }, + { + "fieldPath": "lastEditActorId", + "columnName": "lastEditActorId", + "affinity": "TEXT" + }, + { + "fieldPath": "lastEditActorType", + "columnName": "lastEditActorType", + "affinity": "TEXT" + }, + { + "fieldPath": "lastEditTimestamp", + "columnName": "lastEditTimestamp", + "affinity": "INTEGER" + }, + { + "fieldPath": "renderMarkdown", + "columnName": "markdown", + "affinity": "INTEGER" + }, + { + "fieldPath": "messageParameters", + "columnName": "messageParameters", + "affinity": "TEXT" + }, + { + "fieldPath": "messageType", + "columnName": "messageType", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "parentMessageId", + "columnName": "parent", + "affinity": "INTEGER" + }, + { + "fieldPath": "reactions", + "columnName": "reactions", + "affinity": "TEXT" + }, + { + "fieldPath": "reactionsSelf", + "columnName": "reactionsSelf", + "affinity": "TEXT" + }, + { + "fieldPath": "referenceId", + "columnName": "referenceId", + "affinity": "TEXT" + }, + { + "fieldPath": "sendingFailed", + "columnName": "sendingFailed", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "silent", + "columnName": "silent", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "systemMessageType", + "columnName": "systemMessage", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "timestamp", + "columnName": "timestamp", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": false, + "columnNames": [ + "internalId" + ] + }, + "indices": [ + { + "name": "index_ChatMessages_internalId", + "unique": true, + "columnNames": [ + "internalId" + ], + "orders": [], + "createSql": "CREATE UNIQUE INDEX IF NOT EXISTS `index_ChatMessages_internalId` ON `${TABLE_NAME}` (`internalId`)" + }, + { + "name": "index_ChatMessages_internalConversationId", + "unique": false, + "columnNames": [ + "internalConversationId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_ChatMessages_internalConversationId` ON `${TABLE_NAME}` (`internalConversationId`)" + } + ], + "foreignKeys": [ + { + "table": "Conversations", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "internalConversationId" + ], + "referencedColumns": [ + "internalId" + ] + } + ] + }, + { + "tableName": "ChatBlocks", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `internalConversationId` TEXT NOT NULL, `accountId` INTEGER, `token` TEXT, `oldestMessageId` INTEGER NOT NULL, `newestMessageId` INTEGER NOT NULL, `hasHistory` INTEGER NOT NULL, FOREIGN KEY(`internalConversationId`) REFERENCES `Conversations`(`internalId`) ON UPDATE CASCADE ON DELETE CASCADE )", + "fields": [ + { + "fieldPath": "id", + "columnName": "id", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "internalConversationId", + "columnName": "internalConversationId", + "affinity": "TEXT", + "notNull": true + }, + { + "fieldPath": "accountId", + "columnName": "accountId", + "affinity": "INTEGER" + }, + { + "fieldPath": "token", + "columnName": "token", + "affinity": "TEXT" + }, + { + "fieldPath": "oldestMessageId", + "columnName": "oldestMessageId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "newestMessageId", + "columnName": "newestMessageId", + "affinity": "INTEGER", + "notNull": true + }, + { + "fieldPath": "hasHistory", + "columnName": "hasHistory", + "affinity": "INTEGER", + "notNull": true + } + ], + "primaryKey": { + "autoGenerate": true, + "columnNames": [ + "id" + ] + }, + "indices": [ + { + "name": "index_ChatBlocks_internalConversationId", + "unique": false, + "columnNames": [ + "internalConversationId" + ], + "orders": [], + "createSql": "CREATE INDEX IF NOT EXISTS `index_ChatBlocks_internalConversationId` ON `${TABLE_NAME}` (`internalConversationId`)" + } + ], + "foreignKeys": [ + { + "table": "Conversations", + "onDelete": "CASCADE", + "onUpdate": "CASCADE", + "columns": [ + "internalConversationId" + ], + "referencedColumns": [ + "internalId" + ] + } + ] + } + ], + "setupQueries": [ + "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '506abc931eb3b657cafe6ad1b25f635d')" + ] + } +} \ No newline at end of file diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt index 85c3239be..016182efc 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt @@ -55,6 +55,13 @@ object Migrations { } } + val MIGRATION_13_14 = object:Migration(13,14) { + override fun migrate(db: SupportSQLiteDatabase) { + Log.i("Migrations", "Migrating 13 to 14") + addObjectId(db) + } + } + fun migrateToRoom(db: SupportSQLiteDatabase) { db.execSQL( "CREATE TABLE User_new (" + @@ -265,6 +272,19 @@ object Migrations { } } + + fun addObjectId(db: SupportSQLiteDatabase) { + + try { + db.execSQL( + "ALTER TABLE Conversations " + + "ADD COLUMN objectId TEXT ;" + ) + } catch (e: Exception) { + Log.i("Migrations", "Something went wrong when adding column referenceId to table ChatMessages") + } + } + fun addTempMessagesSupport(db: SupportSQLiteDatabase) { try { db.execSQL( diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt index 94f5a3709..94ac91c1e 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt @@ -49,9 +49,9 @@ import java.util.Locale ChatMessageEntity::class, ChatBlockEntity::class ], - version = 13, + version = 14, autoMigrations = [ - AutoMigration(from = 9, to = 11) + AutoMigration(from = 9, to = 13) ], exportSchema = true ) @@ -115,7 +115,8 @@ abstract class TalkDatabase : RoomDatabase() { Migrations.MIGRATION_8_9, Migrations.MIGRATION_10_11, Migrations.MIGRATION_11_12, - Migrations.MIGRATION_12_13 + Migrations.MIGRATION_12_13, + Migrations.MIGRATION_13_14 ) .allowMainThreadQueries() .addCallback( From 8231e6b35c99b9bb9a7f97e03a2df4b3edc31317 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Tue, 13 May 2025 11:25:25 +0200 Subject: [PATCH 15/22] fix search Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../ConversationsListActivity.kt | 42 +++++++++++-------- .../talk/data/source/local/Migrations.kt | 6 +-- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 71b0f2035..8039e2480 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -210,6 +210,7 @@ class ConversationsListActivity : private var conversationItemsWithHeader: MutableList<AbstractFlexibleItem<*>> = ArrayList() private val searchableConversationItems: MutableList<AbstractFlexibleItem<*>> = ArrayList() private var filterableConversationItems: MutableList<AbstractFlexibleItem<*>> = ArrayList() + private var nearFutureEventConversationItems: MutableList<AbstractFlexibleItem<*>> = ArrayList() private var searchItem: MenuItem? = null private var chooseAccountItem: MenuItem? = null private var searchView: SearchView? = null @@ -519,22 +520,28 @@ class ConversationsListActivity : // Update Conversations conversationItems.clear() conversationItemsWithHeader.clear() - searchableConversationItems.clear() + nearFutureEventConversationItems.clear() for (conversation in list) { if (!futureEvent(conversation)) { - addToConversationItems(conversation) + addToNearFutureEventConversationItems(conversation) } - addToSearchableConversationItems(conversation) + addToConversationItems(conversation) } sortConversations(conversationItems) sortConversations(conversationItemsWithHeader) - // Filter Conversations - if (!hasFilterEnabled()) filterableConversationItems = conversationItems - filterConversation() - adapter?.updateDataSet(filterableConversationItems, false) + if (!hasFilterEnabled() && searchBehaviorSubject.value == false) { + adapter?.updateDataSet(nearFutureEventConversationItems, false) + } else { + // Filter Conversations + if (!hasFilterEnabled()) { + filterableConversationItems = conversationItems + } + filterConversation() + adapter?.updateDataSet(filterableConversationItems, false) + } Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong()) // Fetch Open Conversations @@ -565,14 +572,9 @@ class ConversationsListActivity : AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS } - private fun addToSearchableConversationItems(conversation: ConversationModel) { - val headerTitle = resources!!.getString(R.string.conversations) - val headerItem = callHeaderItems.getOrPut(headerTitle) { - GenericTextHeaderItem(headerTitle, viewThemeUtils) - } - - val conversationItem = ConversationItem(conversation, currentUser!!, this, headerItem, viewThemeUtils) - searchableConversationItems.add(conversationItem) + private fun addToNearFutureEventConversationItems(conversation: ConversationModel) { + val conversationItem = ConversationItem(conversation, currentUser!!, this, null, viewThemeUtils) + nearFutureEventConversationItems.add(conversationItem) } fun filterConversation() { @@ -862,15 +864,19 @@ class ConversationsListActivity : override fun onMenuItemActionCollapse(item: MenuItem): Boolean { adapter?.setHeadersShown(false) + searchBehaviorSubject.onNext(false) if (!hasFilterEnabled()) filterableConversationItems = conversationItemsWithHeader - adapter?.updateDataSet(filterableConversationItems, false) + if (!hasFilterEnabled()) { + adapter?.updateDataSet(nearFutureEventConversationItems, false) + } else { + filterableConversationItems = conversationItems + } adapter?.hideAllHeaders() if (searchHelper != null) { // cancel any pending searches searchHelper!!.cancelSearch() } binding.swipeRefreshLayoutView.isRefreshing = false - searchBehaviorSubject.onNext(false) binding.swipeRefreshLayoutView.isEnabled = true searchView!!.onActionViewCollapsed() @@ -1094,6 +1100,8 @@ class ConversationsListActivity : } private fun fetchOpenConversations(apiVersion: Int) { + searchableConversationItems.clear() + searchableConversationItems.addAll(conversationItemsWithHeader) if (hasSpreedFeatureCapability( currentUser!!.capabilities!!.spreedCapability!!, SpreedFeatures.LISTABLE_ROOMS diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt index 016182efc..68b70c916 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt @@ -278,10 +278,10 @@ object Migrations { try { db.execSQL( "ALTER TABLE Conversations " + - "ADD COLUMN objectId TEXT ;" + "ADD COLUMN objectId TEXT NOT NULL DEFAULT '';" ) - } catch (e: Exception) { - Log.i("Migrations", "Something went wrong when adding column referenceId to table ChatMessages") + } catch (e: SQLException) { + Log.i("Migrations", "Something went wrong when adding column objectId to table Conversations") } } From 9474a02c3a1520db4206738db6c106cce91904e9 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 14 May 2025 11:01:19 +0200 Subject: [PATCH 16/22] show future events in filters and hide them when filters are disabled Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../conversationlist/ConversationsListActivity.kt | 4 ++++ .../nextcloud/talk/data/source/local/Migrations.kt | 4 +--- .../talk/ui/dialog/FilterConversationFragment.kt | 13 +++++++++++++ 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 8039e2480..257a6ea12 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -572,6 +572,10 @@ class ConversationsListActivity : AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS } + fun showOnlyNearFutureEvents() { + adapter?.updateDataSet(nearFutureEventConversationItems, false) + } + private fun addToNearFutureEventConversationItems(conversation: ConversationModel) { val conversationItem = ConversationItem(conversation, currentUser!!, this, null, viewThemeUtils) nearFutureEventConversationItems.add(conversationItem) diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt index 68b70c916..af8089edf 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/Migrations.kt @@ -55,7 +55,7 @@ object Migrations { } } - val MIGRATION_13_14 = object:Migration(13,14) { + val MIGRATION_13_14 = object : Migration(13, 14) { override fun migrate(db: SupportSQLiteDatabase) { Log.i("Migrations", "Migrating 13 to 14") addObjectId(db) @@ -272,9 +272,7 @@ object Migrations { } } - fun addObjectId(db: SupportSQLiteDatabase) { - try { db.execSQL( "ALTER TABLE Conversations " + diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt index d78f3d2e8..80346beba 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt @@ -7,6 +7,7 @@ package com.nextcloud.talk.ui.dialog import android.app.Dialog +import android.content.DialogInterface import android.os.Build import android.os.Bundle import android.view.LayoutInflater @@ -99,6 +100,10 @@ class FilterConversationFragment : DialogFragment() { } binding.buttonClose.setOnClickListener { + val noFiltersActive = !(filterState[MENTION] == true || filterState[UNREAD] == true || filterState[ARCHIVE] == true) + if (noFiltersActive) { + (requireActivity() as ConversationsListActivity).showOnlyNearFutureEvents() + } dismiss() } } @@ -130,6 +135,14 @@ class FilterConversationFragment : DialogFragment() { (requireActivity() as ConversationsListActivity).filterConversation() } + override fun onDismiss(dialog: DialogInterface) { + super.onDismiss(dialog) + val noFiltersActive = !(filterState[MENTION] == true || filterState[UNREAD] == true || filterState[ARCHIVE] == true) + if (noFiltersActive) { + (requireActivity() as ConversationsListActivity).showOnlyNearFutureEvents() + } + } + companion object { private const val FILTER_STATE_ARG = "FILTER_STATE_ARG" From 0a35f23b4ea594daf95b4d5ab15ffff93cb03bf1 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 14 May 2025 11:03:59 +0200 Subject: [PATCH 17/22] ktlintFormat Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../talk/ui/dialog/FilterConversationFragment.kt | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt b/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt index 80346beba..c95a7464a 100644 --- a/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt +++ b/app/src/main/java/com/nextcloud/talk/ui/dialog/FilterConversationFragment.kt @@ -100,7 +100,11 @@ class FilterConversationFragment : DialogFragment() { } binding.buttonClose.setOnClickListener { - val noFiltersActive = !(filterState[MENTION] == true || filterState[UNREAD] == true || filterState[ARCHIVE] == true) + val noFiltersActive = !( + filterState[MENTION] == true || + filterState[UNREAD] == true || + filterState[ARCHIVE] == true + ) if (noFiltersActive) { (requireActivity() as ConversationsListActivity).showOnlyNearFutureEvents() } @@ -137,7 +141,11 @@ class FilterConversationFragment : DialogFragment() { override fun onDismiss(dialog: DialogInterface) { super.onDismiss(dialog) - val noFiltersActive = !(filterState[MENTION] == true || filterState[UNREAD] == true || filterState[ARCHIVE] == true) + val noFiltersActive = !( + filterState[MENTION] == true || + filterState[UNREAD] == true || + filterState[ARCHIVE] == true + ) if (noFiltersActive) { (requireActivity() as ConversationsListActivity).showOnlyNearFutureEvents() } From 945d4a907c88f29a0468b20b9770b248dc16009e Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 14 May 2025 12:38:41 +0200 Subject: [PATCH 18/22] background color of menu item Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- app/src/main/res/layout/item_event_schedule.xml | 2 +- app/src/main/res/values-night/colors.xml | 1 + app/src/main/res/values/colors.xml | 2 ++ 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/res/layout/item_event_schedule.xml b/app/src/main/res/layout/item_event_schedule.xml index 6a9016758..ebc69f470 100644 --- a/app/src/main/res/layout/item_event_schedule.xml +++ b/app/src/main/res/layout/item_event_schedule.xml @@ -12,7 +12,7 @@ xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:padding="16dp" - android:background="@color/dialog_background"> + android:background="@color/popup_menu_color"> <TextView android:id="@+id/event_scheduled" diff --git a/app/src/main/res/values-night/colors.xml b/app/src/main/res/values-night/colors.xml index e433c4160..df8bcb4d6 100644 --- a/app/src/main/res/values-night/colors.xml +++ b/app/src/main/res/values-night/colors.xml @@ -12,6 +12,7 @@ <color name="colorPrimaryDark">#006AA3</color> <color name="colorAccent">@color/colorPrimary</color> <color name="disabled_text">#ff6F6F6F</color> + <color name="popup_menu_color">#FF37474F</color> <!-- App bar --> <color name="appbar">#1E1E1E</color> diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index 7c1c45969..829a9ed53 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -13,6 +13,8 @@ <color name="disabled_text">#ff888888</color> <color name="textColorOnPrimaryBackground">#ffffff</color> <!-- white/black depending on primary color --> <color name="nc_login_text_color">#B3FFFFFF</color> + <color name="popup_menu_color">#FF607D8B</color> + <!-- App bar --> <color name="appbar">@android:color/white</color> From 97aa697ce82733027e24effb680b2ada9393a618 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 14 May 2025 13:53:23 +0200 Subject: [PATCH 19/22] sort near future events Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../nextcloud/talk/conversationlist/ConversationsListActivity.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 257a6ea12..0c481581f 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -531,6 +531,7 @@ class ConversationsListActivity : sortConversations(conversationItems) sortConversations(conversationItemsWithHeader) + sortConversations(nearFutureEventConversationItems) if (!hasFilterEnabled() && searchBehaviorSubject.value == false) { adapter?.updateDataSet(nearFutureEventConversationItems, false) From 1a1d7b1f212599e98ffd99c6522c2630616dcd91 Mon Sep 17 00:00:00 2001 From: sowjanyakch <sowjanya.kch@gmail.com> Date: Wed, 14 May 2025 15:39:49 +0200 Subject: [PATCH 20/22] sort conversations Signed-off-by: sowjanyakch <sowjanya.kch@gmail.com> --- .../talk/conversationlist/ConversationsListActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt index 0c481581f..1579eafc6 100644 --- a/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt +++ b/app/src/main/java/com/nextcloud/talk/conversationlist/ConversationsListActivity.kt @@ -574,7 +574,9 @@ class ConversationsListActivity : } fun showOnlyNearFutureEvents() { + sortConversations(nearFutureEventConversationItems) adapter?.updateDataSet(nearFutureEventConversationItems, false) + adapter?.smoothScrollToPosition(0) } private fun addToNearFutureEventConversationItems(conversation: ConversationModel) { From 2836ba83e2be00ff17a39e7266c08c9e7d5d1704 Mon Sep 17 00:00:00 2001 From: Marcel Hibbe <dev@mhibbe.de> Date: Wed, 14 May 2025 17:00:11 +0200 Subject: [PATCH 21/22] revert 13.json it was accidentally commited in 867ae334 Signed-off-by: Marcel Hibbe <dev@mhibbe.de> --- .../13.json | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json index 100acd968..2e2345001 100644 --- a/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json +++ b/app/schemas/com.nextcloud.talk.data.source.local.TalkDatabase/13.json @@ -2,7 +2,7 @@ "formatVersion": 1, "database": { "version": 13, - "identityHash": "506abc931eb3b657cafe6ad1b25f635d", + "identityHash": "a521f027909f69f4c7d1855f84a2e67f", "entities": [ { "tableName": "User", @@ -138,7 +138,7 @@ }, { "tableName": "Conversations", - "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `objectId` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", + "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`internalId` TEXT NOT NULL, `accountId` INTEGER NOT NULL, `token` TEXT NOT NULL, `displayName` TEXT NOT NULL, `actorId` TEXT NOT NULL, `actorType` TEXT NOT NULL, `avatarVersion` TEXT NOT NULL, `callFlag` INTEGER NOT NULL, `callRecording` INTEGER NOT NULL, `callStartTime` INTEGER NOT NULL, `canDeleteConversation` INTEGER NOT NULL, `canLeaveConversation` INTEGER NOT NULL, `canStartCall` INTEGER NOT NULL, `description` TEXT NOT NULL, `hasCall` INTEGER NOT NULL, `hasPassword` INTEGER NOT NULL, `isCustomAvatar` INTEGER NOT NULL, `isFavorite` INTEGER NOT NULL, `lastActivity` INTEGER NOT NULL, `lastCommonReadMessage` INTEGER NOT NULL, `lastMessage` TEXT, `lastPing` INTEGER NOT NULL, `lastReadMessage` INTEGER NOT NULL, `lobbyState` TEXT NOT NULL, `lobbyTimer` INTEGER NOT NULL, `messageExpiration` INTEGER NOT NULL, `name` TEXT NOT NULL, `notificationCalls` INTEGER NOT NULL, `notificationLevel` TEXT NOT NULL, `objectType` TEXT NOT NULL, `participantType` TEXT NOT NULL, `permissions` INTEGER NOT NULL, `readOnly` TEXT NOT NULL, `recordingConsent` INTEGER NOT NULL, `remoteServer` TEXT, `remoteToken` TEXT, `sessionId` TEXT NOT NULL, `status` TEXT, `statusClearAt` INTEGER, `statusIcon` TEXT, `statusMessage` TEXT, `type` TEXT NOT NULL, `unreadMention` INTEGER NOT NULL, `unreadMentionDirect` INTEGER NOT NULL, `unreadMessages` INTEGER NOT NULL, `hasArchived` INTEGER NOT NULL, PRIMARY KEY(`internalId`), FOREIGN KEY(`accountId`) REFERENCES `User`(`id`) ON UPDATE CASCADE ON DELETE CASCADE )", "fields": [ { "fieldPath": "internalId", @@ -320,12 +320,6 @@ "affinity": "TEXT", "notNull": true }, - { - "fieldPath": "objectId", - "columnName": "objectId", - "affinity": "TEXT", - "notNull": true - }, { "fieldPath": "participantType", "columnName": "participantType", @@ -749,7 +743,7 @@ "views": [], "setupQueries": [ "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)", - "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '506abc931eb3b657cafe6ad1b25f635d')" + "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'a521f027909f69f4c7d1855f84a2e67f')" ] } } \ No newline at end of file From 79ef534e8068035d8686a17223551738bdc5a07b Mon Sep 17 00:00:00 2001 From: Marcel Hibbe <dev@mhibbe.de> Date: Wed, 14 May 2025 17:05:05 +0200 Subject: [PATCH 22/22] fix to only use auto migration when no manual migration is in place this will fix the changes from commits 8eabfd6d and also 46efdf4b0c4fcae0ec7051140348f46853ac035a Signed-off-by: Marcel Hibbe <dev@mhibbe.de> --- .../java/com/nextcloud/talk/data/source/local/TalkDatabase.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt index 94ac91c1e..d86a9f4c0 100644 --- a/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt +++ b/app/src/main/java/com/nextcloud/talk/data/source/local/TalkDatabase.kt @@ -51,7 +51,7 @@ import java.util.Locale ], version = 14, autoMigrations = [ - AutoMigration(from = 9, to = 13) + AutoMigration(from = 9, to = 10) ], exportSchema = true )