mirror of
https://github.com/nextcloud/talk-android
synced 2025-07-09 13:59:48 +01:00
Merge pull request #4969 from nextcloud/improvements_event_conversations
Improvements event conversations
This commit is contained in:
commit
97f793ffbf
@ -258,4 +258,7 @@ interface NcApiCoroutines {
|
|||||||
|
|
||||||
@GET
|
@GET
|
||||||
suspend fun getProfile(@Header("Authorization") authorization: String, @Url url: String): ProfileOverall
|
suspend fun getProfile(@Header("Authorization") authorization: String, @Url url: String): ProfileOverall
|
||||||
|
|
||||||
|
@DELETE
|
||||||
|
suspend fun unbindRoom(@Header("Authorization") authorization: String, @Url url: String): GenericOverall
|
||||||
}
|
}
|
||||||
|
@ -86,6 +86,7 @@ import coil.request.CachePolicy
|
|||||||
import coil.request.ImageRequest
|
import coil.request.ImageRequest
|
||||||
import coil.target.Target
|
import coil.target.Target
|
||||||
import coil.transform.CircleCropTransformation
|
import coil.transform.CircleCropTransformation
|
||||||
|
import com.google.android.material.button.MaterialButton
|
||||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import com.google.android.material.snackbar.Snackbar
|
import com.google.android.material.snackbar.Snackbar
|
||||||
import com.nextcloud.android.common.ui.color.ColorUtil
|
import com.nextcloud.android.common.ui.color.ColorUtil
|
||||||
@ -168,6 +169,10 @@ import com.nextcloud.talk.ui.recyclerview.MessageSwipeCallback
|
|||||||
import com.nextcloud.talk.utils.ApiUtils
|
import com.nextcloud.talk.utils.ApiUtils
|
||||||
import com.nextcloud.talk.utils.AudioUtils
|
import com.nextcloud.talk.utils.AudioUtils
|
||||||
import com.nextcloud.talk.utils.CapabilitiesUtil
|
import com.nextcloud.talk.utils.CapabilitiesUtil
|
||||||
|
import com.nextcloud.talk.utils.CapabilitiesUtil.hasSpreedFeatureCapability
|
||||||
|
import com.nextcloud.talk.utils.CapabilitiesUtil.retentionOfEventRooms
|
||||||
|
import com.nextcloud.talk.utils.CapabilitiesUtil.retentionOfInstantMeetingRoom
|
||||||
|
import com.nextcloud.talk.utils.CapabilitiesUtil.retentionOfSIPRoom
|
||||||
import com.nextcloud.talk.utils.ContactUtils
|
import com.nextcloud.talk.utils.ContactUtils
|
||||||
import com.nextcloud.talk.utils.ConversationUtils
|
import com.nextcloud.talk.utils.ConversationUtils
|
||||||
import com.nextcloud.talk.utils.DateConstants
|
import com.nextcloud.talk.utils.DateConstants
|
||||||
@ -664,6 +669,59 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (currentConversation?.objectType == ConversationEnums.ObjectType.EVENT &&
|
||||||
|
hasSpreedFeatureCapability(
|
||||||
|
conversationUser?.capabilities!!.spreedCapability!!,
|
||||||
|
SpreedFeatures.UNBIND_CONVERSATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val eventEndTimeStamp =
|
||||||
|
currentConversation?.objectId
|
||||||
|
?.split("#")
|
||||||
|
?.getOrNull(1)
|
||||||
|
?.toLongOrNull()
|
||||||
|
val currentTimeStamp = (System.currentTimeMillis() / 1000).toLong()
|
||||||
|
val retentionPeriod = retentionOfEventRooms(spreedCapabilities)
|
||||||
|
val isPastEvent = eventEndTimeStamp?.let { it < currentTimeStamp }
|
||||||
|
if (isPastEvent == true && retentionPeriod != 0) {
|
||||||
|
showConversationDeletionWarning(retentionPeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConversation?.objectType == ConversationEnums.ObjectType.PHONE_TEMPORARY &&
|
||||||
|
hasSpreedFeatureCapability(
|
||||||
|
conversationUser?.capabilities!!.spreedCapability!!,
|
||||||
|
SpreedFeatures.UNBIND_CONVERSATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val retentionPeriod = retentionOfSIPRoom(spreedCapabilities)
|
||||||
|
val systemMessage = currentConversation?.lastMessage?.systemMessageType
|
||||||
|
if (retentionPeriod != 0 && (
|
||||||
|
systemMessage == ChatMessage.SystemMessageType.CALL_ENDED ||
|
||||||
|
systemMessage == ChatMessage.SystemMessageType.CALL_ENDED_EVERYONE
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
showConversationDeletionWarning(retentionPeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentConversation?.objectType == ConversationEnums.ObjectType.INSTANT_MEETING &&
|
||||||
|
hasSpreedFeatureCapability(
|
||||||
|
conversationUser?.capabilities!!.spreedCapability!!,
|
||||||
|
SpreedFeatures.UNBIND_CONVERSATION
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
val retentionPeriod = retentionOfInstantMeetingRoom(spreedCapabilities)
|
||||||
|
val systemMessage = currentConversation?.lastMessage?.systemMessageType
|
||||||
|
if (retentionPeriod != 0 && (
|
||||||
|
systemMessage == ChatMessage.SystemMessageType.CALL_ENDED ||
|
||||||
|
systemMessage == ChatMessage.SystemMessageType.CALL_ENDED_EVERYONE
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
showConversationDeletionWarning(retentionPeriod)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateRoomTimerHandler(MILLIS_250)
|
updateRoomTimerHandler(MILLIS_250)
|
||||||
|
|
||||||
val urlForChatting =
|
val urlForChatting =
|
||||||
@ -1035,6 +1093,27 @@ class ChatActivity :
|
|||||||
binding.voiceRecordingLock.y -= y
|
binding.voiceRecordingLock.y -= y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chatViewModel.unbindRoomResult.observe(this) { uiState ->
|
||||||
|
when (uiState) {
|
||||||
|
is ChatViewModel.UnbindRoomUiState.Success -> {
|
||||||
|
binding.conversationDeleteNotice.visibility = View.GONE
|
||||||
|
Snackbar.make(
|
||||||
|
binding.root,
|
||||||
|
context.getString(R.string.nc_room_retention),
|
||||||
|
Snackbar.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
is ChatViewModel.UnbindRoomUiState.Error -> {
|
||||||
|
Snackbar.make(
|
||||||
|
binding.root,
|
||||||
|
context.getString(R.string.nc_common_error_sorry),
|
||||||
|
Snackbar.LENGTH_LONG
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
else -> { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
chatViewModel.outOfOfficeViewState.observe(this) { uiState ->
|
chatViewModel.outOfOfficeViewState.observe(this) { uiState ->
|
||||||
when (uiState) {
|
when (uiState) {
|
||||||
is ChatViewModel.OutOfOfficeUIState.Error -> {
|
is ChatViewModel.OutOfOfficeUIState.Error -> {
|
||||||
@ -1150,6 +1229,63 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showConversationDeletionWarning(retentionPeriod: Int) {
|
||||||
|
binding.conversationDeleteNotice.visibility = View.VISIBLE
|
||||||
|
binding.conversationDeleteNotice.apply {
|
||||||
|
isClickable = false
|
||||||
|
isFocusable = false
|
||||||
|
bringToFront()
|
||||||
|
}
|
||||||
|
val deleteNoticeText = binding.conversationDeleteNotice.findViewById<TextView>(R.id.deletion_message)
|
||||||
|
|
||||||
|
deleteNoticeText.text = String.format(
|
||||||
|
resources.getString(R.string.nc_conversation_auto_delete_notice),
|
||||||
|
retentionPeriod
|
||||||
|
)
|
||||||
|
|
||||||
|
if (ConversationUtils.isParticipantOwnerOrModerator(currentConversation!!)) {
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.delete_now_button).visibility =
|
||||||
|
View.VISIBLE
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.keep_button).visibility = View.VISIBLE
|
||||||
|
} else {
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.delete_now_button).visibility =
|
||||||
|
View.GONE
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.keep_button).visibility = View.GONE
|
||||||
|
}
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.delete_now_button).setOnClickListener {
|
||||||
|
deleteConversationDialog(it.context)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.conversationDeleteNotice.findViewById<MaterialButton>(R.id.keep_button).setOnClickListener {
|
||||||
|
chatViewModel.unbindRoom(credentials!!, conversationUser?.baseUrl!!, currentConversation?.token!!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun deleteConversationDialog(context: Context) {
|
||||||
|
val dialogBuilder = MaterialAlertDialogBuilder(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(context, dialogBuilder)
|
||||||
|
val dialog = dialogBuilder.show()
|
||||||
|
viewThemeUtils.platform.colorTextButtons(
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE),
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
@ -3041,28 +3177,7 @@ class ChatActivity :
|
|||||||
deleteConversation.visibility = View.VISIBLE
|
deleteConversation.visibility = View.VISIBLE
|
||||||
|
|
||||||
deleteConversation.setOnClickListener {
|
deleteConversation.setOnClickListener {
|
||||||
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
|
deleteConversationDialog(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)
|
|
||||||
)
|
|
||||||
popupWindow.dismiss()
|
popupWindow.dismiss()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -76,4 +76,5 @@ interface ChatNetworkDataSource {
|
|||||||
limit: Int
|
limit: Int
|
||||||
): List<ChatMessageJson>
|
): List<ChatMessageJson>
|
||||||
suspend fun getOpenGraph(credentials: String, baseUrl: String, extractedLinkToPreview: String): Reference?
|
suspend fun getOpenGraph(credentials: String, baseUrl: String, extractedLinkToPreview: String): Reference?
|
||||||
|
suspend fun unbindRoom(credentials: String, baseUrl: String, roomToken: String): GenericOverall
|
||||||
}
|
}
|
||||||
|
@ -217,4 +217,9 @@ class RetrofitChatNetwork(
|
|||||||
extractedLinkToPreview
|
extractedLinkToPreview
|
||||||
).blockingFirst().ocs?.data?.references?.entries?.iterator()?.next()?.value
|
).blockingFirst().ocs?.data?.references?.entries?.iterator()?.next()?.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun unbindRoom(credentials: String, baseUrl: String, roomToken: String): GenericOverall {
|
||||||
|
val url = ApiUtils.getUrlForUnbindingRoom(baseUrl, roomToken)
|
||||||
|
return ncApiCoroutines.unbindRoom(credentials, url)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,6 +146,10 @@ class ChatViewModel @Inject constructor(
|
|||||||
val outOfOfficeViewState: LiveData<OutOfOfficeUIState>
|
val outOfOfficeViewState: LiveData<OutOfOfficeUIState>
|
||||||
get() = _outOfOfficeViewState
|
get() = _outOfOfficeViewState
|
||||||
|
|
||||||
|
private val _unbindRoomResult = MutableLiveData<UnbindRoomUiState>(UnbindRoomUiState.None)
|
||||||
|
val unbindRoomResult: LiveData<UnbindRoomUiState>
|
||||||
|
get() = _unbindRoomResult
|
||||||
|
|
||||||
private val _voiceMessagePlaybackSpeedPreferences: MutableLiveData<Map<String, PlaybackSpeed>> = MutableLiveData()
|
private val _voiceMessagePlaybackSpeedPreferences: MutableLiveData<Map<String, PlaybackSpeed>> = MutableLiveData()
|
||||||
val voiceMessagePlaybackSpeedPreferences: LiveData<Map<String, PlaybackSpeed>>
|
val voiceMessagePlaybackSpeedPreferences: LiveData<Map<String, PlaybackSpeed>>
|
||||||
get() = _voiceMessagePlaybackSpeedPreferences
|
get() = _voiceMessagePlaybackSpeedPreferences
|
||||||
@ -804,6 +808,18 @@ class ChatViewModel @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
|
fun unbindRoom(credentials: String, baseUrl: String, roomToken: String) {
|
||||||
|
viewModelScope.launch {
|
||||||
|
try {
|
||||||
|
val response = chatNetworkDataSource.unbindRoom(credentials, baseUrl, roomToken)
|
||||||
|
_unbindRoomResult.value = UnbindRoomUiState.Success(response.ocs?.meta?.statusCode!!)
|
||||||
|
} catch (exception: Exception) {
|
||||||
|
_unbindRoomResult.value = UnbindRoomUiState.Error(exception.message.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun resendMessage(credentials: String, urlForChat: String, message: ChatMessage) {
|
fun resendMessage(credentials: String, urlForChat: String, message: ChatMessage) {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
chatRepository.resendChatMessage(
|
chatRepository.resendChatMessage(
|
||||||
@ -855,4 +871,10 @@ class ChatViewModel @Inject constructor(
|
|||||||
data class Success(val userAbsence: UserAbsenceData) : OutOfOfficeUIState()
|
data class Success(val userAbsence: UserAbsenceData) : OutOfOfficeUIState()
|
||||||
data class Error(val exception: Exception) : OutOfOfficeUIState()
|
data class Error(val exception: Exception) : OutOfOfficeUIState()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sealed class UnbindRoomUiState {
|
||||||
|
data object None : UnbindRoomUiState()
|
||||||
|
data class Success(val statusCode: Int) : UnbindRoomUiState()
|
||||||
|
data class Error(val message: String) : UnbindRoomUiState()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -523,7 +523,7 @@ class ConversationsListActivity :
|
|||||||
nearFutureEventConversationItems.clear()
|
nearFutureEventConversationItems.clear()
|
||||||
|
|
||||||
for (conversation in list) {
|
for (conversation in list) {
|
||||||
if (!futureEvent(conversation)) {
|
if (!isFutureEvent(conversation)) {
|
||||||
addToNearFutureEventConversationItems(conversation)
|
addToNearFutureEventConversationItems(conversation)
|
||||||
}
|
}
|
||||||
addToConversationItems(conversation)
|
addToConversationItems(conversation)
|
||||||
@ -564,13 +564,14 @@ class ConversationsListActivity :
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun futureEvent(conversation: ConversationModel): Boolean {
|
private fun isFutureEvent(conversation: ConversationModel): Boolean {
|
||||||
if (!conversation.objectId.contains("#")) {
|
if (!conversation.objectId.contains("#")) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return conversation.objectType == ConversationEnums.ObjectType.EVENT &&
|
val eventTimeStart = conversation.objectId.split("#")[0].toLong()
|
||||||
(conversation.objectId.split("#")[0].toLong() - (System.currentTimeMillis() / LONG_1000)) >
|
val currentTimeStampInSeconds = System.currentTimeMillis() / LONG_1000
|
||||||
AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS
|
val sixteenHoursAfterTimeStamp = (eventTimeStart - currentTimeStampInSeconds) > SIXTEEN_HOURS_IN_SECONDS
|
||||||
|
return conversation.objectType == ConversationEnums.ObjectType.EVENT && sixteenHoursAfterTimeStamp
|
||||||
}
|
}
|
||||||
|
|
||||||
fun showOnlyNearFutureEvents() {
|
fun showOnlyNearFutureEvents() {
|
||||||
@ -2156,7 +2157,7 @@ class ConversationsListActivity :
|
|||||||
const val NOTIFICATION_WARNING_DATE_NOT_SET = 0L
|
const val NOTIFICATION_WARNING_DATE_NOT_SET = 0L
|
||||||
const val OFFSET_HEIGHT_DIVIDER: Int = 3
|
const val OFFSET_HEIGHT_DIVIDER: Int = 3
|
||||||
const val ROOM_TYPE_ONE_ONE = "1"
|
const val ROOM_TYPE_ONE_ONE = "1"
|
||||||
private const val AGE_THRESHOLD_FOR_EVENT_CONVERSATIONS: Long = 57600
|
private const val SIXTEEN_HOURS_IN_SECONDS: Long = 57600
|
||||||
const val LONG_1000: Long = 1000
|
const val LONG_1000: Long = 1000
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,9 @@ class ConversationEnums {
|
|||||||
SHARE_PASSWORD,
|
SHARE_PASSWORD,
|
||||||
FILE,
|
FILE,
|
||||||
ROOM,
|
ROOM,
|
||||||
EVENT
|
EVENT,
|
||||||
|
PHONE_TEMPORARY,
|
||||||
|
PHONE_PERSIST,
|
||||||
|
INSTANT_MEETING
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,9 @@ class ConversationObjectTypeConverter : StringBasedTypeConverter<ConversationEnu
|
|||||||
"room" -> ConversationEnums.ObjectType.ROOM
|
"room" -> ConversationEnums.ObjectType.ROOM
|
||||||
"file" -> ConversationEnums.ObjectType.FILE
|
"file" -> ConversationEnums.ObjectType.FILE
|
||||||
"event" -> ConversationEnums.ObjectType.EVENT
|
"event" -> ConversationEnums.ObjectType.EVENT
|
||||||
|
"phone_persist" -> ConversationEnums.ObjectType.PHONE_PERSIST
|
||||||
|
"phone_temporary" -> ConversationEnums.ObjectType.PHONE_TEMPORARY
|
||||||
|
"instant_meeting" -> ConversationEnums.ObjectType.INSTANT_MEETING
|
||||||
else -> ConversationEnums.ObjectType.DEFAULT
|
else -> ConversationEnums.ObjectType.DEFAULT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,6 +33,9 @@ class ConversationObjectTypeConverter : StringBasedTypeConverter<ConversationEnu
|
|||||||
ConversationEnums.ObjectType.ROOM -> "room"
|
ConversationEnums.ObjectType.ROOM -> "room"
|
||||||
ConversationEnums.ObjectType.FILE -> "file"
|
ConversationEnums.ObjectType.FILE -> "file"
|
||||||
ConversationEnums.ObjectType.EVENT -> "event"
|
ConversationEnums.ObjectType.EVENT -> "event"
|
||||||
|
ConversationEnums.ObjectType.PHONE_PERSIST -> "phone_persist"
|
||||||
|
ConversationEnums.ObjectType.PHONE_TEMPORARY -> "phone_temporary"
|
||||||
|
ConversationEnums.ObjectType.INSTANT_MEETING -> "instant_meeting"
|
||||||
else -> ""
|
else -> ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -449,6 +449,10 @@ object ApiUtils {
|
|||||||
return "$baseUrl$OCS_API_VERSION/cloud/users/search/by-phone"
|
return "$baseUrl$OCS_API_VERSION/cloud/users/search/by-phone"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getUrlForUnbindingRoom(baseUrl: String, roomToken: String): String {
|
||||||
|
return "$baseUrl/ocs/v2.php/apps/spreed/api/v4/room/$roomToken/object"
|
||||||
|
}
|
||||||
|
|
||||||
fun getUrlForFileUpload(baseUrl: String, user: String, remotePath: String): String {
|
fun getUrlForFileUpload(baseUrl: String, user: String, remotePath: String): String {
|
||||||
return "$baseUrl/remote.php/dav/files/$user$remotePath"
|
return "$baseUrl/remote.php/dav/files/$user$remotePath"
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,8 @@ enum class SpreedFeatures(val value: String) {
|
|||||||
BAN_V1("ban-v1"),
|
BAN_V1("ban-v1"),
|
||||||
EDIT_MESSAGES_NOTE_TO_SELF("edit-messages-note-to-self"),
|
EDIT_MESSAGES_NOTE_TO_SELF("edit-messages-note-to-self"),
|
||||||
ARCHIVE_CONVERSATIONS("archived-conversations-v2"),
|
ARCHIVE_CONVERSATIONS("archived-conversations-v2"),
|
||||||
CONVERSATION_CREATION_ALL("conversation-creation-all")
|
CONVERSATION_CREATION_ALL("conversation-creation-all"),
|
||||||
|
UNBIND_CONVERSATION("unbind-conversation")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
@ -140,6 +141,36 @@ object CapabilitiesUtil {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun retentionOfEventRooms(spreedCapabilities: SpreedCapability): Int {
|
||||||
|
if (spreedCapabilities.config?.containsKey("conversations") == true) {
|
||||||
|
val map = spreedCapabilities.config!!["conversations"]
|
||||||
|
if (map?.containsKey("retention-event") == true) {
|
||||||
|
return map["retention-event"].toString().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun retentionOfSIPRoom(spreedCapabilities: SpreedCapability): Int {
|
||||||
|
if (spreedCapabilities.config?.containsKey("conversations") == true) {
|
||||||
|
val map = spreedCapabilities.config!!["conversations"]
|
||||||
|
if (map?.containsKey("retention-phone") == true) {
|
||||||
|
return map["retention-phone"].toString().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
fun retentionOfInstantMeetingRoom(spreedCapabilities: SpreedCapability): Int {
|
||||||
|
if (spreedCapabilities.config?.containsKey("conversations") == true) {
|
||||||
|
val map = spreedCapabilities.config!!["conversations"]
|
||||||
|
if (map?.containsKey("retention-instant-meetings") == true) {
|
||||||
|
return map["retention-instant-meetings"].toString().toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun isCallRecordingAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
fun isCallRecordingAvailable(spreedCapabilities: SpreedCapability): Boolean {
|
||||||
if (hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.RECORDING_V1) &&
|
if (hasSpreedFeatureCapability(spreedCapabilities, SpreedFeatures.RECORDING_V1) &&
|
||||||
|
@ -139,6 +139,19 @@
|
|||||||
<include layout="@layout/out_of_office_view" />
|
<include layout="@layout/out_of_office_view" />
|
||||||
</com.google.android.material.card.MaterialCardView>
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
|
|
||||||
|
<com.google.android.material.card.MaterialCardView
|
||||||
|
android:id="@+id/conversation_delete_notice"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:visibility="gone"
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
app:cardCornerRadius="12dp">
|
||||||
|
|
||||||
|
<include layout="@layout/remainder_to_delete_conversation" />
|
||||||
|
</com.google.android.material.card.MaterialCardView>
|
||||||
|
|
||||||
<com.stfalcon.chatkit.messages.MessagesList
|
<com.stfalcon.chatkit.messages.MessagesList
|
||||||
android:id="@+id/messagesListView"
|
android:id="@+id/messagesListView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -12,12 +12,13 @@
|
|||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="16dp"
|
android:padding="16dp"
|
||||||
android:background="@color/popup_menu_color">
|
android:background="@color/grey_600">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/event_scheduled"
|
android:id="@+id/event_scheduled"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:textColor="@color/black"
|
||||||
android:text="@string/nc_event_schedule"
|
android:text="@string/nc_event_schedule"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:textSize="18sp" />
|
android:textSize="18sp" />
|
||||||
@ -26,7 +27,7 @@
|
|||||||
android:id="@+id/meetingTime"
|
android:id="@+id/meetingTime"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:textColor="?android:attr/textColorSecondary"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
tools:text="Meeting at 8:00 pm"/>
|
tools:text="Meeting at 8:00 pm"/>
|
||||||
|
|
||||||
@ -45,7 +46,9 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/archive_conversation"
|
android:text="@string/archive_conversation"
|
||||||
|
android:textColor="@color/black"
|
||||||
android:visibility = "gone"
|
android:visibility = "gone"
|
||||||
|
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:paddingTop="24dp"/>
|
android:paddingTop="24dp"/>
|
||||||
|
|
||||||
@ -54,6 +57,7 @@
|
|||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/unarchive_conversation"
|
android:text="@string/unarchive_conversation"
|
||||||
|
android:textColor="@color/black"
|
||||||
android:visibility = "gone"
|
android:visibility = "gone"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:paddingTop="24dp"/>
|
android:paddingTop="24dp"/>
|
||||||
|
56
app/src/main/res/layout/remainder_to_delete_conversation.xml
Normal file
56
app/src/main/res/layout/remainder_to_delete_conversation.xml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?><!--
|
||||||
|
~ Nextcloud Talk - Android Client
|
||||||
|
~
|
||||||
|
~ SPDX-FileCopyrightText: 2025 Sowjanya Kota <sowjanya.kch@gmail.com>
|
||||||
|
~ SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
android:id="@+id/deletion_warning_container"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:padding="12dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/deletion_message"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nc_conversation_auto_delete_notice"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:lineSpacingExtra="4dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:layout_marginBottom="12dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:gravity="center_horizontal">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/delete_now_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nc_delete_now"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
app:icon="@drawable/ic_delete"
|
||||||
|
app:iconPadding="8dp"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
android:backgroundTint="@color/nc_darkRed"
|
||||||
|
android:layout_marginEnd="16dp" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/keep_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/nc_keep"
|
||||||
|
app:icon="@drawable/ic_check"
|
||||||
|
app:iconPadding="8dp"
|
||||||
|
app:iconGravity="textStart" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
@ -12,7 +12,7 @@
|
|||||||
<color name="colorPrimaryDark">#006AA3</color>
|
<color name="colorPrimaryDark">#006AA3</color>
|
||||||
<color name="colorAccent">@color/colorPrimary</color>
|
<color name="colorAccent">@color/colorPrimary</color>
|
||||||
<color name="disabled_text">#ff6F6F6F</color>
|
<color name="disabled_text">#ff6F6F6F</color>
|
||||||
<color name="popup_menu_color">#FF37474F</color>
|
|
||||||
|
|
||||||
<!-- App bar -->
|
<!-- App bar -->
|
||||||
<color name="appbar">#1E1E1E</color>
|
<color name="appbar">#1E1E1E</color>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
<color name="disabled_text">#ff888888</color>
|
<color name="disabled_text">#ff888888</color>
|
||||||
<color name="textColorOnPrimaryBackground">#ffffff</color> <!-- white/black depending on primary color -->
|
<color name="textColorOnPrimaryBackground">#ffffff</color> <!-- white/black depending on primary color -->
|
||||||
<color name="nc_login_text_color">#B3FFFFFF</color>
|
<color name="nc_login_text_color">#B3FFFFFF</color>
|
||||||
<color name="popup_menu_color">#FF607D8B</color>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- App bar -->
|
<!-- App bar -->
|
||||||
|
@ -513,9 +513,13 @@ How to translate with transifex:
|
|||||||
<string name="nc_reply">Reply</string>
|
<string name="nc_reply">Reply</string>
|
||||||
<string name="nc_reply_privately">Reply privately</string>
|
<string name="nc_reply_privately">Reply privately</string>
|
||||||
<string name="nc_delete_message">Delete</string>
|
<string name="nc_delete_message">Delete</string>
|
||||||
|
<string name="nc_conversation_auto_delete_notice">This conversation will be automatically deleted for everyone in %1$d days of no activity</string>
|
||||||
|
<string name="nc_delete_now">Delete now</string>
|
||||||
|
<string name="nc_keep">Keep</string>
|
||||||
<string name="nc_delete_message_leaked_to_matterbridge">Message deleted successfully, but it might have been leaked to other services</string>
|
<string name="nc_delete_message_leaked_to_matterbridge">Message deleted successfully, but it might have been leaked to other services</string>
|
||||||
<string name="startCallForbidden">You are not allowed to start a call</string>
|
<string name="startCallForbidden">You are not allowed to start a call</string>
|
||||||
<string name="nc_last_moderator_leaving_room_warning">You need to promote a new moderator before you can leave the conversation</string>
|
<string name="nc_last_moderator_leaving_room_warning">You need to promote a new moderator before you can leave the conversation</string>
|
||||||
|
<string name="nc_room_retention">Room is retained successfully</string>
|
||||||
|
|
||||||
<string name="share">Share</string>
|
<string name="share">Share</string>
|
||||||
<string name="send_to">Send to</string>
|
<string name="send_to">Send to</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user