make ControllerViewBindingDelegate nullable

check nullable bindings in all controllers

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
This commit is contained in:
Marcel Hibbe 2023-01-16 14:58:31 +01:00
parent 08d64c7298
commit 4124a65c7a
No known key found for this signature in database
GPG key ID: C793F8B59F43CE7B
17 changed files with 900 additions and 869 deletions

View file

@ -80,7 +80,8 @@ class AccountVerificationController(args: Bundle? = null) :
R.layout.controller_account_verification, R.layout.controller_account_verification,
args args
) { ) {
private val binding: ControllerAccountVerificationBinding by viewBinding(ControllerAccountVerificationBinding::bind) private val binding: ControllerAccountVerificationBinding? by
viewBinding(ControllerAccountVerificationBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -212,7 +213,7 @@ class AccountVerificationController(args: Bundle? = null) :
} else { } else {
if (activity != null && resources != null) { if (activity != null && resources != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.setText( binding?.progressText?.setText(
String.format( String.format(
resources!!.getString(R.string.nc_nextcloud_talk_app_not_installed), resources!!.getString(R.string.nc_nextcloud_talk_app_not_installed),
resources!!.getString(R.string.nc_app_product_name) resources!!.getString(R.string.nc_app_product_name)
@ -230,17 +231,14 @@ class AccountVerificationController(args: Bundle? = null) :
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (activity != null && resources != null) { if (activity != null && resources != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.setText( binding?.progressText?.text = String.format(
String.format(
resources!!.getString(R.string.nc_nextcloud_talk_app_not_installed), resources!!.getString(R.string.nc_nextcloud_talk_app_not_installed),
resources!!.getString(R.string.nc_app_product_name) resources!!.getString(R.string.nc_app_product_name)
) )
)
} }
} }
ApplicationWideMessageHolder.getInstance().setMessageType( ApplicationWideMessageHolder.getInstance().messageType =
ApplicationWideMessageHolder.MessageType.SERVER_WITHOUT_TALK ApplicationWideMessageHolder.MessageType.SERVER_WITHOUT_TALK
)
abortVerification() abortVerification()
} }
@ -279,8 +277,8 @@ class AccountVerificationController(args: Bundle? = null) :
registerForPush() registerForPush()
} else { } else {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = binding?.progressText?.text =
""" ${binding.progressText.text} """ ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_push_disabled)} ${resources!!.getString(R.string.nc_push_disabled)}
""".trimIndent() """.trimIndent()
} }
@ -290,8 +288,8 @@ class AccountVerificationController(args: Bundle? = null) :
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
binding.progressText.text = binding?.progressText?.text =
""" ${binding.progressText.text} """ ${binding?.progressText?.text}
""" """
.trimIndent() + resources!!.getString(R.string.nc_display_name_not_stored) .trimIndent() + resources!!.getString(R.string.nc_display_name_not_stored)
abortVerification() abortVerification()
@ -331,9 +329,9 @@ class AccountVerificationController(args: Bundle? = null) :
} else { } else {
if (activity != null) { if (activity != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = binding?.progressText?.text =
""" """
${binding.progressText.text} ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_display_name_not_fetched)} ${resources!!.getString(R.string.nc_display_name_not_fetched)}
""".trimIndent() """.trimIndent()
} }
@ -346,9 +344,9 @@ class AccountVerificationController(args: Bundle? = null) :
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
if (activity != null) { if (activity != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = binding?.progressText?.text =
""" """
${binding.progressText.text} ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_display_name_not_fetched)} ${resources!!.getString(R.string.nc_display_name_not_fetched)}
""".trimIndent() """.trimIndent()
} }
@ -380,11 +378,17 @@ class AccountVerificationController(args: Bundle? = null) :
if (eventStatus.eventType == EventStatus.EventType.PUSH_REGISTRATION) { if (eventStatus.eventType == EventStatus.EventType.PUSH_REGISTRATION) {
if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood && activity != null) { if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood && activity != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = // try {
binding?.progressText?.text =
""" """
${binding.progressText.text} ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_push_disabled)} ${resources!!.getString(R.string.nc_push_disabled)}
""".trimIndent() """.trimIndent()
// } catch (npe: NullPointerException) {
// // view binding can be null
// // since this is called asynchronously and UI might have been destroyed in the meantime
// Log.i(TAG, "UI destroyed - view binding already gone")
// }
} }
} }
fetchAndStoreCapabilities() fetchAndStoreCapabilities()
@ -392,9 +396,9 @@ class AccountVerificationController(args: Bundle? = null) :
if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood) { if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood) {
if (activity != null) { if (activity != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = binding?.progressText?.text =
""" """
${binding.progressText.text} ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_capabilities_failed)} ${resources!!.getString(R.string.nc_capabilities_failed)}
""".trimIndent() """.trimIndent()
} }
@ -407,9 +411,9 @@ class AccountVerificationController(args: Bundle? = null) :
if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood) { if (internalAccountId == eventStatus.userId && !eventStatus.isAllGood) {
if (activity != null) { if (activity != null) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
binding.progressText.text = binding?.progressText?.text =
""" """
${binding.progressText.text} ${binding?.progressText?.text}
${resources!!.getString(R.string.nc_external_server_failed)} ${resources!!.getString(R.string.nc_external_server_failed)}
""".trimIndent() """.trimIndent()
} }

View file

@ -213,23 +213,7 @@ import java.util.Locale
import java.util.Objects import java.util.Objects
import java.util.concurrent.ExecutionException import java.util.concurrent.ExecutionException
import javax.inject.Inject import javax.inject.Inject
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.MutableMap
import kotlin.collections.chunked
import kotlin.collections.indexOfFirst
import kotlin.collections.indices
import kotlin.collections.isNotEmpty
import kotlin.collections.iterator
import kotlin.collections.map
import kotlin.collections.set import kotlin.collections.set
import kotlin.collections.toList
import kotlin.collections.toMap
import kotlin.collections.toMutableMap
import kotlin.collections.toTypedArray
import kotlin.math.roundToInt import kotlin.math.roundToInt
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@ -246,7 +230,7 @@ class ChatController(args: Bundle) :
CommonMessageInterface, CommonMessageInterface,
PreviewMessageInterface { PreviewMessageInterface {
private val binding: ControllerChatBinding by viewBinding(ControllerChatBinding::bind) private val binding: ControllerChatBinding? by viewBinding(ControllerChatBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -437,7 +421,7 @@ class ChatController(args: Bundle) :
withNullableControllerViewBinding { withNullableControllerViewBinding {
val itemTouchHelper = ItemTouchHelper(messageSwipeController) val itemTouchHelper = ItemTouchHelper(messageSwipeController)
itemTouchHelper.attachToRecyclerView(binding.messagesListView) itemTouchHelper.attachToRecyclerView(binding?.messagesListView)
} }
} }
} }
@ -541,7 +525,7 @@ class ChatController(args: Bundle) :
var adapterWasNull = false var adapterWasNull = false
if (adapter == null) { if (adapter == null) {
binding.progressBar.visibility = View.VISIBLE binding?.progressBar?.visibility = View.VISIBLE
adapterWasNull = true adapterWasNull = true
@ -651,10 +635,10 @@ class ChatController(args: Bundle) :
this this
) )
} else { } else {
binding.messagesListView.visibility = View.VISIBLE binding?.messagesListView?.visibility = View.VISIBLE
} }
binding.messagesListView.setAdapter(adapter) binding?.messagesListView?.setAdapter(adapter)
adapter?.setLoadMoreListener(this) adapter?.setLoadMoreListener(this)
adapter?.setDateHeadersFormatter { format(it) } adapter?.setDateHeadersFormatter { format(it) }
adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) } adapter?.setOnMessageViewLongClickListener { view, message -> onMessageViewLongClick(view, message) }
@ -677,11 +661,11 @@ class ChatController(args: Bundle) :
setupSwipeToReply() setupSwipeToReply()
layoutManager = binding.messagesListView.layoutManager as LinearLayoutManager? layoutManager = binding?.messagesListView?.layoutManager as LinearLayoutManager?
binding.popupBubbleView.setRecyclerView(binding.messagesListView) binding?.popupBubbleView?.setRecyclerView(binding?.messagesListView)
binding.popupBubbleView.setPopupBubbleListener { context -> binding?.popupBubbleView?.setPopupBubbleListener { context ->
if (newMessagesCount != 0) { if (newMessagesCount != 0) {
val scrollPosition = if (newMessagesCount - 1 < 0) { val scrollPosition = if (newMessagesCount - 1 < 0) {
0 0
@ -690,18 +674,18 @@ class ChatController(args: Bundle) :
} }
Handler().postDelayed( Handler().postDelayed(
{ {
binding.messagesListView.smoothScrollToPosition(scrollPosition) binding?.messagesListView?.smoothScrollToPosition(scrollPosition)
}, },
NEW_MESSAGES_POPUP_BUBBLE_DELAY NEW_MESSAGES_POPUP_BUBBLE_DELAY
) )
} }
} }
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.popupBubbleView) binding?.let { viewThemeUtils.material.colorMaterialButtonPrimaryFilled(it.popupBubbleView) }
binding.messageInputView.setPadding(0, 0, 0, 0) binding?.messageInputView?.setPadding(0, 0, 0, 0)
binding.messagesListView.addOnScrollListener(object : RecyclerView.OnScrollListener() { binding?.messagesListView?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
@ -710,8 +694,8 @@ class ChatController(args: Bundle) :
if (layoutManager!!.findFirstCompletelyVisibleItemPosition() < newMessagesCount) { if (layoutManager!!.findFirstCompletelyVisibleItemPosition() < newMessagesCount) {
newMessagesCount = 0 newMessagesCount = 0
if (binding.popupBubbleView.isShown) { if (binding?.popupBubbleView?.isShown == true) {
binding.popupBubbleView.hide() binding?.popupBubbleView?.hide()
} }
} }
} }
@ -723,9 +707,9 @@ class ChatController(args: Bundle) :
val lengthFilter = CapabilitiesUtilNew.getMessageMaxLength(conversationUser) 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
binding.messageInputView.inputEditText?.addTextChangedListener(object : TextWatcher { binding?.messageInputView?.inputEditText?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// unused atm // unused atm
} }
@ -734,19 +718,19 @@ class ChatController(args: Bundle) :
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
try { try {
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),
lengthFilter.toString() lengthFilter.toString()
) )
} else { } else {
binding.messageInputView.inputEditText?.error = null binding?.messageInputView?.inputEditText?.error = null
} }
val editable = binding.messageInputView.inputEditText?.editableText val editable = binding?.messageInputView?.inputEditText?.editableText
if (editable != null && binding.messageInputView.inputEditText != null) { if (editable != null && binding?.messageInputView?.inputEditText != null) {
val mentionSpans = editable.getSpans( val mentionSpans = editable.getSpans(
0, 0,
binding.messageInputView.inputEditText!!.length(), binding?.messageInputView?.inputEditText!!.length(),
Spans.MentionChipSpan::class.java Spans.MentionChipSpan::class.java
) )
var mentionSpan: Spans.MentionChipSpan var mentionSpan: Spans.MentionChipSpan
@ -779,15 +763,15 @@ class ChatController(args: Bundle) :
// Image keyboard support // Image keyboard support
// See: https://developer.android.com/guide/topics/text/image-keyboard // See: https://developer.android.com/guide/topics/text/image-keyboard
(binding.messageInputView.inputEditText as ImageEmojiEditText).onCommitContentListener = { (binding?.messageInputView?.inputEditText as ImageEmojiEditText).onCommitContentListener = {
uploadFile(it.toString(), false) uploadFile(it.toString(), false)
} }
showMicrophoneButton(true) showMicrophoneButton(true)
binding.messageInputView.messageInput.doAfterTextChanged { binding?.messageInputView?.messageInput?.doAfterTextChanged {
try { try {
if (binding.messageInputView.messageInput.text.isEmpty()) { if (binding?.messageInputView?.messageInput?.text?.isEmpty() == true) {
showMicrophoneButton(true) showMicrophoneButton(true)
} else { } else {
showMicrophoneButton(false) showMicrophoneButton(false)
@ -806,7 +790,7 @@ class ChatController(args: Bundle) :
var voiceRecordStartTime = 0L var voiceRecordStartTime = 0L
var voiceRecordEndTime = 0L var voiceRecordEndTime = 0L
binding.messageInputView.recordAudioButton.setOnTouchListener(object : View.OnTouchListener { binding?.messageInputView?.recordAudioButton?.setOnTouchListener(object : View.OnTouchListener {
override fun onTouch(v: View?, event: MotionEvent?): Boolean { override fun onTouch(v: View?, event: MotionEvent?): Boolean {
view.performClick() view.performClick()
when (event?.action) { when (event?.action) {
@ -835,7 +819,7 @@ class ChatController(args: Bundle) :
stopAndDiscardAudioRecording() stopAndDiscardAudioRecording()
showRecordAudioUi(false) showRecordAudioUi(false)
binding.messageInputView.slideToCancelDescription.x = sliderInitX binding?.messageInputView?.slideToCancelDescription?.x = sliderInitX
} }
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
Log.d(TAG, "ACTION_UP. stop recording??") Log.d(TAG, "ACTION_UP. stop recording??")
@ -861,7 +845,7 @@ class ChatController(args: Bundle) :
stopAndSendAudioRecording() stopAndSendAudioRecording()
} }
binding.messageInputView.slideToCancelDescription.x = sliderInitX binding?.messageInputView?.slideToCancelDescription?.x = sliderInitX
} }
MotionEvent.ACTION_MOVE -> { MotionEvent.ACTION_MOVE -> {
Log.d(TAG, "ACTION_MOVE.") Log.d(TAG, "ACTION_MOVE.")
@ -873,26 +857,26 @@ class ChatController(args: Bundle) :
showRecordAudioUi(true) showRecordAudioUi(true)
if (sliderInitX == 0.0F) { if (sliderInitX == 0.0F) {
sliderInitX = binding.messageInputView.slideToCancelDescription.x sliderInitX = binding?.messageInputView?.slideToCancelDescription?.x!!
} }
val movedX: Float = event.x val movedX: Float = event.x
deltaX = movedX - downX deltaX = movedX - downX
// only allow slide to left // only allow slide to left
if (binding.messageInputView.slideToCancelDescription.x > sliderInitX) { if (binding?.messageInputView?.slideToCancelDescription?.x!! > sliderInitX) {
binding.messageInputView.slideToCancelDescription.x = sliderInitX binding?.messageInputView?.slideToCancelDescription?.x = sliderInitX
} }
if (binding.messageInputView.slideToCancelDescription.x < VOICE_RECORD_CANCEL_SLIDER_X) { if (binding?.messageInputView?.slideToCancelDescription?.x!! < VOICE_RECORD_CANCEL_SLIDER_X) {
Log.d(TAG, "stopping recording because slider was moved to left") Log.d(TAG, "stopping recording because slider was moved to left")
stopAndDiscardAudioRecording() stopAndDiscardAudioRecording()
showRecordAudioUi(false) showRecordAudioUi(false)
binding.messageInputView.slideToCancelDescription.x = sliderInitX binding?.messageInputView?.slideToCancelDescription?.x = sliderInitX
return true return true
} else { } else {
binding.messageInputView.slideToCancelDescription.x = binding.messageInputView binding?.messageInputView?.slideToCancelDescription?.x =
.slideToCancelDescription.x + deltaX binding?.messageInputView?.slideToCancelDescription?.x!! + deltaX
downX = movedX downX = movedX
} }
} }
@ -902,26 +886,24 @@ class ChatController(args: Bundle) :
} }
}) })
binding.messageInputView.inputEditText?.setText(sharedText) binding?.messageInputView?.inputEditText?.setText(sharedText)
binding.messageInputView.setAttachmentsListener { binding?.messageInputView?.setAttachmentsListener {
activity?.let { AttachmentDialog(it, this).show() } activity?.let { AttachmentDialog(it, this).show() }
} }
binding.messageInputView.button.setOnClickListener { submitMessage(false) } binding?.messageInputView?.button?.setOnClickListener { submitMessage(false) }
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "silent-send")) {
binding.messageInputView.button.setOnLongClickListener { binding?.messageInputView?.button?.setOnLongClickListener {
showSendButtonMenu() showSendButtonMenu()
true true
} }
} }
binding.messageInputView.button.contentDescription = resources?.getString( binding?.messageInputView?.button?.contentDescription =
R.string resources?.getString(R.string.nc_description_send_message_button)
.nc_description_send_message_button
)
viewThemeUtils.platform.colorImageView(binding.messageInputView.button) binding?.messageInputView?.button?.let { viewThemeUtils.platform.colorImageView(it) }
if (currentConversation != null && currentConversation?.roomId != null) { if (currentConversation != null && currentConversation?.roomId != null) {
loadAvatarForStatusBar() loadAvatarForStatusBar()
@ -942,7 +924,7 @@ class ChatController(args: Bundle) :
private fun showSendButtonMenu() { private fun showSendButtonMenu() {
val popupMenu = PopupMenu( val popupMenu = PopupMenu(
ContextThemeWrapper(view?.context, R.style.ChatSendButtonMenu), ContextThemeWrapper(view?.context, R.style.ChatSendButtonMenu),
binding.messageInputView.button, binding?.messageInputView?.button,
Gravity.END Gravity.END
) )
popupMenu.inflate(R.menu.chat_send_menu) popupMenu.inflate(R.menu.chat_send_menu)
@ -1150,23 +1132,23 @@ class ChatController(args: Bundle) :
private fun showRecordAudioUi(show: Boolean) { private fun showRecordAudioUi(show: Boolean) {
if (show) { if (show) {
binding.messageInputView.microphoneEnabledInfo.visibility = View.VISIBLE binding?.messageInputView?.microphoneEnabledInfo?.visibility = View.VISIBLE
binding.messageInputView.microphoneEnabledInfoBackground.visibility = View.VISIBLE binding?.messageInputView?.microphoneEnabledInfoBackground?.visibility = View.VISIBLE
binding.messageInputView.audioRecordDuration.visibility = View.VISIBLE binding?.messageInputView?.audioRecordDuration?.visibility = View.VISIBLE
binding.messageInputView.slideToCancelDescription.visibility = View.VISIBLE binding?.messageInputView?.slideToCancelDescription?.visibility = View.VISIBLE
binding.messageInputView.attachmentButton.visibility = View.GONE binding?.messageInputView?.attachmentButton?.visibility = View.GONE
binding.messageInputView.smileyButton.visibility = View.GONE binding?.messageInputView?.smileyButton?.visibility = View.GONE
binding.messageInputView.messageInput.visibility = View.GONE binding?.messageInputView?.messageInput?.visibility = View.GONE
binding.messageInputView.messageInput.hint = "" binding?.messageInputView?.messageInput?.hint = ""
} else { } else {
binding.messageInputView.microphoneEnabledInfo.visibility = View.GONE binding?.messageInputView?.microphoneEnabledInfo?.visibility = View.GONE
binding.messageInputView.microphoneEnabledInfoBackground.visibility = View.GONE binding?.messageInputView?.microphoneEnabledInfoBackground?.visibility = View.GONE
binding.messageInputView.audioRecordDuration.visibility = View.GONE binding?.messageInputView?.audioRecordDuration?.visibility = View.GONE
binding.messageInputView.slideToCancelDescription.visibility = View.GONE binding?.messageInputView?.slideToCancelDescription?.visibility = View.GONE
binding.messageInputView.attachmentButton.visibility = View.VISIBLE binding?.messageInputView?.attachmentButton?.visibility = View.VISIBLE
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)
} }
} }
@ -1179,15 +1161,15 @@ class ChatController(args: Bundle) :
} }
private fun startAudioRecording(file: String) { private fun startAudioRecording(file: String) {
binding.messageInputView.audioRecordDuration.base = SystemClock.elapsedRealtime() binding?.messageInputView?.audioRecordDuration?.base = SystemClock.elapsedRealtime()
binding.messageInputView.audioRecordDuration.start() binding?.messageInputView?.audioRecordDuration?.start()
val animation: Animation = AlphaAnimation(1.0f, 0.0f) val animation: Animation = AlphaAnimation(1.0f, 0.0f)
animation.duration = ANIMATION_DURATION animation.duration = ANIMATION_DURATION
animation.interpolator = LinearInterpolator() animation.interpolator = LinearInterpolator()
animation.repeatCount = Animation.INFINITE animation.repeatCount = Animation.INFINITE
animation.repeatMode = Animation.REVERSE animation.repeatMode = Animation.REVERSE
binding.messageInputView.microphoneEnabledInfo.startAnimation(animation) binding?.messageInputView?.microphoneEnabledInfo?.startAnimation(animation)
recorder = MediaRecorder().apply { recorder = MediaRecorder().apply {
setAudioSource(MediaRecorder.AudioSource.MIC) setAudioSource(MediaRecorder.AudioSource.MIC)
@ -1227,8 +1209,8 @@ class ChatController(args: Bundle) :
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
private fun stopAudioRecording() { private fun stopAudioRecording() {
binding.messageInputView.audioRecordDuration.stop() binding?.messageInputView?.audioRecordDuration?.stop()
binding.messageInputView.microphoneEnabledInfo.clearAnimation() binding?.messageInputView?.microphoneEnabledInfo?.clearAnimation()
if (isVoiceRecordingInProgress) { if (isVoiceRecordingInProgress) {
recorder?.apply { recorder?.apply {
@ -1301,9 +1283,9 @@ class ChatController(args: Bundle) :
shouldShowLobby() || shouldShowLobby() ||
!participantPermissions.hasChatPermission() !participantPermissions.hasChatPermission()
) { ) {
binding.messageInputView.visibility = View.GONE binding?.messageInputView?.visibility = View.GONE
} else { } else {
binding.messageInputView.visibility = View.VISIBLE binding?.messageInputView?.visibility = View.VISIBLE
} }
} }
} }
@ -1359,10 +1341,10 @@ class ChatController(args: Bundle) :
} }
if (shouldShowLobby()) { if (shouldShowLobby()) {
binding.lobby.lobbyView.visibility = View.VISIBLE binding?.lobby?.lobbyView?.visibility = View.VISIBLE
binding.messagesListView.visibility = View.GONE binding?.messagesListView?.visibility = View.GONE
binding.messageInputView.visibility = View.GONE binding?.messageInputView?.visibility = View.GONE
binding.progressBar.visibility = View.GONE binding?.progressBar?.visibility = View.GONE
val sb = StringBuilder() val sb = StringBuilder()
sb.append(resources!!.getText(R.string.nc_lobby_waiting)) sb.append(resources!!.getText(R.string.nc_lobby_waiting))
@ -1383,11 +1365,11 @@ class ChatController(args: Bundle) :
} }
sb.append(currentConversation!!.description) sb.append(currentConversation!!.description)
binding.lobby.lobbyTextView.text = sb.toString() binding?.lobby?.lobbyTextView?.text = sb.toString()
} else { } else {
binding.lobby.lobbyView.visibility = View.GONE binding?.lobby?.lobbyView?.visibility = View.GONE
binding.messagesListView.visibility = View.VISIBLE binding?.messagesListView?.visibility = View.VISIBLE
binding.messageInputView.inputEditText?.visibility = View.VISIBLE binding?.messageInputView?.inputEditText?.visibility = View.VISIBLE
if (isFirstMessagesProcessing && pastPreconditionFailed) { if (isFirstMessagesProcessing && pastPreconditionFailed) {
pastPreconditionFailed = false pastPreconditionFailed = false
pullChatMessages(0) pullChatMessages(0)
@ -1397,9 +1379,9 @@ class ChatController(args: Bundle) :
} }
} }
} else { } else {
binding.lobby.lobbyView.visibility = View.GONE binding?.lobby?.lobbyView?.visibility = View.GONE
binding.messagesListView.visibility = View.VISIBLE binding?.messagesListView?.visibility = View.VISIBLE
binding.messageInputView.inputEditText?.visibility = View.VISIBLE binding?.messageInputView?.inputEditText?.visibility = View.VISIBLE
} }
} }
@ -1461,7 +1443,8 @@ class ChatController(args: Bundle) :
} }
} }
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageInputView.context) binding?.messageInputView?.context?.let {
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(it)
.setTitle(confirmationQuestion) .setTitle(confirmationQuestion)
.setMessage(filenamesWithLineBreaks.toString()) .setMessage(filenamesWithLineBreaks.toString())
.setPositiveButton(R.string.nc_yes) { _, _ -> .setPositiveButton(R.string.nc_yes) { _, _ ->
@ -1475,10 +1458,7 @@ class ChatController(args: Bundle) :
// unused atm // unused atm
} }
viewThemeUtils.dialog.colorMaterialAlertDialogBackground( viewThemeUtils.dialog.colorMaterialAlertDialogBackground(it, materialAlertDialogBuilder)
binding.messageInputView.context,
materialAlertDialogBuilder
)
val dialog = materialAlertDialogBuilder.show() val dialog = materialAlertDialogBuilder.show()
@ -1486,6 +1466,7 @@ class ChatController(args: Bundle) :
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
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()
@ -1572,7 +1553,7 @@ class ChatController(args: Bundle) :
it.item is ChatMessage && (it.item as ChatMessage).id == messageId it.item is ChatMessage && (it.item as ChatMessage).id == messageId
} }
if (position != null && position >= 0) { if (position != null && position >= 0) {
binding.messagesListView.smoothScrollToPosition(position) binding?.messagesListView?.smoothScrollToPosition(position)
} else { } else {
// TODO show error that we don't have that message? // TODO show error that we don't have that message?
} }
@ -1732,12 +1713,12 @@ class ChatController(args: Bundle) :
val callback = MentionAutocompleteCallback( val callback = MentionAutocompleteCallback(
activity, activity,
conversationUser!!, conversationUser!!,
binding.messageInputView.inputEditText, binding?.messageInputView?.inputEditText,
viewThemeUtils viewThemeUtils
) )
if (mentionAutocomplete == null && binding.messageInputView.inputEditText != null) { if (mentionAutocomplete == null && binding?.messageInputView?.inputEditText != null) {
mentionAutocomplete = Autocomplete.on<Mention>(binding.messageInputView.inputEditText) mentionAutocomplete = Autocomplete.on<Mention>(binding?.messageInputView?.inputEditText)
.with(elevation) .with(elevation)
.with(backgroundDrawable) .with(backgroundDrawable)
.with(MagicCharPolicy('@')) .with(MagicCharPolicy('@'))
@ -1773,9 +1754,9 @@ class ChatController(args: Bundle) :
ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = roomToken ApplicationWideCurrentRoomHolder.getInstance().currentRoomToken = roomToken
ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser ApplicationWideCurrentRoomHolder.getInstance().userInRoom = conversationUser
val smileyButton = binding.messageInputView.findViewById<ImageButton>(R.id.smileyButton) val smileyButton = binding?.messageInputView?.findViewById<ImageButton>(R.id.smileyButton)
emojiPopup = binding.messageInputView.inputEditText?.let { emojiPopup = binding?.messageInputView?.inputEditText?.let {
EmojiPopup( EmojiPopup(
rootView = view, rootView = view,
editText = it, editText = it,
@ -1793,7 +1774,7 @@ class ChatController(args: Bundle) :
}, },
onEmojiClickListener = { onEmojiClickListener = {
try { try {
binding.messageInputView.inputEditText?.editableText?.append(" ") binding?.messageInputView?.inputEditText?.editableText?.append(" ")
} catch (npe: NullPointerException) { } catch (npe: NullPointerException) {
// view binding can be null // view binding can be null
// since this is called asynchronously and UI might have been destroyed in the meantime // since this is called asynchronously and UI might have been destroyed in the meantime
@ -1807,12 +1788,14 @@ class ChatController(args: Bundle) :
emojiPopup?.toggle() emojiPopup?.toggle()
} }
binding.messageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)?.setOnClickListener { binding?.messageInputView?.findViewById<ImageButton>(R.id.cancelReplyButton)?.setOnClickListener {
cancelReply() cancelReply()
} }
binding?.messageInputView?.findViewById<ImageButton>(R.id.cancelReplyButton)?.let {
viewThemeUtils.platform viewThemeUtils.platform
.themeImageButton(binding.messageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)) .themeImageButton(it)
}
cancelNotificationsForCurrentConversation() cancelNotificationsForCurrentConversation()
@ -1824,8 +1807,8 @@ class ChatController(args: Bundle) :
} }
private fun cancelReply() { private fun cancelReply() {
binding.messageInputView.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.visibility = View.GONE binding?.messageInputView?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.visibility = View.GONE
binding.messageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = View.VISIBLE binding?.messageInputView?.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = View.VISIBLE
} }
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
@ -2087,8 +2070,8 @@ class ChatController(args: Bundle) :
} }
private fun submitMessage(sendWithoutNotification: Boolean) { private fun submitMessage(sendWithoutNotification: Boolean) {
if (binding.messageInputView.inputEditText != null) { if (binding?.messageInputView?.inputEditText != null) {
val editable = binding.messageInputView.inputEditText!!.editableText val editable = binding?.messageInputView?.inputEditText!!.editableText
val mentionSpans = editable.getSpans( val mentionSpans = editable.getSpans(
0, 0,
editable.length, editable.length,
@ -2104,7 +2087,7 @@ class ChatController(args: Bundle) :
editable.replace(editable.getSpanStart(mentionSpan), editable.getSpanEnd(mentionSpan), "@$mentionId") editable.replace(editable.getSpanStart(mentionSpan), editable.getSpanEnd(mentionSpan), "@$mentionId")
} }
binding.messageInputView.inputEditText?.setText("") binding?.messageInputView?.inputEditText?.setText("")
val replyMessageId: Int? = view?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.tag as Int? val replyMessageId: Int? = view?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)?.tag as Int?
sendMessage( sendMessage(
editable, editable,
@ -2143,11 +2126,11 @@ class ChatController(args: Bundle) :
myFirstMessage = message myFirstMessage = message
try { try {
if (binding.popupBubbleView.isShown) { if (binding?.popupBubbleView?.isShown == true) {
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 asynchronously and UI might have been destroyed in the meantime // since this is called asynchronously and UI might have been destroyed in the meantime
@ -2161,11 +2144,11 @@ class ChatController(args: Bundle) :
if (code.toString().startsWith("2")) { if (code.toString().startsWith("2")) {
myFirstMessage = message myFirstMessage = message
if (binding.popupBubbleView.isShown) { if (binding?.popupBubbleView?.isShown == true) {
binding.popupBubbleView.hide() binding?.popupBubbleView?.hide()
} }
binding.messagesListView.smoothScrollToPosition(0) binding?.messagesListView?.smoothScrollToPosition(0)
} }
} }
} }
@ -2379,7 +2362,7 @@ class ChatController(args: Bundle) :
cancelNotificationsForCurrentConversation() cancelNotificationsForCurrentConversation()
isFirstMessagesProcessing = false isFirstMessagesProcessing = false
binding.progressBar.visibility = View.GONE binding?.progressBar?.visibility = View.GONE
} }
historyRead = true historyRead = true
@ -2406,9 +2389,9 @@ class ChatController(args: Bundle) :
cancelNotificationsForCurrentConversation() cancelNotificationsForCurrentConversation()
isFirstMessagesProcessing = false isFirstMessagesProcessing = false
binding.progressBar.visibility = View.GONE binding?.progressBar?.visibility = View.GONE
binding.messagesListView.visibility = View.VISIBLE binding?.messagesListView?.visibility = View.VISIBLE
} }
if (isFromTheFuture) { if (isFromTheFuture) {
@ -2468,7 +2451,7 @@ class ChatController(args: Bundle) :
if (shouldAddNewMessagesNotice && adapter != null) { if (shouldAddNewMessagesNotice && adapter != null) {
layoutManager?.scrollToPositionWithOffset( layoutManager?.scrollToPositionWithOffset(
adapter!!.getMessagePositionByIdInReverse("-1"), adapter!!.getMessagePositionByIdInReverse("-1"),
binding.messagesListView.height / 2 binding?.messagesListView?.height!! / 2
) )
} }
} }
@ -2508,10 +2491,10 @@ class ChatController(args: Bundle) :
private fun modifyMessageCount(shouldAddNewMessagesNotice: Boolean, shouldScroll: Boolean) { private fun modifyMessageCount(shouldAddNewMessagesNotice: Boolean, shouldScroll: Boolean) {
if (!shouldAddNewMessagesNotice && !shouldScroll) { if (!shouldAddNewMessagesNotice && !shouldScroll) {
if (!binding.popupBubbleView.isShown) { if (!binding?.popupBubbleView?.isShown!!) {
newMessagesCount = 1 newMessagesCount = 1
binding.popupBubbleView.show() binding?.popupBubbleView?.show()
} else if (binding.popupBubbleView.isShown) { } else if (binding?.popupBubbleView?.isShown!!) {
newMessagesCount++ newMessagesCount++
} }
} else { } else {
@ -2622,15 +2605,15 @@ class ChatController(args: Bundle) :
super.onCreateOptionsMenu(menu, inflater) super.onCreateOptionsMenu(menu, inflater)
inflater.inflate(R.menu.menu_conversation, menu) inflater.inflate(R.menu.menu_conversation, menu)
binding?.messageInputView?.context?.let {
viewThemeUtils.platform.colorToolbarMenuIcon( viewThemeUtils.platform.colorToolbarMenuIcon(
binding.messageInputView.context, it, menu.findItem(R.id.conversation_voice_call)
menu.findItem(R.id.conversation_voice_call)
) )
viewThemeUtils.platform.colorToolbarMenuIcon( viewThemeUtils.platform.colorToolbarMenuIcon(
binding.messageInputView.context, it, menu.findItem(R.id.conversation_video_call)
menu.findItem(R.id.conversation_video_call)
) )
}
if (conversationUser?.userId == "?") { if (conversationUser?.userId == "?") {
menu.removeItem(R.id.conversation_info) menu.removeItem(R.id.conversation_info)
@ -3148,25 +3131,21 @@ class ChatController(args: Bundle) :
fun replyToMessage(message: IMessage?) { fun replyToMessage(message: IMessage?) {
val chatMessage = message as ChatMessage? val chatMessage = message as ChatMessage?
chatMessage?.let { chatMessage?.let {
binding.messageInputView.findViewById<ImageButton>(R.id.attachmentButton)?.visibility = binding?.messageInputView?.findViewById<ImageButton>(R.id.attachmentButton)?.visibility =
View.GONE View.GONE
binding.messageInputView.findViewById<ImageButton>(R.id.cancelReplyButton)?.visibility = binding?.messageInputView?.findViewById<ImageButton>(R.id.cancelReplyButton)?.visibility =
View.VISIBLE View.VISIBLE
val quotedMessage = binding val quotedMessage = binding?.messageInputView?.findViewById<EmojiTextView>(R.id.quotedMessage)
.messageInputView
.findViewById<EmojiTextView>(R.id.quotedMessage)
quotedMessage?.maxLines = 2 quotedMessage?.maxLines = 2
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 {
val quotedMessageImage = binding val quotedMessageImage = binding?.messageInputView?.findViewById<ImageView>(R.id.quotedMessageImage)
.messageInputView
.findViewById<ImageView>(R.id.quotedMessageImage)
chatMessage.imageUrl?.let { previewImageUrl -> chatMessage.imageUrl?.let { previewImageUrl ->
quotedMessageImage?.visibility = View.VISIBLE quotedMessageImage?.visibility = View.VISIBLE
@ -3184,16 +3163,12 @@ class ChatController(args: Bundle) :
addHeader("Authorization", credentials!!) addHeader("Authorization", credentials!!)
} }
} ?: run { } ?: run {
binding binding?.messageInputView?.findViewById<ImageView>(R.id.quotedMessageImage)?.visibility = View.GONE
.messageInputView
.findViewById<ImageView>(R.id.quotedMessageImage)
?.visibility = View.GONE
} }
} }
val quotedChatMessageView = binding val quotedChatMessageView =
.messageInputView binding?.messageInputView?.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
.findViewById<RelativeLayout>(R.id.quotedChatMessageView)
quotedChatMessageView?.tag = message?.jsonMessageId quotedChatMessageView?.tag = message?.jsonMessageId
quotedChatMessageView?.visibility = View.VISIBLE quotedChatMessageView?.visibility = View.VISIBLE
} }
@ -3201,11 +3176,11 @@ class ChatController(args: Bundle) :
private fun showMicrophoneButton(show: Boolean) { private fun showMicrophoneButton(show: Boolean) {
if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) { if (show && CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "voice-message-sharing")) {
binding.messageInputView.messageSendButton.visibility = View.GONE binding?.messageInputView?.messageSendButton?.visibility = View.GONE
binding.messageInputView.recordAudioButton.visibility = View.VISIBLE binding?.messageInputView?.recordAudioButton?.visibility = View.VISIBLE
} else { } else {
binding.messageInputView.messageSendButton.visibility = View.VISIBLE binding?.messageInputView?.messageSendButton?.visibility = View.VISIBLE
binding.messageInputView.recordAudioButton.visibility = View.GONE binding?.messageInputView?.recordAudioButton?.visibility = View.GONE
} }
} }
@ -3236,7 +3211,7 @@ class ChatController(args: Bundle) :
} }
if (message.reactionsSelf == null) { if (message.reactionsSelf == null) {
message.reactionsSelf = ArrayList<String>() message.reactionsSelf = ArrayList()
} }
var amount = message.reactions!![emoji] var amount = message.reactions!![emoji]
@ -3254,7 +3229,7 @@ class ChatController(args: Bundle) :
} }
if (message.reactionsSelf == null) { if (message.reactionsSelf == null) {
message.reactionsSelf = ArrayList<String>() message.reactionsSelf = ArrayList()
} }
var amount = message.reactions!![emoji] var amount = message.reactions!![emoji]

