|
@@ -83,7 +83,6 @@ import android.widget.RelativeLayout.BELOW
|
|
|
import android.widget.RelativeLayout.LayoutParams
|
|
|
import android.widget.SeekBar
|
|
|
import android.widget.TextView
|
|
|
-import android.widget.Toast
|
|
|
import androidx.activity.OnBackPressedCallback
|
|
|
import androidx.appcompat.app.AlertDialog
|
|
|
import androidx.appcompat.view.ContextThemeWrapper
|
|
@@ -114,6 +113,7 @@ import coil.transform.CircleCropTransformation
|
|
|
import com.google.android.flexbox.FlexboxLayout
|
|
|
import com.google.android.material.button.MaterialButton
|
|
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
|
|
+import com.google.android.material.snackbar.Snackbar
|
|
|
import com.nextcloud.android.common.ui.theme.utils.ColorRole
|
|
|
import com.nextcloud.talk.BuildConfig
|
|
|
import com.nextcloud.talk.R
|
|
@@ -348,6 +348,7 @@ class ChatActivity :
|
|
|
AudioFormat.CHANNEL_IN_MONO,
|
|
|
AudioFormat.ENCODING_PCM_16BIT
|
|
|
)
|
|
|
+ private var voiceRecordDuration = 0L
|
|
|
|
|
|
// messy workaround for a mediaPlayer bug, don't delete
|
|
|
private var lastRecordMediaPosition: Int = 0
|
|
@@ -568,7 +569,7 @@ class ChatActivity :
|
|
|
}
|
|
|
|
|
|
is ChatViewModel.GetRoomErrorState -> {
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
}
|
|
|
|
|
|
else -> {}
|
|
@@ -612,7 +613,7 @@ class ChatActivity :
|
|
|
}
|
|
|
|
|
|
is ChatViewModel.JoinRoomErrorState -> {
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
}
|
|
|
|
|
|
else -> {}
|
|
@@ -1003,7 +1004,11 @@ class ChatActivity :
|
|
|
@SuppressLint("ClickableViewAccessibility")
|
|
|
private fun initVoiceRecordButton() {
|
|
|
if (!isVoiceRecordingLocked) {
|
|
|
- showMicrophoneButton(true)
|
|
|
+ if (binding.messageInputView.messageInput.text!!.isNotEmpty()) {
|
|
|
+ showMicrophoneButton(false)
|
|
|
+ } else {
|
|
|
+ showMicrophoneButton(true)
|
|
|
+ }
|
|
|
} else if (isVoiceRecordingInProgress) {
|
|
|
binding.messageInputView.playPauseBtn.visibility = View.GONE
|
|
|
binding.messageInputView.seekBar.visibility = View.GONE
|
|
@@ -1163,13 +1168,13 @@ class ChatActivity :
|
|
|
showRecordAudioUi(false)
|
|
|
|
|
|
voiceRecordEndTime = System.currentTimeMillis()
|
|
|
- val voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime
|
|
|
+ voiceRecordDuration = voiceRecordEndTime - voiceRecordStartTime
|
|
|
if (voiceRecordDuration < MINIMUM_VOICE_RECORD_DURATION) {
|
|
|
Log.d(TAG, "voiceRecordDuration: $voiceRecordDuration")
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.getString(R.string.nc_voice_message_hold_to_record_info),
|
|
|
- Toast.LENGTH_SHORT
|
|
|
+ Snackbar.LENGTH_SHORT
|
|
|
).show()
|
|
|
stopAndDiscardAudioRecording()
|
|
|
return true
|
|
@@ -1676,16 +1681,16 @@ class ChatActivity :
|
|
|
if (conversationUser != null) {
|
|
|
runOnUiThread {
|
|
|
if (currentConversation?.objectType == ObjectType.ROOM) {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.resources.getString(R.string.switch_to_main_room),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
} else {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.resources.getString(R.string.switch_to_breakout_room),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
}
|
|
|
}
|
|
@@ -1847,7 +1852,7 @@ class ChatActivity :
|
|
|
}
|
|
|
} catch (e: Exception) {
|
|
|
Log.e(TAG, "failed to initialize mediaPlayer", e)
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -2075,6 +2080,7 @@ class ChatActivity :
|
|
|
|
|
|
try {
|
|
|
start()
|
|
|
+ Log.d(TAG, "recording started")
|
|
|
isVoiceRecordingInProgress = true
|
|
|
} catch (e: IllegalStateException) {
|
|
|
Log.e(TAG, "start for audio recording failed")
|
|
@@ -2087,15 +2093,16 @@ class ChatActivity :
|
|
|
private fun stopAndSendAudioRecording() {
|
|
|
if (isVoiceRecordingInProgress) {
|
|
|
stopAudioRecording()
|
|
|
+ Log.d(TAG, "stopped and sent audio recording")
|
|
|
+ val uri = Uri.fromFile(File(currentVoiceRecordFile))
|
|
|
+ uploadFile(uri.toString(), true)
|
|
|
}
|
|
|
-
|
|
|
- val uri = Uri.fromFile(File(currentVoiceRecordFile))
|
|
|
- uploadFile(uri.toString(), true)
|
|
|
}
|
|
|
|
|
|
private fun stopAndDiscardAudioRecording() {
|
|
|
if (isVoiceRecordingInProgress) {
|
|
|
stopAudioRecording()
|
|
|
+ Log.d(TAG, "stopped and discarded audio recording")
|
|
|
}
|
|
|
|
|
|
val cachedFile = File(currentVoiceRecordFile)
|
|
@@ -2109,12 +2116,17 @@ class ChatActivity :
|
|
|
|
|
|
recorder?.apply {
|
|
|
try {
|
|
|
- stop()
|
|
|
+ Log.d(TAG, "recording stopped with $voiceRecordDuration")
|
|
|
+ if (voiceRecordDuration > MINIMUM_VOICE_RECORD_TO_STOP) {
|
|
|
+ stop()
|
|
|
+ }
|
|
|
release()
|
|
|
isVoiceRecordingInProgress = false
|
|
|
Log.d(TAG, "stopped recorder. isVoiceRecordingInProgress = false")
|
|
|
} catch (e: java.lang.IllegalStateException) {
|
|
|
error("error while stopping recorder!" + e)
|
|
|
+ } catch (e: java.lang.RuntimeException) {
|
|
|
+ error("error while stopping recorder!" + e)
|
|
|
}
|
|
|
|
|
|
VibrationUtils.vibrateShort(context)
|
|
@@ -2365,12 +2377,22 @@ class ChatActivity :
|
|
|
)
|
|
|
}
|
|
|
} catch (e: IllegalStateException) {
|
|
|
- Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
|
|
- .show()
|
|
|
+ context.resources?.getString(R.string.nc_upload_failed)?.let {
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
+ it,
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
+ ).show()
|
|
|
+ }
|
|
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
|
|
} catch (e: IllegalArgumentException) {
|
|
|
- Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG)
|
|
|
- .show()
|
|
|
+ context.resources?.getString(R.string.nc_upload_failed)?.let {
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
+ it,
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
+ ).show()
|
|
|
+ }
|
|
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
|
|
}
|
|
|
}
|
|
@@ -2420,20 +2442,22 @@ class ChatActivity :
|
|
|
UploadAndShareFilesWorker.requestStoragePermission(this)
|
|
|
}
|
|
|
} catch (e: IllegalStateException) {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
- context.resources?.getString(R.string.nc_upload_failed),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
+ R.string.nc_upload_failed,
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
)
|
|
|
.show()
|
|
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
|
|
} catch (e: IllegalArgumentException) {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
- context.resources?.getString(R.string.nc_upload_failed),
|
|
|
- Toast.LENGTH_LONG
|
|
|
- )
|
|
|
- .show()
|
|
|
+ context.resources?.getString(R.string.nc_upload_failed)?.let {
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
+ it,
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
+ )
|
|
|
+ .show()
|
|
|
+ }
|
|
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
|
|
}
|
|
|
}
|
|
@@ -2489,28 +2513,28 @@ class ChatActivity :
|
|
|
uploadFiles(filesToUpload)
|
|
|
}
|
|
|
} else {
|
|
|
- Toast
|
|
|
- .makeText(context, context.getString(R.string.read_storage_no_permission), Toast.LENGTH_LONG)
|
|
|
+ Snackbar
|
|
|
+ .make(binding.root, context.getString(R.string.read_storage_no_permission), Snackbar.LENGTH_LONG)
|
|
|
.show()
|
|
|
}
|
|
|
} else if (requestCode == REQUEST_SHARE_FILE_PERMISSION) {
|
|
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
showLocalFilePicker()
|
|
|
} else {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.getString(R.string.nc_file_storage_permission),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
}
|
|
|
} else if (requestCode == REQUEST_RECORD_AUDIO_PERMISSION) {
|
|
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
// do nothing. user will tap on the microphone again if he wants to record audio..
|
|
|
} else {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.getString(R.string.nc_voice_message_missing_audio_permission),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
}
|
|
|
} else if (requestCode == REQUEST_READ_CONTACT_PERMISSION) {
|
|
@@ -2518,20 +2542,20 @@ class ChatActivity :
|
|
|
val intent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
|
|
|
startActivityForResult(intent, REQUEST_CODE_SELECT_CONTACT)
|
|
|
} else {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
context.getString(R.string.nc_share_contact_permission),
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
}
|
|
|
} else if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
|
|
if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
|
|
- Toast
|
|
|
- .makeText(context, context.getString(R.string.camera_permission_granted), Toast.LENGTH_LONG)
|
|
|
+ Snackbar
|
|
|
+ .make(binding.root, context.getString(R.string.camera_permission_granted), Snackbar.LENGTH_LONG)
|
|
|
.show()
|
|
|
} else {
|
|
|
- Toast
|
|
|
- .makeText(context, context.getString(R.string.take_photo_permission), Toast.LENGTH_LONG)
|
|
|
+ Snackbar
|
|
|
+ .make(binding.root, context.getString(R.string.take_photo_permission), Snackbar.LENGTH_LONG)
|
|
|
.show()
|
|
|
}
|
|
|
}
|
|
@@ -2564,7 +2588,10 @@ class ChatActivity :
|
|
|
metaData
|
|
|
)
|
|
|
} catch (e: IllegalArgumentException) {
|
|
|
- Toast.makeText(context, context.resources?.getString(R.string.nc_upload_failed), Toast.LENGTH_LONG).show()
|
|
|
+ context.resources?.getString(R.string.nc_upload_failed)?.let {
|
|
|
+ Snackbar.make(binding.root, it, Snackbar.LENGTH_LONG)
|
|
|
+ .show()
|
|
|
+ }
|
|
|
Log.e(javaClass.simpleName, "Something went wrong when trying to upload file", e)
|
|
|
}
|
|
|
}
|
|
@@ -3565,7 +3592,7 @@ class ChatActivity :
|
|
|
if (conversationUser != null) {
|
|
|
val pp = ParticipantPermissions(conversationUser!!, it)
|
|
|
if (!pp.canStartCall() && currentConversation?.hasCall == false) {
|
|
|
- Toast.makeText(context, R.string.startCallForbidden, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.startCallForbidden, Snackbar.LENGTH_LONG).show()
|
|
|
} else {
|
|
|
ApplicationWideCurrentRoomHolder.getInstance().isDialing = true
|
|
|
val callIntent = getIntentForCall(isVoiceOnlyCall, callWithoutNotification)
|
|
@@ -3726,7 +3753,7 @@ class ChatActivity :
|
|
|
"Deletion of message is skipped because of restrictions by permissions. " +
|
|
|
"This method should not have been called!"
|
|
|
)
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
} else {
|
|
|
var apiVersion = 1
|
|
|
// FIXME Fix API checking with guests?
|
|
@@ -3751,10 +3778,10 @@ class ChatActivity :
|
|
|
|
|
|
override fun onNext(t: ChatOverallSingleMessage) {
|
|
|
if (t.ocs!!.meta!!.statusCode == HttpURLConnection.HTTP_ACCEPTED) {
|
|
|
- Toast.makeText(
|
|
|
- context,
|
|
|
+ Snackbar.make(
|
|
|
+ binding.root,
|
|
|
R.string.nc_delete_message_leaked_to_matterbridge,
|
|
|
- Toast.LENGTH_LONG
|
|
|
+ Snackbar.LENGTH_LONG
|
|
|
).show()
|
|
|
}
|
|
|
}
|
|
@@ -3766,7 +3793,7 @@ class ChatActivity :
|
|
|
message?.id,
|
|
|
e
|
|
|
)
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
}
|
|
|
|
|
|
override fun onComplete() {
|
|
@@ -3956,9 +3983,11 @@ class ChatActivity :
|
|
|
|
|
|
private fun showMicrophoneButton(show: Boolean) {
|
|
|
if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
|
|
|
+ Log.d(TAG, "Microphone shown")
|
|
|
binding.messageInputView.messageSendButton.visibility = View.GONE
|
|
|
binding.messageInputView.recordAudioButton.visibility = View.VISIBLE
|
|
|
} else {
|
|
|
+ Log.d(TAG, "Microphone hidden")
|
|
|
binding.messageInputView.messageSendButton.visibility = View.VISIBLE
|
|
|
binding.messageInputView.recordAudioButton.visibility = View.GONE
|
|
|
}
|
|
@@ -4126,7 +4155,7 @@ class ChatActivity :
|
|
|
|
|
|
override fun onError(e: Throwable) {
|
|
|
Log.e(TAG, "error after clicking on user mention chip", e)
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
}
|
|
|
|
|
|
override fun onComplete() {
|
|
@@ -4160,7 +4189,7 @@ class ChatActivity :
|
|
|
)
|
|
|
File("$outputDir/$videoName$VIDEO_SUFFIX")
|
|
|
} catch (e: IOException) {
|
|
|
- Toast.makeText(context, R.string.nc_common_error_sorry, Toast.LENGTH_LONG).show()
|
|
|
+ Snackbar.make(binding.root, R.string.nc_common_error_sorry, Snackbar.LENGTH_LONG).show()
|
|
|
Log.e(TAG, "error while creating video file", e)
|
|
|
null
|
|
|
}
|
|
@@ -4226,6 +4255,7 @@ class ChatActivity :
|
|
|
private const val REQUEST_CODE_SELECT_REMOTE_FILES = 888
|
|
|
private const val OBJECT_MESSAGE: String = "{object}"
|
|
|
private const val MINIMUM_VOICE_RECORD_DURATION: Int = 1000
|
|
|
+ private const val MINIMUM_VOICE_RECORD_TO_STOP: Int = 200
|
|
|
private const val VOICE_RECORD_CANCEL_SLIDER_X: Int = -50
|
|
|
private const val VOICE_RECORD_LOCK_BUTTON_Y: Int = -130
|
|
|
private const val VOICE_MESSAGE_META_DATA = "{\"messageType\":\"voice-message\"}"
|