Room detail: use ViewStub for FailedMessagesWarningView

This commit is contained in:
ganfra 2021-09-22 18:00:56 +02:00
parent 290586948f
commit ebd5095662
6 changed files with 52 additions and 60 deletions

View file

@ -1,26 +0,0 @@
/*
* Copyright 2019 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package im.vector.app.core.extensions
import android.view.View
import android.view.ViewStub
inline fun <reified T: View> ViewStub.inflateIfNeeded(onInflate: (T) -> Unit) {
if (parent != null) {
onInflate(inflate() as T)
}
}

View file

@ -19,7 +19,6 @@ package im.vector.app.core.ui.views
import android.content.Context
import android.util.AttributeSet
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.isVisible
import im.vector.app.R
import im.vector.app.databinding.ViewFailedMessagesWarningBinding
@ -49,8 +48,4 @@ class FailedMessagesWarningView @JvmOverloads constructor(
views.failedMessagesDeleteAllButton.setOnClickListener { callback?.onDeleteAllClicked() }
views.failedMessagesRetryButton.setOnClickListener { callback?.onRetryClicked() }
}
fun render(hasFailedMessages: Boolean) {
isVisible = hasFailedMessages
}
}

View file

@ -354,7 +354,6 @@ class RoomDetailFragment @Inject constructor(
setupActiveCallView()
setupJumpToBottomView()
setupEmojiButton()
setupFailedMessagesWarningView()
setupRemoveJitsiWidgetView()
setupVoiceMessageView()
@ -615,8 +614,16 @@ class RoomDetailFragment @Inject constructor(
.build(views.composerLayout.views.composerEditText)
}
private fun setupFailedMessagesWarningView() {
views.failedMessagesWarningView.callback = object : FailedMessagesWarningView.Callback {
private val permissionVoiceMessageLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
if (allGranted) {
// In this case, let the user start again the gesture
} else if (deniedPermanently) {
vectorBaseActivity.onPermissionDeniedSnackbar(R.string.denied_permission_voice_message)
}
}
private fun createFailedMessagesWarningCallback(): FailedMessagesWarningView.Callback {
return object : FailedMessagesWarningView.Callback {
override fun onDeleteAllClicked() {
MaterialAlertDialogBuilder(requireContext())
.setTitle(R.string.event_status_delete_all_failed_dialog_title)
@ -634,14 +641,6 @@ class RoomDetailFragment @Inject constructor(
}
}
private val permissionVoiceMessageLauncher = registerForPermissionsResult { allGranted, deniedPermanently ->
if (allGranted) {
// In this case, let the user start again the gesture
} else if (deniedPermanently) {
vectorBaseActivity.onPermissionDeniedSnackbar(R.string.denied_permission_voice_message)
}
}
private fun setupVoiceMessageView() {
views.voiceMessageRecorderView.voiceMessagePlaybackTracker = voiceMessagePlaybackTracker
@ -1361,13 +1360,17 @@ class RoomDetailFragment @Inject constructor(
val summary = state.asyncRoomSummary()
renderToolbar(summary, state.typingMessage)
views.removeJitsiWidgetView.render(state)
views.failedMessagesWarningView.render(state.hasFailedSending)
if (state.hasFailedSending) {
lazyLoadedViews.failedMessagesWarningView(inflateIfNeeded = true, createFailedMessagesWarningCallback())?.isVisible = true
} else {
lazyLoadedViews.failedMessagesWarningView(inflateIfNeeded = false)?.isVisible = false
}
val inviter = state.asyncInviter()
if (summary?.membership == Membership.JOIN) {
views.jumpToBottomView.count = summary.notificationCount
views.jumpToBottomView.drawBadge = summary.hasUnreadMessages
timelineEventController.update(state)
lazyLoadedViews.inviteView?.isVisible = false
lazyLoadedViews.inviteView(false)?.isVisible = false
if (state.tombstoneEvent == null) {
if (state.canSendMessage) {
if (!views.voiceMessageRecorderView.isActive()) {
@ -1390,7 +1393,7 @@ class RoomDetailFragment @Inject constructor(
} else if (summary?.membership == Membership.INVITE && inviter != null) {
views.composerLayout.isVisible = false
views.voiceMessageRecorderView.isVisible = false
lazyLoadedViews.inviteView?.apply {
lazyLoadedViews.inviteView(true)?.apply {
callback = this@RoomDetailFragment
isVisible = true
render(inviter, VectorInviteView.Mode.LARGE, state.changeMembershipState)

View file

@ -16,9 +16,13 @@
package im.vector.app.features.home.room.detail.views
import im.vector.app.core.extensions.inflateIfNeeded
import android.view.View
import android.view.ViewStub
import im.vector.app.core.ui.views.FailedMessagesWarningView
import im.vector.app.databinding.FragmentRoomDetailBinding
import im.vector.app.features.home.room.detail.composer.VoiceMessageRecorderView
import im.vector.app.features.invite.VectorInviteView
import kotlin.reflect.KMutableProperty0
/**
* This is an holder for lazy loading some views of the RoomDetail screen.
@ -28,14 +32,8 @@ class RoomDetailLazyLoadedViews {
private var roomDetailBinding: FragmentRoomDetailBinding? = null
var inviteView: VectorInviteView? = null
private set
get() {
roomDetailBinding?.inviteViewStub?.inflateIfNeeded<VectorInviteView> {
inviteView = it
}
return field
}
private var failedMessagesWarningView: FailedMessagesWarningView? = null
private var inviteView: VectorInviteView? = null
fun bind(roomDetailBinding: FragmentRoomDetailBinding) {
this.roomDetailBinding = roomDetailBinding
@ -44,5 +42,23 @@ class RoomDetailLazyLoadedViews {
fun unBind() {
roomDetailBinding = null
inviteView = null
failedMessagesWarningView = null
}
fun failedMessagesWarningView(inflateIfNeeded: Boolean, callback: FailedMessagesWarningView.Callback? = null): FailedMessagesWarningView? {
return getOrInflate(inflateIfNeeded, roomDetailBinding?.failedMessagesWarningStub, this::failedMessagesWarningView)?.apply {
this.callback = callback
}
}
fun inviteView(inflateIfNeeded: Boolean): VectorInviteView? {
return getOrInflate(inflateIfNeeded, roomDetailBinding?.inviteViewStub, this::inviteView)
}
private inline fun <reified T : View> getOrInflate(inflateIfNeeded: Boolean, stub: ViewStub?, reference: KMutableProperty0<T?>): T? {
if (!inflateIfNeeded || stub == null || stub.parent == null) return reference.get()
val inflatedView = stub.inflate() as T
reference.set(inflatedView)
return inflatedView
}
}

View file

@ -155,15 +155,14 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<im.vector.app.core.ui.views.FailedMessagesWarningView
android:id="@+id/failedMessagesWarningView"
<ViewStub
android:id="@+id/failedMessagesWarningStub"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:inflatedId="@layout/view_stub_failed_message_warning_layout"
app:layout_constraintBottom_toTopOf="@id/composerLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
tools:visibility="visible" />
app:layout_constraintStart_toStartOf="parent" />
<im.vector.app.features.home.room.detail.composer.TextComposerView
android:id="@+id/composerLayout"
@ -204,7 +203,7 @@
android:layout_width="0dp"
android:layout_height="0dp"
app:barrierDirection="top"
app:constraint_referenced_ids="composerLayout,notificationAreaView, failedMessagesWarningView" />
app:constraint_referenced_ids="composerLayout,notificationAreaView, failedMessagesWarningStub" />
<im.vector.app.core.platform.BadgeFloatingActionButton
android:id="@+id/jumpToBottomView"

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<im.vector.app.core.ui.views.FailedMessagesWarningView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>