View file

@ -92,7 +92,7 @@ class ContactsController(args: Bundle) :
BaseController(R.layout.controller_contacts_rv), BaseController(R.layout.controller_contacts_rv),
SearchView.OnQueryTextListener, SearchView.OnQueryTextListener,
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener {
private val binding: ControllerContactsRvBinding by viewBinding(ControllerContactsRvBinding::bind) private val binding: ControllerContactsRvBinding? by viewBinding(ControllerContactsRvBinding::bind)
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
@ -153,13 +153,13 @@ class ContactsController(args: Bundle) :
toggleConversationPrivacyLayout(!isPublicCall) toggleConversationPrivacyLayout(!isPublicCall)
} }
if (isAddingParticipantsView) { if (isAddingParticipantsView) {
binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.visibility = View.GONE binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.GONE
binding.conversationPrivacyToggle.callHeaderLayout.visibility = View.GONE binding?.conversationPrivacyToggle?.callHeaderLayout?.visibility = View.GONE
} else { } else {
binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.setOnClickListener { binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.setOnClickListener {
joinConversationViaLink() joinConversationViaLink()
} }
binding.conversationPrivacyToggle.callHeaderLayout.setOnClickListener { binding?.conversationPrivacyToggle?.callHeaderLayout?.setOnClickListener {
toggleCallHeader() toggleCallHeader()
} }
} }
@ -382,11 +382,13 @@ class ContactsController(args: Bundle) :
super.onPrepareOptionsMenu(menu) super.onPrepareOptionsMenu(menu)
if (searchItem != null) { if (searchItem != null) {
binding?.titleTextView?.let {
viewThemeUtils.platform.colorToolbarMenuIcon( viewThemeUtils.platform.colorToolbarMenuIcon(
binding.titleTextView.context, it.context,
searchItem!! searchItem!!
) )
} }
}
checkAndHandleDoneMenuItem() checkAndHandleDoneMenuItem()
if (adapter?.hasFilter() == true) { if (adapter?.hasFilter() == true) {
@ -451,20 +453,20 @@ class ContactsController(args: Bundle) :
} }
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.controllerGenericRv.swipeRefreshLayout.isRefreshing = false binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
} }
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.controllerGenericRv.swipeRefreshLayout.isRefreshing = false binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
} }
dispose(contactsQueryDisposable) dispose(contactsQueryDisposable)
} }
override fun onComplete() { override fun onComplete() {
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.controllerGenericRv.swipeRefreshLayout.isRefreshing = false binding?.controllerGenericRv?.swipeRefreshLayout?.isRefreshing = false
} }
dispose(contactsQueryDisposable) dispose(contactsQueryDisposable)
alreadyFetching = false alreadyFetching = false
@ -627,31 +629,31 @@ class ContactsController(args: Bundle) :
private fun prepareViews() { private fun prepareViews() {
layoutManager = SmoothScrollLinearLayoutManager(activity) layoutManager = SmoothScrollLinearLayoutManager(activity)
binding.controllerGenericRv.recyclerView.layoutManager = layoutManager binding?.controllerGenericRv?.recyclerView?.layoutManager = layoutManager
binding.controllerGenericRv.recyclerView.setHasFixedSize(true) binding?.controllerGenericRv?.recyclerView?.setHasFixedSize(true)
binding.controllerGenericRv.recyclerView.adapter = adapter binding?.controllerGenericRv?.recyclerView?.adapter = adapter
binding.controllerGenericRv.swipeRefreshLayout.setOnRefreshListener { fetchData() } binding?.controllerGenericRv?.swipeRefreshLayout?.setOnRefreshListener { fetchData() }
viewThemeUtils.androidx.themeSwipeRefreshLayout(binding.controllerGenericRv.swipeRefreshLayout) binding?.controllerGenericRv?.let { viewThemeUtils.androidx.themeSwipeRefreshLayout(it.swipeRefreshLayout) }
binding.joinConversationViaLink.joinConversationViaLinkImageView binding?.joinConversationViaLink?.joinConversationViaLinkImageView
.background ?.background
.setColorFilter( ?.setColorFilter(
ResourcesCompat.getColor(resources!!, R.color.colorBackgroundDarker, null), ResourcesCompat.getColor(resources!!, R.color.colorBackgroundDarker, null),
PorterDuff.Mode.SRC_IN PorterDuff.Mode.SRC_IN
) )
viewThemeUtils.platform.colorImageViewButton(binding.conversationPrivacyToggle.publicCallLink) binding?.conversationPrivacyToggle?.let { viewThemeUtils.platform.colorImageViewButton(it.publicCallLink) }
disengageProgressBar() disengageProgressBar()
} }
private fun disengageProgressBar() { private fun disengageProgressBar() {
if (!alreadyFetching) { if (!alreadyFetching) {
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
binding.controllerGenericRv.root.visibility = View.VISIBLE binding?.controllerGenericRv?.root?.visibility = View.VISIBLE
if (isNewConversationView) { if (isNewConversationView) {
binding.conversationPrivacyToggle.callHeaderLayout.visibility = View.VISIBLE binding?.conversationPrivacyToggle?.callHeaderLayout?.visibility = View.VISIBLE
binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.visibility = View.VISIBLE binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.VISIBLE
} }
} }
} }
@ -698,7 +700,7 @@ class ContactsController(args: Bundle) :
} }
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.controllerGenericRv.swipeRefreshLayout.isEnabled = !adapter!!.hasFilter() binding?.controllerGenericRv?.swipeRefreshLayout?.isEnabled = !adapter!!.hasFilter()
} }
return true return true
@ -929,11 +931,11 @@ class ContactsController(args: Bundle) :
private fun toggleConversationPrivacyLayout(showInitialLayout: Boolean) { private fun toggleConversationPrivacyLayout(showInitialLayout: Boolean) {
withNullableControllerViewBinding { withNullableControllerViewBinding {
if (showInitialLayout) { if (showInitialLayout) {
binding.conversationPrivacyToggle.initialRelativeLayout.visibility = View.VISIBLE binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.VISIBLE
binding.conversationPrivacyToggle.secondaryRelativeLayout.visibility = View.GONE binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.GONE
} else { } else {
binding.conversationPrivacyToggle.initialRelativeLayout.visibility = View.GONE binding?.conversationPrivacyToggle?.initialRelativeLayout?.visibility = View.GONE
binding.conversationPrivacyToggle.secondaryRelativeLayout.visibility = View.VISIBLE binding?.conversationPrivacyToggle?.secondaryRelativeLayout?.visibility = View.VISIBLE
} }
} }
} }
@ -941,10 +943,10 @@ class ContactsController(args: Bundle) :
private fun toggleConversationViaLinkVisibility(isPublicCall: Boolean) { private fun toggleConversationViaLinkVisibility(isPublicCall: Boolean) {
withNullableControllerViewBinding { withNullableControllerViewBinding {
if (isPublicCall) { if (isPublicCall) {
binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.visibility = View.GONE binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.GONE
updateGroupParticipantSelection() updateGroupParticipantSelection()
} else { } else {
binding.joinConversationViaLink.joinConversationViaLinkRelativeLayout.visibility = View.VISIBLE binding?.joinConversationViaLink?.joinConversationViaLinkRelativeLayout?.visibility = View.VISIBLE
} }
} }
} }

