mirror of
https://github.com/nextcloud/talk-android
synced 2025-03-09 23:53:04 +00:00
Merge pull request #4544 from nextcloud/style/noid/detekt-improvements
detekt improvements
This commit is contained in:
commit
a73099da2f
@ -82,9 +82,8 @@ class OutcomingTextMessageViewHolder(itemView: View) :
|
|||||||
itemView
|
itemView
|
||||||
)
|
)
|
||||||
|
|
||||||
val messageParameters = message.messageParameters
|
|
||||||
if (
|
if (
|
||||||
(messageParameters == null || messageParameters.size <= 0) &&
|
(message.messageParameters == null || message.messageParameters!!.size <= 0) &&
|
||||||
TextMatchers.isMessageWithSingleEmoticonOnly(message.text)
|
TextMatchers.isMessageWithSingleEmoticonOnly(message.text)
|
||||||
) {
|
) {
|
||||||
textSize = (textSize * TEXT_SIZE_MULTIPLIER).toFloat()
|
textSize = (textSize * TEXT_SIZE_MULTIPLIER).toFloat()
|
||||||
@ -115,13 +114,29 @@ class OutcomingTextMessageViewHolder(itemView: View) :
|
|||||||
binding.messageQuote.quotedChatMessageView.visibility = View.GONE
|
binding.messageQuote.quotedChatMessageView.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
val readStatusDrawableInt = when (message.readStatus) {
|
setReadStatus(message.readStatus)
|
||||||
|
|
||||||
|
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
|
||||||
|
|
||||||
|
Reaction().showReactions(
|
||||||
|
message,
|
||||||
|
::clickOnReaction,
|
||||||
|
::longClickOnReaction,
|
||||||
|
binding.reactions,
|
||||||
|
context,
|
||||||
|
true,
|
||||||
|
viewThemeUtils
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setReadStatus(readStatus: Enum<ReadStatus>) {
|
||||||
|
val readStatusDrawableInt = when (readStatus) {
|
||||||
ReadStatus.READ -> R.drawable.ic_check_all
|
ReadStatus.READ -> R.drawable.ic_check_all
|
||||||
ReadStatus.SENT -> R.drawable.ic_check
|
ReadStatus.SENT -> R.drawable.ic_check
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
val readStatusContentDescriptionString = when (message.readStatus) {
|
val readStatusContentDescriptionString = when (readStatus) {
|
||||||
ReadStatus.READ -> context.resources?.getString(R.string.nc_message_read)
|
ReadStatus.READ -> context.resources?.getString(R.string.nc_message_read)
|
||||||
ReadStatus.SENT -> context.resources?.getString(R.string.nc_message_sent)
|
ReadStatus.SENT -> context.resources?.getString(R.string.nc_message_sent)
|
||||||
else -> null
|
else -> null
|
||||||
@ -135,18 +150,6 @@ class OutcomingTextMessageViewHolder(itemView: View) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.checkMark.contentDescription = readStatusContentDescriptionString
|
binding.checkMark.contentDescription = readStatusContentDescriptionString
|
||||||
|
|
||||||
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
|
|
||||||
|
|
||||||
Reaction().showReactions(
|
|
||||||
message,
|
|
||||||
::clickOnReaction,
|
|
||||||
::longClickOnReaction,
|
|
||||||
binding.reactions,
|
|
||||||
context,
|
|
||||||
true,
|
|
||||||
viewThemeUtils
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun longClickOnReaction(chatMessage: ChatMessage) {
|
private fun longClickOnReaction(chatMessage: ChatMessage) {
|
||||||
|
@ -131,26 +131,7 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
val readStatusDrawableInt = when (message.readStatus) {
|
setReadStatus(message.readStatus)
|
||||||
ReadStatus.READ -> R.drawable.ic_check_all
|
|
||||||
ReadStatus.SENT -> R.drawable.ic_check
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
val readStatusContentDescriptionString = when (message.readStatus) {
|
|
||||||
ReadStatus.READ -> context?.resources?.getString(R.string.nc_message_read)
|
|
||||||
ReadStatus.SENT -> context?.resources?.getString(R.string.nc_message_sent)
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
|
|
||||||
readStatusDrawableInt?.let { drawableInt ->
|
|
||||||
AppCompatResources.getDrawable(context!!, drawableInt)?.let {
|
|
||||||
binding.checkMark.setImageDrawable(it)
|
|
||||||
viewThemeUtils.talk.themeMessageCheckMark(binding.checkMark)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
binding.checkMark.contentDescription = readStatusContentDescriptionString
|
|
||||||
|
|
||||||
voiceMessageInterface.registerMessageToObservePlaybackSpeedPreferences(message.user.id) { speed ->
|
voiceMessageInterface.registerMessageToObservePlaybackSpeedPreferences(message.user.id) { speed ->
|
||||||
binding.playbackSpeedControlBtn.setSpeed(speed)
|
binding.playbackSpeedControlBtn.setSpeed(speed)
|
||||||
@ -168,6 +149,29 @@ class OutcomingVoiceMessageViewHolder(outcomingView: View) :
|
|||||||
isBound = true
|
isBound = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setReadStatus(readStatus: Enum<ReadStatus>) {
|
||||||
|
val readStatusDrawableInt = when (readStatus) {
|
||||||
|
ReadStatus.READ -> R.drawable.ic_check_all
|
||||||
|
ReadStatus.SENT -> R.drawable.ic_check
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
val readStatusContentDescriptionString = when (readStatus) {
|
||||||
|
ReadStatus.READ -> context?.resources?.getString(R.string.nc_message_read)
|
||||||
|
ReadStatus.SENT -> context?.resources?.getString(R.string.nc_message_sent)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
readStatusDrawableInt?.let { drawableInt ->
|
||||||
|
AppCompatResources.getDrawable(context!!, drawableInt)?.let {
|
||||||
|
binding.checkMark.setImageDrawable(it)
|
||||||
|
viewThemeUtils.talk.themeMessageCheckMark(binding.checkMark)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.checkMark.contentDescription = readStatusContentDescriptionString
|
||||||
|
}
|
||||||
|
|
||||||
private fun longClickOnReaction(chatMessage: ChatMessage) {
|
private fun longClickOnReaction(chatMessage: ChatMessage) {
|
||||||
commonMessageInterface.onLongClickReactions(chatMessage)
|
commonMessageInterface.onLongClickReactions(chatMessage)
|
||||||
}
|
}
|
||||||
|
@ -85,34 +85,7 @@ class SystemMessageViewHolder(itemView: View) : MessageHolders.IncomingTextMessa
|
|||||||
binding.systemMessageLayout.visibility = View.VISIBLE
|
binding.systemMessageLayout.visibility = View.VISIBLE
|
||||||
binding.similarMessagesHint.visibility = View.GONE
|
binding.similarMessagesHint.visibility = View.GONE
|
||||||
if (message.expandableParent) {
|
if (message.expandableParent) {
|
||||||
binding.expandCollapseIcon.visibility = View.VISIBLE
|
processExpandableParent(message, messageString)
|
||||||
|
|
||||||
if (!message.isExpanded) {
|
|
||||||
val similarMessages = String.format(
|
|
||||||
sharedApplication!!.resources.getString(R.string.see_similar_system_messages),
|
|
||||||
message.expandableChildrenAmount
|
|
||||||
)
|
|
||||||
|
|
||||||
binding.messageText.text = messageString
|
|
||||||
binding.similarMessagesHint.visibility = View.VISIBLE
|
|
||||||
binding.similarMessagesHint.text = similarMessages
|
|
||||||
|
|
||||||
binding.expandCollapseIcon.setImageDrawable(
|
|
||||||
ContextCompat.getDrawable(context!!, R.drawable.baseline_unfold_more_24)
|
|
||||||
)
|
|
||||||
binding.systemMessageLayout.setOnClickListener { systemMessageInterface.expandSystemMessage(message) }
|
|
||||||
binding.messageText.setOnClickListener { systemMessageInterface.expandSystemMessage(message) }
|
|
||||||
} else {
|
|
||||||
binding.messageText.text = messageString
|
|
||||||
binding.similarMessagesHint.visibility = View.GONE
|
|
||||||
binding.similarMessagesHint.text = ""
|
|
||||||
|
|
||||||
binding.expandCollapseIcon.setImageDrawable(
|
|
||||||
ContextCompat.getDrawable(context!!, R.drawable.baseline_unfold_less_24)
|
|
||||||
)
|
|
||||||
binding.systemMessageLayout.setOnClickListener { systemMessageInterface.collapseSystemMessages() }
|
|
||||||
binding.messageText.setOnClickListener { systemMessageInterface.collapseSystemMessages() }
|
|
||||||
}
|
|
||||||
} else if (message.hiddenByCollapse) {
|
} else if (message.hiddenByCollapse) {
|
||||||
binding.systemMessageLayout.visibility = View.GONE
|
binding.systemMessageLayout.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
@ -131,6 +104,38 @@ class SystemMessageViewHolder(itemView: View) : MessageHolders.IncomingTextMessa
|
|||||||
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
|
itemView.setTag(R.string.replyable_message_view_tag, message.replyable)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n", "StringFormatInvalid")
|
||||||
|
private fun processExpandableParent(message: ChatMessage, messageString: Spannable) {
|
||||||
|
binding.expandCollapseIcon.visibility = View.VISIBLE
|
||||||
|
|
||||||
|
if (!message.isExpanded) {
|
||||||
|
val similarMessages = String.format(
|
||||||
|
sharedApplication!!.resources.getString(R.string.see_similar_system_messages),
|
||||||
|
message.expandableChildrenAmount
|
||||||
|
)
|
||||||
|
|
||||||
|
binding.messageText.text = messageString
|
||||||
|
binding.similarMessagesHint.visibility = View.VISIBLE
|
||||||
|
binding.similarMessagesHint.text = similarMessages
|
||||||
|
|
||||||
|
binding.expandCollapseIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(context!!, R.drawable.baseline_unfold_more_24)
|
||||||
|
)
|
||||||
|
binding.systemMessageLayout.setOnClickListener { systemMessageInterface.expandSystemMessage(message) }
|
||||||
|
binding.messageText.setOnClickListener { systemMessageInterface.expandSystemMessage(message) }
|
||||||
|
} else {
|
||||||
|
binding.messageText.text = messageString
|
||||||
|
binding.similarMessagesHint.visibility = View.GONE
|
||||||
|
binding.similarMessagesHint.text = ""
|
||||||
|
|
||||||
|
binding.expandCollapseIcon.setImageDrawable(
|
||||||
|
ContextCompat.getDrawable(context!!, R.drawable.baseline_unfold_less_24)
|
||||||
|
)
|
||||||
|
binding.systemMessageLayout.setOnClickListener { systemMessageInterface.collapseSystemMessages() }
|
||||||
|
binding.messageText.setOnClickListener { systemMessageInterface.collapseSystemMessages() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun assignSystemMessageInterface(systemMessageInterface: SystemMessageInterface) {
|
fun assignSystemMessageInterface(systemMessageInterface: SystemMessageInterface) {
|
||||||
this.systemMessageInterface = systemMessageInterface
|
this.systemMessageInterface = systemMessageInterface
|
||||||
}
|
}
|
||||||
|
@ -3387,8 +3387,6 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun shareToNotes(message: ChatMessage, roomToken: String) {
|
fun shareToNotes(message: ChatMessage, roomToken: String) {
|
||||||
val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
|
||||||
val type = message.getCalculateMessageType()
|
|
||||||
var shareUri: Uri? = null
|
var shareUri: Uri? = null
|
||||||
val data: HashMap<String?, String?>?
|
val data: HashMap<String?, String?>?
|
||||||
var metaData: String = ""
|
var metaData: String = ""
|
||||||
@ -3418,6 +3416,17 @@ class ChatActivity :
|
|||||||
"\"longitude\":\"$lon\",\"name\":\"$name\"}"
|
"\"longitude\":\"$lon\",\"name\":\"$name\"}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
shareToNotes(shareUri, roomToken, message, objectId, metaData)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shareToNotes(
|
||||||
|
shareUri: Uri?,
|
||||||
|
roomToken: String,
|
||||||
|
message: ChatMessage,
|
||||||
|
objectId: String,
|
||||||
|
metaData: String
|
||||||
|
) {
|
||||||
|
val type = message.getCalculateMessageType()
|
||||||
when (type) {
|
when (type) {
|
||||||
ChatMessage.MessageType.VOICE_MESSAGE -> {
|
ChatMessage.MessageType.VOICE_MESSAGE -> {
|
||||||
uploadFile(shareUri.toString(), true, token = roomToken)
|
uploadFile(shareUri.toString(), true, token = roomToken)
|
||||||
@ -3432,7 +3441,7 @@ class ChatActivity :
|
|||||||
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
||||||
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
||||||
} catch (e: java.lang.Exception) {
|
} catch (e: java.lang.Exception) {
|
||||||
Log.w(TAG, "File corresponding to the uri does not exist " + shareUri.toString())
|
Log.w(TAG, "File corresponding to the uri does not exist $shareUri")
|
||||||
downloadFileToCache(message, false) {
|
downloadFileToCache(message, false) {
|
||||||
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
uploadFile(shareUri.toString(), false, caption!!, roomToken)
|
||||||
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
Snackbar.make(binding.root, R.string.nc_message_sent, Snackbar.LENGTH_SHORT).show()
|
||||||
@ -3442,6 +3451,7 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage.MessageType.SINGLE_NC_GEOLOCATION_MESSAGE -> {
|
ChatMessage.MessageType.SINGLE_NC_GEOLOCATION_MESSAGE -> {
|
||||||
|
val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||||
chatViewModel.shareLocationToNotes(
|
chatViewModel.shareLocationToNotes(
|
||||||
credentials!!,
|
credentials!!,
|
||||||
ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
ApiUtils.getUrlToSendLocation(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
||||||
@ -3453,6 +3463,7 @@ class ChatActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE -> {
|
ChatMessage.MessageType.REGULAR_TEXT_MESSAGE -> {
|
||||||
|
val apiVersion = ApiUtils.getChatApiVersion(spreedCapabilities, intArrayOf(1))
|
||||||
chatViewModel.shareToNotes(
|
chatViewModel.shareToNotes(
|
||||||
credentials!!,
|
credentials!!,
|
||||||
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
ApiUtils.getUrlForChat(apiVersion, conversationUser!!.baseUrl!!, roomToken),
|
||||||
|
@ -128,7 +128,7 @@ class MessageInputFragment : Fragment() {
|
|||||||
private var mentionAutocomplete: Autocomplete<*>? = null
|
private var mentionAutocomplete: Autocomplete<*>? = null
|
||||||
private var xcounter = 0f
|
private var xcounter = 0f
|
||||||
private var ycounter = 0f
|
private var ycounter = 0f
|
||||||
private var isCollapsed = false
|
private var collapsed = false
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -219,11 +219,7 @@ class MessageInputFragment : Fragment() {
|
|||||||
binding.fragmentCallStarted.callAuthorChipSecondary.text = message.actorDisplayName
|
binding.fragmentCallStarted.callAuthorChipSecondary.text = message.actorDisplayName
|
||||||
val user = userManager.currentUser.blockingGet()
|
val user = userManager.currentUser.blockingGet()
|
||||||
val url: String = if (message.actorType == "guests" || message.actorType == "guest") {
|
val url: String = if (message.actorType == "guests" || message.actorType == "guest") {
|
||||||
ApiUtils.getUrlForGuestAvatar(
|
ApiUtils.getUrlForGuestAvatar(user!!.baseUrl!!, message.actorDisplayName, true)
|
||||||
user!!.baseUrl!!,
|
|
||||||
message.actorDisplayName,
|
|
||||||
true
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
ApiUtils.getUrlForAvatar(user!!.baseUrl!!, message.actorId, false)
|
ApiUtils.getUrlForAvatar(user!!.baseUrl!!, message.actorId, false)
|
||||||
}
|
}
|
||||||
@ -457,20 +453,12 @@ class MessageInputFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.fragmentCallStarted.callStartedCloseBtn.setOnClickListener {
|
binding.fragmentCallStarted.callStartedCloseBtn.setOnClickListener {
|
||||||
isCollapsed = !isCollapsed
|
collapsed = !collapsed
|
||||||
if (isCollapsed) {
|
binding.fragmentCallStarted.callAuthorLayout.visibility = if (collapsed) View.GONE else View.VISIBLE
|
||||||
binding.fragmentCallStarted.callAuthorLayout.visibility = View.GONE
|
binding.fragmentCallStarted.callBtnLayout.visibility = if (collapsed) View.GONE else View.VISIBLE
|
||||||
binding.fragmentCallStarted.callBtnLayout.visibility = View.GONE
|
binding.fragmentCallStarted.callAuthorChipSecondary.visibility = if (collapsed) View.VISIBLE else View.GONE
|
||||||
binding.fragmentCallStarted.callAuthorChipSecondary.visibility = View.VISIBLE
|
binding.fragmentCallStarted.callStartedSecondaryText.visibility = if (collapsed) View.VISIBLE else View.GONE
|
||||||
binding.fragmentCallStarted.callStartedSecondaryText.visibility = View.VISIBLE
|
setDropDown(collapsed)
|
||||||
} else {
|
|
||||||
binding.fragmentCallStarted.callAuthorLayout.visibility = View.VISIBLE
|
|
||||||
binding.fragmentCallStarted.callBtnLayout.visibility = View.VISIBLE
|
|
||||||
binding.fragmentCallStarted.callAuthorChipSecondary.visibility = View.GONE
|
|
||||||
binding.fragmentCallStarted.callStartedSecondaryText.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
setDropDown(isCollapsed)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,50 +506,12 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result.second.isNotEmpty()) {
|
if (result.second.isNotEmpty()) {
|
||||||
val chatMessagesJson = result.second
|
chatMessagesFromSync = updateMessagesData(
|
||||||
|
result.second,
|
||||||
handleUpdateMessages(chatMessagesJson)
|
blockContainingQueriedMessage,
|
||||||
|
lookIntoFuture,
|
||||||
chatMessagesFromSync = chatMessagesJson.map {
|
hasHistory
|
||||||
it.asEntity(currentUser.id!!)
|
|
||||||
}
|
|
||||||
|
|
||||||
chatDao.upsertChatMessages(chatMessagesFromSync)
|
|
||||||
|
|
||||||
val oldestIdFromSync = chatMessagesFromSync.minByOrNull { it.id }!!.id
|
|
||||||
val newestIdFromSync = chatMessagesFromSync.maxByOrNull { it.id }!!.id
|
|
||||||
Log.d(TAG, "oldestIdFromSync: $oldestIdFromSync")
|
|
||||||
Log.d(TAG, "newestIdFromSync: $newestIdFromSync")
|
|
||||||
|
|
||||||
var oldestMessageIdForNewChatBlock = oldestIdFromSync
|
|
||||||
var newestMessageIdForNewChatBlock = newestIdFromSync
|
|
||||||
|
|
||||||
if (blockContainingQueriedMessage != null) {
|
|
||||||
if (lookIntoFuture) {
|
|
||||||
val oldestMessageIdFromBlockOfQueriedMessage = blockContainingQueriedMessage.oldestMessageId
|
|
||||||
Log.d(TAG, "oldestMessageIdFromBlockOfQueriedMessage: $oldestMessageIdFromBlockOfQueriedMessage")
|
|
||||||
oldestMessageIdForNewChatBlock = oldestMessageIdFromBlockOfQueriedMessage
|
|
||||||
} else {
|
|
||||||
val newestMessageIdFromBlockOfQueriedMessage = blockContainingQueriedMessage.newestMessageId
|
|
||||||
Log.d(TAG, "newestMessageIdFromBlockOfQueriedMessage: $newestMessageIdFromBlockOfQueriedMessage")
|
|
||||||
newestMessageIdForNewChatBlock = newestMessageIdFromBlockOfQueriedMessage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Log.d(TAG, "oldestMessageIdForNewChatBlock: $oldestMessageIdForNewChatBlock")
|
|
||||||
Log.d(TAG, "newestMessageIdForNewChatBlock: $newestMessageIdForNewChatBlock")
|
|
||||||
|
|
||||||
val newChatBlock = ChatBlockEntity(
|
|
||||||
internalConversationId = internalConversationId,
|
|
||||||
accountId = conversationModel.accountId,
|
|
||||||
token = conversationModel.token,
|
|
||||||
oldestMessageId = oldestMessageIdForNewChatBlock,
|
|
||||||
newestMessageId = newestMessageIdForNewChatBlock,
|
|
||||||
hasHistory = hasHistory
|
|
||||||
)
|
)
|
||||||
chatBlocksDao.upsertChatBlock(newChatBlock)
|
|
||||||
|
|
||||||
updateBlocks(newChatBlock)
|
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "no data is updated...")
|
Log.d(TAG, "no data is updated...")
|
||||||
}
|
}
|
||||||
@ -557,6 +519,57 @@ class OfflineFirstChatRepository @Inject constructor(
|
|||||||
return chatMessagesFromSync
|
return chatMessagesFromSync
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun OfflineFirstChatRepository.updateMessagesData(
|
||||||
|
chatMessagesJson: List<ChatMessageJson>,
|
||||||
|
blockContainingQueriedMessage: ChatBlockEntity?,
|
||||||
|
lookIntoFuture: Boolean,
|
||||||
|
hasHistory: Boolean
|
||||||
|
): List<ChatMessageEntity> {
|
||||||
|
handleUpdateMessages(chatMessagesJson)
|
||||||
|
|
||||||
|
val chatMessagesFromSyncToProcess = chatMessagesJson.map {
|
||||||
|
it.asEntity(currentUser.id!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
chatDao.upsertChatMessages(chatMessagesFromSyncToProcess)
|
||||||
|
|
||||||
|
val oldestIdFromSync = chatMessagesFromSyncToProcess.minByOrNull { it.id }!!.id
|
||||||
|
val newestIdFromSync = chatMessagesFromSyncToProcess.maxByOrNull { it.id }!!.id
|
||||||
|
Log.d(TAG, "oldestIdFromSync: $oldestIdFromSync")
|
||||||
|
Log.d(TAG, "newestIdFromSync: $newestIdFromSync")
|
||||||
|
|
||||||
|
var oldestMessageIdForNewChatBlock = oldestIdFromSync
|
||||||
|
var newestMessageIdForNewChatBlock = newestIdFromSync
|
||||||
|
|
||||||
|
if (blockContainingQueriedMessage != null) {
|
||||||
|
if (lookIntoFuture) {
|
||||||
|
val oldestMessageIdFromBlockOfQueriedMessage = blockContainingQueriedMessage.oldestMessageId
|
||||||
|
Log.d(TAG, "oldestMessageIdFromBlockOfQueriedMessage: $oldestMessageIdFromBlockOfQueriedMessage")
|
||||||
|
oldestMessageIdForNewChatBlock = oldestMessageIdFromBlockOfQueriedMessage
|
||||||
|
} else {
|
||||||
|
val newestMessageIdFromBlockOfQueriedMessage = blockContainingQueriedMessage.newestMessageId
|
||||||
|
Log.d(TAG, "newestMessageIdFromBlockOfQueriedMessage: $newestMessageIdFromBlockOfQueriedMessage")
|
||||||
|
newestMessageIdForNewChatBlock = newestMessageIdFromBlockOfQueriedMessage
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(TAG, "oldestMessageIdForNewChatBlock: $oldestMessageIdForNewChatBlock")
|
||||||
|
Log.d(TAG, "newestMessageIdForNewChatBlock: $newestMessageIdForNewChatBlock")
|
||||||
|
|
||||||
|
val newChatBlock = ChatBlockEntity(
|
||||||
|
internalConversationId = internalConversationId,
|
||||||
|
accountId = conversationModel.accountId,
|
||||||
|
token = conversationModel.token,
|
||||||
|
oldestMessageId = oldestMessageIdForNewChatBlock,
|
||||||
|
newestMessageId = newestMessageIdForNewChatBlock,
|
||||||
|
hasHistory = hasHistory
|
||||||
|
)
|
||||||
|
chatBlocksDao.upsertChatBlock(newChatBlock)
|
||||||
|
|
||||||
|
updateBlocks(newChatBlock)
|
||||||
|
return chatMessagesFromSyncToProcess
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun handleUpdateMessages(messagesJson: List<ChatMessageJson>) {
|
private suspend fun handleUpdateMessages(messagesJson: List<ChatMessageJson>) {
|
||||||
messagesJson.forEach { messageJson ->
|
messagesJson.forEach { messageJson ->
|
||||||
when (messageJson.systemMessageType) {
|
when (messageJson.systemMessageType) {
|
||||||
|
@ -21,6 +21,7 @@ import android.view.MenuItem
|
|||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.View.GONE
|
import android.view.View.GONE
|
||||||
import android.view.View.VISIBLE
|
import android.view.View.VISIBLE
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.appcompat.app.AlertDialog
|
import androidx.appcompat.app.AlertDialog
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.fragment.app.FragmentTransaction
|
import androidx.fragment.app.FragmentTransaction
|
||||||
@ -204,33 +205,7 @@ class ConversationInfoActivity :
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initObservers() {
|
private fun initObservers() {
|
||||||
viewModel.viewState.observe(this) { state ->
|
initViewStateObserver()
|
||||||
when (state) {
|
|
||||||
is ConversationInfoViewModel.GetRoomSuccessState -> {
|
|
||||||
conversation = state.conversationModel
|
|
||||||
viewModel.getCapabilities(conversationUser, conversationToken, conversation!!)
|
|
||||||
if (ConversationUtils.isNoteToSelfConversation(conversation)) {
|
|
||||||
binding.shareConversationButton.visibility = GONE
|
|
||||||
}
|
|
||||||
val canGeneratePrettyURL = CapabilitiesUtil.canGeneratePrettyURL(conversationUser)
|
|
||||||
binding.shareConversationButton.setOnClickListener {
|
|
||||||
ShareUtils.shareConversationLink(
|
|
||||||
this,
|
|
||||||
conversationUser.baseUrl,
|
|
||||||
conversation?.token,
|
|
||||||
conversation?.name,
|
|
||||||
canGeneratePrettyURL
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
is ConversationInfoViewModel.GetRoomErrorState -> {
|
|
||||||
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
viewModel.getCapabilitiesViewState.observe(this) { state ->
|
viewModel.getCapabilitiesViewState.observe(this) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
@ -289,6 +264,36 @@ class ConversationInfoActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initViewStateObserver() {
|
||||||
|
viewModel.viewState.observe(this) { state ->
|
||||||
|
when (state) {
|
||||||
|
is ConversationInfoViewModel.GetRoomSuccessState -> {
|
||||||
|
conversation = state.conversationModel
|
||||||
|
viewModel.getCapabilities(conversationUser, conversationToken, conversation!!)
|
||||||
|
if (ConversationUtils.isNoteToSelfConversation(conversation)) {
|
||||||
|
binding.shareConversationButton.visibility = GONE
|
||||||
|
}
|
||||||
|
val canGeneratePrettyURL = CapabilitiesUtil.canGeneratePrettyURL(conversationUser)
|
||||||
|
binding.shareConversationButton.setOnClickListener {
|
||||||
|
ShareUtils.shareConversationLink(
|
||||||
|
this,
|
||||||
|
conversationUser.baseUrl,
|
||||||
|
conversation?.token,
|
||||||
|
conversation?.name,
|
||||||
|
canGeneratePrettyURL
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
is ConversationInfoViewModel.GetRoomErrorState -> {
|
||||||
|
Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun setupActionBar() {
|
private fun setupActionBar() {
|
||||||
setSupportActionBar(binding.conversationInfoToolbar)
|
setSupportActionBar(binding.conversationInfoToolbar)
|
||||||
binding.conversationInfoToolbar.setNavigationOnClickListener {
|
binding.conversationInfoToolbar.setNavigationOnClickListener {
|
||||||
@ -1330,117 +1335,59 @@ class ConversationInfoActivity :
|
|||||||
|
|
||||||
val userItem = adapter?.getItem(position) as ParticipantItem
|
val userItem = adapter?.getItem(position) as ParticipantItem
|
||||||
val participant = userItem.model
|
val participant = userItem.model
|
||||||
|
|
||||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||||
|
|
||||||
if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser.userId) {
|
if (participant.calculatedActorType == USERS && participant.calculatedActorId == conversationUser.userId) {
|
||||||
if (participant.attendeePin?.isNotEmpty() == true) {
|
if (participant.attendeePin?.isNotEmpty() == true) {
|
||||||
val items = mutableListOf(
|
launchRemoveAttendeeFromConversationDialog(
|
||||||
BasicListItemWithImage(
|
participant,
|
||||||
R.drawable.ic_lock_grey600_24px,
|
apiVersion,
|
||||||
context.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
context.getString(R.string.nc_attendee_pin, participant.attendeePin),
|
||||||
)
|
R.drawable.ic_lock_grey600_24px
|
||||||
)
|
)
|
||||||
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
|
|
||||||
cornerRadius(res = R.dimen.corner_radius)
|
|
||||||
|
|
||||||
title(text = participant.displayName)
|
|
||||||
viewThemeUtils.material.colorBottomSheetBackground(this.view)
|
|
||||||
listItemsWithImage(items = items) { _, index, _ ->
|
|
||||||
if (index == 0) {
|
|
||||||
removeAttendeeFromConversation(apiVersion, participant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return true
|
} else if (participant.type == Participant.ParticipantType.OWNER) {
|
||||||
}
|
|
||||||
|
|
||||||
if (participant.type == Participant.ParticipantType.OWNER) {
|
|
||||||
// Can not moderate owner
|
// Can not moderate owner
|
||||||
return true
|
} else if (participant.calculatedActorType == GROUPS) {
|
||||||
}
|
launchRemoveAttendeeFromConversationDialog(
|
||||||
|
participant,
|
||||||
if (participant.calculatedActorType == GROUPS) {
|
apiVersion,
|
||||||
val items = mutableListOf(
|
context.getString(R.string.nc_remove_group_and_members)
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.ic_delete_grey600_24dp,
|
|
||||||
context.getString(R.string.nc_remove_group_and_members)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
|
} else if (participant.calculatedActorType == CIRCLES) {
|
||||||
cornerRadius(res = R.dimen.corner_radius)
|
launchRemoveAttendeeFromConversationDialog(
|
||||||
|
participant,
|
||||||
title(text = participant.displayName)
|
apiVersion,
|
||||||
listItemsWithImage(items = items) { _, index, _ ->
|
context.getString(R.string.nc_remove_team_and_members)
|
||||||
if (index == 0) {
|
|
||||||
removeAttendeeFromConversation(apiVersion, participant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (participant.calculatedActorType == CIRCLES) {
|
|
||||||
val items = mutableListOf(
|
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.ic_delete_grey600_24dp,
|
|
||||||
context.getString(R.string.nc_remove_team_and_members)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
|
} else {
|
||||||
cornerRadius(res = R.dimen.corner_radius)
|
launchDefaultActions(participant, apiVersion)
|
||||||
|
|
||||||
title(text = participant.displayName)
|
|
||||||
listItemsWithImage(items = items) { _, index, _ ->
|
|
||||||
if (index == 0) {
|
|
||||||
removeAttendeeFromConversation(apiVersion, participant)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
val items = mutableListOf(
|
@SuppressLint("CheckResult")
|
||||||
BasicListItemWithImage(
|
private fun launchDefaultActions(participant: Participant, apiVersion: Int) {
|
||||||
R.drawable.ic_lock_grey600_24px,
|
val items = getDefaultActionItems(participant)
|
||||||
context.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
|
||||||
),
|
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.ic_pencil_grey600_24dp,
|
|
||||||
context.getString(R.string.nc_promote)
|
|
||||||
),
|
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.ic_pencil_grey600_24dp,
|
|
||||||
context.getString(R.string.nc_demote)
|
|
||||||
),
|
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.ic_delete_grey600_24dp,
|
|
||||||
context.getString(R.string.nc_remove_participant)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (CapabilitiesUtil.isBanningAvailable(conversationUser.capabilities?.spreedCapability!!)) {
|
if (CapabilitiesUtil.isBanningAvailable(conversationUser.capabilities?.spreedCapability!!)) {
|
||||||
items.add(
|
items.add(BasicListItemWithImage(R.drawable.baseline_block_24, context.getString(R.string.ban_participant)))
|
||||||
BasicListItemWithImage(
|
|
||||||
R.drawable.baseline_block_24,
|
|
||||||
context.getString(R.string.ban_participant)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (participant.type == Participant.ParticipantType.MODERATOR ||
|
when (participant.type) {
|
||||||
participant.type == Participant.ParticipantType.GUEST_MODERATOR
|
Participant.ParticipantType.MODERATOR, Participant.ParticipantType.GUEST_MODERATOR -> {
|
||||||
) {
|
items.removeAt(1)
|
||||||
items.removeAt(1)
|
}
|
||||||
} else if (participant.type == Participant.ParticipantType.USER ||
|
|
||||||
participant.type == Participant.ParticipantType.GUEST
|
Participant.ParticipantType.USER, Participant.ParticipantType.GUEST -> {
|
||||||
) {
|
items.removeAt(2)
|
||||||
items.removeAt(2)
|
}
|
||||||
} else {
|
|
||||||
// Self joined users can not be promoted nor demoted
|
else -> {
|
||||||
items.removeAt(2)
|
// Self joined users can not be promoted nor demoted
|
||||||
items.removeAt(1)
|
items.removeAt(2)
|
||||||
|
items.removeAt(1)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (participant.attendeePin == null || participant.attendeePin!!.isEmpty()) {
|
if (participant.attendeePin == null || participant.attendeePin!!.isEmpty()) {
|
||||||
@ -1483,21 +1430,61 @@ class ConversationInfoActivity :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true
|
}
|
||||||
|
|
||||||
|
@SuppressLint("StringFormatInvalid")
|
||||||
|
private fun getDefaultActionItems(participant: Participant): MutableList<BasicListItemWithImage> {
|
||||||
|
val items = mutableListOf(
|
||||||
|
BasicListItemWithImage(
|
||||||
|
R.drawable.ic_lock_grey600_24px,
|
||||||
|
context.getString(R.string.nc_attendee_pin, participant.attendeePin)
|
||||||
|
),
|
||||||
|
BasicListItemWithImage(
|
||||||
|
R.drawable.ic_pencil_grey600_24dp,
|
||||||
|
context.getString(R.string.nc_promote)
|
||||||
|
),
|
||||||
|
BasicListItemWithImage(
|
||||||
|
R.drawable.ic_pencil_grey600_24dp,
|
||||||
|
context.getString(R.string.nc_demote)
|
||||||
|
),
|
||||||
|
BasicListItemWithImage(
|
||||||
|
R.drawable.ic_delete_grey600_24dp,
|
||||||
|
context.getString(R.string.nc_remove_participant)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return items
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("CheckResult")
|
||||||
|
private fun launchRemoveAttendeeFromConversationDialog(
|
||||||
|
participant: Participant,
|
||||||
|
apiVersion: Int,
|
||||||
|
itemText: String,
|
||||||
|
@DrawableRes itemIcon: Int = R.drawable.ic_delete_grey600_24dp
|
||||||
|
) {
|
||||||
|
val items = mutableListOf(BasicListItemWithImage(itemIcon, itemText))
|
||||||
|
MaterialDialog(this, BottomSheet(WRAP_CONTENT)).show {
|
||||||
|
cornerRadius(res = R.dimen.corner_radius)
|
||||||
|
|
||||||
|
title(text = participant.displayName)
|
||||||
|
listItemsWithImage(items = items) { _, index, _ ->
|
||||||
|
if (index == 0) {
|
||||||
|
removeAttendeeFromConversation(apiVersion, participant)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun MaterialDialog.handleBan(participant: Participant) {
|
private fun MaterialDialog.handleBan(participant: Participant) {
|
||||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.API_V4, 1))
|
||||||
val binding = DialogBanParticipantBinding.inflate(layoutInflater)
|
val binding = DialogBanParticipantBinding.inflate(layoutInflater)
|
||||||
val actorTypeConverter = EnumActorTypeConverter()
|
val actorTypeConverter = EnumActorTypeConverter()
|
||||||
val dialog = MaterialAlertDialogBuilder(context)
|
val dialog = MaterialAlertDialogBuilder(context).setView(binding.root).create()
|
||||||
.setView(binding.root)
|
|
||||||
.create()
|
|
||||||
binding.avatarImage.loadUserAvatar(
|
binding.avatarImage.loadUserAvatar(
|
||||||
conversationUser,
|
conversationUser,
|
||||||
participant.actorId!!,
|
participant.actorId!!,
|
||||||
true,
|
requestBigSize = true,
|
||||||
false
|
ignoreCache = false
|
||||||
)
|
)
|
||||||
binding.displayNameText.text = participant.actorId
|
binding.displayNameText.text = participant.actorId
|
||||||
binding.buttonBan.setOnClickListener {
|
binding.buttonBan.setOnClickListener {
|
||||||
|
@ -122,6 +122,45 @@ class ConversationInfoEditActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initObservers() {
|
private fun initObservers() {
|
||||||
|
initViewStateObserver()
|
||||||
|
conversationInfoEditViewModel.renameRoomUiState.observe(this) { uiState ->
|
||||||
|
when (uiState) {
|
||||||
|
is ConversationInfoEditViewModel.RenameRoomUiState.None -> {
|
||||||
|
}
|
||||||
|
is ConversationInfoEditViewModel.RenameRoomUiState.Success -> {
|
||||||
|
if (CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) {
|
||||||
|
saveConversationDescription()
|
||||||
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is ConversationInfoEditViewModel.RenameRoomUiState.Error -> {
|
||||||
|
Snackbar
|
||||||
|
.make(binding.root, context.getString(R.string.default_error_msg), Snackbar.LENGTH_LONG)
|
||||||
|
.show()
|
||||||
|
Log.e(TAG, "Error while saving conversation name", uiState.exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
conversationInfoEditViewModel.setConversationDescriptionUiState.observe(this) { uiState ->
|
||||||
|
when (uiState) {
|
||||||
|
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.None -> {
|
||||||
|
}
|
||||||
|
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Success -> {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Error -> {
|
||||||
|
Snackbar
|
||||||
|
.make(binding.root, context.getString(R.string.default_error_msg), Snackbar.LENGTH_LONG)
|
||||||
|
.show()
|
||||||
|
Log.e(TAG, "Error while saving conversation description", uiState.exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initViewStateObserver() {
|
||||||
conversationInfoEditViewModel.viewState.observe(this) { state ->
|
conversationInfoEditViewModel.viewState.observe(this) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is ConversationInfoEditViewModel.GetRoomSuccessState -> {
|
is ConversationInfoEditViewModel.GetRoomSuccessState -> {
|
||||||
@ -131,7 +170,7 @@ class ConversationInfoEditActivity : BaseActivity() {
|
|||||||
|
|
||||||
binding.conversationName.setText(conversation!!.displayName)
|
binding.conversationName.setText(conversation!!.displayName)
|
||||||
|
|
||||||
if (conversation!!.description != null && conversation!!.description!!.isNotEmpty()) {
|
if (conversation!!.description.isNotEmpty()) {
|
||||||
binding.conversationDescription.setText(conversation!!.description)
|
binding.conversationDescription.setText(conversation!!.description)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,45 +206,6 @@ class ConversationInfoEditActivity : BaseActivity() {
|
|||||||
else -> {}
|
else -> {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
conversationInfoEditViewModel.renameRoomUiState.observe(this) { uiState ->
|
|
||||||
when (uiState) {
|
|
||||||
is ConversationInfoEditViewModel.RenameRoomUiState.None -> {
|
|
||||||
}
|
|
||||||
is ConversationInfoEditViewModel.RenameRoomUiState.Success -> {
|
|
||||||
if (CapabilitiesUtil.isConversationDescriptionEndpointAvailable(spreedCapabilities)) {
|
|
||||||
saveConversationDescription()
|
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is ConversationInfoEditViewModel.RenameRoomUiState.Error -> {
|
|
||||||
Snackbar.make(
|
|
||||||
binding.root,
|
|
||||||
context.getString(R.string.default_error_msg),
|
|
||||||
Snackbar.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
Log.e(TAG, "Error while saving conversation name", uiState.exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
conversationInfoEditViewModel.setConversationDescriptionUiState.observe(this) { uiState ->
|
|
||||||
when (uiState) {
|
|
||||||
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.None -> {
|
|
||||||
}
|
|
||||||
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Success -> {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
is ConversationInfoEditViewModel.SetConversationDescriptionUiState.Error -> {
|
|
||||||
Snackbar.make(
|
|
||||||
binding.root,
|
|
||||||
context.getString(R.string.default_error_msg),
|
|
||||||
Snackbar.LENGTH_LONG
|
|
||||||
).show()
|
|
||||||
Log.e(TAG, "Error while saving conversation description", uiState.exception)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupAvatarOptions() {
|
private fun setupAvatarOptions() {
|
||||||
|
@ -325,18 +325,12 @@ class ConversationsListActivity :
|
|||||||
conversationsListViewModel.getFederationInvitationsViewState.observe(this) { state ->
|
conversationsListViewModel.getFederationInvitationsViewState.observe(this) { state ->
|
||||||
when (state) {
|
when (state) {
|
||||||
is ConversationsListViewModel.GetFederationInvitationsStartState -> {
|
is ConversationsListViewModel.GetFederationInvitationsStartState -> {
|
||||||
binding.conversationListHintInclude.conversationListHintLayout.visibility =
|
binding.conversationListHintInclude.conversationListHintLayout.visibility = View.GONE
|
||||||
View.GONE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is ConversationsListViewModel.GetFederationInvitationsSuccessState -> {
|
is ConversationsListViewModel.GetFederationInvitationsSuccessState -> {
|
||||||
if (state.showInvitationsHint) {
|
binding.conversationListHintInclude.conversationListHintLayout.visibility =
|
||||||
binding.conversationListHintInclude.conversationListHintLayout.visibility =
|
if (state.showInvitationsHint) View.VISIBLE else View.GONE
|
||||||
View.VISIBLE
|
|
||||||
} else {
|
|
||||||
binding.conversationListHintInclude.conversationListHintLayout.visibility =
|
|
||||||
View.GONE
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
is ConversationsListViewModel.GetFederationInvitationsErrorState -> {
|
is ConversationsListViewModel.GetFederationInvitationsErrorState -> {
|
||||||
@ -387,31 +381,35 @@ class ConversationsListActivity :
|
|||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
conversationsListViewModel.getRoomsFlow
|
conversationsListViewModel.getRoomsFlow
|
||||||
.onEach { list ->
|
.onEach { list ->
|
||||||
// Update Conversations
|
setConversationList(list)
|
||||||
conversationItems.clear()
|
|
||||||
conversationItemsWithHeader.clear()
|
|
||||||
for (conversation in list) {
|
|
||||||
addToConversationItems(conversation)
|
|
||||||
}
|
|
||||||
sortConversations(conversationItems)
|
|
||||||
sortConversations(conversationItemsWithHeader)
|
|
||||||
|
|
||||||
// Filter Conversations
|
|
||||||
if (!hasFilterEnabled()) filterableConversationItems = conversationItems
|
|
||||||
filterConversation()
|
|
||||||
adapter!!.updateDataSet(filterableConversationItems, false)
|
|
||||||
Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong())
|
|
||||||
|
|
||||||
// Fetch Open Conversations
|
|
||||||
val apiVersion = ApiUtils.getConversationApiVersion(
|
|
||||||
currentUser!!,
|
|
||||||
intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)
|
|
||||||
)
|
|
||||||
fetchOpenConversations(apiVersion)
|
|
||||||
}.collect()
|
}.collect()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun setConversationList(list: List<ConversationModel>) {
|
||||||
|
// Update Conversations
|
||||||
|
conversationItems.clear()
|
||||||
|
conversationItemsWithHeader.clear()
|
||||||
|
for (conversation in list) {
|
||||||
|
addToConversationItems(conversation)
|
||||||
|
}
|
||||||
|
sortConversations(conversationItems)
|
||||||
|
sortConversations(conversationItemsWithHeader)
|
||||||
|
|
||||||
|
// Filter Conversations
|
||||||
|
if (!hasFilterEnabled()) filterableConversationItems = conversationItems
|
||||||
|
filterConversation()
|
||||||
|
adapter!!.updateDataSet(filterableConversationItems, false)
|
||||||
|
Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong())
|
||||||
|
|
||||||
|
// Fetch Open Conversations
|
||||||
|
val apiVersion = ApiUtils.getConversationApiVersion(
|
||||||
|
currentUser!!,
|
||||||
|
intArrayOf(ApiUtils.API_V4, ApiUtils.API_V3, 1)
|
||||||
|
)
|
||||||
|
fetchOpenConversations(apiVersion)
|
||||||
|
}
|
||||||
|
|
||||||
private fun hasFilterEnabled(): Boolean {
|
private fun hasFilterEnabled(): Boolean {
|
||||||
for ((k, v) in filterState) {
|
for ((k, v) in filterState) {
|
||||||
if (k != FilterConversationFragment.DEFAULT && v) return true
|
if (k != FilterConversationFragment.DEFAULT && v) return true
|
||||||
|
@ -282,7 +282,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
if (appPreferences.pushToken.isNullOrEmpty()) {
|
if (appPreferences.pushToken.isNullOrEmpty()) {
|
||||||
addValue(context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing))
|
addValue(context.resources.getString(R.string.nc_diagnose_firebase_push_token_missing))
|
||||||
} else {
|
} else {
|
||||||
addValue("${appPreferences.pushToken.substring(0, 5)}...")
|
addValue("${appPreferences.pushToken.substring(0, PUSH_TOKEN_PREFIX_END)}...")
|
||||||
}
|
}
|
||||||
|
|
||||||
addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated))
|
addKey(context.resources.getString(R.string.nc_diagnose_firebase_push_token_latest_generated))
|
||||||
@ -466,6 +466,7 @@ class DiagnoseActivity : BaseActivity() {
|
|||||||
val TAG = DiagnoseActivity::class.java.simpleName
|
val TAG = DiagnoseActivity::class.java.simpleName
|
||||||
private const val MARKDOWN_HEADLINE = "###"
|
private const val MARKDOWN_HEADLINE = "###"
|
||||||
private const val MARKDOWN_BOLD = "**"
|
private const val MARKDOWN_BOLD = "**"
|
||||||
|
private const val PUSH_TOKEN_PREFIX_END: Int = 5
|
||||||
private const val ORIGINAL_NEXTCLOUD_TALK_APPLICATION_ID = "com.nextcloud.talk2"
|
private const val ORIGINAL_NEXTCLOUD_TALK_APPLICATION_ID = "com.nextcloud.talk2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -292,16 +292,74 @@ class ContactAddressBookWorker(val context: Context, workerParameters: WorkerPar
|
|||||||
return hasLinkedAccount
|
return hasLinkedAccount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createOps(
|
||||||
|
cloudId: String,
|
||||||
|
numbers: MutableList<String>,
|
||||||
|
displayName: String?
|
||||||
|
): ArrayList<ContentProviderOperation> {
|
||||||
|
val ops = ArrayList<ContentProviderOperation>()
|
||||||
|
val rawContactsUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().build()
|
||||||
|
val dataUri = ContactsContract.Data.CONTENT_URI.buildUpon().build()
|
||||||
|
|
||||||
|
ops.add(
|
||||||
|
ContentProviderOperation
|
||||||
|
.newInsert(rawContactsUri)
|
||||||
|
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
|
||||||
|
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType)
|
||||||
|
.withValue(
|
||||||
|
ContactsContract.RawContacts.AGGREGATION_MODE,
|
||||||
|
ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT
|
||||||
|
)
|
||||||
|
.withValue(ContactsContract.RawContacts.SYNC2, cloudId)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
ops.add(
|
||||||
|
ContentProviderOperation
|
||||||
|
.newInsert(dataUri)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(
|
||||||
|
ContactsContract.Data.MIMETYPE,
|
||||||
|
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
||||||
|
)
|
||||||
|
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, numbers[0])
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
ops.add(
|
||||||
|
ContentProviderOperation
|
||||||
|
.newInsert(dataUri)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(
|
||||||
|
ContactsContract.Data.MIMETYPE,
|
||||||
|
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
|
||||||
|
)
|
||||||
|
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
ops.add(
|
||||||
|
ContentProviderOperation
|
||||||
|
.newInsert(dataUri)
|
||||||
|
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
||||||
|
.withValue(
|
||||||
|
ContactsContract.Data.MIMETYPE,
|
||||||
|
"vnd.android.cursor.item/vnd.com.nextcloud.talk2.chat"
|
||||||
|
)
|
||||||
|
.withValue(ContactsContract.Data.DATA1, cloudId)
|
||||||
|
.withValue(
|
||||||
|
ContactsContract.Data.DATA2,
|
||||||
|
String.format(
|
||||||
|
context.resources.getString(R.string.nc_phone_book_integration_chat_via),
|
||||||
|
accountName
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
return ops
|
||||||
|
}
|
||||||
|
|
||||||
fun createLinkedAccount(lookupKey: String, cloudId: String) {
|
fun createLinkedAccount(lookupKey: String, cloudId: String) {
|
||||||
val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey)
|
val lookupUri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_LOOKUP_URI, lookupKey)
|
||||||
val lookupContactUri = ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri)
|
val lookupContactUri = ContactsContract.Contacts.lookupContact(context.contentResolver, lookupUri)
|
||||||
val contactCursor = context.contentResolver.query(
|
val contactCursor = context.contentResolver.query(lookupContactUri, null, null, null, null)
|
||||||
lookupContactUri,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
null
|
|
||||||
)
|
|
||||||
|
|
||||||
if (contactCursor != null) {
|
if (contactCursor != null) {
|
||||||
if (contactCursor.count > 0) {
|
if (contactCursor.count > 0) {
|
||||||
@ -319,71 +377,14 @@ class ContactAddressBookWorker(val context: Context, workerParameters: WorkerPar
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val ops = ArrayList<ContentProviderOperation>()
|
val ops = createOps(cloudId, numbers, displayName)
|
||||||
val rawContactsUri = ContactsContract.RawContacts.CONTENT_URI.buildUpon().build()
|
|
||||||
val dataUri = ContactsContract.Data.CONTENT_URI.buildUpon().build()
|
|
||||||
|
|
||||||
ops.add(
|
|
||||||
ContentProviderOperation
|
|
||||||
.newInsert(rawContactsUri)
|
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName)
|
|
||||||
.withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType)
|
|
||||||
.withValue(
|
|
||||||
ContactsContract.RawContacts.AGGREGATION_MODE,
|
|
||||||
ContactsContract.RawContacts.AGGREGATION_MODE_DEFAULT
|
|
||||||
)
|
|
||||||
.withValue(ContactsContract.RawContacts.SYNC2, cloudId)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
ops.add(
|
|
||||||
ContentProviderOperation
|
|
||||||
.newInsert(dataUri)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(
|
|
||||||
ContactsContract.Data.MIMETYPE,
|
|
||||||
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
|
||||||
)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, numbers[0])
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
ops.add(
|
|
||||||
ContentProviderOperation
|
|
||||||
.newInsert(dataUri)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(
|
|
||||||
ContactsContract.Data.MIMETYPE,
|
|
||||||
ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE
|
|
||||||
)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
ops.add(
|
|
||||||
ContentProviderOperation
|
|
||||||
.newInsert(dataUri)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(
|
|
||||||
ContactsContract.Data.MIMETYPE,
|
|
||||||
"vnd.android.cursor.item/vnd.com.nextcloud.talk2.chat"
|
|
||||||
)
|
|
||||||
.withValue(ContactsContract.Data.DATA1, cloudId)
|
|
||||||
.withValue(
|
|
||||||
ContactsContract.Data.DATA2,
|
|
||||||
String.format(
|
|
||||||
context.resources.getString(
|
|
||||||
R.string.nc_phone_book_integration_chat_via
|
|
||||||
),
|
|
||||||
accountName
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.build()
|
|
||||||
)
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
|
context.contentResolver.applyBatch(ContactsContract.AUTHORITY, ops)
|
||||||
} catch (e: OperationApplicationException) {
|
} catch (e: OperationApplicationException) {
|
||||||
Log.e(javaClass.simpleName, "", e)
|
Log.e(TAG, "", e)
|
||||||
} catch (e: RemoteException) {
|
} catch (e: RemoteException) {
|
||||||
Log.e(javaClass.simpleName, "", e)
|
Log.e(TAG, "", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(
|
Log.d(
|
||||||
|
@ -217,8 +217,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
private fun handleCallPushMessage() {
|
private fun handleCallPushMessage() {
|
||||||
val userBeingCalled = userManager.getUserWithId(signatureVerification.user!!.id!!).blockingGet()
|
val userBeingCalled = userManager.getUserWithId(signatureVerification.user!!.id!!).blockingGet()
|
||||||
|
|
||||||
fun prepareCallNotificationScreen(conversation: ConversationModel) {
|
fun createBundle(conversation: ConversationModel): Bundle {
|
||||||
val fullScreenIntent = Intent(context, CallNotificationActivity::class.java)
|
|
||||||
val bundle = Bundle()
|
val bundle = Bundle()
|
||||||
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
bundle.putString(KEY_ROOM_TOKEN, pushMessage.id)
|
||||||
bundle.putInt(KEY_NOTIFICATION_TIMESTAMP, pushMessage.timestamp.toInt())
|
bundle.putInt(KEY_NOTIFICATION_TIMESTAMP, pushMessage.timestamp.toInt())
|
||||||
@ -248,6 +247,12 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
BundleKeys.KEY_IS_MODERATOR,
|
BundleKeys.KEY_IS_MODERATOR,
|
||||||
ConversationUtils.isParticipantOwnerOrModerator(conversation)
|
ConversationUtils.isParticipantOwnerOrModerator(conversation)
|
||||||
)
|
)
|
||||||
|
return bundle
|
||||||
|
}
|
||||||
|
|
||||||
|
fun prepareCallNotificationScreen(conversation: ConversationModel) {
|
||||||
|
val fullScreenIntent = Intent(context, CallNotificationActivity::class.java)
|
||||||
|
val bundle = createBundle(conversation)
|
||||||
|
|
||||||
fullScreenIntent.putExtras(bundle)
|
fullScreenIntent.putExtras(bundle)
|
||||||
fullScreenIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
fullScreenIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
@ -509,6 +514,42 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
|
|
||||||
val autoCancelOnClick = TYPE_RECORDING != pushMessage.type
|
val autoCancelOnClick = TYPE_RECORDING != pushMessage.type
|
||||||
|
|
||||||
|
val notificationBuilder =
|
||||||
|
createNotificationBuilder(category, contentTitle, contentText, baseUrl, pendingIntent, autoCancelOnClick)
|
||||||
|
val activeStatusBarNotification = findNotificationForRoom(
|
||||||
|
context,
|
||||||
|
signatureVerification.user!!,
|
||||||
|
pushMessage.id!!
|
||||||
|
)
|
||||||
|
|
||||||
|
// NOTE - systemNotificationId is an internal ID used on the device only.
|
||||||
|
// It is NOT the same as the notification ID used in communication with the server.
|
||||||
|
val systemNotificationId: Int =
|
||||||
|
activeStatusBarNotification?.id ?: calculateCRC32(System.currentTimeMillis().toString()).toInt()
|
||||||
|
|
||||||
|
if ((TYPE_CHAT == pushMessage.type || TYPE_REMINDER == pushMessage.type) &&
|
||||||
|
pushMessage.notificationUser != null
|
||||||
|
) {
|
||||||
|
prepareChatNotification(notificationBuilder, activeStatusBarNotification, systemNotificationId)
|
||||||
|
addReplyAction(notificationBuilder, systemNotificationId)
|
||||||
|
addMarkAsReadAction(notificationBuilder, systemNotificationId)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_RECORDING == pushMessage.type && ncNotification != null) {
|
||||||
|
addDismissRecordingAvailableAction(notificationBuilder, systemNotificationId, ncNotification)
|
||||||
|
addShareRecordingToChatAction(notificationBuilder, systemNotificationId, ncNotification)
|
||||||
|
}
|
||||||
|
sendNotification(systemNotificationId, notificationBuilder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createNotificationBuilder(
|
||||||
|
category: String,
|
||||||
|
contentTitle: CharSequence?,
|
||||||
|
contentText: CharSequence?,
|
||||||
|
baseUrl: String?,
|
||||||
|
pendingIntent: PendingIntent?,
|
||||||
|
autoCancelOnClick: Boolean
|
||||||
|
): NotificationCompat.Builder {
|
||||||
val notificationBuilder = NotificationCompat.Builder(context!!, "1")
|
val notificationBuilder = NotificationCompat.Builder(context!!, "1")
|
||||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||||
.setCategory(category)
|
.setCategory(category)
|
||||||
@ -551,30 +592,7 @@ class NotificationWorker(context: Context, workerParams: WorkerParameters) : Wor
|
|||||||
notificationBuilder.setContentIntent(pendingIntent)
|
notificationBuilder.setContentIntent(pendingIntent)
|
||||||
val groupName = signatureVerification.user!!.id.toString() + "@" + pushMessage.id
|
val groupName = signatureVerification.user!!.id.toString() + "@" + pushMessage.id
|
||||||
notificationBuilder.setGroup(calculateCRC32(groupName).toString())
|
notificationBuilder.setGroup(calculateCRC32(groupName).toString())
|
||||||
val activeStatusBarNotification = findNotificationForRoom(
|
return notificationBuilder
|
||||||
context,
|
|
||||||
signatureVerification.user!!,
|
|
||||||
pushMessage.id!!
|
|
||||||
)
|
|
||||||
|
|
||||||
// NOTE - systemNotificationId is an internal ID used on the device only.
|
|
||||||
// It is NOT the same as the notification ID used in communication with the server.
|
|
||||||
val systemNotificationId: Int =
|
|
||||||
activeStatusBarNotification?.id ?: calculateCRC32(System.currentTimeMillis().toString()).toInt()
|
|
||||||
|
|
||||||
if ((TYPE_CHAT == pushMessage.type || TYPE_REMINDER == pushMessage.type) &&
|
|
||||||
pushMessage.notificationUser != null
|
|
||||||
) {
|
|
||||||
prepareChatNotification(notificationBuilder, activeStatusBarNotification, systemNotificationId)
|
|
||||||
addReplyAction(notificationBuilder, systemNotificationId)
|
|
||||||
addMarkAsReadAction(notificationBuilder, systemNotificationId)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (TYPE_RECORDING == pushMessage.type && ncNotification != null) {
|
|
||||||
addDismissRecordingAvailableAction(notificationBuilder, systemNotificationId, ncNotification)
|
|
||||||
addShareRecordingToChatAction(notificationBuilder, systemNotificationId, ncNotification)
|
|
||||||
}
|
|
||||||
sendNotification(systemNotificationId, notificationBuilder.build())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLargeIcon(): Bitmap {
|
private fun getLargeIcon(): Bitmap {
|
||||||
|
@ -74,33 +74,21 @@ class SaveFileToStorageWorker(val context: Context, workerParameters: WorkerPara
|
|||||||
MediaScannerConnection.scanFile(context, arrayOf(cacheFile.absolutePath), null, null)
|
MediaScannerConnection.scanFile(context, arrayOf(cacheFile.absolutePath), null, null)
|
||||||
|
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Toast.makeText(
|
Toast.makeText(context, R.string.nc_save_success, Toast.LENGTH_SHORT).show()
|
||||||
context,
|
|
||||||
context.resources.getString(R.string.nc_save_success),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.success()
|
return Result.success()
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
Log.e(TAG, "Something went wrong when trying to save file to internal storage", e)
|
Log.e(TAG, "Something went wrong when trying to save file to internal storage", e)
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Toast.makeText(
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_SHORT).show()
|
||||||
context,
|
|
||||||
context.resources.getString(R.string.nc_common_error_sorry),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.failure()
|
return Result.failure()
|
||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
Log.e(TAG, "Something went wrong when trying to save file to internal storage", e)
|
Log.e(TAG, "Something went wrong when trying to save file to internal storage", e)
|
||||||
Handler(Looper.getMainLooper()).post {
|
Handler(Looper.getMainLooper()).post {
|
||||||
Toast.makeText(
|
Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_SHORT).show()
|
||||||
context,
|
|
||||||
context.resources.getString(R.string.nc_common_error_sorry),
|
|
||||||
Toast.LENGTH_SHORT
|
|
||||||
).show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.failure()
|
return Result.failure()
|
||||||
|
@ -110,46 +110,10 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
fileName = FileUtils.getFileName(sourceFileUri, context)
|
fileName = FileUtils.getFileName(sourceFileUri, context)
|
||||||
file = FileUtils.getFileFromUri(context, sourceFileUri)
|
file = FileUtils.getFileFromUri(context, sourceFileUri)
|
||||||
val remotePath = getRemotePath(currentUser)
|
val remotePath = getRemotePath(currentUser)
|
||||||
val uploadSuccess: Boolean
|
|
||||||
|
|
||||||
initNotificationSetup()
|
initNotificationSetup()
|
||||||
file?.let { isChunkedUploading = it.length() > CHUNK_UPLOAD_THRESHOLD_SIZE }
|
file?.let { isChunkedUploading = it.length() > CHUNK_UPLOAD_THRESHOLD_SIZE }
|
||||||
if (file == null) {
|
val uploadSuccess: Boolean = uploadFile(sourceFileUri, metaData, remotePath)
|
||||||
uploadSuccess = false
|
|
||||||
} else if (isChunkedUploading) {
|
|
||||||
Log.d(TAG, "starting chunked upload because size is " + file!!.length())
|
|
||||||
|
|
||||||
initNotificationWithPercentage()
|
|
||||||
val mimeType = context.contentResolver.getType(sourceFileUri)?.toMediaTypeOrNull()
|
|
||||||
|
|
||||||
chunkedFileUploader = ChunkedFileUploader(
|
|
||||||
okHttpClient,
|
|
||||||
currentUser,
|
|
||||||
roomToken,
|
|
||||||
metaData,
|
|
||||||
this
|
|
||||||
)
|
|
||||||
|
|
||||||
uploadSuccess = chunkedFileUploader!!.upload(
|
|
||||||
file!!,
|
|
||||||
mimeType,
|
|
||||||
remotePath
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
Log.d(TAG, "starting normal upload (not chunked) of $fileName")
|
|
||||||
|
|
||||||
uploadSuccess = FileUploader(
|
|
||||||
context,
|
|
||||||
currentUser,
|
|
||||||
roomToken,
|
|
||||||
ncApi
|
|
||||||
).upload(
|
|
||||||
sourceFileUri,
|
|
||||||
fileName,
|
|
||||||
remotePath,
|
|
||||||
metaData
|
|
||||||
).blockingFirst()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uploadSuccess) {
|
if (uploadSuccess) {
|
||||||
cancelNotification()
|
cancelNotification()
|
||||||
@ -169,16 +133,31 @@ class UploadAndShareFilesWorker(val context: Context, workerParameters: WorkerPa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun uploadFile(sourceFileUri: Uri, metaData: String?, remotePath: String): Boolean {
|
||||||
|
return if (file == null) {
|
||||||
|
false
|
||||||
|
} else if (isChunkedUploading) {
|
||||||
|
Log.d(TAG, "starting chunked upload because size is " + file!!.length())
|
||||||
|
|
||||||
|
initNotificationWithPercentage()
|
||||||
|
val mimeType = context.contentResolver.getType(sourceFileUri)?.toMediaTypeOrNull()
|
||||||
|
|
||||||
|
chunkedFileUploader = ChunkedFileUploader(okHttpClient, currentUser, roomToken, metaData, this)
|
||||||
|
chunkedFileUploader!!.upload(file!!, mimeType, remotePath)
|
||||||
|
} else {
|
||||||
|
Log.d(TAG, "starting normal upload (not chunked) of $fileName")
|
||||||
|
|
||||||
|
FileUploader(context, currentUser, roomToken, ncApi)
|
||||||
|
.upload(sourceFileUri, fileName, remotePath, metaData)
|
||||||
|
.blockingFirst()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getRemotePath(currentUser: User): String {
|
private fun getRemotePath(currentUser: User): String {
|
||||||
var remotePath = CapabilitiesUtil.getAttachmentFolder(
|
val remotePath = CapabilitiesUtil.getAttachmentFolder(
|
||||||
currentUser.capabilities!!.spreedCapability!!
|
currentUser.capabilities!!.spreedCapability!!
|
||||||
) + "/" + fileName
|
) + "/" + fileName
|
||||||
remotePath = RemoteFileUtils.getNewPathIfFileExists(
|
return RemoteFileUtils.getNewPathIfFileExists(ncApi, currentUser, remotePath)
|
||||||
ncApi,
|
|
||||||
currentUser,
|
|
||||||
remotePath
|
|
||||||
)
|
|
||||||
return remotePath
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTransferProgress(percentage: Int) {
|
override fun onTransferProgress(percentage: Int) {
|
||||||
|
@ -117,15 +117,14 @@ class PushUtils {
|
|||||||
private fun saveKeyToFile(key: Key, path: String): Int {
|
private fun saveKeyToFile(key: Key, path: String): Int {
|
||||||
val encoded = key.encoded
|
val encoded = key.encoded
|
||||||
try {
|
try {
|
||||||
if (!File(path).exists()) {
|
return if (!File(path).exists() && !File(path).createNewFile()) {
|
||||||
if (!File(path).createNewFile()) {
|
-1
|
||||||
return -1
|
} else {
|
||||||
|
FileOutputStream(path).use { keyFileOutputStream ->
|
||||||
|
keyFileOutputStream.write(encoded)
|
||||||
|
0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FileOutputStream(path).use { keyFileOutputStream ->
|
|
||||||
keyFileOutputStream.write(encoded)
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
} catch (e: FileNotFoundException) {
|
} catch (e: FileNotFoundException) {
|
||||||
Log.d(TAG, "Failed to save key to file")
|
Log.d(TAG, "Failed to save key to file")
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
|
# SPDX-FileCopyrightText: 2017-2024 Nextcloud GmbH and Nextcloud contributors
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
build:
|
build:
|
||||||
maxIssues: 99
|
maxIssues: 82
|
||||||
weights:
|
weights:
|
||||||
# complexity: 2
|
# complexity: 2
|
||||||
# LongParameterList: 1
|
# LongParameterList: 1
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
DO NOT TOUCH; GENERATED BY DRONE
|
DO NOT TOUCH; GENERATED BY DRONE
|
||||||
<span class="mdl-layout-title">Lint Report: 72 errors and 158 warnings</span>
|
<span class="mdl-layout-title">Lint Report: 71 errors and 158 warnings</span>
|
||||||
|
Loading…
Reference in New Issue
Block a user