mirror of
https://github.com/element-hq/element-android
synced 2024-11-23 18:05:36 +03:00
[Rich text editor] Implement full screen editor mode (simple approach) (#7436)
* Rich text editor: implement full screen editor mode using ConstraintSets * Add back press handler * Change ToggleFullScreen to SetFullScreen, fix rebase issues * Add warning to fragment_timeline* files
This commit is contained in:
parent
65a5ae9d3d
commit
d242ab049b
21 changed files with 705 additions and 53 deletions
1
changelog.d/7436.feature
Normal file
1
changelog.d/7436.feature
Normal file
|
@ -0,0 +1 @@
|
|||
Rich text editor: add full screen mode.
|
|
@ -3423,5 +3423,6 @@
|
|||
<string name="rich_text_editor_format_italic">Apply italic format</string>
|
||||
<string name="rich_text_editor_format_strikethrough">Apply strikethrough format</string>
|
||||
<string name="rich_text_editor_format_underline">Apply underline format</string>
|
||||
<string name="rich_text_editor_full_screen_toggle">Toggle full screen mode</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -150,7 +150,8 @@
|
|||
|
||||
<activity
|
||||
android:name=".features.home.room.detail.RoomDetailActivity"
|
||||
android:parentActivityName=".features.home.HomeActivity">
|
||||
android:parentActivityName=".features.home.HomeActivity"
|
||||
android:windowSoftInputMode="adjustResize">
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".features.home.HomeActivity" />
|
||||
|
|
|
@ -29,7 +29,13 @@ import androidx.appcompat.widget.SearchView
|
|||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.transition.ChangeBounds
|
||||
import androidx.transition.Fade
|
||||
import androidx.transition.Transition
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.transition.TransitionSet
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.animations.SimpleTransitionListener
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
|
||||
/**
|
||||
|
@ -90,3 +96,18 @@ fun View.setAttributeBackground(@AttrRes attributeId: Int) {
|
|||
val attribute = ThemeUtils.getAttribute(context, attributeId)!!
|
||||
setBackgroundResource(attribute.resourceId)
|
||||
}
|
||||
|
||||
fun ViewGroup.animateLayoutChange(animationDuration: Long, transitionComplete: (() -> Unit)? = null) {
|
||||
val transition = TransitionSet().apply {
|
||||
ordering = TransitionSet.ORDERING_SEQUENTIAL
|
||||
addTransition(ChangeBounds())
|
||||
addTransition(Fade(Fade.IN))
|
||||
duration = animationDuration
|
||||
addListener(object : SimpleTransitionListener() {
|
||||
override fun onTransitionEnd(transition: Transition) {
|
||||
transitionComplete?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
TransitionManager.beginDelayedTransition((parent as? ViewGroup ?: this), transition)
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ class JumpToBottomViewVisibilityManager(
|
|||
private val layoutManager: LinearLayoutManager
|
||||
) {
|
||||
|
||||
private var canShowButtonOnScroll = true
|
||||
|
||||
init {
|
||||
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
|
@ -43,7 +45,7 @@ class JumpToBottomViewVisibilityManager(
|
|||
|
||||
if (scrollingToPast) {
|
||||
jumpToBottomView.hide()
|
||||
} else {
|
||||
} else if (canShowButtonOnScroll) {
|
||||
maybeShowJumpToBottomViewVisibility()
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +68,13 @@ class JumpToBottomViewVisibilityManager(
|
|||
}
|
||||
}
|
||||
|
||||
fun hideAndPreventVisibilityChangesWithScrolling() {
|
||||
jumpToBottomView.hide()
|
||||
canShowButtonOnScroll = false
|
||||
}
|
||||
|
||||
private fun maybeShowJumpToBottomViewVisibility() {
|
||||
canShowButtonOnScroll = true
|
||||
if (layoutManager.findFirstVisibleItemPosition() > 1) {
|
||||
jumpToBottomView.show()
|
||||
} else {
|
||||
|
|
|
@ -32,7 +32,9 @@ import android.view.ViewGroup
|
|||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.addCallback
|
||||
import androidx.appcompat.view.menu.MenuBuilder
|
||||
import androidx.constraintlayout.widget.ConstraintSet
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.graphics.drawable.DrawableCompat
|
||||
import androidx.core.net.toUri
|
||||
|
@ -64,6 +66,7 @@ import im.vector.app.core.dialogs.ConfirmationDialogBuilder
|
|||
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelper
|
||||
import im.vector.app.core.dialogs.GalleryOrCameraDialogHelperFactory
|
||||
import im.vector.app.core.epoxy.LayoutManagerStateRestorer
|
||||
import im.vector.app.core.extensions.animateLayoutChange
|
||||
import im.vector.app.core.extensions.cleanup
|
||||
import im.vector.app.core.extensions.commitTransaction
|
||||
import im.vector.app.core.extensions.containsRtLOverride
|
||||
|
@ -183,7 +186,9 @@ import im.vector.app.features.widgets.WidgetArgs
|
|||
import im.vector.app.features.widgets.WidgetKind
|
||||
import im.vector.app.features.widgets.permissions.RoomWidgetPermissionBottomSheet
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
@ -337,6 +342,7 @@ class TimelineFragment :
|
|||
setupJumpToBottomView()
|
||||
setupRemoveJitsiWidgetView()
|
||||
setupLiveLocationIndicator()
|
||||
setupBackPressHandling()
|
||||
|
||||
views.includeRoomToolbar.roomToolbarContentView.debouncedClicks {
|
||||
navigator.openRoomProfile(requireActivity(), timelineArgs.roomId)
|
||||
|
@ -414,6 +420,31 @@ class TimelineFragment :
|
|||
if (savedInstanceState == null) {
|
||||
handleSpaceShare()
|
||||
}
|
||||
|
||||
views.scrim.setOnClickListener {
|
||||
messageComposerViewModel.handle(MessageComposerAction.SetFullScreen(false))
|
||||
}
|
||||
|
||||
messageComposerViewModel.stateFlow.map { it.isFullScreen }
|
||||
.distinctUntilChanged()
|
||||
.onEach { isFullScreen ->
|
||||
toggleFullScreenEditor(isFullScreen)
|
||||
}
|
||||
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
}
|
||||
|
||||
private fun setupBackPressHandling() {
|
||||
requireActivity().onBackPressedDispatcher.addCallback(viewLifecycleOwner) {
|
||||
withState(messageComposerViewModel) { state ->
|
||||
if (state.isFullScreen) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.SetFullScreen(false))
|
||||
} else {
|
||||
remove() // Remove callback to avoid infinite loop
|
||||
@Suppress("DEPRECATION")
|
||||
requireActivity().onBackPressed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupRemoveJitsiWidgetView() {
|
||||
|
@ -1016,7 +1047,13 @@ class TimelineFragment :
|
|||
override fun onLayoutCompleted(state: RecyclerView.State) {
|
||||
super.onLayoutCompleted(state)
|
||||
updateJumpToReadMarkerViewVisibility()
|
||||
jumpToBottomViewVisibilityManager.maybeShowJumpToBottomViewVisibilityWithDelay()
|
||||
withState(messageComposerViewModel) { composerState ->
|
||||
if (!composerState.isFullScreen) {
|
||||
jumpToBottomViewVisibilityManager.maybeShowJumpToBottomViewVisibilityWithDelay()
|
||||
} else {
|
||||
jumpToBottomViewVisibilityManager.hideAndPreventVisibilityChangesWithScrolling()
|
||||
}
|
||||
}
|
||||
}
|
||||
}.apply {
|
||||
// For local rooms, pin the view's content to the top edge (the layout is reversed)
|
||||
|
@ -2002,6 +2039,19 @@ class TimelineFragment :
|
|||
}
|
||||
}
|
||||
|
||||
private fun toggleFullScreenEditor(isFullScreen: Boolean) {
|
||||
views.composerContainer.animateLayoutChange(200)
|
||||
|
||||
val constraintSet = ConstraintSet()
|
||||
val constraintSetId = if (isFullScreen) {
|
||||
R.layout.fragment_timeline_fullscreen
|
||||
} else {
|
||||
R.layout.fragment_timeline
|
||||
}
|
||||
constraintSet.clone(requireContext(), constraintSetId)
|
||||
constraintSet.applyTo(views.rootConstraintLayout)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the current room is a Thread room, false otherwise.
|
||||
*/
|
||||
|
|
|
@ -34,6 +34,8 @@ sealed class MessageComposerAction : VectorViewModelAction {
|
|||
data class SlashCommandConfirmed(val parsedCommand: ParsedCommand) : MessageComposerAction()
|
||||
data class InsertUserDisplayName(val userId: String) : MessageComposerAction()
|
||||
|
||||
data class SetFullScreen(val isFullScreen: Boolean) : MessageComposerAction()
|
||||
|
||||
// Voice Message
|
||||
data class InitializeVoiceRecorder(val attachmentData: ContentAttachmentData) : MessageComposerAction()
|
||||
data class OnVoiceRecordingUiStateChanged(val uiState: VoiceMessageRecorderView.RecordingUiState) : MessageComposerAction()
|
||||
|
|
|
@ -92,6 +92,7 @@ import im.vector.app.features.settings.VectorPreferences
|
|||
import im.vector.app.features.share.SharedData
|
||||
import im.vector.app.features.voice.VoiceFailure
|
||||
import kotlinx.coroutines.flow.debounce
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
@ -219,6 +220,13 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
|
|||
}
|
||||
}
|
||||
|
||||
messageComposerViewModel.stateFlow.map { it.isFullScreen }
|
||||
.distinctUntilChanged()
|
||||
.onEach { isFullScreen ->
|
||||
composer.toggleFullScreen(isFullScreen)
|
||||
}
|
||||
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
handleShareData()
|
||||
}
|
||||
|
@ -297,7 +305,7 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
|
|||
// Show keyboard when the user started a thread
|
||||
composerEditText.showKeyboard(andRequestFocus = true)
|
||||
}
|
||||
composer.callback = object : PlainTextComposerLayout.Callback {
|
||||
composer.callback = object : Callback {
|
||||
override fun onAddAttachment() {
|
||||
if (!::attachmentTypeSelector.isInitialized) {
|
||||
attachmentTypeSelector = AttachmentTypeSelectorView(vectorBaseActivity, vectorBaseActivity.layoutInflater, this@MessageComposerFragment)
|
||||
|
@ -320,8 +328,12 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
|
|||
composer.emojiButton?.isVisible = isEmojiKeyboardVisible
|
||||
}
|
||||
|
||||
override fun onSendMessage(text: CharSequence) {
|
||||
override fun onSendMessage(text: CharSequence) = withState(messageComposerViewModel) { state ->
|
||||
sendTextMessage(text, composer.formattedText)
|
||||
|
||||
if (state.isFullScreen) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.SetFullScreen(false))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCloseRelatedMessage() {
|
||||
|
@ -335,6 +347,10 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
|
|||
override fun onTextChanged(text: CharSequence) {
|
||||
messageComposerViewModel.handle(MessageComposerAction.OnTextChanged(text))
|
||||
}
|
||||
|
||||
override fun onFullScreenModeChanged() = withState(messageComposerViewModel) { state ->
|
||||
messageComposerViewModel.handle(MessageComposerAction.SetFullScreen(!state.isFullScreen))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -461,7 +477,7 @@ class MessageComposerFragment : VectorBaseFragment<FragmentComposerBinding>(), A
|
|||
composer.sendButton.alpha = 0f
|
||||
composer.sendButton.isVisible = true
|
||||
composer.sendButton.animate().alpha(1f).setDuration(150).start()
|
||||
} else {
|
||||
} else if (!event.isVisible) {
|
||||
composer.sendButton.isInvisible = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,13 +30,14 @@ interface MessageComposerView {
|
|||
val emojiButton: ImageButton?
|
||||
val sendButton: ImageButton
|
||||
val attachmentButton: ImageButton
|
||||
val fullScreenButton: ImageButton?
|
||||
val composerRelatedMessageTitle: TextView
|
||||
val composerRelatedMessageContent: TextView
|
||||
val composerRelatedMessageImage: ImageView
|
||||
val composerRelatedMessageActionIcon: ImageView
|
||||
val composerRelatedMessageAvatar: ImageView
|
||||
|
||||
var callback: PlainTextComposerLayout.Callback?
|
||||
var callback: Callback?
|
||||
|
||||
var isVisible: Boolean
|
||||
|
||||
|
@ -44,6 +45,15 @@ interface MessageComposerView {
|
|||
fun expand(animate: Boolean = true, transitionComplete: (() -> Unit)? = null)
|
||||
fun setTextIfDifferent(text: CharSequence?): Boolean
|
||||
fun replaceFormattedContent(text: CharSequence)
|
||||
fun toggleFullScreen(newValue: Boolean)
|
||||
|
||||
fun setInvisible(isInvisible: Boolean)
|
||||
}
|
||||
|
||||
interface Callback : ComposerEditText.Callback {
|
||||
fun onCloseRelatedMessage()
|
||||
fun onSendMessage(text: CharSequence)
|
||||
fun onAddAttachment()
|
||||
fun onExpandOrCompactChange()
|
||||
fun onFullScreenModeChanged()
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package im.vector.app.features.home.room.detail.composer
|
||||
|
||||
import android.text.SpannableString
|
||||
import androidx.lifecycle.asFlow
|
||||
import com.airbnb.mvrx.MavericksViewModelFactory
|
||||
import dagger.assisted.Assisted
|
||||
|
@ -122,6 +123,7 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
is MessageComposerAction.AudioSeekBarMovedTo -> handleAudioSeekBarMovedTo(action)
|
||||
is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(action)
|
||||
is MessageComposerAction.InsertUserDisplayName -> handleInsertUserDisplayName(action)
|
||||
is MessageComposerAction.SetFullScreen -> handleSetFullScreen(action)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,12 +132,11 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
}
|
||||
|
||||
private fun handleOnTextChanged(action: MessageComposerAction.OnTextChanged) {
|
||||
setState {
|
||||
// Makes sure currentComposerText is upToDate when accessing further setState
|
||||
currentComposerText = action.text
|
||||
this
|
||||
val needsSendButtonVisibilityUpdate = currentComposerText.isEmpty() != action.text.isEmpty()
|
||||
currentComposerText = SpannableString(action.text)
|
||||
if (needsSendButtonVisibilityUpdate) {
|
||||
updateIsSendButtonVisibility(true)
|
||||
}
|
||||
updateIsSendButtonVisibility(true)
|
||||
}
|
||||
|
||||
private fun subscribeToStateInternal() {
|
||||
|
@ -163,6 +164,10 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleSetFullScreen(action: MessageComposerAction.SetFullScreen) {
|
||||
setState { copy(isFullScreen = action.isFullScreen) }
|
||||
}
|
||||
|
||||
private fun observePowerLevelAndEncryption() {
|
||||
combine(
|
||||
PowerLevelsFlowFactory(room).createFlow(),
|
||||
|
|
|
@ -70,6 +70,7 @@ data class MessageComposerViewState(
|
|||
val voiceRecordingUiState: VoiceMessageRecorderView.RecordingUiState = VoiceMessageRecorderView.RecordingUiState.Idle,
|
||||
val voiceBroadcastState: VoiceBroadcastState? = null,
|
||||
val text: CharSequence? = null,
|
||||
val isFullScreen: Boolean = false,
|
||||
) : MavericksState {
|
||||
|
||||
val isVoiceRecording = when (voiceRecordingUiState) {
|
||||
|
|
|
@ -49,13 +49,6 @@ class PlainTextComposerLayout @JvmOverloads constructor(
|
|||
defStyleAttr: Int = 0
|
||||
) : ConstraintLayout(context, attrs, defStyleAttr), MessageComposerView {
|
||||
|
||||
interface Callback : ComposerEditText.Callback {
|
||||
fun onCloseRelatedMessage()
|
||||
fun onSendMessage(text: CharSequence)
|
||||
fun onAddAttachment()
|
||||
fun onExpandOrCompactChange()
|
||||
}
|
||||
|
||||
private val views: ComposerLayoutBinding
|
||||
|
||||
override var callback: Callback? = null
|
||||
|
@ -83,6 +76,7 @@ class PlainTextComposerLayout @JvmOverloads constructor(
|
|||
}
|
||||
override val attachmentButton: ImageButton
|
||||
get() = views.attachmentButton
|
||||
override val fullScreenButton: ImageButton? = null
|
||||
override val composerRelatedMessageActionIcon: ImageView
|
||||
get() = views.composerRelatedMessageActionIcon
|
||||
override val composerRelatedMessageAvatar: ImageView
|
||||
|
@ -155,6 +149,10 @@ class PlainTextComposerLayout @JvmOverloads constructor(
|
|||
return views.composerEditText.setTextIfDifferent(text)
|
||||
}
|
||||
|
||||
override fun toggleFullScreen(newValue: Boolean) {
|
||||
// Plain text composer has no full screen
|
||||
}
|
||||
|
||||
private fun applyNewConstraintSet(animate: Boolean, transitionComplete: (() -> Unit)?) {
|
||||
// val wasSendButtonInvisible = views.sendButton.isInvisible
|
||||
if (animate) {
|
||||
|
|
|
@ -21,7 +21,6 @@ import android.text.Editable
|
|||
import android.text.TextWatcher
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.EditText
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ImageView
|
||||
|
@ -33,13 +32,8 @@ import androidx.constraintlayout.widget.ConstraintSet
|
|||
import androidx.core.text.toSpannable
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.transition.ChangeBounds
|
||||
import androidx.transition.Fade
|
||||
import androidx.transition.Transition
|
||||
import androidx.transition.TransitionManager
|
||||
import androidx.transition.TransitionSet
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.animations.SimpleTransitionListener
|
||||
import im.vector.app.core.extensions.animateLayoutChange
|
||||
import im.vector.app.core.extensions.setTextIfDifferent
|
||||
import im.vector.app.databinding.ComposerRichTextLayoutBinding
|
||||
import im.vector.app.databinding.ViewRichTextMenuButtonBinding
|
||||
|
@ -56,12 +50,13 @@ class RichTextComposerLayout @JvmOverloads constructor(
|
|||
|
||||
private val views: ComposerRichTextLayoutBinding
|
||||
|
||||
override var callback: PlainTextComposerLayout.Callback? = null
|
||||
override var callback: Callback? = null
|
||||
|
||||
private var currentConstraintSetId: Int = -1
|
||||
|
||||
private val animationDuration = 100L
|
||||
|
||||
private var isFullScreen = false
|
||||
|
||||
override val text: Editable?
|
||||
get() = views.composerEditText.text
|
||||
override val formattedText: String?
|
||||
|
@ -74,6 +69,8 @@ class RichTextComposerLayout @JvmOverloads constructor(
|
|||
get() = views.sendButton
|
||||
override val attachmentButton: ImageButton
|
||||
get() = views.attachmentButton
|
||||
override val fullScreenButton: ImageButton?
|
||||
get() = views.composerFullScreenButton
|
||||
override val composerRelatedMessageActionIcon: ImageView
|
||||
get() = views.composerRelatedMessageActionIcon
|
||||
override val composerRelatedMessageAvatar: ImageView
|
||||
|
@ -124,6 +121,10 @@ class RichTextComposerLayout @JvmOverloads constructor(
|
|||
callback?.onAddAttachment()
|
||||
}
|
||||
|
||||
views.composerFullScreenButton.setOnClickListener {
|
||||
callback?.onFullScreenModeChanged()
|
||||
}
|
||||
|
||||
setupRichTextMenu()
|
||||
}
|
||||
|
||||
|
@ -205,34 +206,30 @@ class RichTextComposerLayout @JvmOverloads constructor(
|
|||
return views.composerEditText.setTextIfDifferent(text)
|
||||
}
|
||||
|
||||
override fun toggleFullScreen(newValue: Boolean) {
|
||||
val constraintSetId = if (newValue) R.layout.composer_rich_text_layout_constraint_set_fullscreen else currentConstraintSetId
|
||||
ConstraintSet().also {
|
||||
it.clone(context, constraintSetId)
|
||||
it.applyTo(this)
|
||||
}
|
||||
|
||||
updateTextFieldBorder(newValue)
|
||||
}
|
||||
|
||||
private fun applyNewConstraintSet(animate: Boolean, transitionComplete: (() -> Unit)?) {
|
||||
// val wasSendButtonInvisible = views.sendButton.isInvisible
|
||||
if (animate) {
|
||||
configureAndBeginTransition(transitionComplete)
|
||||
animateLayoutChange(animationDuration, transitionComplete)
|
||||
}
|
||||
ConstraintSet().also {
|
||||
it.clone(context, currentConstraintSetId)
|
||||
it.applyTo(this)
|
||||
}
|
||||
|
||||
// Might be updated by view state just after, but avoid blinks
|
||||
// views.sendButton.isInvisible = wasSendButtonInvisible
|
||||
}
|
||||
|
||||
private fun configureAndBeginTransition(transitionComplete: (() -> Unit)? = null) {
|
||||
val transition = TransitionSet().apply {
|
||||
ordering = TransitionSet.ORDERING_SEQUENTIAL
|
||||
addTransition(ChangeBounds())
|
||||
addTransition(Fade(Fade.IN))
|
||||
duration = animationDuration
|
||||
addListener(object : SimpleTransitionListener() {
|
||||
override fun onTransitionEnd(transition: Transition) {
|
||||
transitionComplete?.invoke()
|
||||
}
|
||||
})
|
||||
}
|
||||
TransitionManager.beginDelayedTransition((parent as? ViewGroup ?: this), transition)
|
||||
}
|
||||
|
||||
override fun setInvisible(isInvisible: Boolean) {
|
||||
this.isInvisible = isInvisible
|
||||
}
|
||||
|
|
9
vector/src/main/res/drawable/ic_composer_full_screen.xml
Normal file
9
vector/src/main/res/drawable/ic_composer_full_screen.xml
Normal file
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="48dp"
|
||||
android:height="48dp"
|
||||
android:viewportWidth="48"
|
||||
android:viewportHeight="48">
|
||||
<path
|
||||
android:pathData="M17.125,31.5C16.944,31.5 16.795,31.441 16.677,31.323C16.559,31.205 16.5,31.056 16.5,30.875V25.875C16.5,25.694 16.559,25.545 16.677,25.427C16.795,25.309 16.944,25.25 17.125,25.25C17.306,25.25 17.455,25.309 17.573,25.427C17.691,25.545 17.75,25.694 17.75,25.875V29.375L29.375,17.75H25.875C25.694,17.75 25.545,17.691 25.427,17.573C25.309,17.455 25.25,17.306 25.25,17.125C25.25,16.944 25.309,16.795 25.427,16.677C25.545,16.559 25.694,16.5 25.875,16.5H30.875C31.056,16.5 31.205,16.559 31.323,16.677C31.441,16.795 31.5,16.944 31.5,17.125V22.125C31.5,22.306 31.441,22.455 31.323,22.573C31.205,22.691 31.056,22.75 30.875,22.75C30.694,22.75 30.545,22.691 30.427,22.573C30.309,22.455 30.25,22.306 30.25,22.125V18.625L18.625,30.25H22.125C22.306,30.25 22.455,30.309 22.573,30.427C22.691,30.545 22.75,30.694 22.75,30.875C22.75,31.056 22.691,31.205 22.573,31.323C22.455,31.441 22.306,31.5 22.125,31.5H17.125Z"
|
||||
android:fillColor="#C1C6CD"/>
|
||||
</vector>
|
|
@ -3,7 +3,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
tools:constraintSet="@layout/composer_rich_text_layout_constraint_set_compact"
|
||||
tools:parentTag="androidx.constraintlayout.widget.ConstraintLayout">
|
||||
|
||||
|
@ -108,12 +108,24 @@
|
|||
style="@style/Widget.Vector.EditText.RichTextComposer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top"
|
||||
android:nextFocusLeft="@id/composerEditText"
|
||||
android:nextFocusUp="@id/composerEditText"
|
||||
tools:hint="@string/room_message_placeholder"
|
||||
tools:text="@tools:sample/lorem/random"
|
||||
tools:ignore="MissingConstraints" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/composerFullScreenButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
android:src="@drawable/ic_composer_full_screen"
|
||||
android:background="?android:attr/selectableItemBackgroundBorderless"
|
||||
android:contentDescription="@string/rich_text_editor_full_screen_toggle" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/sendButton"
|
||||
android:layout_width="0dp"
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/composerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
@ -114,6 +114,7 @@
|
|||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/option_send_files"
|
||||
android:src="@drawable/ic_attachment"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sendButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/sendButton"
|
||||
|
@ -142,14 +143,26 @@
|
|||
android:hint="@string/room_message_placeholder"
|
||||
android:nextFocusLeft="@id/composerEditText"
|
||||
android:nextFocusUp="@id/composerEditText"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toStartOf="@id/composerFullScreenButton"
|
||||
app:layout_constraintStart_toStartOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/composerFullScreenButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
android:src="@drawable/ic_composer_full_screen"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/rich_text_editor_full_screen_toggle" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/sendButton"
|
||||
android:layout_width="56dp"
|
||||
|
@ -163,6 +176,7 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
@ -173,6 +187,7 @@
|
|||
app:layout_constraintStart_toEndOf="@id/attachmentButton"
|
||||
app:layout_constraintEnd_toStartOf="@id/sendButton"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/composerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
@ -156,14 +156,26 @@
|
|||
android:hint="@string/room_message_placeholder"
|
||||
android:nextFocusLeft="@id/composerEditText"
|
||||
android:nextFocusUp="@id/composerEditText"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toStartOf="@id/composerFullScreenButton"
|
||||
app:layout_constraintStart_toStartOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/composerFullScreenButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
android:src="@drawable/ic_composer_full_screen"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/rich_text_editor_full_screen_toggle" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/sendButton"
|
||||
android:layout_width="56dp"
|
||||
|
|
|
@ -0,0 +1,217 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/composerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent">
|
||||
|
||||
<View
|
||||
android:id="@+id/related_message_background"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?colorSurface"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_height="40dp" />
|
||||
|
||||
<View
|
||||
android:id="@+id/related_message_background_top_separator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?vctr_list_separator"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/composerRelatedMessageAvatar"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/composerRelatedMessageTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textStyle="bold"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="@id/composerRelatedMessageContent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="@tools:sample/first_names" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/composerRelatedMessageContent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/composerRelatedMessageActionIcon"
|
||||
android:layout_width="20dp"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="38dp"
|
||||
android:alpha="0"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintEnd_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="parent"
|
||||
app:tint="?vctr_content_primary"
|
||||
tools:ignore="MissingConstraints,MissingPrefix"
|
||||
tools:src="@drawable/ic_edit" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/composerRelatedMessageImage"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:importantForAccessibility="no"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="parent"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:src="@tools:sample/backgrounds/scenic" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/composerRelatedMessageCloseButton"
|
||||
android:layout_width="22dp"
|
||||
android:layout_height="22dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/action_cancel"
|
||||
android:src="@drawable/ic_close_round"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="parent"
|
||||
app:layout_constraintStart_toEndOf="parent"
|
||||
app:tint="?colorError"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/composer_preview_barrier"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:barrierDirection="bottom"
|
||||
app:barrierMargin="8dp"
|
||||
app:constraint_referenced_ids="composerRelatedMessageContent,composerRelatedMessageActionIcon"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/attachmentButton"
|
||||
android:layout_width="@dimen/composer_attachment_size"
|
||||
android:layout_height="@dimen/composer_attachment_size"
|
||||
android:layout_margin="@dimen/composer_attachment_margin"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/option_send_files"
|
||||
android:src="@drawable/ic_attachment"
|
||||
app:layout_constraintBottom_toBottomOf="@id/sendButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@id/sendButton"
|
||||
app:layout_goneMarginBottom="57dp"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
tools:ignore="MissingPrefix" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/composerEditTextOuterBorder"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:minHeight="40dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:background="@drawable/bg_composer_rich_edit_text_expanded"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintBottom_toTopOf="@id/sendButton"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
|
||||
<io.element.android.wysiwyg.EditorEditText
|
||||
android:id="@+id/composerEditText"
|
||||
style="@style/Widget.Vector.EditText.RichTextComposer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:hint="@string/room_message_placeholder"
|
||||
android:nextFocusLeft="@id/composerEditText"
|
||||
android:nextFocusUp="@id/composerEditText"
|
||||
android:layout_marginStart="12dp"
|
||||
android:layout_marginVertical="10dp"
|
||||
android:gravity="top"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toStartOf="@id/composerFullScreenButton"
|
||||
app:layout_constraintStart_toStartOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
tools:text="@tools:sample/lorem/random" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/composerFullScreenButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintEnd_toEndOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintBottom_toBottomOf="@id/composerEditTextOuterBorder"
|
||||
app:layout_constraintVertical_bias="0"
|
||||
android:src="@drawable/ic_composer_full_screen"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/rich_text_editor_full_screen_toggle" />
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/sendButton"
|
||||
android:layout_width="56dp"
|
||||
android:layout_height="@dimen/composer_min_height"
|
||||
android:layout_marginEnd="2dp"
|
||||
android:background="@drawable/bg_send"
|
||||
android:contentDescription="@string/action_send"
|
||||
android:scaleType="center"
|
||||
android:src="@drawable/ic_send"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
tools:ignore="MissingPrefix"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<HorizontalScrollView android:id="@+id/richTextMenuScrollView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="@id/sendButton"
|
||||
app:layout_constraintStart_toEndOf="@id/attachmentButton"
|
||||
app:layout_constraintEnd_toStartOf="@id/sendButton"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintVertical_bias="1"
|
||||
android:fillViewport="true">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/richTextMenu"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</HorizontalScrollView>
|
||||
|
||||
<!--
|
||||
<ImageButton
|
||||
android:id="@+id/voiceMessageMicButton"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginBottom="12dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:contentDescription="@string/a11y_start_voice_message"
|
||||
android:src="@drawable/ic_voice_mic"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent" />
|
||||
-->
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<im.vector.app.features.home.room.detail.composer.PlainTextComposerLayout
|
||||
android:id="@+id/composerLayout"
|
||||
|
@ -19,7 +19,7 @@
|
|||
<im.vector.app.features.home.room.detail.composer.RichTextComposerLayout
|
||||
android:id="@+id/richTextComposerLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?android:colorBackground"
|
||||
android:minHeight="56dp"
|
||||
android:transitionName="composer"
|
||||
|
|
|
@ -6,6 +6,21 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- ========================
|
||||
/!\ Constraints for this layout are defined in external layout files that are used as constraint set for animation.
|
||||
/!\ These 2 files must be modified to stay coherent!
|
||||
======================== -->
|
||||
|
||||
<View android:id="@+id/scrim"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:visibility="gone"
|
||||
android:background="#44000000" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -98,6 +113,7 @@
|
|||
android:layout_height="wrap_content"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
@ -128,6 +144,7 @@
|
|||
android:id="@+id/composerContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:colorBackground"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
@ -165,6 +182,7 @@
|
|||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/a11y_jump_to_bottom"
|
||||
android:src="@drawable/ic_expand_more"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="#FFFFFF"
|
||||
app:badgeBackgroundColor="?colorPrimary"
|
||||
app:badgeTextColor="?colorOnPrimary"
|
||||
|
|
258
vector/src/main/res/layout/fragment_timeline_fullscreen.xml
Normal file
258
vector/src/main/res/layout/fragment_timeline_fullscreen.xml
Normal file
|
@ -0,0 +1,258 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/rootConstraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<!-- ========================
|
||||
/!\ Constraints for this layout are defined in external layout files that are used as constraint set for animation.
|
||||
/!\ These 2 files must be modified to stay coherent!
|
||||
======================== -->
|
||||
|
||||
<View android:id="@+id/scrim"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:translationZ="10dp"
|
||||
android:visibility="visible"
|
||||
android:background="#44000000" />
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appBarLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<im.vector.app.core.ui.views.CurrentCallsView
|
||||
android:id="@+id/currentCallsView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="48dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/roomToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?actionBarSize"
|
||||
android:transitionName="toolbar">
|
||||
|
||||
<include
|
||||
android:id="@+id/includeThreadToolbar"
|
||||
layout="@layout/view_room_detail_thread_toolbar" />
|
||||
|
||||
<include
|
||||
android:id="@+id/includeRoomToolbar"
|
||||
layout="@layout/view_room_detail_toolbar" />
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<im.vector.app.features.sync.widget.SyncStateView
|
||||
android:id="@+id/syncStateView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout" />
|
||||
|
||||
<im.vector.app.features.location.live.LiveLocationStatusView
|
||||
android:id="@+id/liveLocationStatusIndicator"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/syncStateView"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<im.vector.app.features.call.conference.RemoveJitsiWidgetView
|
||||
android:id="@+id/removeJitsiWidgetView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:colorBackground"
|
||||
android:minHeight="54dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/liveLocationStatusIndicator" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/timelineRecyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:overScrollMode="always"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toTopOf="@id/typingMessageView"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView"
|
||||
tools:listitem="@layout/item_timeline_event_base" />
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
android:id="@+id/jumpToReadMarkerView"
|
||||
style="?vctr_jump_to_unread_style"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/room_jump_to_first_unread"
|
||||
android:visibility="invisible"
|
||||
app:chipIcon="@drawable/ic_jump_to_unread"
|
||||
app:chipIconTint="?colorPrimary"
|
||||
app:closeIcon="@drawable/ic_close_24dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/removeJitsiWidgetView" />
|
||||
|
||||
<im.vector.app.core.ui.views.TypingMessageView
|
||||
android:id="@+id/typingMessageView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="20dp"
|
||||
android:paddingEnd="20dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/timelineRecyclerView" />
|
||||
|
||||
<im.vector.app.core.ui.views.NotificationAreaView
|
||||
android:id="@+id/notificationAreaView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/failedMessagesWarningStub"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inflatedId="@+id/failedMessagesWarningStub"
|
||||
android:layout="@layout/view_stub_failed_message_warning_layout"
|
||||
app:layout_constraintBottom_toTopOf="@id/composerContainer"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
tools:layout_height="300dp" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/composerContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:colorBackground"
|
||||
android:translationZ="48dp"
|
||||
android:layout_marginTop="10dp"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/voiceMessageRecorderContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:translationZ="48dp"
|
||||
android:background="?android:colorBackground"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<ViewStub
|
||||
android:id="@+id/inviteViewStub"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:colorBackground"
|
||||
android:layout="@layout/view_stub_invite_layout"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/appBarLayout" />
|
||||
|
||||
<androidx.constraintlayout.widget.Barrier
|
||||
android:id="@+id/bottomBarrier"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:barrierDirection="top"
|
||||
app:constraint_referenced_ids="notificationAreaView,failedMessagesWarningStub" />
|
||||
|
||||
<im.vector.app.core.platform.BadgeFloatingActionButton
|
||||
android:id="@+id/jumpToBottomView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:contentDescription="@string/a11y_jump_to_bottom"
|
||||
android:src="@drawable/ic_expand_more"
|
||||
android:visibility="gone"
|
||||
app:backgroundTint="#FFFFFF"
|
||||
app:badgeBackgroundColor="?colorPrimary"
|
||||
app:badgeTextColor="?colorOnPrimary"
|
||||
app:badgeTextPadding="2dp"
|
||||
app:badgeTextSize="10sp"
|
||||
app:layout_constraintBottom_toTopOf="@id/bottomBarrier"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:tint="@android:color/black" />
|
||||
|
||||
<im.vector.app.core.ui.views.CompatKonfetti
|
||||
android:id="@+id/viewKonfetti"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<com.jetradarmobile.snowfall.SnowfallView
|
||||
android:id="@+id/viewSnowFall"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="?vctr_chat_effect_snow_background"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<!-- Room not found layout -->
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:id="@+id/roomNotFound"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:background="?android:colorBackground"
|
||||
android:elevation="10dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="gone">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/roomNotFoundIcon"
|
||||
android:layout_width="60dp"
|
||||
android:layout_height="60dp"
|
||||
android:importantForAccessibility="no"
|
||||
android:src="@drawable/ic_alert_triangle"
|
||||
app:layout_constraintBottom_toTopOf="@id/roomNotFoundText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_chainStyle="packed" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/roomNotFoundText"
|
||||
style="@style/Widget.Vector.TextView.Subtitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||
android:gravity="center"
|
||||
android:paddingHorizontal="16dp"
|
||||
android:text="@string/timeline_error_room_not_found"
|
||||
android:textColor="?vctr_content_primary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/roomNotFoundIcon" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
Reference in a new issue