View file

@ -63,9 +63,9 @@ import com.nextcloud.talk.data.user.model.User
import com.nextcloud.talk.databinding.ControllerConversationInfoBinding import com.nextcloud.talk.databinding.ControllerConversationInfoBinding
import com.nextcloud.talk.events.EventStatus import com.nextcloud.talk.events.EventStatus
import com.nextcloud.talk.extensions.loadAvatar import com.nextcloud.talk.extensions.loadAvatar
import com.nextcloud.talk.extensions.loadSystemAvatar
import com.nextcloud.talk.extensions.loadGroupCallAvatar import com.nextcloud.talk.extensions.loadGroupCallAvatar
import com.nextcloud.talk.extensions.loadPublicCallAvatar import com.nextcloud.talk.extensions.loadPublicCallAvatar
import com.nextcloud.talk.extensions.loadSystemAvatar
import com.nextcloud.talk.jobs.DeleteConversationWorker import com.nextcloud.talk.jobs.DeleteConversationWorker
import com.nextcloud.talk.jobs.LeaveConversationWorker import com.nextcloud.talk.jobs.LeaveConversationWorker
import com.nextcloud.talk.models.json.conversations.Conversation import com.nextcloud.talk.models.json.conversations.Conversation
@ -107,7 +107,7 @@ class ConversationInfoController(args: Bundle) :
), ),
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener {
private val binding: ControllerConversationInfoBinding by viewBinding(ControllerConversationInfoBinding::bind) private val binding: ControllerConversationInfoBinding? by viewBinding(ControllerConversationInfoBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -173,19 +173,19 @@ class ConversationInfoController(args: Bundle) :
databaseStorageModule = DatabaseStorageModule(conversationUser!!, conversationToken) databaseStorageModule = DatabaseStorageModule(conversationUser!!, conversationToken)
} }
binding.notificationSettingsView.notificationSettings.setStorageModule(databaseStorageModule) binding?.notificationSettingsView?.notificationSettings?.setStorageModule(databaseStorageModule)
binding.webinarInfoView.webinarSettings.setStorageModule(databaseStorageModule) binding?.webinarInfoView?.webinarSettings?.setStorageModule(databaseStorageModule)
binding.guestAccessView.guestAccessSettings.setStorageModule(databaseStorageModule) binding?.guestAccessView?.guestAccessSettings?.setStorageModule(databaseStorageModule)
binding.deleteConversationAction.setOnClickListener { showDeleteConversationDialog() } binding?.deleteConversationAction?.setOnClickListener { showDeleteConversationDialog() }
binding.leaveConversationAction.setOnClickListener { leaveConversation() } binding?.leaveConversationAction?.setOnClickListener { leaveConversation() }
binding.clearConversationHistory.setOnClickListener { showClearHistoryDialog() } binding?.clearConversationHistory?.setOnClickListener { showClearHistoryDialog() }
binding.addParticipantsAction.setOnClickListener { addParticipants() } binding?.addParticipantsAction?.setOnClickListener { addParticipants() }
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "rich-object-list-media")) {
binding.showSharedItemsAction.setOnClickListener { showSharedItems() } binding?.showSharedItemsAction?.setOnClickListener { showSharedItems() }
} else { } else {
binding.categorySharedItems.visibility = GONE binding?.categorySharedItems?.visibility = GONE
} }
fetchRoomInfo() fetchRoomInfo()
@ -195,19 +195,19 @@ class ConversationInfoController(args: Bundle) :
} }
private fun themeSwitchPreferences() { private fun themeSwitchPreferences() {
binding.run { binding?.run {
listOf( listOf(
binding.webinarInfoView.conversationInfoLobby, binding?.webinarInfoView?.conversationInfoLobby!!,
binding.notificationSettingsView.callNotifications, binding?.notificationSettingsView?.callNotifications!!,
binding.notificationSettingsView.conversationInfoPriorityConversation, binding?.notificationSettingsView?.conversationInfoPriorityConversation!!,
binding.guestAccessView.guestAccessAllowSwitch, binding?.guestAccessView?.guestAccessAllowSwitch!!,
binding.guestAccessView.guestAccessPasswordSwitch binding?.guestAccessView?.guestAccessPasswordSwitch!!
).forEach(viewThemeUtils.talk::colorSwitchPreference) ).forEach(viewThemeUtils.talk::colorSwitchPreference)
} }
} }
private fun themeCategories() { private fun themeCategories() {
binding.run { binding?.run {
listOf( listOf(
conversationInfoName, conversationInfoName,
conversationDescription, conversationDescription,
@ -216,9 +216,9 @@ class ConversationInfoController(args: Bundle) :
ownOptions, ownOptions,
categorySharedItems, categorySharedItems,
categoryConversationSettings, categoryConversationSettings,
binding.guestAccessView.guestAccessCategory, binding?.guestAccessView?.guestAccessCategory!!,
binding.webinarInfoView.conversationInfoWebinar, binding?.webinarInfoView?.conversationInfoWebinar!!,
binding.notificationSettingsView.notificationSettingsCategory binding?.notificationSettingsView?.notificationSettingsCategory!!
).forEach(viewThemeUtils.talk::colorPreferenceCategory) ).forEach(viewThemeUtils.talk::colorPreferenceCategory)
} }
} }
@ -237,9 +237,9 @@ class ConversationInfoController(args: Bundle) :
override fun onViewBound(view: View) { override fun onViewBound(view: View) {
super.onViewBound(view) super.onViewBound(view)
binding.addParticipantsAction.visibility = GONE binding?.addParticipantsAction?.visibility = GONE
viewThemeUtils.platform.colorCircularProgressBar(binding.progressBar) binding?.progressBar?.let { viewThemeUtils.platform.colorCircularProgressBar(it) }
} }
private fun setupWebinaryView() { private fun setupWebinaryView() {
@ -247,16 +247,16 @@ class ConversationInfoController(args: Bundle) :
webinaryRoomType(conversation!!) && webinaryRoomType(conversation!!) &&
conversation!!.canModerate(conversationUser!!) conversation!!.canModerate(conversationUser!!)
) { ) {
binding.webinarInfoView.webinarSettings.visibility = VISIBLE binding?.webinarInfoView?.webinarSettings?.visibility = VISIBLE
val isLobbyOpenToModeratorsOnly = val isLobbyOpenToModeratorsOnly =
conversation!!.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY conversation!!.lobbyState == Conversation.LobbyState.LOBBY_STATE_MODERATORS_ONLY
(binding.webinarInfoView.conversationInfoLobby.findViewById<View>(R.id.mp_checkable) as SwitchCompat) (binding?.webinarInfoView?.conversationInfoLobby?.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.isChecked = isLobbyOpenToModeratorsOnly .isChecked = isLobbyOpenToModeratorsOnly
reconfigureLobbyTimerView() reconfigureLobbyTimerView()
binding.webinarInfoView.startTimePreferences.setOnClickListener { binding?.webinarInfoView?.startTimePreferences?.setOnClickListener {
MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show { MaterialDialog(activity!!, BottomSheet(WRAP_CONTENT)).show {
val currentTimeCalendar = Calendar.getInstance() val currentTimeCalendar = Calendar.getInstance()
if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) { if (conversation!!.lobbyTimer != null && conversation!!.lobbyTimer != 0L) {
@ -277,13 +277,13 @@ class ConversationInfoController(args: Bundle) :
} }
} }
(binding.webinarInfoView.conversationInfoLobby.findViewById<View>(R.id.mp_checkable) as SwitchCompat) (binding?.webinarInfoView?.conversationInfoLobby?.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.setOnCheckedChangeListener { _, _ -> .setOnCheckedChangeListener { _, _ ->
reconfigureLobbyTimerView() reconfigureLobbyTimerView()
submitLobbyChanges() submitLobbyChanges()
} }
} else { } else {
binding.webinarInfoView.webinarSettings.visibility = GONE binding?.webinarInfoView?.webinarSettings?.visibility = GONE
} }
} }
@ -294,7 +294,7 @@ class ConversationInfoController(args: Bundle) :
private fun reconfigureLobbyTimerView(dateTime: Calendar? = null) { private fun reconfigureLobbyTimerView(dateTime: Calendar? = null) {
val isChecked = val isChecked =
(binding.webinarInfoView.conversationInfoLobby.findViewById<View>(R.id.mp_checkable) as SwitchCompat) (binding?.webinarInfoView?.conversationInfoLobby?.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.isChecked .isChecked
if (dateTime != null && isChecked) { if (dateTime != null && isChecked) {
@ -313,25 +313,25 @@ class ConversationInfoController(args: Bundle) :
conversation!!.lobbyTimer != java.lang.Long.MIN_VALUE && conversation!!.lobbyTimer != java.lang.Long.MIN_VALUE &&
conversation!!.lobbyTimer != 0L conversation!!.lobbyTimer != 0L
) { ) {
binding.webinarInfoView.startTimePreferences.setSummary( binding?.webinarInfoView?.startTimePreferences?.setSummary(
dateUtils.getLocalDateTimeStringFromTimestamp( dateUtils.getLocalDateTimeStringFromTimestamp(
conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER, conversation!!.lobbyTimer!! * DateConstants.SECOND_DIVIDER,
) )
) )
} else { } else {
binding.webinarInfoView.startTimePreferences.setSummary(R.string.nc_manual) binding?.webinarInfoView?.startTimePreferences?.setSummary(R.string.nc_manual)
} }
if (isChecked) { if (isChecked) {
binding.webinarInfoView.startTimePreferences.visibility = VISIBLE binding?.webinarInfoView?.startTimePreferences?.visibility = VISIBLE
} else { } else {
binding.webinarInfoView.startTimePreferences.visibility = GONE binding?.webinarInfoView?.startTimePreferences?.visibility = GONE
} }
} }
fun submitLobbyChanges() { fun submitLobbyChanges() {
val state = if ( val state = if (
(binding.webinarInfoView.conversationInfoLobby.findViewById<View>(R.id.mp_checkable) as SwitchCompat) (binding?.webinarInfoView?.conversationInfoLobby?.findViewById<View>(R.id.mp_checkable) as SwitchCompat)
.isChecked .isChecked
) 1 else 0 ) 1 else 0
@ -376,8 +376,13 @@ class ConversationInfoController(args: Bundle) :
private fun showDeleteConversationDialog() { private fun showDeleteConversationDialog() {
if (activity != null) { if (activity != null) {
val dialogBuilder = MaterialAlertDialogBuilder(binding.conversationInfoName.context) binding?.conversationInfoName?.let {
.setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)) val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
context, R.drawable.ic_delete_black_24dp
)
)
.setTitle(R.string.nc_delete_call) .setTitle(R.string.nc_delete_call)
.setMessage(R.string.nc_delete_conversation_more) .setMessage(R.string.nc_delete_conversation_more)
.setPositiveButton(R.string.nc_delete) { _, _ -> .setPositiveButton(R.string.nc_delete) { _, _ ->
@ -386,8 +391,9 @@ class ConversationInfoController(args: Bundle) :
.setNegativeButton(R.string.nc_cancel) { _, _ -> .setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm // unused atm
} }
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(binding.conversationInfoName.context, dialogBuilder) .colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
@ -395,6 +401,7 @@ class ConversationInfoController(args: Bundle) :
) )
} }
} }
}
private fun setupAdapter() { private fun setupAdapter() {
if (activity != null) { if (activity != null) {
@ -403,9 +410,9 @@ class ConversationInfoController(args: Bundle) :
} }
val layoutManager = SmoothScrollLinearLayoutManager(activity) val layoutManager = SmoothScrollLinearLayoutManager(activity)
binding.recyclerView.layoutManager = layoutManager binding?.recyclerView?.layoutManager = layoutManager
binding.recyclerView.setHasFixedSize(true) binding?.recyclerView?.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding?.recyclerView?.adapter = adapter
adapter!!.addListener(this) adapter!!.addListener(this)
} }
@ -446,7 +453,7 @@ class ConversationInfoController(args: Bundle) :
setupAdapter() setupAdapter()
binding.participantsListCategory.visibility = VISIBLE binding?.participantsListCategory?.visibility = VISIBLE
adapter!!.updateDataSet(userItems) adapter!!.updateDataSet(userItems)
} }
@ -548,8 +555,13 @@ class ConversationInfoController(args: Bundle) :
private fun showClearHistoryDialog() { private fun showClearHistoryDialog() {
if (activity != null) { if (activity != null) {
val dialogBuilder = MaterialAlertDialogBuilder(binding.conversationInfoName.context) binding?.conversationInfoName?.context?.let {
.setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)) val dialogBuilder = MaterialAlertDialogBuilder(it)
.setIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
context, R.drawable.ic_delete_black_24dp
)
)
.setTitle(R.string.nc_clear_history) .setTitle(R.string.nc_clear_history)
.setMessage(R.string.nc_clear_history_warning) .setMessage(R.string.nc_clear_history_warning)
.setPositiveButton(R.string.nc_delete_all) { _, _ -> .setPositiveButton(R.string.nc_delete_all) { _, _ ->
@ -558,8 +570,9 @@ class ConversationInfoController(args: Bundle) :
.setNegativeButton(R.string.nc_cancel) { _, _ -> .setNegativeButton(R.string.nc_cancel) { _, _ ->
// unused atm // unused atm
} }
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(binding.conversationInfoName.context, dialogBuilder) .colorMaterialAlertDialogBackground(it, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
@ -567,6 +580,7 @@ class ConversationInfoController(args: Bundle) :
) )
} }
} }
}
private fun clearHistory() { private fun clearHistory() {
val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1)) val apiVersion = ApiUtils.getChatApiVersion(conversationUser, intArrayOf(1))
@ -638,70 +652,72 @@ class ConversationInfoController(args: Bundle) :
val conversationCopy = conversation val conversationCopy = conversation
if (conversationCopy!!.canModerate(conversationUser)) { if (conversationCopy!!.canModerate(conversationUser)) {
binding.addParticipantsAction.visibility = VISIBLE binding?.addParticipantsAction?.visibility = VISIBLE
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "clear-history")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "clear-history")) {
binding.clearConversationHistory.visibility = VISIBLE binding?.clearConversationHistory?.visibility = VISIBLE
} else { } else {
binding.clearConversationHistory.visibility = GONE binding?.clearConversationHistory?.visibility = GONE
} }
} else { } else {
binding.addParticipantsAction.visibility = GONE binding?.addParticipantsAction?.visibility = GONE
binding.clearConversationHistory.visibility = GONE binding?.clearConversationHistory?.visibility = GONE
} }
if (isAttached && (!isBeingDestroyed || !isDestroyed)) { if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
binding.ownOptions.visibility = VISIBLE binding?.ownOptions?.visibility = VISIBLE
setupWebinaryView() setupWebinaryView()
if (!conversation!!.canLeave()) { if (!conversation!!.canLeave()) {
binding.leaveConversationAction.visibility = GONE binding?.leaveConversationAction?.visibility = GONE
} else { } else {
binding.leaveConversationAction.visibility = VISIBLE binding?.leaveConversationAction?.visibility = VISIBLE
} }
if (!conversation!!.canDelete(conversationUser)) { if (!conversation!!.canDelete(conversationUser)) {
binding.deleteConversationAction.visibility = GONE binding?.deleteConversationAction?.visibility = GONE
} else { } else {
binding.deleteConversationAction.visibility = VISIBLE binding?.deleteConversationAction?.visibility = VISIBLE
} }
if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) { if (Conversation.ConversationType.ROOM_SYSTEM == conversation!!.type) {
binding.notificationSettingsView.callNotifications.visibility = GONE binding?.notificationSettingsView?.callNotifications?.visibility = GONE
} }
if (conversation!!.notificationCalls === null) { if (conversation!!.notificationCalls === null) {
binding.notificationSettingsView.callNotifications.visibility = GONE binding?.notificationSettingsView?.callNotifications?.visibility = GONE
} else { } else {
binding.notificationSettingsView.callNotifications.value = binding?.notificationSettingsView?.callNotifications?.value =
conversationCopy.notificationCalls == 1 conversationCopy.notificationCalls == 1
} }
getListOfParticipants() getListOfParticipants()
binding.progressBar.visibility = GONE binding?.progressBar?.visibility = GONE
binding.conversationInfoName.visibility = VISIBLE binding?.conversationInfoName?.visibility = VISIBLE
binding.displayNameText.text = conversation!!.displayName binding?.displayNameText?.text = conversation!!.displayName
if (conversation!!.description != null && !conversation!!.description!!.isEmpty()) { if (conversation!!.description != null && !conversation!!.description!!.isEmpty()) {
binding.descriptionText.text = conversation!!.description binding?.descriptionText?.text = conversation!!.description
binding.conversationDescription.visibility = VISIBLE binding?.conversationDescription?.visibility = VISIBLE
} }
loadConversationAvatar() loadConversationAvatar()
adjustNotificationLevelUI() adjustNotificationLevelUI()
initExpiringMessageOption() initExpiringMessageOption()
binding?.let {
GuestAccessHelper( GuestAccessHelper(
this@ConversationInfoController, this@ConversationInfoController,
binding, it,
conversation!!, conversation!!,
conversationUser conversationUser
).setupGuestAccess() ).setupGuestAccess()
}
binding.notificationSettingsView.notificationSettings.visibility = VISIBLE binding?.notificationSettingsView?.notificationSettings?.visibility = VISIBLE
} }
} catch (npe: NullPointerException) { } catch (npe: NullPointerException) {
// view binding can be null // view binding can be null
@ -725,11 +741,11 @@ class ConversationInfoController(args: Bundle) :
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration") CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "message-expiration")
) { ) {
databaseStorageModule?.setMessageExpiration(conversation!!.messageExpiration) databaseStorageModule?.setMessageExpiration(conversation!!.messageExpiration)
binding.conversationInfoExpireMessages.setStorageModule(databaseStorageModule) binding?.conversationInfoExpireMessages?.setStorageModule(databaseStorageModule)
binding.conversationInfoExpireMessages.visibility = View.VISIBLE binding?.conversationInfoExpireMessages?.visibility = VISIBLE
binding.conversationInfoExpireMessagesExplanation.visibility = View.VISIBLE binding?.conversationInfoExpireMessagesExplanation?.visibility = VISIBLE
} else { } else {
binding.categoryConversationSettings.visibility = View.GONE binding?.categoryConversationSettings?.visibility = GONE
} }
} }
@ -739,8 +755,8 @@ class ConversationInfoController(args: Bundle) :
conversationUser != null && conversationUser != null &&
CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels") CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "notification-levels")
) { ) {
binding.notificationSettingsView.conversationInfoMessageNotifications.isEnabled = true binding?.notificationSettingsView?.conversationInfoMessageNotifications?.isEnabled = true
binding.notificationSettingsView.conversationInfoMessageNotifications.alpha = 1.0f binding?.notificationSettingsView?.conversationInfoMessageNotifications?.alpha = 1.0f
if (conversation!!.notificationLevel != Conversation.NotificationLevel.DEFAULT) { if (conversation!!.notificationLevel != Conversation.NotificationLevel.DEFAULT) {
val stringValue: String = val stringValue: String =
@ -751,13 +767,13 @@ class ConversationInfoController(args: Bundle) :
else -> "mention" else -> "mention"
} }
binding.notificationSettingsView.conversationInfoMessageNotifications.value = stringValue binding?.notificationSettingsView?.conversationInfoMessageNotifications?.value = stringValue
} else { } else {
setProperNotificationValue(conversation) setProperNotificationValue(conversation)
} }
} else { } else {
binding.notificationSettingsView.conversationInfoMessageNotifications.isEnabled = false binding?.notificationSettingsView?.conversationInfoMessageNotifications?.isEnabled = false
binding.notificationSettingsView.conversationInfoMessageNotifications.alpha = LOW_EMPHASIS_OPACITY binding?.notificationSettingsView?.conversationInfoMessageNotifications?.alpha = LOW_EMPHASIS_OPACITY
setProperNotificationValue(conversation) setProperNotificationValue(conversation)
} }
} }
@ -767,28 +783,28 @@ class ConversationInfoController(args: Bundle) :
if (conversation!!.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) { if (conversation!!.type == Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL) {
// hack to see if we get mentioned always or just on mention // hack to see if we get mentioned always or just on mention
if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag")) { if (CapabilitiesUtilNew.hasSpreedFeatureCapability(conversationUser, "mention-flag")) {
binding.notificationSettingsView.conversationInfoMessageNotifications.value = "always" binding?.notificationSettingsView?.conversationInfoMessageNotifications?.value = "always"
} else { } else {
binding.notificationSettingsView.conversationInfoMessageNotifications.value = "mention" binding?.notificationSettingsView?.conversationInfoMessageNotifications?.value = "mention"
} }
} else { } else {
binding.notificationSettingsView.conversationInfoMessageNotifications.value = "mention" binding?.notificationSettingsView?.conversationInfoMessageNotifications?.value = "mention"
} }
} }
private fun loadConversationAvatar() { private fun loadConversationAvatar() {
when (conversation!!.type) { when (conversation!!.type) {
Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) { Conversation.ConversationType.ROOM_TYPE_ONE_TO_ONE_CALL -> if (!TextUtils.isEmpty(conversation!!.name)) {
conversation!!.name?.let { binding.avatarImage.loadAvatar(conversationUser!!, it) } conversation!!.name?.let { binding?.avatarImage?.loadAvatar(conversationUser!!, it) }
} }
Conversation.ConversationType.ROOM_GROUP_CALL -> { Conversation.ConversationType.ROOM_GROUP_CALL -> {
binding.avatarImage.loadGroupCallAvatar(viewThemeUtils) binding?.avatarImage?.loadGroupCallAvatar(viewThemeUtils)
} }
Conversation.ConversationType.ROOM_PUBLIC_CALL -> { Conversation.ConversationType.ROOM_PUBLIC_CALL -> {
binding.avatarImage.loadPublicCallAvatar(viewThemeUtils) binding?.avatarImage?.loadPublicCallAvatar(viewThemeUtils)
} }
Conversation.ConversationType.ROOM_SYSTEM -> { Conversation.ConversationType.ROOM_SYSTEM -> {
binding.avatarImage.loadSystemAvatar() binding?.avatarImage?.loadSystemAvatar()
} }
else -> { else -> {

View file

@ -157,7 +157,7 @@ class ConversationsListController(bundle: Bundle) :
@Inject @Inject
lateinit var unifiedSearchRepository: UnifiedSearchRepository lateinit var unifiedSearchRepository: UnifiedSearchRepository
private val binding: ControllerConversationsRvBinding by viewBinding(ControllerConversationsRvBinding::bind) private val binding: ControllerConversationsRvBinding? by viewBinding(ControllerConversationsRvBinding::bind)
override val title: String override val title: String
get() = resources!!.getString(R.string.nc_app_product_name) get() = resources!!.getString(R.string.nc_app_product_name)
@ -200,7 +200,7 @@ class ConversationsListController(bundle: Bundle) :
if (adapter == null) { if (adapter == null) {
adapter = FlexibleAdapter(conversationItems, activity, true) adapter = FlexibleAdapter(conversationItems, activity, true)
} else { } else {
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
} }
adapter!!.addListener(this) adapter!!.addListener(this)
prepareViews() prepareViews()
@ -410,7 +410,7 @@ class ConversationsListController(bundle: Bundle) :
adapter!!.updateDataSet(searchableConversationItems, false) adapter!!.updateDataSet(searchableConversationItems, false)
adapter!!.showAllHeaders() adapter!!.showAllHeaders()
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isEnabled = false binding?.swipeRefreshLayoutView?.isEnabled = false
} }
return true return true
} }
@ -422,10 +422,10 @@ class ConversationsListController(bundle: Bundle) :
if (searchHelper != null) { if (searchHelper != null) {
// cancel any pending searches // cancel any pending searches
searchHelper!!.cancelSearch() searchHelper!!.cancelSearch()
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
} }
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isEnabled = true binding?.swipeRefreshLayoutView?.isEnabled = true
} }
searchView!!.onActionViewCollapsed() searchView!!.onActionViewCollapsed()
val mainActivity = getActivity() as MainActivity? val mainActivity = getActivity() as MainActivity?
@ -441,7 +441,7 @@ class ConversationsListController(bundle: Bundle) :
.resetStatusBar(mainActivity) .resetStatusBar(mainActivity)
} }
} }
val layoutManager = binding.recyclerView.layoutManager as SmoothScrollLinearLayoutManager? val layoutManager = binding?.recyclerView?.layoutManager as SmoothScrollLinearLayoutManager?
layoutManager?.scrollToPositionWithOffset(0, 0) layoutManager?.scrollToPositionWithOffset(0, 0)
return true return true
} }
@ -503,7 +503,7 @@ class ConversationsListController(bundle: Bundle) :
} }
if (adapterWasNull) { if (adapterWasNull) {
adapterWasNull = false adapterWasNull = false
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
} }
initOverallLayout(ocs!!.data!!.isNotEmpty()) initOverallLayout(ocs!!.data!!.isNotEmpty())
for (conversation in ocs.data!!) { for (conversation in ocs.data!!) {
@ -515,19 +515,19 @@ class ConversationsListController(bundle: Bundle) :
Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong()) Handler().postDelayed({ checkToShowUnreadBubble() }, UNREAD_BUBBLE_DELAY.toLong())
fetchOpenConversations(apiVersion) fetchOpenConversations(apiVersion)
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
} }
}, { throwable: Throwable -> }, { throwable: Throwable ->
handleHttpExceptions(throwable) handleHttpExceptions(throwable)
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
showErrorDialog() showErrorDialog()
} }
dispose(roomsQueryDisposable) dispose(roomsQueryDisposable)
}) { }) {
dispose(roomsQueryDisposable) dispose(roomsQueryDisposable)
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
} }
isRefreshing = false isRefreshing = false
} }
@ -535,18 +535,18 @@ class ConversationsListController(bundle: Bundle) :
private fun initOverallLayout(isConversationListNotEmpty: Boolean) { private fun initOverallLayout(isConversationListNotEmpty: Boolean) {
if (isConversationListNotEmpty) { if (isConversationListNotEmpty) {
if (binding.emptyLayout.visibility != View.GONE) { if (binding?.emptyLayout?.visibility != View.GONE) {
binding.emptyLayout.visibility = View.GONE binding?.emptyLayout?.visibility = View.GONE
} }
if (binding.swipeRefreshLayoutView.visibility != View.VISIBLE) { if (binding?.swipeRefreshLayoutView?.visibility != View.VISIBLE) {
binding.swipeRefreshLayoutView.visibility = View.VISIBLE binding?.swipeRefreshLayoutView?.visibility = View.VISIBLE
} }
} else { } else {
if (binding.emptyLayout.visibility != View.VISIBLE) { if (binding?.emptyLayout?.visibility != View.VISIBLE) {
binding.emptyLayout.visibility = View.VISIBLE binding?.emptyLayout?.visibility = View.VISIBLE
} }
if (binding.swipeRefreshLayoutView.visibility != View.GONE) { if (binding?.swipeRefreshLayoutView?.visibility != View.GONE) {
binding.swipeRefreshLayoutView.visibility = View.GONE binding?.swipeRefreshLayoutView?.visibility = View.GONE
} }
} }
} }
@ -584,7 +584,8 @@ class ConversationsListController(bundle: Bundle) :
} }
private fun showErrorDialog() { private fun showErrorDialog() {
val dialogBuilder = MaterialAlertDialogBuilder(binding.floatingActionButton.context) binding?.floatingActionButton?.let {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon( .setIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon( viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
context, context,
@ -594,12 +595,14 @@ class ConversationsListController(bundle: Bundle) :
.setTitle(R.string.error_loading_chats) .setTitle(R.string.error_loading_chats)
.setCancelable(false) .setCancelable(false)
.setNegativeButton(R.string.close, null) .setNegativeButton(R.string.close, null)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.floatingActionButton.context, dialogBuilder)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_NEGATIVE) dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
) )
} }
}
private fun sortConversations(conversationItems: MutableList<AbstractFlexibleItem<*>>) { private fun sortConversations(conversationItems: MutableList<AbstractFlexibleItem<*>>) {
conversationItems.sortWith { o1: AbstractFlexibleItem<*>, o2: AbstractFlexibleItem<*> -> conversationItems.sortWith { o1: AbstractFlexibleItem<*>, o2: AbstractFlexibleItem<*> ->
@ -678,10 +681,10 @@ class ConversationsListController(bundle: Bundle) :
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
private fun prepareViews() { private fun prepareViews() {
layoutManager = SmoothScrollLinearLayoutManager(Objects.requireNonNull(activity)) layoutManager = SmoothScrollLinearLayoutManager(Objects.requireNonNull(activity))
binding.recyclerView.layoutManager = layoutManager binding?.recyclerView?.layoutManager = layoutManager
binding.recyclerView.setHasFixedSize(true) binding?.recyclerView?.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding?.recyclerView?.adapter = adapter
binding.recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() { binding?.recyclerView?.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) { override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState) super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE) { if (newState == RecyclerView.SCROLL_STATE_IDLE) {
@ -689,21 +692,21 @@ class ConversationsListController(bundle: Bundle) :
} }
} }
}) })
binding.recyclerView.setOnTouchListener { v: View, _: MotionEvent? -> binding?.recyclerView?.setOnTouchListener { v: View, _: MotionEvent? ->
if (isAttached && (!isBeingDestroyed || !isDestroyed)) { if (isAttached && (!isBeingDestroyed || !isDestroyed)) {
val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager val imm = activity!!.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(v.windowToken, 0) imm.hideSoftInputFromWindow(v.windowToken, 0)
} }
false false
} }
binding.swipeRefreshLayoutView.setOnRefreshListener { fetchRooms() } binding?.swipeRefreshLayoutView?.setOnRefreshListener { fetchRooms() }
viewThemeUtils.androidx.themeSwipeRefreshLayout(binding.swipeRefreshLayoutView) binding?.swipeRefreshLayoutView?.let { viewThemeUtils.androidx.themeSwipeRefreshLayout(it) }
binding.emptyLayout.setOnClickListener { showNewConversationsScreen() } binding?.emptyLayout?.setOnClickListener { showNewConversationsScreen() }
binding.floatingActionButton.setOnClickListener { binding?.floatingActionButton?.setOnClickListener {
run(context) run(context)
showNewConversationsScreen() showNewConversationsScreen()
} }
viewThemeUtils.material.themeFAB(binding.floatingActionButton) binding?.floatingActionButton?.let { viewThemeUtils.material.themeFAB(it) }
if (activity != null && activity is MainActivity) { if (activity != null && activity is MainActivity) {
val activity = activity as MainActivity? val activity = activity as MainActivity?
activity!!.binding.switchAccountButton.setOnClickListener { activity!!.binding.switchAccountButton.setOnClickListener {
@ -722,13 +725,13 @@ class ConversationsListController(bundle: Bundle) :
} }
} }
} }
binding.newMentionPopupBubble.hide() binding?.newMentionPopupBubble?.hide()
binding.newMentionPopupBubble.setPopupBubbleListener { binding?.newMentionPopupBubble?.setPopupBubbleListener {
binding.recyclerView.smoothScrollToPosition( binding?.recyclerView?.smoothScrollToPosition(
nextUnreadConversationScrollPosition nextUnreadConversationScrollPosition
) )
} }
viewThemeUtils.material.colorMaterialButtonPrimaryFilled(binding.newMentionPopupBubble) binding?.newMentionPopupBubble?.let { viewThemeUtils.material.colorMaterialButtonPrimaryFilled(it) }
} }
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
@ -740,14 +743,14 @@ class ConversationsListController(bundle: Bundle) :
val position = adapter!!.getGlobalPositionOf(flexItem) val position = adapter!!.getGlobalPositionOf(flexItem)
if (hasUnreadItems(conversation) && position > lastVisibleItem) { if (hasUnreadItems(conversation) && position > lastVisibleItem) {
nextUnreadConversationScrollPosition = position nextUnreadConversationScrollPosition = position
if (!binding.newMentionPopupBubble.isShown) { if (!binding?.newMentionPopupBubble?.isShown!!) {
binding.newMentionPopupBubble.show() binding?.newMentionPopupBubble?.show()
} }
return return
} }
} }
nextUnreadConversationScrollPosition = 0 nextUnreadConversationScrollPosition = 0
binding.newMentionPopupBubble.hide() binding?.newMentionPopupBubble?.hide()
} catch (e: NullPointerException) { } catch (e: NullPointerException) {
Log.d( Log.d(
TAG, TAG,
@ -852,7 +855,7 @@ class ConversationsListController(bundle: Bundle) :
@SuppressLint("CheckResult") // handled by helper @SuppressLint("CheckResult") // handled by helper
private fun startMessageSearch(search: String?) { private fun startMessageSearch(search: String?) {
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = true binding?.swipeRefreshLayoutView?.isRefreshing = true
} }
searchHelper?.startMessageSearch(search!!) searchHelper?.startMessageSearch(search!!)
?.subscribeOn(Schedulers.io()) ?.subscribeOn(Schedulers.io())
@ -866,7 +869,7 @@ class ConversationsListController(bundle: Bundle) :
@SuppressLint("CheckResult") // handled by helper @SuppressLint("CheckResult") // handled by helper
private fun loadMoreMessages() { private fun loadMoreMessages() {
binding.swipeRefreshLayoutView.isRefreshing = true binding?.swipeRefreshLayoutView?.isRefreshing = true
val observable = searchHelper!!.loadMore() val observable = searchHelper!!.loadMore()
observable?.observeOn(AndroidSchedulers.mainThread()) observable?.observeOn(AndroidSchedulers.mainThread())
?.subscribe({ results: MessageSearchResults -> onMessageSearchResult(results) }) { throwable: Throwable -> ?.subscribe({ results: MessageSearchResults -> onMessageSearchResult(results) }) { throwable: Throwable ->
@ -977,7 +980,8 @@ class ConversationsListController(bundle: Bundle) :
selectedConversation!!.displayName selectedConversation!!.displayName
) )
} }
val dialogBuilder = MaterialAlertDialogBuilder(binding.floatingActionButton.context) binding?.floatingActionButton?.let {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.upload)) .setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.upload))
.setTitle(confirmationQuestion) .setTitle(confirmationQuestion)
.setMessage(fileNamesWithLineBreaks.toString()) .setMessage(fileNamesWithLineBreaks.toString())
@ -988,13 +992,15 @@ class ConversationsListController(bundle: Bundle) :
.setNegativeButton(R.string.nc_no) { _, _ -> .setNegativeButton(R.string.nc_no) { _, _ ->
Log.d(TAG, "sharing files aborted, going back to share-to screen") Log.d(TAG, "sharing files aborted, going back to share-to screen")
} }
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(binding.floatingActionButton.context, dialogBuilder) .colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE) dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
) )
}
} else { } else {
requestStoragePermission(this@ConversationsListController) requestStoragePermission(this@ConversationsListController)
} }
@ -1161,7 +1167,8 @@ class ConversationsListController(bundle: Bundle) :
) { ) {
val conversation = Parcels.unwrap<Conversation>(conversationMenuBundle!!.getParcelable(KEY_ROOM)) val conversation = Parcels.unwrap<Conversation>(conversationMenuBundle!!.getParcelable(KEY_ROOM))
if (conversation != null) { if (conversation != null) {
val dialogBuilder = MaterialAlertDialogBuilder(binding.floatingActionButton.context) binding?.floatingActionButton?.let {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon( .setIcon(
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp) .colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)
@ -1181,8 +1188,9 @@ class ConversationsListController(bundle: Bundle) :
.setNegativeButton(R.string.nc_cancel) { _, _ -> .setNegativeButton(R.string.nc_cancel) { _, _ ->
conversationMenuBundle = null conversationMenuBundle = null
} }
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(binding.floatingActionButton.context, dialogBuilder) .colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
@ -1191,6 +1199,7 @@ class ConversationsListController(bundle: Bundle) :
} }
} }
} }
}
private fun isInternalUserEqualsCurrentUser(currentUser: User?, conversationMenuBundle: Bundle?): Boolean { private fun isInternalUserEqualsCurrentUser(currentUser: User?, conversationMenuBundle: Bundle?): Boolean {
return currentUser != null && conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID) == currentUser.id return currentUser != null && conversationMenuBundle!!.getLong(KEY_INTERNAL_USER_ID) == currentUser.id
@ -1198,8 +1207,13 @@ class ConversationsListController(bundle: Bundle) :
private fun showUnauthorizedDialog() { private fun showUnauthorizedDialog() {
if (activity != null) { if (activity != null) {
val dialogBuilder = MaterialAlertDialogBuilder(binding.floatingActionButton.context) binding?.floatingActionButton?.let {
.setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_delete_black_24dp)) val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(
viewThemeUtils.dialog.colorMaterialAlertDialogIcon(
context, R.drawable.ic_delete_black_24dp
)
)
.setTitle(R.string.nc_dialog_invalid_password) .setTitle(R.string.nc_dialog_invalid_password)
.setMessage(R.string.nc_dialog_reauth_or_delete) .setMessage(R.string.nc_dialog_reauth_or_delete)
.setCancelable(false) .setCancelable(false)
@ -1229,8 +1243,9 @@ class ConversationsListController(bundle: Bundle) :
.popChangeHandler(VerticalChangeHandler()) .popChangeHandler(VerticalChangeHandler())
) )
} }
viewThemeUtils.dialog viewThemeUtils.dialog
.colorMaterialAlertDialogBackground(binding.floatingActionButton.context, dialogBuilder) .colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
@ -1238,9 +1253,11 @@ class ConversationsListController(bundle: Bundle) :
) )
} }
} }
}
private fun showServerEOLDialog() { private fun showServerEOLDialog() {
val dialogBuilder = MaterialAlertDialogBuilder(binding.floatingActionButton.context) binding?.floatingActionButton?.let {
val dialogBuilder = MaterialAlertDialogBuilder(it.context)
.setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_warning_white)) .setIcon(viewThemeUtils.dialog.colorMaterialAlertDialogIcon(context, R.drawable.ic_warning_white))
.setTitle(R.string.nc_settings_server_eol_title) .setTitle(R.string.nc_settings_server_eol_title)
.setMessage(R.string.nc_settings_server_eol) .setMessage(R.string.nc_settings_server_eol)
@ -1272,13 +1289,15 @@ class ConversationsListController(bundle: Bundle) :
activity!!.finish() activity!!.finish()
} }
} }
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(binding.floatingActionButton.context, dialogBuilder)
viewThemeUtils.dialog.colorMaterialAlertDialogBackground(it.context, dialogBuilder)
val dialog = dialogBuilder.show() val dialog = dialogBuilder.show()
viewThemeUtils.platform.colorTextButtons( viewThemeUtils.platform.colorTextButtons(
dialog.getButton(AlertDialog.BUTTON_POSITIVE), dialog.getButton(AlertDialog.BUTTON_POSITIVE),
dialog.getButton(AlertDialog.BUTTON_NEGATIVE) dialog.getButton(AlertDialog.BUTTON_NEGATIVE)
) )
} }
}
private fun deleteConversation(data: Data) { private fun deleteConversation(data: Data) {
val deleteConversationWorker = val deleteConversationWorker =
@ -1309,18 +1328,18 @@ class ConversationsListController(bundle: Bundle) :
} }
// add unified search result at the end of the list // add unified search result at the end of the list
adapter!!.addItems(adapter!!.mainItemCount + adapter!!.scrollableHeaders.size, adapterItems) adapter!!.addItems(adapter!!.mainItemCount + adapter!!.scrollableHeaders.size, adapterItems)
binding.recyclerView.scrollToPosition(0) binding?.recyclerView?.scrollToPosition(0)
} }
} }
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
} }
} }
private fun onMessageSearchError(throwable: Throwable) { private fun onMessageSearchError(throwable: Throwable) {
handleHttpExceptions(throwable) handleHttpExceptions(throwable)
withNullableControllerViewBinding { withNullableControllerViewBinding {
binding.swipeRefreshLayoutView.isRefreshing = false binding?.swipeRefreshLayoutView?.isRefreshing = false
showErrorDialog() showErrorDialog()
} }
} }

