mirror of
https://github.com/nextcloud/talk-android
synced 2025-06-20 03:59:35 +01:00
Merge pull request #2355 from nextcloud/chrore/fix-warnings-in-chatController
Fix warnings in ChatController
This commit is contained in:
commit
7deb8bef8d
@ -238,32 +238,32 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
var roomToken: String? = null
|
var roomToken: String? = null
|
||||||
val conversationUser: User?
|
val conversationUser: User?
|
||||||
val roomPassword: String
|
private val roomPassword: String
|
||||||
var credentials: String? = null
|
var credentials: String? = null
|
||||||
var currentConversation: Conversation? = null
|
var currentConversation: Conversation? = null
|
||||||
var inConversation = false
|
var inConversation = false
|
||||||
var historyRead = false
|
private var historyRead = false
|
||||||
var globalLastKnownFutureMessageId = -1
|
private var globalLastKnownFutureMessageId = -1
|
||||||
var globalLastKnownPastMessageId = -1
|
private var globalLastKnownPastMessageId = -1
|
||||||
var adapter: TalkMessagesListAdapter<ChatMessage>? = null
|
var adapter: TalkMessagesListAdapter<ChatMessage>? = null
|
||||||
var mentionAutocomplete: Autocomplete<*>? = null
|
private var mentionAutocomplete: Autocomplete<*>? = null
|
||||||
var layoutManager: LinearLayoutManager? = null
|
var layoutManager: LinearLayoutManager? = null
|
||||||
var pullChatMessagesPending = false
|
var pullChatMessagesPending = false
|
||||||
var lookingIntoFuture = false
|
private var lookingIntoFuture = false
|
||||||
var newMessagesCount = 0
|
var newMessagesCount = 0
|
||||||
var startCallFromNotification: Boolean? = null
|
var startCallFromNotification: Boolean? = null
|
||||||
val roomId: String
|
val roomId: String
|
||||||
val voiceOnly: Boolean
|
val voiceOnly: Boolean
|
||||||
var isFirstMessagesProcessing = true
|
var isFirstMessagesProcessing = true
|
||||||
var emojiPopup: EmojiPopup? = null
|
private var emojiPopup: EmojiPopup? = null
|
||||||
|
|
||||||
var myFirstMessage: CharSequence? = null
|
var myFirstMessage: CharSequence? = null
|
||||||
var checkingLobbyStatus: Boolean = false
|
var checkingLobbyStatus: Boolean = false
|
||||||
|
|
||||||
var conversationInfoMenuItem: MenuItem? = null
|
private var conversationInfoMenuItem: MenuItem? = null
|
||||||
var conversationVoiceCallMenuItem: MenuItem? = null
|
private var conversationVoiceCallMenuItem: MenuItem? = null
|
||||||
var conversationVideoMenuItem: MenuItem? = null
|
private var conversationVideoMenuItem: MenuItem? = null
|
||||||
var conversationSharedItemsItem: MenuItem? = null
|
private var conversationSharedItemsItem: MenuItem? = null
|
||||||
|
|
||||||
var magicWebSocketInstance: MagicWebSocketInstance? = null
|
var magicWebSocketInstance: MagicWebSocketInstance? = null
|
||||||
|
|
||||||
@ -271,8 +271,8 @@ class ChatController(args: Bundle) :
|
|||||||
var pastPreconditionFailed = false
|
var pastPreconditionFailed = false
|
||||||
var futurePreconditionFailed = false
|
var futurePreconditionFailed = false
|
||||||
|
|
||||||
val filesToUpload: MutableList<String> = ArrayList()
|
private val filesToUpload: MutableList<String> = ArrayList()
|
||||||
var sharedText: String
|
private var sharedText: String
|
||||||
var isVoiceRecordingInProgress: Boolean = false
|
var isVoiceRecordingInProgress: Boolean = false
|
||||||
var currentVoiceRecordFile: String = ""
|
var currentVoiceRecordFile: String = ""
|
||||||
|
|
||||||
@ -280,7 +280,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
var mediaPlayer: MediaPlayer? = null
|
var mediaPlayer: MediaPlayer? = null
|
||||||
lateinit var mediaPlayerHandler: Handler
|
lateinit var mediaPlayerHandler: Handler
|
||||||
var currentlyPlayedVoiceMessage: ChatMessage? = null
|
private var currentlyPlayedVoiceMessage: ChatMessage? = null
|
||||||
|
|
||||||
var hasChatPermission: Boolean = false
|
var hasChatPermission: Boolean = false
|
||||||
|
|
||||||
@ -306,10 +306,10 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
this.roomPassword = args.getString(BundleKeys.KEY_CONVERSATION_PASSWORD, "")
|
this.roomPassword = args.getString(BundleKeys.KEY_CONVERSATION_PASSWORD, "")
|
||||||
|
|
||||||
if (conversationUser?.userId == "?") {
|
credentials = if (conversationUser?.userId == "?") {
|
||||||
credentials = null
|
null
|
||||||
} else {
|
} else {
|
||||||
credentials = ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token)
|
ApiUtils.getCredentials(conversationUser!!.username, conversationUser.token)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (args.containsKey(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) {
|
if (args.containsKey(BundleKeys.KEY_FROM_NOTIFICATION_START_CALL)) {
|
||||||
@ -329,7 +329,7 @@ class ChatController(args: Bundle) :
|
|||||||
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
val apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||||
|
|
||||||
val startNanoTime = System.nanoTime()
|
val startNanoTime = System.nanoTime()
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - calling: " + startNanoTime)
|
Log.d(TAG, "getRoomInfo - getRoom - calling: $startNanoTime")
|
||||||
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser.baseUrl, roomToken))
|
ncApi.getRoom(credentials, ApiUtils.getUrlForRoom(apiVersion, conversationUser.baseUrl, roomToken))
|
||||||
?.subscribeOn(Schedulers.io())
|
?.subscribeOn(Schedulers.io())
|
||||||
?.observeOn(AndroidSchedulers.mainThread())
|
?.observeOn(AndroidSchedulers.mainThread())
|
||||||
@ -340,7 +340,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - got response: " + startNanoTime)
|
Log.d(TAG, "getRoomInfo - getRoom - got response: $startNanoTime")
|
||||||
currentConversation = roomOverall.ocs!!.data
|
currentConversation = roomOverall.ocs!!.data
|
||||||
Log.d(
|
Log.d(
|
||||||
TAG,
|
TAG,
|
||||||
@ -367,7 +367,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
} catch (npe: NullPointerException) {
|
} catch (npe: NullPointerException) {
|
||||||
// view binding can be null
|
// view binding can be null
|
||||||
// since this is called asynchrously and UI might have been destroyed in the meantime
|
// since this is called asynchronously and UI might have been destroyed in the meantime
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone")
|
Log.i(TAG, "UI destroyed - view binding already gone")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -377,7 +377,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onComplete() {
|
override fun onComplete() {
|
||||||
Log.d(TAG, "getRoomInfo - getRoom - onComplete: " + startNanoTime)
|
Log.d(TAG, "getRoomInfo - getRoom - onComplete: $startNanoTime")
|
||||||
if (shouldRepeat) {
|
if (shouldRepeat) {
|
||||||
if (lobbyTimerHandler == null) {
|
if (lobbyTimerHandler == null) {
|
||||||
lobbyTimerHandler = Handler()
|
lobbyTimerHandler = Handler()
|
||||||
@ -582,14 +582,13 @@ class ChatController(args: Bundle) :
|
|||||||
this
|
this
|
||||||
)
|
)
|
||||||
|
|
||||||
var senderId = ""
|
val senderId = if (!conversationUser.userId.equals("?")) {
|
||||||
if (!conversationUser?.userId.equals("?")) {
|
"users/" + conversationUser.userId
|
||||||
senderId = "users/" + conversationUser?.userId
|
|
||||||
} else {
|
} else {
|
||||||
senderId = currentConversation?.actorType + "/" + currentConversation?.actorId
|
currentConversation?.actorType + "/" + currentConversation?.actorId
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: " + senderId)
|
Log.d(TAG, "Initialize TalkMessagesListAdapter with senderId: $senderId")
|
||||||
|
|
||||||
adapter = TalkMessagesListAdapter(
|
adapter = TalkMessagesListAdapter(
|
||||||
senderId,
|
senderId,
|
||||||
@ -618,7 +617,7 @@ class ChatController(args: Bundle) :
|
|||||||
R.id.playPauseBtn
|
R.id.playPauseBtn
|
||||||
) { view, message ->
|
) { view, message ->
|
||||||
val filename = message.selectedIndividualHashMap!!["name"]
|
val filename = message.selectedIndividualHashMap!!["name"]
|
||||||
val file = File(context!!.cacheDir, filename!!)
|
val file = File(context.cacheDir, filename!!)
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
if (message.isPlayingVoiceMessage) {
|
if (message.isPlayingVoiceMessage) {
|
||||||
pausePlayback(message)
|
pausePlayback(message)
|
||||||
@ -638,11 +637,10 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
binding.popupBubbleView.setPopupBubbleListener { context ->
|
binding.popupBubbleView.setPopupBubbleListener { context ->
|
||||||
if (newMessagesCount != 0) {
|
if (newMessagesCount != 0) {
|
||||||
val scrollPosition: Int
|
val scrollPosition = if (newMessagesCount - 1 < 0) {
|
||||||
if (newMessagesCount - 1 < 0) {
|
0
|
||||||
scrollPosition = 0
|
|
||||||
} else {
|
} else {
|
||||||
scrollPosition = newMessagesCount - 1
|
newMessagesCount - 1
|
||||||
}
|
}
|
||||||
Handler().postDelayed(
|
Handler().postDelayed(
|
||||||
{
|
{
|
||||||
@ -676,7 +674,7 @@ class ChatController(args: Bundle) :
|
|||||||
})
|
})
|
||||||
|
|
||||||
val filters = arrayOfNulls<InputFilter>(1)
|
val filters = arrayOfNulls<InputFilter>(1)
|
||||||
val lengthFilter = CapabilitiesUtilNew.getMessageMaxLength(conversationUser) ?: MESSAGE_MAX_LENGTH
|
val lengthFilter = CapabilitiesUtilNew.getMessageMaxLength(conversationUser)
|
||||||
|
|
||||||
filters[0] = InputFilter.LengthFilter(lengthFilter)
|
filters[0] = InputFilter.LengthFilter(lengthFilter)
|
||||||
binding.messageInputView.inputEditText?.filters = filters
|
binding.messageInputView.inputEditText?.filters = filters
|
||||||
@ -692,7 +690,7 @@ class ChatController(args: Bundle) :
|
|||||||
if (s.length >= lengthFilter) {
|
if (s.length >= lengthFilter) {
|
||||||
binding.messageInputView.inputEditText?.error = String.format(
|
binding.messageInputView.inputEditText?.error = String.format(
|
||||||
Objects.requireNonNull<Resources>(resources).getString(R.string.nc_limit_hit),
|
Objects.requireNonNull<Resources>(resources).getString(R.string.nc_limit_hit),
|
||||||
Integer.toString(lengthFilter)
|
lengthFilter.toString()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
binding.messageInputView.inputEditText?.error = null
|
binding.messageInputView.inputEditText?.error = null
|
||||||
@ -771,7 +769,7 @@ class ChatController(args: Bundle) :
|
|||||||
requestRecordAudioPermissions()
|
requestRecordAudioPermissions()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if (!UploadAndShareFilesWorker.isStoragePermissionGranted(context!!)) {
|
if (!UploadAndShareFilesWorker.isStoragePermissionGranted(context)) {
|
||||||
UploadAndShareFilesWorker.requestStoragePermission(this@ChatController)
|
UploadAndShareFilesWorker.requestStoragePermission(this@ChatController)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -803,10 +801,10 @@ class ChatController(args: Bundle) :
|
|||||||
voiceRecordEndTime = System.currentTimeMillis()
|
voiceRecordEndTime = System.currentTimeMillis()
|
||||||
val voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime
|
val voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime
|
||||||
if (voiceRecordDuration < MINIMUM_VOICE_RECORD_DURATION) {
|
if (voiceRecordDuration < MINIMUM_VOICE_RECORD_DURATION) {
|
||||||
Log.d(TAG, "voiceRecordDuration: " + voiceRecordDuration)
|
Log.d(TAG, "voiceRecordDuration: $voiceRecordDuration")
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context!!.getString(R.string.nc_voice_message_hold_to_record_info),
|
context.getString(R.string.nc_voice_message_hold_to_record_info),
|
||||||
Toast.LENGTH_SHORT
|
Toast.LENGTH_SHORT
|
||||||
).show()
|
).show()
|
||||||
stopAndDiscardAudioRecording()
|
stopAndDiscardAudioRecording()
|
||||||
@ -993,7 +991,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
if (mediaPlayer == null) {
|
if (mediaPlayer == null) {
|
||||||
val fileName = message.selectedIndividualHashMap!!["name"]
|
val fileName = message.selectedIndividualHashMap!!["name"]
|
||||||
val absolutePath = context!!.cacheDir.absolutePath + "/" + fileName
|
val absolutePath = context.cacheDir.absolutePath + "/" + fileName
|
||||||
mediaPlayer = MediaPlayer().apply {
|
mediaPlayer = MediaPlayer().apply {
|
||||||
setDataSource(absolutePath)
|
setDataSource(absolutePath)
|
||||||
prepare()
|
prepare()
|
||||||
@ -1050,12 +1048,12 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
// check if download worker is already running
|
// check if download worker is already running
|
||||||
val workers = WorkManager.getInstance(
|
val workers = WorkManager.getInstance(
|
||||||
context!!
|
context
|
||||||
).getWorkInfosByTag(fileId!!)
|
).getWorkInfosByTag(fileId!!)
|
||||||
try {
|
try {
|
||||||
for (workInfo in workers.get()) {
|
for (workInfo in workers.get()) {
|
||||||
if (workInfo.state == WorkInfo.State.RUNNING || workInfo.state == WorkInfo.State.ENQUEUED) {
|
if (workInfo.state == WorkInfo.State.RUNNING || workInfo.state == WorkInfo.State.ENQUEUED) {
|
||||||
Log.d(TAG, "Download worker for " + fileId + " is already running or scheduled")
|
Log.d(TAG, "Download worker for $fileId is already running or scheduled")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1081,7 +1079,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
WorkManager.getInstance().enqueue(downloadWorker)
|
WorkManager.getInstance().enqueue(downloadWorker)
|
||||||
|
|
||||||
WorkManager.getInstance(context!!).getWorkInfoByIdLiveData(downloadWorker.id)
|
WorkManager.getInstance(context).getWorkInfoByIdLiveData(downloadWorker.id)
|
||||||
.observeForever { workInfo: WorkInfo ->
|
.observeForever { workInfo: WorkInfo ->
|
||||||
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
if (workInfo.state == WorkInfo.State.SUCCEEDED) {
|
||||||
startPlayback(message)
|
startPlayback(message)
|
||||||
@ -1096,13 +1094,13 @@ class ChatController(args: Bundle) :
|
|||||||
val date: String = simpleDateFormat.format(Date())
|
val date: String = simpleDateFormat.format(Date())
|
||||||
|
|
||||||
val fileNameWithoutSuffix = String.format(
|
val fileNameWithoutSuffix = String.format(
|
||||||
context!!.resources.getString(R.string.nc_voice_message_filename),
|
context.resources.getString(R.string.nc_voice_message_filename),
|
||||||
date,
|
date,
|
||||||
currentConversation!!.displayName
|
currentConversation!!.displayName
|
||||||
)
|
)
|
||||||
val fileName = fileNameWithoutSuffix + VOICE_MESSAGE_FILE_SUFFIX
|
val fileName = fileNameWithoutSuffix + VOICE_MESSAGE_FILE_SUFFIX
|
||||||
|
|
||||||
currentVoiceRecordFile = "${context!!.cacheDir.absolutePath}/$fileName"
|
currentVoiceRecordFile = "${context.cacheDir.absolutePath}/$fileName"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showRecordAudioUi(show: Boolean) {
|
private fun showRecordAudioUi(show: Boolean) {
|
||||||
@ -1124,14 +1122,14 @@ class ChatController(args: Bundle) :
|
|||||||
binding.messageInputView.smileyButton.visibility = View.VISIBLE
|
binding.messageInputView.smileyButton.visibility = View.VISIBLE
|
||||||
binding.messageInputView.messageInput.visibility = View.VISIBLE
|
binding.messageInputView.messageInput.visibility = View.VISIBLE
|
||||||
binding.messageInputView.messageInput.hint =
|
binding.messageInputView.messageInput.hint =
|
||||||
context?.resources?.getString(R.string.nc_hint_enter_a_message)
|
context.resources?.getString(R.string.nc_hint_enter_a_message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isRecordAudioPermissionGranted(): Boolean {
|
private fun isRecordAudioPermissionGranted(): Boolean {
|
||||||
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
return PermissionChecker.checkSelfPermission(
|
return PermissionChecker.checkSelfPermission(
|
||||||
context!!,
|
context,
|
||||||
Manifest.permission.RECORD_AUDIO
|
Manifest.permission.RECORD_AUDIO
|
||||||
) == PermissionChecker.PERMISSION_GRANTED
|
) == PermissionChecker.PERMISSION_GRANTED
|
||||||
} else {
|
} else {
|
||||||
@ -1211,7 +1209,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun vibrate() {
|
fun vibrate() {
|
||||||
val vibrator = context?.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
val vibrator = context.getSystemService(Context.VIBRATOR_SERVICE) as Vibrator
|
||||||
if (Build.VERSION.SDK_INT >= O) {
|
if (Build.VERSION.SDK_INT >= O) {
|
||||||
vibrator.vibrate(VibrationEffect.createOneShot(SHORT_VIBRATE, VibrationEffect.DEFAULT_AMPLITUDE))
|
vibrator.vibrate(VibrationEffect.createOneShot(SHORT_VIBRATE, VibrationEffect.DEFAULT_AMPLITUDE))
|
||||||
} else {
|
} else {
|
||||||
@ -1403,25 +1401,25 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
require(filesToUpload.isNotEmpty())
|
require(filesToUpload.isNotEmpty())
|
||||||
|
|
||||||
val filenamesWithLinebreaks = StringBuilder("\n")
|
val filenamesWithLineBreaks = StringBuilder("\n")
|
||||||
|
|
||||||
for (file in filesToUpload) {
|
for (file in filesToUpload) {
|
||||||
val filename = UriUtils.getFileName(Uri.parse(file), context)
|
val filename = UriUtils.getFileName(Uri.parse(file), context)
|
||||||
filenamesWithLinebreaks.append(filename).append("\n")
|
filenamesWithLineBreaks.append(filename).append("\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
val confirmationQuestion = when (filesToUpload.size) {
|
val confirmationQuestion = when (filesToUpload.size) {
|
||||||
1 -> context?.resources?.getString(R.string.nc_upload_confirm_send_single)?.let {
|
1 -> context.resources?.getString(R.string.nc_upload_confirm_send_single)?.let {
|
||||||
String.format(it, title.trim())
|
String.format(it, title.trim())
|
||||||
}
|
}
|
||||||
else -> context?.resources?.getString(R.string.nc_upload_confirm_send_multiple)?.let {
|
else -> context.resources?.getString(R.string.nc_upload_confirm_send_multiple)?.let {
|
||||||
String.format(it, title.trim())
|
String.format(it, title.trim())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageInputView.context)
|
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageInputView.context)
|
||||||
.setTitle(confirmationQuestion)
|
.setTitle(confirmationQuestion)
|
||||||
.setMessage(filenamesWithLinebreaks.toString())
|
.setMessage(filenamesWithLineBreaks.toString())
|
||||||
.setPositiveButton(R.string.nc_yes) { _, _ ->
|
.setPositiveButton(R.string.nc_yes) { _, _ ->
|
||||||
if (UploadAndShareFilesWorker.isStoragePermissionGranted(context)) {
|
if (UploadAndShareFilesWorker.isStoragePermissionGranted(context)) {
|
||||||
uploadFiles(filesToUpload, false)
|
uploadFiles(filesToUpload, false)
|
||||||
@ -1445,11 +1443,11 @@ class ChatController(args: Bundle) :
|
|||||||
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
|
||||||
)
|
)
|
||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||||
}
|
}
|
||||||
@ -1460,8 +1458,8 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
val id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
|
val id = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts._ID))
|
||||||
val fileName = ContactUtils.getDisplayNameFromDeviceContact(context!!, id) + ".vcf"
|
val fileName = ContactUtils.getDisplayNameFromDeviceContact(context, id) + ".vcf"
|
||||||
val file = File(context?.cacheDir, fileName)
|
val file = File(context.cacheDir, fileName)
|
||||||
writeContactToVcfFile(cursor, file)
|
writeContactToVcfFile(cursor, file)
|
||||||
|
|
||||||
val shareUri = FileProvider.getUriForFile(
|
val shareUri = FileProvider.getUriForFile(
|
||||||
@ -1486,7 +1484,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
require(filesToUpload.isNotEmpty())
|
require(filesToUpload.isNotEmpty())
|
||||||
|
|
||||||
if (UploadAndShareFilesWorker.isStoragePermissionGranted(context!!)) {
|
if (UploadAndShareFilesWorker.isStoragePermissionGranted(context)) {
|
||||||
uploadFiles(filesToUpload, false)
|
uploadFiles(filesToUpload, false)
|
||||||
} else {
|
} else {
|
||||||
UploadAndShareFilesWorker.requestStoragePermission(this)
|
UploadAndShareFilesWorker.requestStoragePermission(this)
|
||||||
@ -1494,7 +1492,7 @@ class ChatController(args: Bundle) :
|
|||||||
} catch (e: IllegalStateException) {
|
} catch (e: IllegalStateException) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context?.resources?.getString(R.string.nc_upload_failed),
|
context.resources?.getString(R.string.nc_upload_failed),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
)
|
)
|
||||||
.show()
|
.show()
|
||||||
@ -1502,7 +1500,7 @@ class ChatController(args: Bundle) :
|
|||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context?.resources?.getString(R.string.nc_upload_failed),
|
context.resources?.getString(R.string.nc_upload_failed),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
)
|
)
|
||||||
.show()
|
.show()
|
||||||
@ -1554,7 +1552,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast
|
Toast
|
||||||
.makeText(context, context?.getString(R.string.read_storage_no_permission), Toast.LENGTH_LONG)
|
.makeText(context, context.getString(R.string.read_storage_no_permission), Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
} else if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
|
} else if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
|
||||||
@ -1563,7 +1561,7 @@ class ChatController(args: Bundle) :
|
|||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context!!.getString(R.string.nc_voice_message_missing_audio_permission),
|
context.getString(R.string.nc_voice_message_missing_audio_permission),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
@ -1574,17 +1572,17 @@ class ChatController(args: Bundle) :
|
|||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context!!.getString(R.string.nc_share_contact_permission),
|
context.getString(R.string.nc_share_contact_permission),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
} else if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
} else if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||||
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||||
Log.d(TAG, "launch cam activity since permission for cam has been granted")
|
Log.d(TAG, "launch cam activity since permission for cam has been granted")
|
||||||
startActivityForResult(TakePhotoActivity.createIntent(context!!), REQUEST_CODE_PICK_CAMERA)
|
startActivityForResult(TakePhotoActivity.createIntent(context), REQUEST_CODE_PICK_CAMERA)
|
||||||
} else {
|
} else {
|
||||||
Toast
|
Toast
|
||||||
.makeText(context, context?.getString(R.string.take_photo_permission), Toast.LENGTH_LONG)
|
.makeText(context, context.getString(R.string.take_photo_permission), Toast.LENGTH_LONG)
|
||||||
.show()
|
.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1621,12 +1619,12 @@ class ChatController(args: Bundle) :
|
|||||||
if (!isVoiceMessage) {
|
if (!isVoiceMessage) {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
context,
|
context,
|
||||||
context?.getString(R.string.nc_upload_in_progess),
|
context.getString(R.string.nc_upload_in_progess),
|
||||||
Toast.LENGTH_LONG
|
Toast.LENGTH_LONG
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
} catch (e: IllegalArgumentException) {
|
} catch (e: IllegalArgumentException) {
|
||||||
Toast.makeText(context, context?.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
|
Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
|
||||||
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1640,7 +1638,7 @@ class ChatController(args: Bundle) :
|
|||||||
startActivityForResult(
|
startActivityForResult(
|
||||||
Intent.createChooser(
|
Intent.createChooser(
|
||||||
action,
|
action,
|
||||||
context?.resources?.getString(
|
context.resources?.getString(
|
||||||
R.string.nc_upload_choose_local_files
|
R.string.nc_upload_choose_local_files
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
@ -1724,7 +1722,7 @@ class ChatController(args: Bundle) :
|
|||||||
eventBus.register(this)
|
eventBus.register(this)
|
||||||
|
|
||||||
if (conversationUser?.userId != "?" &&
|
if (conversationUser?.userId != "?" &&
|
||||||
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") ?: false &&
|
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag") &&
|
||||||
activity != null
|
activity != null
|
||||||
) {
|
) {
|
||||||
activity?.findViewById<View>(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() }
|
activity?.findViewById<View>(R.id.toolbar)?.setOnClickListener { v -> showConversationInfoScreen() }
|
||||||
@ -1743,13 +1741,13 @@ class ChatController(args: Bundle) :
|
|||||||
onEmojiPopupShownListener = {
|
onEmojiPopupShownListener = {
|
||||||
if (resources != null) {
|
if (resources != null) {
|
||||||
smileyButton?.setImageDrawable(
|
smileyButton?.setImageDrawable(
|
||||||
ContextCompat.getDrawable(context!!, R.drawable.ic_baseline_keyboard_24)
|
ContextCompat.getDrawable(context, R.drawable.ic_baseline_keyboard_24)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onEmojiPopupDismissListener = {
|
onEmojiPopupDismissListener = {
|
||||||
smileyButton?.setImageDrawable(
|
smileyButton?.setImageDrawable(
|
||||||
ContextCompat.getDrawable(context!!, R.drawable.ic_insert_emoticon_black_24dp)
|
ContextCompat.getDrawable(context, R.drawable.ic_insert_emoticon_black_24dp)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
onEmojiClickListener = {
|
onEmojiClickListener = {
|
||||||
@ -1777,7 +1775,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
cancelNotificationsForCurrentConversation()
|
cancelNotificationsForCurrentConversation()
|
||||||
|
|
||||||
Log.d(TAG, "onAttach inConversation: " + inConversation.toString())
|
Log.d(TAG, "onAttach inConversation: $inConversation")
|
||||||
if (inConversation) {
|
if (inConversation) {
|
||||||
Log.d(TAG, "execute joinRoomWithPassword in onAttach")
|
Log.d(TAG, "execute joinRoomWithPassword in onAttach")
|
||||||
joinRoomWithPassword()
|
joinRoomWithPassword()
|
||||||
@ -1881,11 +1879,11 @@ class ChatController(args: Bundle) :
|
|||||||
var apiVersion = 1
|
var apiVersion = 1
|
||||||
// FIXME Fix API checking with guests?
|
// FIXME Fix API checking with guests?
|
||||||
if (conversationUser != null) {
|
if (conversationUser != null) {
|
||||||
apiVersion = ApiUtils.getConversationApiVersion(conversationUser!!, intArrayOf(ApiUtils.APIv4, 1))
|
apiVersion = ApiUtils.getConversationApiVersion(conversationUser, intArrayOf(ApiUtils.APIv4, 1))
|
||||||
}
|
}
|
||||||
|
|
||||||
val startNanoTime = System.nanoTime()
|
val startNanoTime = System.nanoTime()
|
||||||
Log.d(TAG, "joinRoomWithPassword - joinRoom - calling: " + startNanoTime)
|
Log.d(TAG, "joinRoomWithPassword - joinRoom - calling: $startNanoTime")
|
||||||
ncApi.joinRoom(
|
ncApi.joinRoom(
|
||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForParticipantsActive(apiVersion, conversationUser?.baseUrl, roomToken),
|
ApiUtils.getUrlForParticipantsActive(apiVersion, conversationUser?.baseUrl, roomToken),
|
||||||
@ -1901,7 +1899,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
@Suppress("Detekt.TooGenericExceptionCaught")
|
@Suppress("Detekt.TooGenericExceptionCaught")
|
||||||
override fun onNext(roomOverall: RoomOverall) {
|
override fun onNext(roomOverall: RoomOverall) {
|
||||||
Log.d(TAG, "joinRoomWithPassword - joinRoom - got response: " + startNanoTime)
|
Log.d(TAG, "joinRoomWithPassword - joinRoom - got response: $startNanoTime")
|
||||||
inConversation = true
|
inConversation = true
|
||||||
currentConversation?.sessionId = roomOverall.ocs!!.data!!.sessionId
|
currentConversation?.sessionId = roomOverall.ocs!!.data!!.sessionId
|
||||||
Log.d(TAG, "joinRoomWithPassword - sessionId: " + currentConversation?.sessionId)
|
Log.d(TAG, "joinRoomWithPassword - sessionId: " + currentConversation?.sessionId)
|
||||||
@ -1915,7 +1913,7 @@ class ChatController(args: Bundle) :
|
|||||||
checkLobbyState()
|
checkLobbyState()
|
||||||
} catch (npe: NullPointerException) {
|
} catch (npe: NullPointerException) {
|
||||||
// view binding can be null
|
// view binding can be null
|
||||||
// since this is called asynchrously and UI might have been destroyed in the meantime
|
// since this is called asynchronously and UI might have been destroyed in the meantime
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone")
|
Log.i(TAG, "UI destroyed - view binding already gone")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1971,7 +1969,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
val startNanoTime = System.nanoTime()
|
val startNanoTime = System.nanoTime()
|
||||||
Log.d(TAG, "leaveRoom - leaveRoom - calling: " + startNanoTime)
|
Log.d(TAG, "leaveRoom - leaveRoom - calling: $startNanoTime")
|
||||||
ncApi.leaveRoom(
|
ncApi.leaveRoom(
|
||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForParticipantsActive(
|
ApiUtils.getUrlForParticipantsActive(
|
||||||
@ -1988,7 +1986,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onNext(genericOverall: GenericOverall) {
|
override fun onNext(genericOverall: GenericOverall) {
|
||||||
Log.d(TAG, "leaveRoom - leaveRoom - got response: " + startNanoTime)
|
Log.d(TAG, "leaveRoom - leaveRoom - got response: $startNanoTime")
|
||||||
checkingLobbyStatus = false
|
checkingLobbyStatus = false
|
||||||
|
|
||||||
if (lobbyTimerHandler != null) {
|
if (lobbyTimerHandler != null) {
|
||||||
@ -2012,7 +2010,7 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onComplete() {
|
override fun onComplete() {
|
||||||
Log.d(TAG, "leaveRoom - leaveRoom - completed: " + startNanoTime)
|
Log.d(TAG, "leaveRoom - leaveRoom - completed: $startNanoTime")
|
||||||
disposables.dispose()
|
disposables.dispose()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -2055,7 +2053,7 @@ class ChatController(args: Bundle) :
|
|||||||
if (conversationUser != null) {
|
if (conversationUser != null) {
|
||||||
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
|
||||||
|
|
||||||
ncApi!!.sendChatMessage(
|
ncApi.sendChatMessage(
|
||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, roomToken),
|
ApiUtils.getUrlForChat(apiVersion, conversationUser.baseUrl, roomToken),
|
||||||
message,
|
message,
|
||||||
@ -2075,14 +2073,14 @@ class ChatController(args: Bundle) :
|
|||||||
myFirstMessage = message
|
myFirstMessage = message
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (binding.popupBubbleView.isShown == true) {
|
if (binding.popupBubbleView.isShown) {
|
||||||
binding.popupBubbleView.hide()
|
binding.popupBubbleView.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.messagesListView.smoothScrollToPosition(0)
|
binding.messagesListView.smoothScrollToPosition(0)
|
||||||
} catch (npe: NullPointerException) {
|
} catch (npe: NullPointerException) {
|
||||||
// view binding can be null
|
// view binding can be null
|
||||||
// since this is called asynchrously and UI might have been destroyed in the meantime
|
// since this is called asynchronously and UI might have been destroyed in the meantime
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone")
|
Log.i(TAG, "UI destroyed - view binding already gone")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2090,10 +2088,10 @@ class ChatController(args: Bundle) :
|
|||||||
override fun onError(e: Throwable) {
|
override fun onError(e: Throwable) {
|
||||||
if (e is HttpException) {
|
if (e is HttpException) {
|
||||||
val code = e.code()
|
val code = e.code()
|
||||||
if (Integer.toString(code).startsWith("2")) {
|
if (code.toString().startsWith("2")) {
|
||||||
myFirstMessage = message
|
myFirstMessage = message
|
||||||
|
|
||||||
if (binding.popupBubbleView.isShown == true) {
|
if (binding.popupBubbleView.isShown) {
|
||||||
binding.popupBubbleView.hide()
|
binding.popupBubbleView.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2112,12 +2110,12 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
private fun setupWebsocket() {
|
private fun setupWebsocket() {
|
||||||
if (conversationUser != null) {
|
if (conversationUser != null) {
|
||||||
if (WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!) != null) {
|
|
||||||
magicWebSocketInstance =
|
magicWebSocketInstance =
|
||||||
|
if (WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!) != null) {
|
||||||
WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!)
|
WebSocketConnectionHelper.getMagicWebSocketInstanceForUserId(conversationUser.id!!)
|
||||||
} else {
|
} else {
|
||||||
Log.d(TAG, "magicWebSocketInstance became null")
|
Log.d(TAG, "magicWebSocketInstance became null")
|
||||||
magicWebSocketInstance = null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2166,11 +2164,10 @@ class ChatController(args: Bundle) :
|
|||||||
fieldMap["limit"] = MESSAGE_PULL_LIMIT
|
fieldMap["limit"] = MESSAGE_PULL_LIMIT
|
||||||
fieldMap["setReadMarker"] = setReadMarker
|
fieldMap["setReadMarker"] = setReadMarker
|
||||||
|
|
||||||
val lastKnown: Int
|
val lastKnown = if (lookIntoFuture > 0) {
|
||||||
if (lookIntoFuture > 0) {
|
globalLastKnownFutureMessageId
|
||||||
lastKnown = globalLastKnownFutureMessageId
|
|
||||||
} else {
|
} else {
|
||||||
lastKnown = globalLastKnownPastMessageId
|
globalLastKnownPastMessageId
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldMap["lastKnownMessageId"] = lastKnown
|
fieldMap["lastKnownMessageId"] = lastKnown
|
||||||
@ -2185,7 +2182,6 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lookIntoFuture > 0) {
|
if (lookIntoFuture > 0) {
|
||||||
val finalTimeout = timeout
|
|
||||||
Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture > 0] - calling")
|
Log.d(TAG, "pullChatMessages - pullChatMessages[lookIntoFuture > 0] - calling")
|
||||||
ncApi.pullChatMessages(
|
ncApi.pullChatMessages(
|
||||||
credentials,
|
credentials,
|
||||||
@ -2210,11 +2206,11 @@ class ChatController(args: Bundle) :
|
|||||||
} else if (response.code() == HTTP_CODE_PRECONDITION_FAILED) {
|
} else if (response.code() == HTTP_CODE_PRECONDITION_FAILED) {
|
||||||
futurePreconditionFailed = true
|
futurePreconditionFailed = true
|
||||||
} else {
|
} else {
|
||||||
processMessages(response, true, finalTimeout)
|
processMessagesResponse(response, true)
|
||||||
}
|
}
|
||||||
} catch (npe: NullPointerException) {
|
} catch (npe: NullPointerException) {
|
||||||
// view binding can be null
|
// view binding can be null
|
||||||
// since this is called asynchrously and UI might have been destroyed in the meantime
|
// since this is called asynchronously and UI might have been destroyed in the meantime
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone")
|
Log.i(TAG, "UI destroyed - view binding already gone")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2252,11 +2248,11 @@ class ChatController(args: Bundle) :
|
|||||||
if (response.code() == HTTP_CODE_PRECONDITION_FAILED) {
|
if (response.code() == HTTP_CODE_PRECONDITION_FAILED) {
|
||||||
pastPreconditionFailed = true
|
pastPreconditionFailed = true
|
||||||
} else {
|
} else {
|
||||||
processMessages(response, false, 0)
|
processMessagesResponse(response, false)
|
||||||
}
|
}
|
||||||
} catch (e: NullPointerException) {
|
} catch (e: NullPointerException) {
|
||||||
// view binding can be null
|
// view binding can be null
|
||||||
// since this is called asynchrously and UI might have been destroyed in the meantime
|
// since this is called asynchronously and UI might have been destroyed in the meantime
|
||||||
Log.i(TAG, "UI destroyed - view binding already gone", e)
|
Log.i(TAG, "UI destroyed - view binding already gone", e)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2297,29 +2293,40 @@ class ChatController(args: Bundle) :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processMessages(response: Response<*>, isFromTheFuture: Boolean, timeout: Int) {
|
private fun processMessagesResponse(response: Response<*>, isFromTheFuture: Boolean) {
|
||||||
val xChatLastGivenHeader: String? = response.headers().get("X-Chat-Last-Given")
|
|
||||||
val xChatLastCommonRead = response.headers().get("X-Chat-Last-Common-Read")?.let {
|
val xChatLastCommonRead = response.headers()["X-Chat-Last-Common-Read"]?.let {
|
||||||
Integer.parseInt(it)
|
Integer.parseInt(it)
|
||||||
}
|
}
|
||||||
if (response.headers().size > 0 && !TextUtils.isEmpty(xChatLastGivenHeader)) {
|
|
||||||
val header = Integer.parseInt(xChatLastGivenHeader!!)
|
processHeaderChatLastGiven(response, isFromTheFuture)
|
||||||
if (header > 0) {
|
|
||||||
if (isFromTheFuture) {
|
|
||||||
globalLastKnownFutureMessageId = header
|
|
||||||
} else {
|
|
||||||
if (globalLastKnownFutureMessageId == -1) {
|
|
||||||
globalLastKnownFutureMessageId = header
|
|
||||||
}
|
|
||||||
globalLastKnownPastMessageId = header
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.code() == HTTP_CODE_OK) {
|
if (response.code() == HTTP_CODE_OK) {
|
||||||
val chatOverall = response.body() as ChatOverall?
|
val chatOverall = response.body() as ChatOverall?
|
||||||
val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data!!)
|
val chatMessageList = handleSystemMessages(chatOverall?.ocs!!.data!!)
|
||||||
|
|
||||||
|
processMessages(chatMessageList, isFromTheFuture, xChatLastCommonRead)
|
||||||
|
} else if (response.code() == HTTP_CODE_NOT_MODIFIED && !isFromTheFuture) {
|
||||||
|
if (isFirstMessagesProcessing) {
|
||||||
|
cancelNotificationsForCurrentConversation()
|
||||||
|
|
||||||
|
isFirstMessagesProcessing = false
|
||||||
|
binding.progressBar.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
|
historyRead = true
|
||||||
|
|
||||||
|
if (!lookingIntoFuture && inConversation) {
|
||||||
|
pullChatMessages(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processMessages(
|
||||||
|
chatMessageList: List<ChatMessage>,
|
||||||
|
isFromTheFuture: Boolean,
|
||||||
|
xChatLastCommonRead: Int?
|
||||||
|
) {
|
||||||
if (chatMessageList.isNotEmpty() &&
|
if (chatMessageList.isNotEmpty() &&
|
||||||
ChatMessage.SystemMessageType.CLEARED_CHAT == chatMessageList[0].systemMessageType
|
ChatMessage.SystemMessageType.CLEARED_CHAT == chatMessageList[0].systemMessageType
|
||||||
) {
|
) {
|
||||||
@ -2336,24 +2343,117 @@ class ChatController(args: Bundle) :
|
|||||||
binding.messagesListView.visibility = View.VISIBLE
|
binding.messagesListView.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFromTheFuture) {
|
||||||
|
processMessagesFromTheFuture(chatMessageList)
|
||||||
|
} else {
|
||||||
|
processMessagesNotFromTheFuture(chatMessageList)
|
||||||
|
}
|
||||||
|
|
||||||
|
updateReadStatusOfAllMessages(xChatLastCommonRead)
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
|
||||||
|
if (inConversation) {
|
||||||
|
pullChatMessages(1, 1, xChatLastCommonRead)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateReadStatusOfAllMessages(xChatLastCommonRead: Int?) {
|
||||||
|
for (message in adapter!!.items) {
|
||||||
|
xChatLastCommonRead?.let {
|
||||||
|
updateReadStatusOfMessage(message, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateReadStatusOfMessage(
|
||||||
|
message: MessagesListAdapter<IMessage>.Wrapper<Any>,
|
||||||
|
xChatLastCommonRead: Int
|
||||||
|
) {
|
||||||
|
if (message.item is ChatMessage) {
|
||||||
|
val chatMessage = message.item as ChatMessage
|
||||||
|
|
||||||
|
if (chatMessage.jsonMessageId <= xChatLastCommonRead) {
|
||||||
|
chatMessage.readStatus = ReadStatus.READ
|
||||||
|
} else {
|
||||||
|
chatMessage.readStatus = ReadStatus.SENT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processMessagesFromTheFuture(chatMessageList: List<ChatMessage>) {
|
||||||
|
|
||||||
|
val shouldAddNewMessagesNotice = (adapter?.itemCount ?: 0) > 0 && chatMessageList.isNotEmpty()
|
||||||
|
|
||||||
|
if (shouldAddNewMessagesNotice) {
|
||||||
|
val unreadChatMessage = ChatMessage()
|
||||||
|
unreadChatMessage.jsonMessageId = -1
|
||||||
|
unreadChatMessage.actorId = "-1"
|
||||||
|
unreadChatMessage.timestamp = chatMessageList[0].timestamp
|
||||||
|
unreadChatMessage.message = context.getString(R.string.nc_new_messages)
|
||||||
|
adapter?.addToStart(unreadChatMessage, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
determinePreviousMessageIds(chatMessageList)
|
||||||
|
|
||||||
|
addMessagesToAdapter(shouldAddNewMessagesNotice, chatMessageList)
|
||||||
|
|
||||||
|
if (shouldAddNewMessagesNotice && adapter != null) {
|
||||||
|
layoutManager?.scrollToPositionWithOffset(
|
||||||
|
adapter!!.getMessagePositionByIdInReverse("-1"),
|
||||||
|
binding.messagesListView.height / 2
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addMessagesToAdapter(
|
||||||
|
shouldAddNewMessagesNotice: Boolean,
|
||||||
|
chatMessageList: List<ChatMessage>
|
||||||
|
) {
|
||||||
|
val isThereANewNotice =
|
||||||
|
shouldAddNewMessagesNotice || adapter?.getMessagePositionByIdInReverse("-1") != -1
|
||||||
|
for (chatMessage in chatMessageList) {
|
||||||
|
chatMessage.activeUser = conversationUser
|
||||||
|
|
||||||
|
val shouldScroll =
|
||||||
|
!isThereANewNotice &&
|
||||||
|
!shouldAddNewMessagesNotice &&
|
||||||
|
layoutManager?.findFirstVisibleItemPosition() == 0 ||
|
||||||
|
adapter != null &&
|
||||||
|
adapter?.itemCount == 0
|
||||||
|
|
||||||
|
modifyMessageCount(shouldAddNewMessagesNotice, shouldScroll)
|
||||||
|
|
||||||
|
adapter?.let {
|
||||||
|
chatMessage.isGrouped = (
|
||||||
|
it.isPreviousSameAuthor(
|
||||||
|
chatMessage.actorId,
|
||||||
|
-1
|
||||||
|
) && it.getSameAuthorLastMessagesCount(chatMessage.actorId) %
|
||||||
|
GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD > 0
|
||||||
|
)
|
||||||
|
chatMessage.isOneToOneConversation =
|
||||||
|
(currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
|
||||||
|
it.addToStart(chatMessage, shouldScroll)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun modifyMessageCount(shouldAddNewMessagesNotice: Boolean, shouldScroll: Boolean) {
|
||||||
|
if (!shouldAddNewMessagesNotice && !shouldScroll) {
|
||||||
|
if (!binding.popupBubbleView.isShown) {
|
||||||
|
newMessagesCount = 1
|
||||||
|
binding.popupBubbleView.show()
|
||||||
|
} else if (binding.popupBubbleView.isShown) {
|
||||||
|
newMessagesCount++
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
newMessagesCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun processMessagesNotFromTheFuture(chatMessageList: List<ChatMessage>) {
|
||||||
var countGroupedMessages = 0
|
var countGroupedMessages = 0
|
||||||
if (!isFromTheFuture) {
|
determinePreviousMessageIds(chatMessageList)
|
||||||
var previousMessageId = NO_PREVIOUS_MESSAGE_ID
|
|
||||||
for (i in chatMessageList.indices.reversed()) {
|
|
||||||
val chatMessage = chatMessageList[i]
|
|
||||||
|
|
||||||
if (previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
|
|
||||||
chatMessage.previousMessageId = previousMessageId
|
|
||||||
} else if (adapter?.isEmpty != true) {
|
|
||||||
if (adapter!!.items[0].item is ChatMessage) {
|
|
||||||
chatMessage.previousMessageId = (adapter!!.items[0].item as ChatMessage).jsonMessageId
|
|
||||||
} else if (adapter!!.items.size > 1 && adapter!!.items[1].item is ChatMessage) {
|
|
||||||
chatMessage.previousMessageId = (adapter!!.items[1].item as ChatMessage).jsonMessageId
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
previousMessageId = chatMessage.jsonMessageId
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i in chatMessageList.indices) {
|
for (i in chatMessageList.indices) {
|
||||||
if (chatMessageList.size > i + 1) {
|
if (chatMessageList.size > i + 1) {
|
||||||
@ -2378,116 +2478,46 @@ class ChatController(args: Bundle) :
|
|||||||
adapter?.addToEnd(chatMessageList, false)
|
adapter?.addToEnd(chatMessageList, false)
|
||||||
}
|
}
|
||||||
scrollToRequestedMessageIfNeeded()
|
scrollToRequestedMessageIfNeeded()
|
||||||
} else {
|
|
||||||
var chatMessage: ChatMessage
|
|
||||||
|
|
||||||
val shouldAddNewMessagesNotice = (adapter?.itemCount ?: 0) > 0 && chatMessageList.isNotEmpty()
|
|
||||||
|
|
||||||
if (shouldAddNewMessagesNotice) {
|
|
||||||
val unreadChatMessage = ChatMessage()
|
|
||||||
unreadChatMessage.jsonMessageId = -1
|
|
||||||
unreadChatMessage.actorId = "-1"
|
|
||||||
unreadChatMessage.timestamp = chatMessageList[0].timestamp
|
|
||||||
unreadChatMessage.message = context?.getString(R.string.nc_new_messages)
|
|
||||||
adapter?.addToStart(unreadChatMessage, false)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val isThereANewNotice =
|
private fun determinePreviousMessageIds(chatMessageList: List<ChatMessage>) {
|
||||||
shouldAddNewMessagesNotice || adapter?.getMessagePositionByIdInReverse("-1") != -1
|
|
||||||
|
|
||||||
var previousMessageId = NO_PREVIOUS_MESSAGE_ID
|
var previousMessageId = NO_PREVIOUS_MESSAGE_ID
|
||||||
for (i in chatMessageList.indices.reversed()) {
|
for (i in chatMessageList.indices.reversed()) {
|
||||||
val chatMessageItem = chatMessageList[i]
|
val chatMessage = chatMessageList[i]
|
||||||
|
|
||||||
if (previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
|
if (previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
|
||||||
chatMessageItem.previousMessageId = previousMessageId
|
chatMessage.previousMessageId = previousMessageId
|
||||||
} else if (adapter?.isEmpty != true) {
|
} else if (adapter?.isEmpty != true) {
|
||||||
if (adapter!!.items[0].item is ChatMessage) {
|
if (adapter!!.items[0].item is ChatMessage) {
|
||||||
chatMessageItem.previousMessageId = (adapter!!.items[0].item as ChatMessage).jsonMessageId
|
chatMessage.previousMessageId = (adapter!!.items[0].item as ChatMessage).jsonMessageId
|
||||||
} else if (adapter!!.items.size > 1 && adapter!!.items[1].item is ChatMessage) {
|
} else if (adapter!!.items.size > 1 && adapter!!.items[1].item is ChatMessage) {
|
||||||
chatMessageItem.previousMessageId = (adapter!!.items[1].item as ChatMessage).jsonMessageId
|
chatMessage.previousMessageId = (adapter!!.items[1].item as ChatMessage).jsonMessageId
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
previousMessageId = chatMessageItem.jsonMessageId
|
previousMessageId = chatMessage.jsonMessageId
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i in chatMessageList.indices) {
|
private fun processHeaderChatLastGiven(response: Response<*>, isFromTheFuture: Boolean) {
|
||||||
chatMessage = chatMessageList[i]
|
val xChatLastGivenHeader: String? = response.headers()["X-Chat-Last-Given"]
|
||||||
|
|
||||||
chatMessage.activeUser = conversationUser
|
val header = if (response.headers().size > 0 &&
|
||||||
|
xChatLastGivenHeader?.isNotEmpty() == true
|
||||||
val shouldScroll =
|
) {
|
||||||
!isThereANewNotice &&
|
xChatLastGivenHeader.toInt()
|
||||||
!shouldAddNewMessagesNotice &&
|
|
||||||
layoutManager?.findFirstVisibleItemPosition() == 0 ||
|
|
||||||
adapter != null &&
|
|
||||||
adapter?.itemCount == 0
|
|
||||||
|
|
||||||
if (!shouldAddNewMessagesNotice && !shouldScroll) {
|
|
||||||
if (!binding.popupBubbleView.isShown) {
|
|
||||||
newMessagesCount = 1
|
|
||||||
binding.popupBubbleView.show()
|
|
||||||
} else if (binding.popupBubbleView.isShown == true) {
|
|
||||||
newMessagesCount++
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
newMessagesCount = 0
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter != null) {
|
if (header > 0) {
|
||||||
chatMessage.isGrouped = (
|
if (isFromTheFuture) {
|
||||||
adapter!!.isPreviousSameAuthor(
|
globalLastKnownFutureMessageId = header
|
||||||
chatMessage.actorId,
|
|
||||||
-1
|
|
||||||
) && adapter!!.getSameAuthorLastMessagesCount(chatMessage.actorId) %
|
|
||||||
GROUPED_MESSAGES_SAME_AUTHOR_THRESHOLD > 0
|
|
||||||
)
|
|
||||||
chatMessage.isOneToOneConversation =
|
|
||||||
(currentConversation?.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL)
|
|
||||||
adapter?.addToStart(chatMessage, shouldScroll)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (shouldAddNewMessagesNotice && adapter != null) {
|
|
||||||
layoutManager?.scrollToPositionWithOffset(
|
|
||||||
adapter!!.getMessagePositionByIdInReverse("-1"),
|
|
||||||
binding.messagesListView.height / 2
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// update read status of all messages
|
|
||||||
for (message in adapter!!.items) {
|
|
||||||
xChatLastCommonRead?.let {
|
|
||||||
if (message.item is ChatMessage) {
|
|
||||||
val chatMessage = message.item as ChatMessage
|
|
||||||
|
|
||||||
if (chatMessage.jsonMessageId <= it) {
|
|
||||||
chatMessage.readStatus = ReadStatus.READ
|
|
||||||
} else {
|
} else {
|
||||||
chatMessage.readStatus = ReadStatus.SENT
|
if (globalLastKnownFutureMessageId == -1) {
|
||||||
|
globalLastKnownFutureMessageId = header
|
||||||
}
|
}
|
||||||
}
|
globalLastKnownPastMessageId = header
|
||||||
}
|
|
||||||
}
|
|
||||||
adapter?.notifyDataSetChanged()
|
|
||||||
|
|
||||||
if (inConversation) {
|
|
||||||
pullChatMessages(1, 1, xChatLastCommonRead)
|
|
||||||
}
|
|
||||||
} else if (response.code() == HTTP_CODE_NOT_MODIFIED && !isFromTheFuture) {
|
|
||||||
if (isFirstMessagesProcessing) {
|
|
||||||
cancelNotificationsForCurrentConversation()
|
|
||||||
|
|
||||||
isFirstMessagesProcessing = false
|
|
||||||
binding.progressBar.visibility = View.GONE
|
|
||||||
}
|
|
||||||
|
|
||||||
historyRead = true
|
|
||||||
|
|
||||||
if (!lookingIntoFuture && inConversation) {
|
|
||||||
pullChatMessages(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2760,7 +2790,7 @@ class ChatController(args: Bundle) :
|
|||||||
currentConversation,
|
currentConversation,
|
||||||
isShowMessageDeletionButton(message),
|
isShowMessageDeletionButton(message),
|
||||||
hasChatPermission,
|
hasChatPermission,
|
||||||
ncApi!!
|
ncApi
|
||||||
).show()
|
).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2838,7 +2868,7 @@ class ChatController(args: Bundle) :
|
|||||||
message?.user?.id?.substring(INVITE_LENGTH),
|
message?.user?.id?.substring(INVITE_LENGTH),
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
ncApi!!.createRoom(
|
ncApi.createRoom(
|
||||||
credentials,
|
credentials,
|
||||||
retrofitBucket.url,
|
retrofitBucket.url,
|
||||||
retrofitBucket.queryMap
|
retrofitBucket.queryMap
|
||||||
@ -2857,7 +2887,7 @@ class ChatController(args: Bundle) :
|
|||||||
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
bundle.putString(KEY_ROOM_ID, roomOverall.ocs!!.data!!.roomId)
|
||||||
|
|
||||||
// FIXME once APIv2+ is used only, the createRoom already returns all the data
|
// FIXME once APIv2+ is used only, the createRoom already returns all the data
|
||||||
ncApi!!.getRoom(
|
ncApi.getRoom(
|
||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForRoom(
|
ApiUtils.getUrlForRoom(
|
||||||
apiVersion,
|
apiVersion,
|
||||||
@ -2921,7 +2951,7 @@ class ChatController(args: Bundle) :
|
|||||||
fun markAsUnread(message: IMessage?) {
|
fun markAsUnread(message: IMessage?) {
|
||||||
val chatMessage = message as ChatMessage?
|
val chatMessage = message as ChatMessage?
|
||||||
if (chatMessage!!.previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
|
if (chatMessage!!.previousMessageId > NO_PREVIOUS_MESSAGE_ID) {
|
||||||
ncApi!!.setChatReadMarker(
|
ncApi.setChatReadMarker(
|
||||||
credentials,
|
credentials,
|
||||||
ApiUtils.getUrlForSetChatReadMarker(
|
ApiUtils.getUrlForSetChatReadMarker(
|
||||||
ApiUtils.getChatApiVersion(conversationUser, intArrayOf(ApiUtils.APIv1)),
|
ApiUtils.getChatApiVersion(conversationUser, intArrayOf(ApiUtils.APIv1)),
|
||||||
@ -2966,7 +2996,7 @@ class ChatController(args: Bundle) :
|
|||||||
return !message.isDeleted || // copy message
|
return !message.isDeleted || // copy message
|
||||||
message.replyable || // reply to
|
message.replyable || // reply to
|
||||||
message.replyable && // reply privately
|
message.replyable && // reply privately
|
||||||
conversationUser?.userId?.isNotEmpty() == true && conversationUser?.userId != "?" &&
|
conversationUser?.userId?.isNotEmpty() == true && conversationUser.userId != "?" &&
|
||||||
message.user.id.startsWith("users/") &&
|
message.user.id.startsWith("users/") &&
|
||||||
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
|
message.user.id.substring(ACTOR_LENGTH) != currentConversation?.actorId &&
|
||||||
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
currentConversation?.type != Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL ||
|
||||||
@ -2993,7 +3023,7 @@ class ChatController(args: Bundle) :
|
|||||||
quotedMessage?.ellipsize = TextUtils.TruncateAt.END
|
quotedMessage?.ellipsize = TextUtils.TruncateAt.END
|
||||||
quotedMessage?.text = it.text
|
quotedMessage?.text = it.text
|
||||||
binding.messageInputView.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text =
|
binding.messageInputView.findViewById<EmojiTextView>(R.id.quotedMessageAuthor)?.text =
|
||||||
it.actorDisplayName ?: context!!.getText(R.string.nc_nick_guest)
|
it.actorDisplayName ?: context.getText(R.string.nc_nick_guest)
|
||||||
|
|
||||||
conversationUser?.let { currentUser ->
|
conversationUser?.let { currentUser ->
|
||||||
val quotedMessageImage = binding
|
val quotedMessageImage = binding
|
||||||
@ -3091,7 +3121,7 @@ class ChatController(args: Bundle) :
|
|||||||
|
|
||||||
val isOlderThanSixHours = message
|
val isOlderThanSixHours = message
|
||||||
.createdAt
|
.createdAt
|
||||||
?.before(Date(System.currentTimeMillis() - AGE_THREHOLD_FOR_DELETE_MESSAGE)) == true
|
.before(Date(System.currentTimeMillis() - AGE_THRESHOLD_FOR_DELETE_MESSAGE))
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
!isUserAllowedByPrivileges -> false
|
!isUserAllowedByPrivileges -> false
|
||||||
@ -3219,7 +3249,7 @@ class ChatController(args: Bundle) :
|
|||||||
if (!permissionUtil.isCameraPermissionGranted()) {
|
if (!permissionUtil.isCameraPermissionGranted()) {
|
||||||
requestCameraPermissions()
|
requestCameraPermissions()
|
||||||
} else {
|
} else {
|
||||||
startActivityForResult(TakePhotoActivity.createIntent(context!!), REQUEST_CODE_PICK_CAMERA)
|
startActivityForResult(TakePhotoActivity.createIntent(context), REQUEST_CODE_PICK_CAMERA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3244,8 +3274,7 @@ class ChatController(args: Bundle) :
|
|||||||
private const val POP_CURRENT_CONTROLLER_DELAY: Long = 100
|
private const val POP_CURRENT_CONTROLLER_DELAY: Long = 100
|
||||||
private const val LOBBY_TIMER_DELAY: Long = 5000
|
private const val LOBBY_TIMER_DELAY: Long = 5000
|
||||||
private const val HTTP_CODE_OK: Int = 200
|
private const val HTTP_CODE_OK: Int = 200
|
||||||
private const val MESSAGE_MAX_LENGTH: Int = 1000
|
private const val AGE_THRESHOLD_FOR_DELETE_MESSAGE: Int = 21600000 // (6 hours in millis = 6 * 3600 * 1000)
|
||||||
private const val AGE_THREHOLD_FOR_DELETE_MESSAGE: Int = 21600000 // (6 hours in millis = 6 * 3600 * 1000)
|
|
||||||
private const val REQUEST_CODE_CHOOSE_FILE: Int = 555
|
private const val REQUEST_CODE_CHOOSE_FILE: Int = 555
|
||||||
private const val REQUEST_CODE_SELECT_CONTACT: Int = 666
|
private const val REQUEST_CODE_SELECT_CONTACT: Int = 666
|
||||||
private const val REQUEST_CODE_MESSAGE_SEARCH: Int = 777
|
private const val REQUEST_CODE_MESSAGE_SEARCH: Int = 777
|
||||||
|
Loading…
Reference in New Issue
Block a user