View file

@ -63,7 +63,7 @@ class GeocodingController(args: Bundle) :
args args
), ),
SearchView.OnQueryTextListener { SearchView.OnQueryTextListener {
private val binding: ControllerGeocodingBinding by viewBinding(ControllerGeocodingBinding::bind) private val binding: ControllerGeocodingBinding? by viewBinding(ControllerGeocodingBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -94,8 +94,8 @@ class GeocodingController(args: Bundle) :
} }
private fun initAdapter(addresses: List<Address>) { private fun initAdapter(addresses: List<Address>) {
adapter = GeocodingAdapter(binding.geocodingResults.context!!, addresses) adapter = GeocodingAdapter(binding?.geocodingResults?.context!!, addresses)
binding.geocodingResults.adapter = adapter binding?.geocodingResults?.adapter = adapter
} }
override fun onAttach(view: View) { override fun onAttach(view: View) {
@ -110,7 +110,7 @@ class GeocodingController(args: Bundle) :
Log.e(TAG, "search string that was passed to GeocodingController was null or empty") Log.e(TAG, "search string that was passed to GeocodingController was null or empty")
} }
binding.geocodingResults.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> binding?.geocodingResults?.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->
val address: Address = adapter.getItem(position) as Address val address: Address = adapter.getItem(position) as Address
val listener: GeocodingResultListener? = targetController as GeocodingResultListener? val listener: GeocodingResultListener? = targetController as GeocodingResultListener?
listener?.receiveChosenGeocodingResult(address.latitude, address.longitude, address.displayName) listener?.receiveChosenGeocodingResult(address.latitude, address.longitude, address.displayName)

View file

@ -90,7 +90,7 @@ class LocationPickerController(args: Bundle) :
SearchView.OnQueryTextListener, SearchView.OnQueryTextListener,
LocationListener, LocationListener,
GeocodingController.GeocodingResultListener { GeocodingController.GeocodingResultListener {
private val binding: ControllerLocationBinding by viewBinding(ControllerLocationBinding::bind) private val binding: ControllerLocationBinding? by viewBinding(ControllerLocationBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -164,13 +164,13 @@ class LocationPickerController(args: Bundle) :
override fun onViewBound(view: View) { override fun onViewBound(view: View) {
setLocationDescription(false, receivedChosenGeocodingResult) setLocationDescription(false, receivedChosenGeocodingResult)
binding.shareLocation.isClickable = false binding?.shareLocation?.isClickable = false
binding.shareLocation.setOnClickListener { binding?.shareLocation?.setOnClickListener {
if (readyToShareLocation) { if (readyToShareLocation) {
shareLocation( shareLocation(
binding.map.mapCenter?.latitude, binding?.map?.mapCenter?.latitude,
binding.map.mapCenter?.longitude, binding?.map?.mapCenter?.longitude,
binding.placeName.text.toString() binding?.placeName?.text.toString()
) )
} else { } else {
Log.w(TAG, "readyToShareLocation was false while user tried to share location.") Log.w(TAG, "readyToShareLocation was false while user tried to share location.")
@ -217,8 +217,8 @@ class LocationPickerController(args: Bundle) :
@Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod") @Suppress("Detekt.TooGenericExceptionCaught", "Detekt.ComplexMethod")
private fun initMap() { private fun initMap() {
binding.map.setTileSource(TileSourceFactory.MAPNIK) binding?.map?.setTileSource(TileSourceFactory.MAPNIK)
binding.map.onResume() binding?.map?.onResume()
locationManager = activity!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager locationManager = activity!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager
@ -229,12 +229,12 @@ class LocationPickerController(args: Bundle) :
} }
val copyrightOverlay = CopyrightOverlay(context) val copyrightOverlay = CopyrightOverlay(context)
binding.map.overlays?.add(copyrightOverlay) binding?.map?.overlays?.add(copyrightOverlay)
binding.map.setMultiTouchControls(true) binding?.map?.setMultiTouchControls(true)
binding.map.isTilesScaledToDpi = true binding?.map?.isTilesScaledToDpi = true
locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding.map) locationOverlay = MyLocationNewOverlay(GpsMyLocationProvider(context), binding?.map)
locationOverlay.enableMyLocation() locationOverlay.enableMyLocation()
locationOverlay.setPersonHotspot(PERSON_HOT_SPOT_X, PERSON_HOT_SPOT_Y) locationOverlay.setPersonHotspot(PERSON_HOT_SPOT_X, PERSON_HOT_SPOT_Y)
locationOverlay.setPersonIcon( locationOverlay.setPersonIcon(
@ -242,9 +242,9 @@ class LocationPickerController(args: Bundle) :
ResourcesCompat.getDrawable(resources!!, R.drawable.current_location_circle, null) ResourcesCompat.getDrawable(resources!!, R.drawable.current_location_circle, null)
) )
) )
binding.map.overlays?.add(locationOverlay) binding?.map?.overlays?.add(locationOverlay)
val mapController = binding.map.controller val mapController = binding?.map?.controller
if (receivedChosenGeocodingResult) { if (receivedChosenGeocodingResult) {
mapController?.setZoom(ZOOM_LEVEL_RECEIVED_RESULT) mapController?.setZoom(ZOOM_LEVEL_RECEIVED_RESULT)
@ -273,16 +273,16 @@ class LocationPickerController(args: Bundle) :
mapController?.setCenter(GeoPoint(geocodedLat, geocodedLon)) mapController?.setCenter(GeoPoint(geocodedLat, geocodedLon))
} }
binding.centerMapButton.setOnClickListener { binding?.centerMapButton?.setOnClickListener {
if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) { if (myLocation.latitude == COORDINATE_ZERO && myLocation.longitude == COORDINATE_ZERO) {
Toast.makeText(context, context?.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show() Toast.makeText(context, context.getString(R.string.nc_location_unknown), Toast.LENGTH_LONG).show()
} else { } else {
mapController?.animateTo(myLocation) mapController?.animateTo(myLocation)
moveToCurrentLocationWasClicked = true moveToCurrentLocationWasClicked = true
} }
} }
binding.map.addMapListener( binding?.map?.addMapListener(
delayedMapListener() delayedMapListener()
) )
} }
@ -298,12 +298,12 @@ class LocationPickerController(args: Bundle) :
moveToCurrentLocationWasClicked = false moveToCurrentLocationWasClicked = false
} }
receivedChosenGeocodingResult -> { receivedChosenGeocodingResult -> {
binding.shareLocation.isClickable = true binding?.shareLocation?.isClickable = true
setLocationDescription(isGpsLocation = false, isGeocodedResult = true) setLocationDescription(isGpsLocation = false, isGeocodedResult = true)
receivedChosenGeocodingResult = false receivedChosenGeocodingResult = false
} }
else -> { else -> {
binding.shareLocation.isClickable = true binding?.shareLocation?.isClickable = true
setLocationDescription(isGpsLocation = false, isGeocodedResult = false) setLocationDescription(isGpsLocation = false, isGeocodedResult = false)
} }
} }
@ -364,19 +364,19 @@ class LocationPickerController(args: Bundle) :
private fun setLocationDescription(isGpsLocation: Boolean, isGeocodedResult: Boolean) { private fun setLocationDescription(isGpsLocation: Boolean, isGeocodedResult: Boolean) {
when { when {
isGpsLocation -> { isGpsLocation -> {
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_current_location) binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_current_location)
binding.placeName.visibility = View.GONE binding?.placeName?.visibility = View.GONE
binding.placeName.text = "" binding?.placeName?.text = ""
} }
isGeocodedResult -> { isGeocodedResult -> {
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location)
binding.placeName.visibility = View.VISIBLE binding?.placeName?.visibility = View.VISIBLE
binding.placeName.text = geocodedName binding?.placeName?.text = geocodedName
} }
else -> { else -> {
binding.shareLocationDescription.text = context!!.getText(R.string.nc_share_this_location) binding?.shareLocationDescription?.text = context!!.getText(R.string.nc_share_this_location)
binding.placeName.visibility = View.GONE binding?.placeName?.visibility = View.GONE
binding.placeName.text = "" binding?.placeName?.text = ""
} }
} }
} }

View file

@ -47,7 +47,7 @@ import java.util.concurrent.Executors
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class LockedController : BaseController(R.layout.controller_locked) { class LockedController : BaseController(R.layout.controller_locked) {
private val binding: ControllerLockedBinding by viewBinding(ControllerLockedBinding::bind) private val binding: ControllerLockedBinding? by viewBinding(ControllerLockedBinding::bind)
override val appBarLayoutType: AppBarLayoutType override val appBarLayoutType: AppBarLayoutType
get() = AppBarLayoutType.EMPTY get() = AppBarLayoutType.EMPTY
@ -60,7 +60,7 @@ class LockedController : BaseController(R.layout.controller_locked) {
override fun onViewBound(view: View) { override fun onViewBound(view: View) {
super.onViewBound(view) super.onViewBound(view)
sharedApplication!!.componentApplication.inject(this) sharedApplication!!.componentApplication.inject(this)
binding.unlockContainer.setOnClickListener { binding?.unlockContainer?.setOnClickListener {
unlock() unlock()
} }
} }

View file

@ -96,7 +96,7 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
@Suppress("Detekt.TooManyFunctions") @Suppress("Detekt.TooManyFunctions")
class ProfileController : BaseController(R.layout.controller_profile) { class ProfileController : BaseController(R.layout.controller_profile) {
private val binding: ControllerProfileBinding by viewBinding(ControllerProfileBinding::bind) private val binding: ControllerProfileBinding? by viewBinding(ControllerProfileBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -146,11 +146,11 @@ class ProfileController : BaseController(R.layout.controller_profile) {
edit = !edit edit = !edit
if (edit) { if (edit) {
item.setTitle(R.string.save) item.setTitle(R.string.save)
binding.emptyList.root.visibility = View.GONE binding?.emptyList?.root?.visibility = View.GONE
binding.userinfoList.visibility = View.VISIBLE binding?.userinfoList?.visibility = View.VISIBLE
if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) { if (CapabilitiesUtilNew.isAvatarEndpointAvailable(currentUser!!)) {
// TODO later avatar can also be checked via user fields, for now it is in Talk capability // TODO later avatar can also be checked via user fields, for now it is in Talk capability
binding.avatarButtons.visibility = View.VISIBLE binding?.avatarButtons?.visibility = View.VISIBLE
} }
ncApi.getEditableUserProfileFields( ncApi.getEditableUserProfileFields(
ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token), ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token),
@ -179,10 +179,10 @@ class ProfileController : BaseController(R.layout.controller_profile) {
}) })
} else { } else {
item.setTitle(R.string.edit) item.setTitle(R.string.edit)
binding.avatarButtons.visibility = View.INVISIBLE binding?.avatarButtons?.visibility = View.INVISIBLE
if (adapter!!.filteredDisplayList.isEmpty()) { if (adapter!!.filteredDisplayList.isEmpty()) {
binding.emptyList.root.visibility = View.VISIBLE binding?.emptyList?.root?.visibility = View.VISIBLE
binding.userinfoList.visibility = View.GONE binding?.userinfoList?.visibility = View.GONE
} }
} }
adapter!!.notifyDataSetChanged() adapter!!.notifyDataSetChanged()
@ -194,14 +194,14 @@ class ProfileController : BaseController(R.layout.controller_profile) {
override fun onAttach(view: View) { override fun onAttach(view: View) {
super.onAttach(view) super.onAttach(view)
adapter = UserInfoAdapter(null, viewThemeUtils, this) adapter = UserInfoAdapter(null, viewThemeUtils, this)
binding.userinfoList.adapter = adapter binding?.userinfoList?.adapter = adapter
binding.userinfoList.setItemViewCacheSize(DEFAULT_CACHE_SIZE) binding?.userinfoList?.setItemViewCacheSize(DEFAULT_CACHE_SIZE)
currentUser = userManager.currentUser.blockingGet() currentUser = userManager.currentUser.blockingGet()
val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token) val credentials = ApiUtils.getCredentials(currentUser!!.username, currentUser!!.token)
binding.avatarUpload.setOnClickListener { sendSelectLocalFileIntent() } binding?.avatarUpload?.setOnClickListener { sendSelectLocalFileIntent() }
binding.avatarChoose.setOnClickListener { showBrowserScreen() } binding?.avatarChoose?.setOnClickListener { showBrowserScreen() }
binding.avatarCamera.setOnClickListener { checkPermissionAndTakePicture() } binding?.avatarCamera?.setOnClickListener { checkPermissionAndTakePicture() }
binding.avatarDelete.setOnClickListener { binding?.avatarDelete?.setOnClickListener {
ncApi.deleteAvatar( ncApi.deleteAvatar(
credentials, credentials,
ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl) ApiUtils.getUrlForTempAvatar(currentUser!!.baseUrl)
@ -216,7 +216,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
override fun onNext(genericOverall: GenericOverall) { override fun onNext(genericOverall: GenericOverall) {
DisplayUtils.loadAvatarImage( DisplayUtils.loadAvatarImage(
currentUser, currentUser,
binding.avatarImage, binding?.avatarImage,
true true
) )
} }
@ -230,7 +230,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
}) })
} }
ViewCompat.setTransitionName(binding.avatarImage, "userAvatar.transitionTag") binding?.avatarImage?.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") }
ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl)) ncApi.getUserProfile(credentials, ApiUtils.getUrlForUserProfile(currentUser!!.baseUrl))
.retry(DEFAULT_RETRIES) .retry(DEFAULT_RETRIES)
.subscribeOn(Schedulers.io()) .subscribeOn(Schedulers.io())
@ -262,10 +262,12 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
private fun colorIcons() { private fun colorIcons() {
viewThemeUtils.material.themeFAB(binding.avatarChoose) binding?.let {
viewThemeUtils.material.themeFAB(binding.avatarCamera) viewThemeUtils.material.themeFAB(it.avatarChoose)
viewThemeUtils.material.themeFAB(binding.avatarUpload) viewThemeUtils.material.themeFAB(it.avatarCamera)
viewThemeUtils.material.themeFAB(binding.avatarDelete) viewThemeUtils.material.themeFAB(it.avatarUpload)
viewThemeUtils.material.themeFAB(it.avatarDelete)
}
} }
private fun isAllEmpty(items: Array<String?>): Boolean { private fun isAllEmpty(items: Array<String?>): Boolean {
@ -283,13 +285,13 @@ class ProfileController : BaseController(R.layout.controller_profile) {
return return
} }
if (currentUser!!.baseUrl != null) { if (currentUser!!.baseUrl != null) {
binding.userinfoBaseurl.text = Uri.parse(currentUser!!.baseUrl).host binding?.userinfoBaseurl?.text = Uri.parse(currentUser!!.baseUrl).host
} }
DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false) DisplayUtils.loadAvatarImage(currentUser, binding?.avatarImage, false)
if (!TextUtils.isEmpty(userInfo?.displayName)) { if (!TextUtils.isEmpty(userInfo?.displayName)) {
binding.userinfoFullName.text = userInfo?.displayName binding?.userinfoFullName?.text = userInfo?.displayName
} }
binding.loadingContent.visibility = View.VISIBLE binding?.loadingContent?.visibility = View.VISIBLE
adapter!!.setData(createUserInfoDetails(userInfo)) adapter!!.setData(createUserInfoDetails(userInfo))
if (isAllEmpty( if (isAllEmpty(
arrayOf( arrayOf(
@ -302,18 +304,18 @@ class ProfileController : BaseController(R.layout.controller_profile) {
) )
) )
) { ) {
binding.userinfoList.visibility = View.GONE binding?.userinfoList?.visibility = View.GONE
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
binding.emptyList.root.visibility = View.VISIBLE binding?.emptyList?.root?.visibility = View.VISIBLE
setErrorMessageForMultiList( setErrorMessageForMultiList(
activity!!.getString(R.string.userinfo_no_info_headline), activity!!.getString(R.string.userinfo_no_info_headline),
activity!!.getString(R.string.userinfo_no_info_text), activity!!.getString(R.string.userinfo_no_info_text),
R.drawable.ic_user R.drawable.ic_user
) )
} else { } else {
binding.emptyList.root.visibility = View.GONE binding?.emptyList?.root?.visibility = View.GONE
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
binding.userinfoList.visibility = View.VISIBLE binding?.userinfoList?.visibility = View.VISIBLE
} }
// show edit button // show edit button
@ -354,13 +356,13 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
try { try {
binding.emptyList.emptyListViewHeadline.text = headline binding?.emptyList?.emptyListViewHeadline?.text = headline
binding.emptyList.emptyListViewText.text = message binding?.emptyList?.emptyListViewText?.text = message
binding.emptyList.emptyListIcon.setImageResource(errorResource) binding?.emptyList?.emptyListIcon?.setImageResource(errorResource)
binding.emptyList.emptyListIcon.visibility = View.VISIBLE binding?.emptyList?.emptyListIcon?.visibility = View.VISIBLE
binding.emptyList.emptyListViewText.visibility = View.VISIBLE binding?.emptyList?.emptyListViewText?.visibility = View.VISIBLE
binding.userinfoList.visibility = View.GONE binding?.userinfoList?.visibility = View.GONE
binding.loadingContent.visibility = View.GONE binding?.loadingContent?.visibility = View.GONE
} catch (npe: NullPointerException) { } catch (npe: NullPointerException) {
// view binding can be null // view binding can be null
// since this is called asynchronously and UI might have been destroyed in the meantime // since this is called asynchronously and UI might have been destroyed in the meantime
@ -453,7 +455,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
override fun onNext(userProfileOverall: GenericOverall) { override fun onNext(userProfileOverall: GenericOverall) {
Log.d(TAG, "Successfully saved: " + item.text + " as " + item.field) Log.d(TAG, "Successfully saved: " + item.text + " as " + item.field)
if (item.field == Field.DISPLAYNAME) { if (item.field == Field.DISPLAYNAME) {
binding.userinfoFullName.text = item.text binding?.userinfoFullName?.text = item.text
} }
} }
@ -646,7 +648,7 @@ class ProfileController : BaseController(R.layout.controller_profile) {
} }
override fun onNext(genericOverall: GenericOverall) { override fun onNext(genericOverall: GenericOverall) {
DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, true) DisplayUtils.loadAvatarImage(currentUser, binding?.avatarImage, true)
} }
override fun onError(e: Throwable) { override fun onError(e: Throwable) {

View file

@ -57,7 +57,7 @@ class RingtoneSelectionController(args: Bundle) :
args args
), ),
FlexibleAdapter.OnItemClickListener { FlexibleAdapter.OnItemClickListener {
private val binding: ControllerGenericRvBinding by viewBinding(ControllerGenericRvBinding::bind) private val binding: ControllerGenericRvBinding? by viewBinding(ControllerGenericRvBinding::bind)
private var adapter: FlexibleAdapter<*>? = null private var adapter: FlexibleAdapter<*>? = null
private var adapterDataObserver: RecyclerView.AdapterDataObserver? = null private var adapterDataObserver: RecyclerView.AdapterDataObserver? = null
@ -89,9 +89,9 @@ class RingtoneSelectionController(args: Bundle) :
private fun prepareViews() { private fun prepareViews() {
val layoutManager: RecyclerView.LayoutManager = SmoothScrollLinearLayoutManager(activity) val layoutManager: RecyclerView.LayoutManager = SmoothScrollLinearLayoutManager(activity)
binding.recyclerView.layoutManager = layoutManager binding?.recyclerView?.layoutManager = layoutManager
binding.recyclerView.setHasFixedSize(true) binding?.recyclerView?.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding?.recyclerView?.adapter = adapter
adapterDataObserver = object : RecyclerView.AdapterDataObserver() { adapterDataObserver = object : RecyclerView.AdapterDataObserver() {
override fun onChanged() { override fun onChanged() {
super.onChanged() super.onChanged()
@ -99,7 +99,7 @@ class RingtoneSelectionController(args: Bundle) :
} }
} }
adapter!!.registerAdapterDataObserver(adapterDataObserver!!) adapter!!.registerAdapterDataObserver(adapterDataObserver!!)
binding.swipeRefreshLayout.isEnabled = false binding?.swipeRefreshLayout?.isEnabled = false
} }
@SuppressLint("LongLogTag") @SuppressLint("LongLogTag")

View file

@ -63,7 +63,7 @@ import javax.inject.Inject
class ServerSelectionController : class ServerSelectionController :
BaseController(R.layout.controller_server_selection) { BaseController(R.layout.controller_server_selection) {
private val binding: ControllerServerSelectionBinding by viewBinding(ControllerServerSelectionBinding::bind) private val binding: ControllerServerSelectionBinding? by viewBinding(ControllerServerSelectionBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -99,14 +99,14 @@ class ServerSelectionController :
actionBar?.hide() actionBar?.hide()
binding.hostUrlInputHelperText.text = String.format( binding?.hostUrlInputHelperText?.text = String.format(
resources!!.getString(R.string.nc_server_helper_text), resources!!.getString(R.string.nc_server_helper_text),
resources!!.getString(R.string.nc_server_product_name) resources!!.getString(R.string.nc_server_product_name)
) )
binding.serverEntryTextInputLayout.setEndIconOnClickListener { checkServerAndProceed() } binding?.serverEntryTextInputLayout?.setEndIconOnClickListener { checkServerAndProceed() }
if (resources!!.getBoolean(R.bool.hide_auth_cert)) { if (resources!!.getBoolean(R.bool.hide_auth_cert)) {
binding.certTextView.visibility = View.GONE binding?.certTextView?.visibility = View.GONE
} }
val loggedInUsers = userManager.users.blockingGet() val loggedInUsers = userManager.users.blockingGet()
@ -117,21 +117,21 @@ class ServerSelectionController :
} else if (isAbleToShowProviderLink() && loggedInUsers.isEmpty()) { } else if (isAbleToShowProviderLink() && loggedInUsers.isEmpty()) {
showVisitProvidersInfo() showVisitProvidersInfo()
} else { } else {
binding.importOrChooseProviderText.visibility = View.INVISIBLE binding?.importOrChooseProviderText?.visibility = View.INVISIBLE
} }
binding.serverEntryTextInputEditText.requestFocus() binding?.serverEntryTextInputEditText?.requestFocus()
if (!TextUtils.isEmpty(resources!!.getString(R.string.weblogin_url))) { if (!TextUtils.isEmpty(resources!!.getString(R.string.weblogin_url))) {
binding.serverEntryTextInputEditText.setText(resources!!.getString(R.string.weblogin_url)) binding?.serverEntryTextInputEditText?.setText(resources!!.getString(R.string.weblogin_url))
checkServerAndProceed() checkServerAndProceed()
} }
binding.serverEntryTextInputEditText.setOnEditorActionListener { _: TextView?, i: Int, _: KeyEvent? -> binding?.serverEntryTextInputEditText?.setOnEditorActionListener { _: TextView?, i: Int, _: KeyEvent? ->
if (i == EditorInfo.IME_ACTION_DONE) { if (i == EditorInfo.IME_ACTION_DONE) {
checkServerAndProceed() checkServerAndProceed()
} }
false false
} }
binding.certTextView.setOnClickListener { onCertClick() } binding?.certTextView?.setOnClickListener { onCertClick() }
} }
private fun isAbleToShowProviderLink(): Boolean { private fun isAbleToShowProviderLink(): Boolean {
@ -145,25 +145,26 @@ class ServerSelectionController :
) )
) { ) {
if (availableAccounts.size > 1) { if (availableAccounts.size > 1) {
binding.importOrChooseProviderText.text = String.format( binding?.importOrChooseProviderText?.text = String.format(
resources!!.getString(R.string.nc_server_import_accounts), resources!!.getString(R.string.nc_server_import_accounts),
AccountUtils.getAppNameBasedOnPackage(resources!!.getString(R.string.nc_import_accounts_from)) AccountUtils.getAppNameBasedOnPackage(resources!!.getString(R.string.nc_import_accounts_from))
) )
} else { } else {
binding.importOrChooseProviderText.text = String.format( binding?.importOrChooseProviderText?.text = String.format(
resources!!.getString(R.string.nc_server_import_account), resources!!.getString(R.string.nc_server_import_account),
AccountUtils.getAppNameBasedOnPackage(resources!!.getString(R.string.nc_import_accounts_from)) AccountUtils.getAppNameBasedOnPackage(resources!!.getString(R.string.nc_import_accounts_from))
) )
} }
} else { } else {
if (availableAccounts.size > 1) { if (availableAccounts.size > 1) {
binding.importOrChooseProviderText.text = binding?.importOrChooseProviderText?.text =
resources!!.getString(R.string.nc_server_import_accounts_plain) resources!!.getString(R.string.nc_server_import_accounts_plain)
} else { } else {
binding.importOrChooseProviderText.text = resources!!.getString(R.string.nc_server_import_account_plain) binding?.importOrChooseProviderText?.text =
resources!!.getString(R.string.nc_server_import_account_plain)
} }
} }
binding.importOrChooseProviderText.setOnClickListener { binding?.importOrChooseProviderText?.setOnClickListener {
val bundle = Bundle() val bundle = Bundle()
bundle.putBoolean(KEY_IS_ACCOUNT_IMPORT, true) bundle.putBoolean(KEY_IS_ACCOUNT_IMPORT, true)
router.pushController( router.pushController(
@ -177,8 +178,8 @@ class ServerSelectionController :
} }
private fun showVisitProvidersInfo() { private fun showVisitProvidersInfo() {
binding.importOrChooseProviderText.setText(R.string.nc_get_from_provider) binding?.importOrChooseProviderText?.setText(R.string.nc_get_from_provider)
binding.importOrChooseProviderText.setOnClickListener { binding?.importOrChooseProviderText?.setOnClickListener {
val browserIntent = Intent( val browserIntent = Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
Uri.parse( Uri.parse(
@ -199,12 +200,12 @@ class ServerSelectionController :
private fun checkServerAndProceed() { private fun checkServerAndProceed() {
dispose() dispose()
try { try {
var url: String = binding.serverEntryTextInputEditText.text.toString().trim { it <= ' ' } var url: String = binding?.serverEntryTextInputEditText?.text.toString().trim { it <= ' ' }
binding.serverEntryTextInputEditText.isEnabled = false binding?.serverEntryTextInputEditText?.isEnabled = false
showserverEntryProgressBar() showserverEntryProgressBar()
if (binding.importOrChooseProviderText.visibility != View.INVISIBLE) { if (binding?.importOrChooseProviderText?.visibility != View.INVISIBLE) {
binding.importOrChooseProviderText.visibility = View.INVISIBLE binding?.importOrChooseProviderText?.visibility = View.INVISIBLE
binding.certTextView.visibility = View.INVISIBLE binding?.certTextView?.visibility = View.INVISIBLE
} }
if (url.endsWith("/")) { if (url.endsWith("/")) {
url = url.substring(0, url.length - 1) url = url.substring(0, url.length - 1)
@ -282,19 +283,19 @@ class ServerSelectionController :
hideserverEntryProgressBar() hideserverEntryProgressBar()
} }
binding.serverEntryTextInputEditText.isEnabled = true binding?.serverEntryTextInputEditText?.isEnabled = true
if (binding.importOrChooseProviderText.visibility != View.INVISIBLE) { if (binding?.importOrChooseProviderText?.visibility != View.INVISIBLE) {
binding.importOrChooseProviderText.visibility = View.VISIBLE binding?.importOrChooseProviderText?.visibility = View.VISIBLE
binding.certTextView.visibility = View.VISIBLE binding?.certTextView?.visibility = View.VISIBLE
} }
dispose() dispose()
} }
}) { }) {
hideserverEntryProgressBar() hideserverEntryProgressBar()
if (binding.importOrChooseProviderText.visibility != View.INVISIBLE) { if (binding?.importOrChooseProviderText?.visibility != View.INVISIBLE) {
binding.importOrChooseProviderText.visibility = View.VISIBLE binding?.importOrChooseProviderText?.visibility = View.VISIBLE
binding.certTextView.visibility = View.VISIBLE binding?.certTextView?.visibility = View.VISIBLE
} }
dispose() dispose()
} }
@ -305,19 +306,19 @@ class ServerSelectionController :
} }
private fun setErrorText(text: String) { private fun setErrorText(text: String) {
binding.errorText.text = text binding?.errorText?.text = text
binding.errorText.visibility = View.VISIBLE binding?.errorText?.visibility = View.VISIBLE
binding.serverEntryProgressBar.visibility = View.GONE binding?.serverEntryProgressBar?.visibility = View.GONE
} }
private fun showserverEntryProgressBar() { private fun showserverEntryProgressBar() {
binding.errorText.visibility = View.GONE binding?.errorText?.visibility = View.GONE
binding.serverEntryProgressBar.visibility = View.VISIBLE binding?.serverEntryProgressBar?.visibility = View.VISIBLE
} }
private fun hideserverEntryProgressBar() { private fun hideserverEntryProgressBar() {
binding.errorText.visibility = View.GONE binding?.errorText?.visibility = View.GONE
binding.serverEntryProgressBar.visibility = View.INVISIBLE binding?.serverEntryProgressBar?.visibility = View.INVISIBLE
} }
override fun onAttach(view: View) { override fun onAttach(view: View) {
@ -358,9 +359,9 @@ class ServerSelectionController :
activity!!.runOnUiThread { activity!!.runOnUiThread {
try { try {
if (!TextUtils.isEmpty(appPreferences!!.temporaryClientCertAlias)) { if (!TextUtils.isEmpty(appPreferences!!.temporaryClientCertAlias)) {
binding.certTextView.setText(R.string.nc_change_cert_auth) binding?.certTextView?.setText(R.string.nc_change_cert_auth)
} else { } else {
binding.certTextView.setText(R.string.nc_configure_cert_auth) binding?.certTextView?.setText(R.string.nc_configure_cert_auth)
} }
hideserverEntryProgressBar() hideserverEntryProgressBar()
} catch (npe: java.lang.NullPointerException) { } catch (npe: java.lang.NullPointerException) {

View file

@ -106,7 +106,7 @@ import javax.inject.Inject
@AutoInjector(NextcloudTalkApplication::class) @AutoInjector(NextcloudTalkApplication::class)
class SettingsController : BaseController(R.layout.controller_settings) { class SettingsController : BaseController(R.layout.controller_settings) {
private val binding: ControllerSettingsBinding by viewBinding(ControllerSettingsBinding::bind) private val binding: ControllerSettingsBinding? by viewBinding(ControllerSettingsBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -144,7 +144,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
setHasOptionsMenu(true) setHasOptionsMenu(true)
sharedApplication!!.componentApplication.inject(this) sharedApplication!!.componentApplication.inject(this)
ViewCompat.setTransitionName((binding.avatarImage), "userAvatar.transitionTag") binding?.avatarImage?.let { ViewCompat.setTransitionName(it, "userAvatar.transitionTag") }
getCurrentUser() getCurrentUser()
@ -154,10 +154,10 @@ class SettingsController : BaseController(R.layout.controller_settings) {
setupLicenceSetting() setupLicenceSetting()
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
binding.settingsIncognitoKeyboard.visibility = View.GONE binding?.settingsIncognitoKeyboard?.visibility = View.GONE
} }
binding.settingsScreenLock.setSummary( binding?.settingsScreenLock?.setSummary(
String.format( String.format(
Locale.getDefault(), Locale.getDefault(),
resources!!.getString(R.string.nc_settings_screen_lock_desc), resources!!.getString(R.string.nc_settings_screen_lock_desc),
@ -167,7 +167,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
setupPrivacyUrl() setupPrivacyUrl()
setupSourceCodeUrl() setupSourceCodeUrl()
binding.settingsVersion.setSummary("v" + BuildConfig.VERSION_NAME) binding?.settingsVersion?.setSummary("v" + BuildConfig.VERSION_NAME)
setupSoundSettings() setupSoundSettings()
@ -178,15 +178,15 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private fun setupPhoneBookIntegration() { private fun setupPhoneBookIntegration() {
if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser!!)) { if (CapabilitiesUtilNew.isPhoneBookIntegrationAvailable(currentUser!!)) {
binding.settingsPhoneBookIntegration.visibility = View.VISIBLE binding?.settingsPhoneBookIntegration?.visibility = View.VISIBLE
} else { } else {
binding.settingsPhoneBookIntegration.visibility = View.GONE binding?.settingsPhoneBookIntegration?.visibility = View.GONE
} }
} }
private fun setupSoundSettings() { private fun setupSoundSettings() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
binding.settingsCallSound.setOnClickListener { binding?.settingsCallSound?.setOnClickListener {
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID) intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
intent.putExtra( intent.putExtra(
@ -196,7 +196,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
startActivity(intent) startActivity(intent)
} }
binding.settingsMessageSound.setOnClickListener { binding?.settingsMessageSound?.setOnClickListener {
val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS) val intent = Intent(Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS)
intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID) intent.putExtra(Settings.EXTRA_APP_PACKAGE, BuildConfig.APPLICATION_ID)
intent.putExtra( intent.putExtra(
@ -206,7 +206,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
startActivity(intent) startActivity(intent)
} }
} else { } else {
binding.settingsCallSound.setOnClickListener { binding?.settingsCallSound?.setOnClickListener {
val bundle = Bundle() val bundle = Bundle()
bundle.putBoolean(KEY_ARE_CALL_SOUNDS, true) bundle.putBoolean(KEY_ARE_CALL_SOUNDS, true)
@ -216,7 +216,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
.popChangeHandler(HorizontalChangeHandler()) .popChangeHandler(HorizontalChangeHandler())
) )
} }
binding.settingsMessageSound.setOnClickListener { binding?.settingsMessageSound?.setOnClickListener {
val bundle = Bundle() val bundle = Bundle()
bundle.putBoolean(KEY_ARE_CALL_SOUNDS, false) bundle.putBoolean(KEY_ARE_CALL_SOUNDS, false)
@ -231,7 +231,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private fun setupSourceCodeUrl() { private fun setupSourceCodeUrl() {
if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_source_code_url))) { if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_source_code_url))) {
binding.settingsSourceCode.addPreferenceClickListener { binding?.settingsSourceCode?.addPreferenceClickListener {
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
@ -240,13 +240,13 @@ class SettingsController : BaseController(R.layout.controller_settings) {
) )
} }
} else { } else {
binding.settingsSourceCode.visibility = View.GONE binding?.settingsSourceCode?.visibility = View.GONE
} }
} }
private fun setupPrivacyUrl() { private fun setupPrivacyUrl() {
if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_privacy_url))) { if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_privacy_url))) {
binding.settingsPrivacy.addPreferenceClickListener { binding?.settingsPrivacy?.addPreferenceClickListener {
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
@ -255,13 +255,13 @@ class SettingsController : BaseController(R.layout.controller_settings) {
) )
} }
} else { } else {
binding.settingsPrivacy.visibility = View.GONE binding?.settingsPrivacy?.visibility = View.GONE
} }
} }
private fun setupLicenceSetting() { private fun setupLicenceSetting() {
if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_gpl3_url))) { if (!TextUtils.isEmpty(resources!!.getString(R.string.nc_gpl3_url))) {
binding.settingsLicence.addPreferenceClickListener { binding?.settingsLicence?.addPreferenceClickListener {
startActivity( startActivity(
Intent( Intent(
Intent.ACTION_VIEW, Intent.ACTION_VIEW,
@ -270,15 +270,15 @@ class SettingsController : BaseController(R.layout.controller_settings) {
) )
} }
} else { } else {
binding.settingsLicence.visibility = View.GONE binding?.settingsLicence?.visibility = View.GONE
} }
} }
private fun setupSettingsScreen() { private fun setupSettingsScreen() {
val listWithIntFields: MutableList<String> = ArrayList() val listWithIntFields: MutableList<String> = ArrayList()
listWithIntFields.add("proxy_port") listWithIntFields.add("proxy_port")
binding.settingsScreen.setUserInputModule(MagicUserInputModule(activity, listWithIntFields)) binding?.settingsScreen?.setUserInputModule(MagicUserInputModule(activity, listWithIntFields))
binding.settingsScreen.setVisibilityController( binding?.settingsScreen?.setVisibilityController(
R.id.settings_proxy_use_credentials, R.id.settings_proxy_use_credentials,
Arrays.asList(R.id.settings_proxy_username_edit, R.id.settings_proxy_password_edit), Arrays.asList(R.id.settings_proxy_username_edit, R.id.settings_proxy_password_edit),
true true
@ -297,7 +297,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
Log.e(TAG, "Failed to create uri") Log.e(TAG, "Failed to create uri")
} }
binding.settingsClientCert.addPreferenceClickListener { binding?.settingsClientCert?.addPreferenceClickListener {
KeyChain.choosePrivateKeyAlias( KeyChain.choosePrivateKeyAlias(
activity!!, activity!!,
{ alias: String? -> { alias: String? ->
@ -305,9 +305,9 @@ class SettingsController : BaseController(R.layout.controller_settings) {
activity!!.runOnUiThread { activity!!.runOnUiThread {
if (finalAlias != null) { if (finalAlias != null) {
binding.settingsClientCert.setTitle(R.string.nc_client_cert_change) binding?.settingsClientCert?.setTitle(R.string.nc_client_cert_change)
} else { } else {
binding.settingsClientCert.setTitle(R.string.nc_client_cert_setup) binding?.settingsClientCert?.setTitle(R.string.nc_client_cert_setup)
} }
} }
@ -370,7 +370,8 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private fun showRemoveAccountWarning() { private fun showRemoveAccountWarning() {
if (activity != null) { if (activity != null) {
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(binding.messageText.context) binding?.messageText?.context?.let {
val materialAlertDialogBuilder = MaterialAlertDialogBuilder(it)
.setTitle(R.string.nc_settings_remove_account) .setTitle(R.string.nc_settings_remove_account)
.setMessage(R.string.nc_settings_remove_confirmation) .setMessage(R.string.nc_settings_remove_confirmation)
.setPositiveButton(R.string.nc_settings_remove) { _, _ -> .setPositiveButton(R.string.nc_settings_remove) { _, _ ->
@ -381,7 +382,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} }
viewThemeUtils.dialog.colorMaterialAlertDialogBackground( viewThemeUtils.dialog.colorMaterialAlertDialogBackground(
binding.messageText.context, it,
materialAlertDialogBuilder materialAlertDialogBuilder
) )
@ -393,6 +394,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
) )
} }
} }
}
private fun removeCurrentAccount() { private fun removeCurrentAccount() {
val otherUserExists = userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet() val otherUserExists = userManager.scheduleUserForDeletionWithId(currentUser!!.id!!).blockingGet()
@ -428,38 +430,38 @@ class SettingsController : BaseController(R.layout.controller_settings) {
actionBar?.show() actionBar?.show()
dispose(null) dispose(null)
binding.settingsVersion.setOnClickListener { binding?.settingsVersion?.setOnClickListener {
sendLogs() sendLogs()
} }
if (!TextUtils.isEmpty(currentUser!!.clientCertificate)) { if (!TextUtils.isEmpty(currentUser!!.clientCertificate)) {
binding.settingsClientCert.setTitle(R.string.nc_client_cert_change) binding?.settingsClientCert?.setTitle(R.string.nc_client_cert_change)
} else { } else {
binding.settingsClientCert.setTitle(R.string.nc_client_cert_setup) binding?.settingsClientCert?.setTitle(R.string.nc_client_cert_setup)
} }
setupCheckables() setupCheckables()
setupScreenLockSetting() setupScreenLockSetting()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
binding.settingsNotificationsCategory.setTitle( binding?.settingsNotificationsCategory?.setTitle(
resources!!.getString(R.string.nc_settings_notification_sounds_post_oreo) resources!!.getString(R.string.nc_settings_notification_sounds_post_oreo)
) )
} }
val callRingtoneUri = getCallRingtoneUri(view.context, (appPreferences)!!) val callRingtoneUri = getCallRingtoneUri(view.context, (appPreferences)!!)
binding.settingsCallSound.setSummary(getRingtoneName(view.context, callRingtoneUri)) binding?.settingsCallSound?.setSummary(getRingtoneName(view.context, callRingtoneUri))
val messageRingtoneUri = getMessageRingtoneUri(view.context, (appPreferences)!!) val messageRingtoneUri = getMessageRingtoneUri(view.context, (appPreferences)!!)
binding.settingsMessageSound.setSummary(getRingtoneName(view.context, messageRingtoneUri)) binding?.settingsMessageSound?.setSummary(getRingtoneName(view.context, messageRingtoneUri))
setupProxyTypeSettings() setupProxyTypeSettings()
setupProxyCredentialSettings() setupProxyCredentialSettings()
if (currentUser != null) { if (currentUser != null) {
binding.baseUrlText.text = Uri.parse(currentUser!!.baseUrl).host binding?.baseUrlText?.text = Uri.parse(currentUser!!.baseUrl).host
setupServerAgeWarning() setupServerAgeWarning()
binding.settingsReauthorize.addPreferenceClickListener { binding?.settingsReauthorize?.addPreferenceClickListener {
router.pushController( router.pushController(
RouterTransaction.with(WebViewLoginController(currentUser!!.baseUrl, true)) RouterTransaction.with(WebViewLoginController(currentUser!!.baseUrl, true))
.pushChangeHandler(VerticalChangeHandler()) .pushChangeHandler(VerticalChangeHandler())
@ -468,19 +470,19 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} }
if (currentUser!!.displayName != null) { if (currentUser!!.displayName != null) {
binding.displayNameText.text = currentUser!!.displayName binding?.displayNameText?.text = currentUser!!.displayName
} }
DisplayUtils.loadAvatarImage(currentUser, binding.avatarImage, false) DisplayUtils.loadAvatarImage(currentUser, binding?.avatarImage, false)
setupProfileQueryDisposable() setupProfileQueryDisposable()
binding.settingsRemoveAccount.addPreferenceClickListener { binding?.settingsRemoveAccount?.addPreferenceClickListener {
showRemoveAccountWarning() showRemoveAccountWarning()
} }
} }
setupMessageView() setupMessageView()
binding.avatarContainer.setOnClickListener { binding?.avatarContainer?.setOnClickListener {
router router
.pushController( .pushController(
RouterTransaction.with(ProfileController()) RouterTransaction.with(ProfileController())
@ -495,7 +497,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} }
private fun themeSwitchPreferences() { private fun themeSwitchPreferences() {
binding.run { binding?.run {
listOf( listOf(
settingsScreenLock, settingsScreenLock,
settingsScreenSecurity, settingsScreenSecurity,
@ -508,7 +510,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} }
private fun themeCategories() { private fun themeCategories() {
binding.run { binding?.run {
listOf( listOf(
settingsNotificationsCategory, settingsNotificationsCategory,
settingsAboutCategory, settingsAboutCategory,
@ -539,54 +541,62 @@ class SettingsController : BaseController(R.layout.controller_settings) {
if (ApplicationWideMessageHolder.getInstance().messageType != null) { if (ApplicationWideMessageHolder.getInstance().messageType != null) {
when (ApplicationWideMessageHolder.getInstance().messageType) { when (ApplicationWideMessageHolder.getInstance().messageType) {
ApplicationWideMessageHolder.MessageType.ACCOUNT_UPDATED_NOT_ADDED -> { ApplicationWideMessageHolder.MessageType.ACCOUNT_UPDATED_NOT_ADDED -> {
binding.messageText.setTextColor( binding?.messageText?.let {
viewThemeUtils.getScheme(binding.messageText.context).primary it.setTextColor(
viewThemeUtils.getScheme(it.context).primary
) )
binding.messageText.text = resources!!.getString(R.string.nc_settings_account_updated) it.text = resources!!.getString(R.string.nc_settings_account_updated)
binding.messageView.visibility = View.VISIBLE binding?.messageView?.visibility = View.VISIBLE
}
} }
ApplicationWideMessageHolder.MessageType.SERVER_WITHOUT_TALK -> { ApplicationWideMessageHolder.MessageType.SERVER_WITHOUT_TALK -> {
binding.messageText.setTextColor(resources!!.getColor(R.color.nc_darkRed)) binding?.messageText?.let {
binding.messageText.text = resources!!.getString(R.string.nc_settings_wrong_account) it.setTextColor(resources!!.getColor(R.color.nc_darkRed))
binding.messageView.visibility = View.VISIBLE it.text = resources!!.getString(R.string.nc_settings_wrong_account)
binding.messageText.setTextColor( binding?.messageView?.visibility = View.VISIBLE
viewThemeUtils.getScheme(binding.messageText.context).primary it.setTextColor(
viewThemeUtils.getScheme(it.context).primary
) )
binding.messageText.text = resources!!.getString(R.string.nc_Server_account_imported) it.text = resources!!.getString(R.string.nc_Server_account_imported)
binding.messageView.visibility = View.VISIBLE binding?.messageView?.visibility = View.VISIBLE
}
} }
ApplicationWideMessageHolder.MessageType.ACCOUNT_WAS_IMPORTED -> { ApplicationWideMessageHolder.MessageType.ACCOUNT_WAS_IMPORTED -> {
binding.messageText.setTextColor( binding?.messageText?.let {
viewThemeUtils.getScheme(binding.messageText.context).primary it.setTextColor(
viewThemeUtils.getScheme(it.context).primary
) )
binding.messageText.text = resources!!.getString(R.string.nc_Server_account_imported) it.text = resources!!.getString(R.string.nc_Server_account_imported)
binding.messageView.visibility = View.VISIBLE binding?.messageView?.visibility = View.VISIBLE
}
} }
ApplicationWideMessageHolder.MessageType.FAILED_TO_IMPORT_ACCOUNT -> { ApplicationWideMessageHolder.MessageType.FAILED_TO_IMPORT_ACCOUNT -> {
binding.messageText.setTextColor(resources!!.getColor(R.color.nc_darkRed)) binding?.messageText?.let {
binding.messageText.text = resources!!.getString(R.string.nc_server_failed_to_import_account) it.setTextColor(resources!!.getColor(R.color.nc_darkRed))
binding.messageView.visibility = View.VISIBLE it.text = resources!!.getString(R.string.nc_server_failed_to_import_account)
binding?.messageView?.visibility = View.VISIBLE
}
} }
else -> binding.messageView.visibility = View.GONE else -> binding?.messageView?.visibility = View.GONE
} }
ApplicationWideMessageHolder.getInstance().setMessageType(null) ApplicationWideMessageHolder.getInstance().messageType = null
binding.messageView.animate() binding?.messageView?.animate()
.translationY(0f) ?.translationY(0f)
.alpha(0.0f) ?.alpha(0.0f)
.setDuration(DURATION) ?.setDuration(DURATION)
.setStartDelay(START_DELAY) ?.setStartDelay(START_DELAY)
.setListener(object : AnimatorListenerAdapter() { ?.setListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) { override fun onAnimationEnd(animation: Animator) {
super.onAnimationEnd(animation) super.onAnimationEnd(animation)
binding.messageView.visibility = View.GONE binding?.messageView?.visibility = View.GONE
} }
}) })
} else { } else {
binding.messageView.visibility = View.GONE binding?.messageView?.visibility = View.GONE
} }
} }
@ -614,7 +624,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
if ((!TextUtils.isEmpty(displayName) && !(displayName == currentUser!!.displayName))) { if ((!TextUtils.isEmpty(displayName) && !(displayName == currentUser!!.displayName))) {
currentUser!!.displayName = displayName currentUser!!.displayName = displayName
userManager.updateOrCreateUser(currentUser!!) userManager.updateOrCreateUser(currentUser!!)
binding.displayNameText.text = currentUser!!.displayName binding?.displayNameText?.text = currentUser!!.displayName
} }
}, },
{ dispose(profileQueryDisposable) }, { dispose(profileQueryDisposable) },
@ -625,74 +635,74 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private fun setupServerAgeWarning() { private fun setupServerAgeWarning() {
when { when {
CapabilitiesUtilNew.isServerEOL(currentUser!!) -> { CapabilitiesUtilNew.isServerEOL(currentUser!!) -> {
binding.serverAgeWarningText.setTextColor(ContextCompat.getColor((context)!!, R.color.nc_darkRed)) binding?.serverAgeWarningText?.setTextColor(ContextCompat.getColor((context)!!, R.color.nc_darkRed))
binding.serverAgeWarningText.setText(R.string.nc_settings_server_eol) binding?.serverAgeWarningText?.setText(R.string.nc_settings_server_eol)
binding.serverAgeWarningIcon.setColorFilter( binding?.serverAgeWarningIcon?.setColorFilter(
ContextCompat.getColor((context)!!, R.color.nc_darkRed), ContextCompat.getColor((context), R.color.nc_darkRed),
PorterDuff.Mode.SRC_IN PorterDuff.Mode.SRC_IN
) )
} }
CapabilitiesUtilNew.isServerAlmostEOL(currentUser!!) -> { CapabilitiesUtilNew.isServerAlmostEOL(currentUser!!) -> {
binding.serverAgeWarningText.setTextColor( binding?.serverAgeWarningText?.setTextColor(
ContextCompat.getColor((context)!!, R.color.nc_darkYellow) ContextCompat.getColor((context), R.color.nc_darkYellow)
) )
binding.serverAgeWarningText.setText(R.string.nc_settings_server_almost_eol) binding?.serverAgeWarningText?.setText(R.string.nc_settings_server_almost_eol)
binding.serverAgeWarningIcon.setColorFilter( binding?.serverAgeWarningIcon?.setColorFilter(
ContextCompat.getColor((context)!!, R.color.nc_darkYellow), ContextCompat.getColor((context), R.color.nc_darkYellow),
PorterDuff.Mode.SRC_IN PorterDuff.Mode.SRC_IN
) )
} }
else -> { else -> {
binding.serverAgeWarningTextCard.visibility = View.GONE binding?.serverAgeWarningTextCard?.visibility = View.GONE
} }
} }
} }
private fun setupCheckables() { private fun setupCheckables() {
(binding.settingsScreenSecurity.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsScreenSecurity?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isScreenSecured appPreferences.isScreenSecured
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
(binding.settingsIncognitoKeyboard.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsIncognitoKeyboard?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isKeyboardIncognito appPreferences.isKeyboardIncognito
} }
(binding.settingsIncognitoKeyboard.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsIncognitoKeyboard?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isKeyboardIncognito appPreferences.isKeyboardIncognito
if (CapabilitiesUtilNew.isReadStatusAvailable(userManager.currentUser.blockingGet())) { if (CapabilitiesUtilNew.isReadStatusAvailable(userManager.currentUser.blockingGet())) {
(binding.settingsReadPrivacy.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsReadPrivacy?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
!CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!) !CapabilitiesUtilNew.isReadStatusPrivate(currentUser!!)
} else { } else {
binding.settingsReadPrivacy.visibility = View.GONE binding?.settingsReadPrivacy?.visibility = View.GONE
} }
(binding.settingsPhoneBookIntegration.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsPhoneBookIntegration?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isPhoneBookIntegrationEnabled appPreferences.isPhoneBookIntegrationEnabled
} }
private fun setupScreenLockSetting() { private fun setupScreenLockSetting() {
val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager val keyguardManager = context.getSystemService(Context.KEYGUARD_SERVICE) as KeyguardManager
if (keyguardManager.isKeyguardSecure) { if (keyguardManager.isKeyguardSecure) {
binding.settingsScreenLock.isEnabled = true binding?.settingsScreenLock?.isEnabled = true
binding.settingsScreenLockTimeout.isEnabled = true binding?.settingsScreenLockTimeout?.isEnabled = true
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsScreenLock?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isScreenLocked appPreferences.isScreenLocked
binding.settingsScreenLockTimeout.isEnabled = appPreferences.isScreenLocked binding?.settingsScreenLockTimeout?.isEnabled = appPreferences.isScreenLocked
if (appPreferences.isScreenLocked) { if (appPreferences.isScreenLocked) {
binding.settingsScreenLockTimeout.alpha = ENABLED_ALPHA binding?.settingsScreenLockTimeout?.alpha = ENABLED_ALPHA
} else { } else {
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA binding?.settingsScreenLockTimeout?.alpha = DISABLED_ALPHA
} }
binding.settingsScreenLock.alpha = ENABLED_ALPHA binding?.settingsScreenLock?.alpha = ENABLED_ALPHA
} else { } else {
binding.settingsScreenLock.isEnabled = false binding?.settingsScreenLock?.isEnabled = false
binding.settingsScreenLockTimeout.isEnabled = false binding?.settingsScreenLockTimeout?.isEnabled = false
appPreferences.removeScreenLock() appPreferences.removeScreenLock()
appPreferences.removeScreenLockTimeout() appPreferences.removeScreenLockTimeout()
(binding.settingsScreenLock.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = false (binding?.settingsScreenLock?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = false
binding.settingsScreenLock.alpha = DISABLED_ALPHA binding?.settingsScreenLock?.alpha = DISABLED_ALPHA
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA binding?.settingsScreenLockTimeout?.alpha = DISABLED_ALPHA
} }
} }
@ -710,40 +720,40 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} }
private fun hideProxySettings() { private fun hideProxySettings() {
appPreferences?.removeProxyHost() appPreferences.removeProxyHost()
appPreferences?.removeProxyPort() appPreferences.removeProxyPort()
appPreferences?.removeProxyCredentials() appPreferences.removeProxyCredentials()
appPreferences?.removeProxyUsername() appPreferences.removeProxyUsername()
appPreferences?.removeProxyPassword() appPreferences.removeProxyPassword()
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_host_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_host_edit)?.visibility = View.GONE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_port_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_port_edit)?.visibility = View.GONE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_use_credentials).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_use_credentials)?.visibility =
View.GONE View.GONE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_username_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_username_edit)?.visibility = View.GONE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_password_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_password_edit)?.visibility = View.GONE
} }
private fun showProxySettings() { private fun showProxySettings() {
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_host_edit).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_host_edit)?.visibility =
View.VISIBLE View.VISIBLE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_port_edit).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_port_edit)?.visibility =
View.VISIBLE View.VISIBLE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_use_credentials).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_use_credentials)?.visibility =
View.VISIBLE View.VISIBLE
} }
private fun showProxyCredentials() { private fun showProxyCredentials() {
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_username_edit).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_username_edit)?.visibility =
View.VISIBLE View.VISIBLE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_password_edit).visibility = binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_password_edit)?.visibility =
View.VISIBLE View.VISIBLE
} }
private fun hideProxyCredentials() { private fun hideProxyCredentials() {
appPreferences?.removeProxyUsername() appPreferences.removeProxyUsername()
appPreferences?.removeProxyPassword() appPreferences.removeProxyPassword()
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_username_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_username_edit)?.visibility = View.GONE
binding.settingsScreen.findViewById<View>(R.id.settings_proxy_password_edit).visibility = View.GONE binding?.settingsScreen?.findViewById<View>(R.id.settings_proxy_password_edit)?.visibility = View.GONE
} }
private fun dispose(disposable: Disposable?) { private fun dispose(disposable: Disposable?) {
@ -784,7 +794,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
checkForPhoneNumber() checkForPhoneNumber()
} else { } else {
appPreferences.setPhoneBookIntegration(false) appPreferences.setPhoneBookIntegration(false)
(binding.settingsPhoneBookIntegration.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsPhoneBookIntegration?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
appPreferences.isPhoneBookIntegrationEnabled appPreferences.isPhoneBookIntegrationEnabled
Toast.makeText( Toast.makeText(
context, context,
@ -802,11 +812,11 @@ class SettingsController : BaseController(R.layout.controller_settings) {
private inner class ScreenLockListener : OnPreferenceValueChangedListener<Boolean> { private inner class ScreenLockListener : OnPreferenceValueChangedListener<Boolean> {
override fun onChanged(newValue: Boolean) { override fun onChanged(newValue: Boolean) {
binding.settingsScreenLockTimeout.isEnabled = newValue binding?.settingsScreenLockTimeout?.isEnabled = newValue
if (newValue) { if (newValue) {
binding.settingsScreenLockTimeout.alpha = ENABLED_ALPHA binding?.settingsScreenLockTimeout?.alpha = ENABLED_ALPHA
} else { } else {
binding.settingsScreenLockTimeout.alpha = DISABLED_ALPHA binding?.settingsScreenLockTimeout?.alpha = DISABLED_ALPHA
} }
} }
} }
@ -844,11 +854,11 @@ class SettingsController : BaseController(R.layout.controller_settings) {
} else { } else {
when (newValue) { when (newValue) {
"HTTP" -> "HTTP" ->
binding.settingsProxyPortEdit.value = "3128" binding?.settingsProxyPortEdit?.value = "3128"
"DIRECT" -> "DIRECT" ->
binding.settingsProxyPortEdit.value = "8080" binding?.settingsProxyPortEdit?.value = "8080"
"SOCKS" -> "SOCKS" ->
binding.settingsProxyPortEdit.value = "1080" binding?.settingsProxyPortEdit?.value = "1080"
else -> { else -> {
} }
} }
@ -1031,7 +1041,7 @@ class SettingsController : BaseController(R.layout.controller_settings) {
override fun onError(e: Throwable) { override fun onError(e: Throwable) {
appPreferences.setReadPrivacy(!newValue) appPreferences.setReadPrivacy(!newValue)
(binding.settingsReadPrivacy.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked = (binding?.settingsReadPrivacy?.findViewById<View>(R.id.mp_checkable) as Checkable).isChecked =
!newValue !newValue
} }

View file

@ -63,7 +63,7 @@ class SwitchAccountController(args: Bundle? = null) :
R.layout.controller_generic_rv, R.layout.controller_generic_rv,
args args
) { ) {
private val binding: ControllerGenericRvBinding by viewBinding(ControllerGenericRvBinding::bind) private val binding: ControllerGenericRvBinding? by viewBinding(ControllerGenericRvBinding::bind)
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
@ -118,7 +118,7 @@ class SwitchAccountController(args: Bundle? = null) :
override fun onViewBound(view: View) { override fun onViewBound(view: View) {
super.onViewBound(view) super.onViewBound(view)
binding.swipeRefreshLayout.isEnabled = false binding?.swipeRefreshLayout?.isEnabled = false
actionBar?.show() actionBar?.show()
@ -167,10 +167,10 @@ class SwitchAccountController(args: Bundle? = null) :
private fun prepareViews() { private fun prepareViews() {
val layoutManager: LinearLayoutManager = SmoothScrollLinearLayoutManager(activity) val layoutManager: LinearLayoutManager = SmoothScrollLinearLayoutManager(activity)
binding.recyclerView.layoutManager = layoutManager binding?.recyclerView?.layoutManager = layoutManager
binding.recyclerView.setHasFixedSize(true) binding?.recyclerView?.setHasFixedSize(true)
binding.recyclerView.adapter = adapter binding?.recyclerView?.adapter = adapter
binding.swipeRefreshLayout.isEnabled = false binding?.swipeRefreshLayout?.isEnabled = false
} }
private fun reauthorizeFromImport(account: Account?) { private fun reauthorizeFromImport(account: Account?) {

View file

@ -82,7 +82,7 @@ class WebViewLoginController(args: Bundle? = null) : BaseController(
R.layout.controller_web_view_login, R.layout.controller_web_view_login,
args args
) { ) {
private val binding: ControllerWebViewLoginBinding by viewBinding(ControllerWebViewLoginBinding::bind) private val binding: ControllerWebViewLoginBinding? by viewBinding(ControllerWebViewLoginBinding::bind)
@Inject @Inject
lateinit var userManager: UserManager lateinit var userManager: UserManager
@ -137,25 +137,25 @@ class WebViewLoginController(args: Bundle? = null) : BaseController(
actionBar?.hide() actionBar?.hide()
assembledPrefix = resources!!.getString(R.string.nc_talk_login_scheme) + PROTOCOL_SUFFIX + "login/" assembledPrefix = resources!!.getString(R.string.nc_talk_login_scheme) + PROTOCOL_SUFFIX + "login/"
binding.webview.settings.allowFileAccess = false binding?.webview?.settings?.allowFileAccess = false
binding.webview.settings.allowFileAccessFromFileURLs = false binding?.webview?.settings?.allowFileAccessFromFileURLs = false
binding.webview.settings.javaScriptEnabled = true binding?.webview?.settings?.javaScriptEnabled = true
binding.webview.settings.javaScriptCanOpenWindowsAutomatically = false binding?.webview?.settings?.javaScriptCanOpenWindowsAutomatically = false
binding.webview.settings.domStorageEnabled = true binding?.webview?.settings?.domStorageEnabled = true
binding.webview.settings.setUserAgentString(webLoginUserAgent) binding?.webview?.settings?.setUserAgentString(webLoginUserAgent)
binding.webview.settings.saveFormData = false binding?.webview?.settings?.saveFormData = false
binding.webview.settings.savePassword = false binding?.webview?.settings?.savePassword = false
binding.webview.settings.setRenderPriority(WebSettings.RenderPriority.HIGH) binding?.webview?.settings?.setRenderPriority(WebSettings.RenderPriority.HIGH)
binding.webview.clearCache(true) binding?.webview?.clearCache(true)
binding.webview.clearFormData() binding?.webview?.clearFormData()
binding.webview.clearHistory() binding?.webview?.clearHistory()
WebView.clearClientCertPreferences(null) WebView.clearClientCertPreferences(null)
webViewFidoBridge = WebViewFidoBridge.createInstanceForWebView(activity as AppCompatActivity?, binding.webview) webViewFidoBridge = WebViewFidoBridge.createInstanceForWebView(activity as AppCompatActivity?, binding?.webview)
CookieSyncManager.createInstance(activity) CookieSyncManager.createInstance(activity)
android.webkit.CookieManager.getInstance().removeAllCookies(null) android.webkit.CookieManager.getInstance().removeAllCookies(null)
val headers: MutableMap<String, String> = HashMap() val headers: MutableMap<String, String> = HashMap()
headers.put("OCS-APIRequest", "true") headers.put("OCS-APIRequest", "true")
binding.webview.webViewClient = object : WebViewClient() { binding?.webview?.webViewClient = object : WebViewClient() {
private var basePageLoaded = false private var basePageLoaded = false
override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? { override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
webViewFidoBridge?.delegateShouldInterceptRequest(view, request) webViewFidoBridge?.delegateShouldInterceptRequest(view, request)
@ -181,24 +181,24 @@ class WebViewLoginController(args: Bundle? = null) : BaseController(
try { try {
loginStep++ loginStep++
if (!basePageLoaded) { if (!basePageLoaded) {
binding.progressBar.visibility = View.GONE binding?.progressBar?.visibility = View.GONE
binding.webview.visibility = View.VISIBLE binding?.webview?.visibility = View.VISIBLE
basePageLoaded = true basePageLoaded = true
} }
if (!TextUtils.isEmpty(username)) { if (!TextUtils.isEmpty(username)) {
if (loginStep == 1) { if (loginStep == 1) {
binding.webview.loadUrl( binding?.webview?.loadUrl(
"javascript: {document.getElementsByClassName('login')[0].click(); };" "javascript: {document.getElementsByClassName('login')[0].click(); };"
) )
} else if (!automatedLoginAttempted) { } else if (!automatedLoginAttempted) {
automatedLoginAttempted = true automatedLoginAttempted = true
if (TextUtils.isEmpty(password)) { if (TextUtils.isEmpty(password)) {
binding.webview.loadUrl( binding?.webview?.loadUrl(
"javascript:var justStore = document.getElementById('user').value = '$username';" "javascript:var justStore = document.getElementById('user').value = '$username';"
) )
} else { } else {
binding.webview.loadUrl( binding?.webview?.loadUrl(
"javascript: {" + "javascript: {" +
"document.getElementById('user').value = '" + username + "';" + "document.getElementById('user').value = '" + username + "';" +
"document.getElementById('password').value = '" + password + "';" + "document.getElementById('password').value = '" + password + "';" +
@ -308,7 +308,7 @@ class WebViewLoginController(args: Bundle? = null) : BaseController(
super.onReceivedError(view, errorCode, description, failingUrl) super.onReceivedError(view, errorCode, description, failingUrl)
} }
} }
binding.webview.loadUrl("$baseUrl/index.php/login/flow", headers) binding?.webview?.loadUrl("$baseUrl/index.php/login/flow", headers)
} }
private fun dispose() { private fun dispose() {

View file

@ -62,7 +62,7 @@ class EntryMenuController(args: Bundle) :
R.layout.controller_entry_menu, R.layout.controller_entry_menu,
args args
) { ) {
private val binding: ControllerEntryMenuBinding by viewBinding(ControllerEntryMenuBinding::bind) private val binding: ControllerEntryMenuBinding? by viewBinding(ControllerEntryMenuBinding::bind)
@Inject @Inject
lateinit var eventBus: EventBus lateinit var eventBus: EventBus
@ -87,11 +87,11 @@ class EntryMenuController(args: Bundle) :
if (ApplicationWideMessageHolder.MessageType.CALL_PASSWORD_WRONG == if (ApplicationWideMessageHolder.MessageType.CALL_PASSWORD_WRONG ==
ApplicationWideMessageHolder.getInstance().messageType ApplicationWideMessageHolder.getInstance().messageType
) { ) {
binding.textInputLayout.error = resources?.getString(R.string.nc_wrong_password) binding?.textInputLayout?.error = resources?.getString(R.string.nc_wrong_password)
ApplicationWideMessageHolder.getInstance().setMessageType(null) ApplicationWideMessageHolder.getInstance().messageType = null
if (binding.okButton.isEnabled) { if (binding?.okButton?.isEnabled == true) {
binding.okButton.isEnabled = false binding?.okButton?.isEnabled = false
binding.okButton.alpha = OPACITY_BUTTON_DISABLED binding?.okButton?.alpha = OPACITY_BUTTON_DISABLED
} }
} }
} }
@ -100,13 +100,13 @@ class EntryMenuController(args: Bundle) :
super.onViewBound(view) super.onViewBound(view)
if (conversation != null && operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) { if (conversation != null && operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
binding.textEdit.setText(conversation!!.name) binding?.textEdit?.setText(conversation!!.name)
} }
binding.textEdit.setOnEditorActionListener { v, actionId, event -> binding?.textEdit?.setOnEditorActionListener { v, actionId, event ->
@Suppress("IMPLICIT_BOXING_IN_IDENTITY_EQUALS") @Suppress("IMPLICIT_BOXING_IN_IDENTITY_EQUALS")
if (actionId === EditorInfo.IME_ACTION_DONE && binding.okButton.isEnabled) { if (actionId === EditorInfo.IME_ACTION_DONE && binding?.okButton?.isEnabled == true) {
binding.okButton.callOnClick() binding?.okButton?.callOnClick()
return@setOnEditorActionListener true return@setOnEditorActionListener true
} }
false false
@ -118,57 +118,59 @@ class EntryMenuController(args: Bundle) :
when (operation) { when (operation) {
ConversationOperationEnum.OPS_CODE_INVITE_USERS, ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> { ConversationOperationEnum.OPS_CODE_INVITE_USERS, ConversationOperationEnum.OPS_CODE_RENAME_ROOM -> {
labelText = resources!!.getString(R.string.nc_call_name) labelText = resources!!.getString(R.string.nc_call_name)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT
binding.smileyButton.visibility = View.VISIBLE binding?.smileyButton?.visibility = View.VISIBLE
emojiPopup = EmojiPopup( emojiPopup = binding?.let {
EmojiPopup(
rootView = view, rootView = view,
editText = binding.textEdit, editText = it.textEdit,
onEmojiPopupShownListener = { onEmojiPopupShownListener = {
viewThemeUtils.platform.colorImageView(binding.smileyButton) viewThemeUtils.platform.colorImageView(it.smileyButton)
}, },
onEmojiPopupDismissListener = { onEmojiPopupDismissListener = {
binding.smileyButton.imageTintList = ColorStateList.valueOf( it.smileyButton.imageTintList = ColorStateList.valueOf(
ResourcesCompat.getColor(resources!!, R.color.medium_emphasis_text, context.theme) ResourcesCompat.getColor(resources!!, R.color.medium_emphasis_text, context.theme)
) )
}, },
onEmojiClickListener = { onEmojiClickListener = {
binding.textEdit.editableText.append(" ") binding?.textEdit?.editableText?.append(" ")
} }
) )
} }
}
ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> { ConversationOperationEnum.OPS_CODE_JOIN_ROOM -> {
// 99 is joining a conversation via password // 99 is joining a conversation via password
labelText = resources!!.getString(R.string.nc_password) labelText = resources!!.getString(R.string.nc_password)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_PASSWORD
} }
ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> { ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM -> {
labelText = resources!!.getString(R.string.nc_conversation_link) labelText = resources!!.getString(R.string.nc_conversation_link)
binding.textEdit.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI binding?.textEdit?.inputType = InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI
} }
else -> { else -> {
} }
} }
if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) { if (PASSWORD_ENTRY_OPERATIONS.contains(operation)) {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_PASSWORD_TOGGLE
} else { } else {
binding.textInputLayout.endIconMode = TextInputLayout.END_ICON_NONE binding?.textInputLayout?.endIconMode = TextInputLayout.END_ICON_NONE
} }
viewThemeUtils.material.colorTextInputLayout(binding.textInputLayout) binding?.textInputLayout?.let { viewThemeUtils.material.colorTextInputLayout(it) }
viewThemeUtils.material.colorMaterialButtonText(binding.okButton) binding?.okButton?.let { viewThemeUtils.material.colorMaterialButtonText(it) }
binding.textInputLayout.hint = labelText binding?.textInputLayout?.hint = labelText
binding.textInputLayout.requestFocus() binding?.textInputLayout?.requestFocus()
binding.smileyButton.setOnClickListener { onSmileyClick() } binding?.smileyButton?.setOnClickListener { onSmileyClick() }
binding.okButton.setOnClickListener { onOkButtonClick() } binding?.okButton?.setOnClickListener { onOkButtonClick() }
} }
private fun textEditAddChangedListener() { private fun textEditAddChangedListener() {
binding.textEdit.addTextChangedListener(object : TextWatcher { binding?.textEdit?.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) { override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
// unused atm // unused atm
} }
@ -181,46 +183,46 @@ class EntryMenuController(args: Bundle) :
if (!TextUtils.isEmpty(s)) { if (!TextUtils.isEmpty(s)) {
if (operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) { if (operation === ConversationOperationEnum.OPS_CODE_RENAME_ROOM) {
if (conversation!!.name == null || !conversation!!.name.equals(s.toString())) { if (conversation!!.name == null || !conversation!!.name.equals(s.toString())) {
if (!binding.okButton.isEnabled) { if (!binding?.okButton?.isEnabled!!) {
binding.okButton.isEnabled = true binding?.okButton?.isEnabled = true
binding.okButton.alpha = OPACITY_ENABLED binding?.okButton?.alpha = OPACITY_ENABLED
} }
binding.textInputLayout.isErrorEnabled = false binding?.textInputLayout?.isErrorEnabled = false
} else { } else {
if (binding.okButton.isEnabled) { if (binding?.okButton?.isEnabled == true) {
binding.okButton.isEnabled = false binding?.okButton?.isEnabled = false
binding.okButton.alpha = OPACITY_DISABLED binding?.okButton?.alpha = OPACITY_DISABLED
} }
binding.textInputLayout.error = resources?.getString(R.string.nc_call_name_is_same) binding?.textInputLayout?.error = resources?.getString(R.string.nc_call_name_is_same)
} }
} else if (operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM) { } else if (operation !== ConversationOperationEnum.OPS_CODE_GET_AND_JOIN_ROOM) {
if (!binding.okButton.isEnabled) { if (!binding?.okButton?.isEnabled!!) {
binding.okButton.isEnabled = true binding?.okButton?.isEnabled = true
binding.okButton.alpha = OPACITY_ENABLED binding?.okButton?.alpha = OPACITY_ENABLED
} }
binding.textInputLayout.isErrorEnabled = false binding?.textInputLayout?.isErrorEnabled = false
} else if ( } else if (
UriUtils.hasHttpProtocollPrefixed(binding.textEdit.text.toString()) && UriUtils.hasHttpProtocollPrefixed(binding?.textEdit?.text.toString()) &&
binding.textEdit.text.toString().contains("/call/") binding?.textEdit?.text.toString().contains("/call/")
) { ) {
if (!binding.okButton.isEnabled) { if (!binding?.okButton?.isEnabled!!) {
binding.okButton.isEnabled = true binding?.okButton?.isEnabled = true
binding.okButton.alpha = OPACITY_ENABLED binding?.okButton?.alpha = OPACITY_ENABLED
} }
binding.textInputLayout.isErrorEnabled = false binding?.textInputLayout?.isErrorEnabled = false
} else { } else {
if (binding.okButton.isEnabled) { if (binding?.okButton?.isEnabled == true) {
binding.okButton.isEnabled = false binding?.okButton?.isEnabled = false
binding.okButton.alpha = OPACITY_DISABLED binding?.okButton?.alpha = OPACITY_DISABLED
} }
binding.textInputLayout.error = resources?.getString(R.string.nc_wrong_link) binding?.textInputLayout?.error = resources?.getString(R.string.nc_wrong_link)
} }
} else { } else {
if (binding.okButton.isEnabled) { if (binding?.okButton?.isEnabled == true) {
binding.okButton.isEnabled = false binding?.okButton?.isEnabled = false
binding.okButton.alpha = OPACITY_DISABLED binding?.okButton?.alpha = OPACITY_DISABLED
} }
binding.textInputLayout.isErrorEnabled = false binding?.textInputLayout?.isErrorEnabled = false
} }
} }
}) })
@ -238,7 +240,7 @@ class EntryMenuController(args: Bundle) :
operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS
) { ) {
val bundle = Bundle() val bundle = Bundle()
conversation!!.name = binding.textEdit.text.toString() conversation!!.name = binding?.textEdit?.text.toString()
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation)) bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation) bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
router.pushController( router.pushController(
@ -249,14 +251,14 @@ class EntryMenuController(args: Bundle) :
} else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) { } else if (operation !== ConversationOperationEnum.OPS_CODE_INVITE_USERS) {
val bundle = Bundle() val bundle = Bundle()
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation) bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
bundle.putString(BundleKeys.KEY_CALL_URL, binding.textEdit.text.toString()) bundle.putString(BundleKeys.KEY_CALL_URL, binding?.textEdit?.text.toString())
router.pushController( router.pushController(
RouterTransaction.with(OperationsMenuController(bundle)) RouterTransaction.with(OperationsMenuController(bundle))
.pushChangeHandler(HorizontalChangeHandler()) .pushChangeHandler(HorizontalChangeHandler())
.popChangeHandler(HorizontalChangeHandler()) .popChangeHandler(HorizontalChangeHandler())
) )
} else if (operation === ConversationOperationEnum.OPS_CODE_INVITE_USERS) { } else if (operation === ConversationOperationEnum.OPS_CODE_INVITE_USERS) {
originalBundle.putString(BundleKeys.KEY_CONVERSATION_NAME, binding.textEdit.text.toString()) originalBundle.putString(BundleKeys.KEY_CONVERSATION_NAME, binding?.textEdit?.text.toString())
router.pushController( router.pushController(
RouterTransaction.with( RouterTransaction.with(
OperationsMenuController( OperationsMenuController(
@ -273,12 +275,12 @@ class EntryMenuController(args: Bundle) :
val bundle = Bundle() val bundle = Bundle()
bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation)) bundle.putParcelable(BundleKeys.KEY_ROOM, Parcels.wrap<Any>(conversation))
bundle.putString(BundleKeys.KEY_CALL_URL, callUrl) bundle.putString(BundleKeys.KEY_CALL_URL, callUrl)
bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding.textEdit.text.toString()) bundle.putString(BundleKeys.KEY_CONVERSATION_PASSWORD, binding?.textEdit?.text.toString())
bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation) bundle.putSerializable(BundleKeys.KEY_OPERATION_CODE, operation)
if (originalBundle.containsKey(BundleKeys.KEY_SERVER_CAPABILITIES)) { if (originalBundle.containsKey(BundleKeys.KEY_SERVER_CAPABILITIES)) {
bundle.putParcelable( bundle.putParcelable(
BundleKeys.KEY_SERVER_CAPABILITIES, BundleKeys.KEY_SERVER_CAPABILITIES,
originalBundle.getParcelable<Parcelable>(BundleKeys.KEY_SERVER_CAPABILITIES) originalBundle.getParcelable(BundleKeys.KEY_SERVER_CAPABILITIES)
) )
} }
router.pushController( router.pushController(

View file

@ -83,7 +83,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
R.layout.controller_operations_menu, R.layout.controller_operations_menu,
args args
) { ) {
private val binding: ControllerOperationsMenuBinding by viewBinding(ControllerOperationsMenuBinding::bind) private val binding: ControllerOperationsMenuBinding? by viewBinding(ControllerOperationsMenuBinding::bind)
@Inject @Inject
lateinit var ncApi: NcApi lateinit var ncApi: NcApi
@ -117,7 +117,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
sharedApplication!!.componentApplication.inject(this) sharedApplication!!.componentApplication.inject(this)
currentUser = userManager.currentUser.blockingGet() currentUser = userManager.currentUser.blockingGet()
viewThemeUtils.platform.colorCircularProgressBar(binding.progressBar) binding?.progressBar?.let { viewThemeUtils.platform.colorCircularProgressBar(it) }
if (!TextUtils.isEmpty(callUrl) && callUrl.contains("/call")) { if (!TextUtils.isEmpty(callUrl) && callUrl.contains("/call")) {
conversationToken = callUrl.substring(callUrl.lastIndexOf("/") + 1) conversationToken = callUrl.substring(callUrl.lastIndexOf("/") + 1)
@ -476,10 +476,10 @@ class OperationsMenuController(args: Bundle) : BaseController(
@Suppress("Detekt.TooGenericExceptionCaught") @Suppress("Detekt.TooGenericExceptionCaught")
private fun showResultImage(everythingOK: Boolean, isGuestSupportError: Boolean) { private fun showResultImage(everythingOK: Boolean, isGuestSupportError: Boolean) {
try { try {
binding.progressBar.visibility = View.GONE binding?.progressBar?.visibility = View.GONE
if (resources != null) { if (resources != null) {
if (everythingOK) { if (everythingOK) {
binding.resultImageView.setImageDrawable( binding?.resultImageView?.setImageDrawable(
DisplayUtils.getTintedDrawable( DisplayUtils.getTintedDrawable(
resources, resources,
R.drawable.ic_check_circle_black_24dp, R.drawable.ic_check_circle_black_24dp,
@ -487,7 +487,7 @@ class OperationsMenuController(args: Bundle) : BaseController(
) )
) )
} else { } else {
binding.resultImageView.setImageDrawable( binding?.resultImageView?.setImageDrawable(
DisplayUtils.getTintedDrawable( DisplayUtils.getTintedDrawable(
resources, resources,
R.drawable.ic_cancel_black_24dp, R.drawable.ic_cancel_black_24dp,
@ -496,35 +496,35 @@ class OperationsMenuController(args: Bundle) : BaseController(
) )
} }
} }
binding.resultImageView.visibility = View.VISIBLE binding?.resultImageView?.visibility = View.VISIBLE
if (everythingOK) { if (everythingOK) {
binding.resultTextView.setText(R.string.nc_all_ok_operation) binding?.resultTextView?.setText(R.string.nc_all_ok_operation)
} else { } else {
binding.resultTextView.setTextColor(resources!!.getColor(R.color.nc_darkRed)) binding?.resultTextView?.setTextColor(resources!!.getColor(R.color.nc_darkRed))
if (!isGuestSupportError) { if (!isGuestSupportError) {
binding.resultTextView.setText(R.string.nc_failed_to_perform_operation) binding?.resultTextView?.setText(R.string.nc_failed_to_perform_operation)
} else { } else {
binding.resultTextView.setText(R.string.nc_failed_signaling_settings) binding?.resultTextView?.setText(R.string.nc_failed_signaling_settings)
binding.webButton.setOnClickListener { binding?.webButton?.setOnClickListener {
val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(callUrl)) val browserIntent = Intent(Intent.ACTION_VIEW, Uri.parse(callUrl))
startActivity(browserIntent) startActivity(browserIntent)
} }
binding.webButton.visibility = View.VISIBLE binding?.webButton?.visibility = View.VISIBLE
} }
} }
binding.resultTextView.visibility = View.VISIBLE binding?.resultTextView?.visibility = View.VISIBLE
if (everythingOK) { if (everythingOK) {
eventBus!!.post(ConversationsListFetchDataEvent()) eventBus.post(ConversationsListFetchDataEvent())
} else { } else {
binding.resultImageView.setImageDrawable( binding?.resultImageView?.setImageDrawable(
DisplayUtils.getTintedDrawable( DisplayUtils.getTintedDrawable(
resources, resources,
R.drawable.ic_cancel_black_24dp, R.drawable.ic_cancel_black_24dp,
R.color.nc_darkRed R.color.nc_darkRed
) )
) )
binding.okButton.setOnClickListener { v: View? -> eventBus!!.post(ConversationsListFetchDataEvent()) } binding?.okButton?.setOnClickListener { v: View? -> eventBus.post(ConversationsListFetchDataEvent()) }
binding.okButton.visibility = View.VISIBLE binding?.okButton?.visibility = View.VISIBLE
} }
} catch (npe: NullPointerException) { } catch (npe: NullPointerException) {
Log.i(TAG, "Controller already closed", npe) Log.i(TAG, "Controller already closed", npe)

View file

@ -25,13 +25,13 @@ import com.bluelinelabs.conductor.Controller
import kotlin.properties.ReadOnlyProperty import kotlin.properties.ReadOnlyProperty
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
fun <T : ViewBinding> Controller.viewBinding(bindingFactory: (View) -> T) = fun <T : ViewBinding> Controller.viewBinding(bindingFactory: (View) -> T?) =
ControllerViewBindingDelegate(this, bindingFactory) ControllerViewBindingDelegate(this, bindingFactory)
class ControllerViewBindingDelegate<T : ViewBinding>( class ControllerViewBindingDelegate<T : ViewBinding>(
controller: Controller, controller: Controller,
private val viewBinder: (View) -> T private val viewBinder: (View) -> T?
) : ReadOnlyProperty<Controller, T>, LifecycleObserver { ) : ReadOnlyProperty<Controller, T?>, LifecycleObserver {
private var binding: T? = null private var binding: T? = null
@ -43,7 +43,7 @@ class ControllerViewBindingDelegate<T : ViewBinding>(
}) })
} }
override fun getValue(thisRef: Controller, property: KProperty<*>): T { override fun getValue(thisRef: Controller, property: KProperty <*>): T? {
return binding ?: viewBinder(thisRef.view!!).also { binding = it } return binding ?: thisRef.view?.let { viewBinder(it).also { binding = it } }
} }
} }