Add basic timeline voice broadcast item
This commit is contained in:
parent
bcc84c8025
commit
daf4fc0f6d
@ -55,6 +55,8 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageLocationItem
|
|||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageLocationItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MessageLocationItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MessageTextItem_
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastItem
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceBroadcastItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem_
|
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem_
|
||||||
import im.vector.app.features.home.room.detail.timeline.item.PollItem
|
import im.vector.app.features.home.room.detail.timeline.item.PollItem
|
||||||
@ -200,7 +202,7 @@ class MessageItemFactory @Inject constructor(
|
|||||||
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
|
is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes)
|
is MessageLocationContent -> buildLocationItem(messageContent, informationData, highlight, attributes)
|
||||||
is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes)
|
is MessageBeaconInfoContent -> liveLocationShareMessageItemFactory.create(params.event, highlight, attributes)
|
||||||
is MessageVoiceBroadcastInfoContent -> buildVoiceBroadcastItem(messageContent, informationData, highlight, callback, attributes)
|
is MessageVoiceBroadcastInfoContent -> buildVoiceBroadcastItem(messageContent, highlight, callback, attributes)
|
||||||
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes)
|
else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes)
|
||||||
}
|
}
|
||||||
return messageItem?.apply {
|
return messageItem?.apply {
|
||||||
@ -723,32 +725,16 @@ class MessageItemFactory @Inject constructor(
|
|||||||
|
|
||||||
private fun buildVoiceBroadcastItem(
|
private fun buildVoiceBroadcastItem(
|
||||||
messageContent: MessageVoiceBroadcastInfoContent,
|
messageContent: MessageVoiceBroadcastInfoContent,
|
||||||
@Suppress("UNUSED_PARAMETER")
|
|
||||||
informationData: MessageInformationData,
|
|
||||||
highlight: Boolean,
|
highlight: Boolean,
|
||||||
callback: TimelineEventController.Callback?,
|
callback: TimelineEventController.Callback?,
|
||||||
attributes: AbsMessageItem.Attributes,
|
attributes: AbsMessageItem.Attributes,
|
||||||
): MessageTextItem? {
|
): MessageVoiceBroadcastItem? {
|
||||||
val htmlBody = "voice broadcast state: ${messageContent.voiceBroadcastState}"
|
return MessageVoiceBroadcastItem_()
|
||||||
val formattedBody = span {
|
|
||||||
text = htmlBody
|
|
||||||
textColor = colorProvider.getColorFromAttribute(R.attr.vctr_content_secondary)
|
|
||||||
textStyle = "italic"
|
|
||||||
}
|
|
||||||
|
|
||||||
val bindingOptions = spanUtils.getBindingOptions(htmlBody)
|
|
||||||
val message = formattedBody.linkify(callback)
|
|
||||||
|
|
||||||
return MessageTextItem_()
|
|
||||||
.leftGuideline(avatarSizeProvider.leftGuideline)
|
|
||||||
.previewUrlRetriever(callback?.getPreviewUrlRetriever())
|
|
||||||
.imageContentRenderer(imageContentRenderer)
|
|
||||||
.previewUrlCallback(callback)
|
|
||||||
.attributes(attributes)
|
.attributes(attributes)
|
||||||
.message(message.toEpoxyCharSequence())
|
|
||||||
.bindingOptions(bindingOptions)
|
|
||||||
.highlighted(highlight)
|
.highlighted(highlight)
|
||||||
.movementMethod(createLinkMovementMethod(callback))
|
.playingState(messageContent.voiceBroadcastStateStr.toEpoxyCharSequence())
|
||||||
|
.leftGuideline(avatarSizeProvider.leftGuideline)
|
||||||
|
.callback(callback)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun List<Int?>?.toFft(): List<Int>? {
|
private fun List<Int?>?.toFft(): List<Int>? {
|
||||||
|
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 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.features.home.room.detail.timeline.item
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.widget.ImageButton
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.airbnb.epoxy.EpoxyAttribute
|
||||||
|
import com.airbnb.epoxy.EpoxyModelClass
|
||||||
|
import im.vector.app.R
|
||||||
|
import im.vector.app.features.home.room.detail.RoomDetailAction
|
||||||
|
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
|
||||||
|
import im.vector.app.features.voicebroadcast.model.VoiceBroadcastState
|
||||||
|
import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence
|
||||||
|
|
||||||
|
@EpoxyModelClass
|
||||||
|
abstract class MessageVoiceBroadcastItem : AbsMessageItem<MessageVoiceBroadcastItem.Holder>() {
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var callback: TimelineEventController.Callback? = null
|
||||||
|
|
||||||
|
@EpoxyAttribute
|
||||||
|
var playingState: EpoxyCharSequence? = null
|
||||||
|
|
||||||
|
override fun bind(holder: Holder) {
|
||||||
|
super.bind(holder)
|
||||||
|
bindVoiceBroadcastItem(holder)
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("SetTextI18n") // Temporary text
|
||||||
|
private fun bindVoiceBroadcastItem(holder: Holder) {
|
||||||
|
with(holder) {
|
||||||
|
currentStateText.text = "Voice Broadcast state: ${playingState?.charSequence ?: "None"}"
|
||||||
|
val voiceBroadcastState = VoiceBroadcastState.values().find { it.value == playingState?.charSequence }
|
||||||
|
playButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.PAUSED
|
||||||
|
pauseButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED || voiceBroadcastState == VoiceBroadcastState.RESUMED
|
||||||
|
stopButton.isEnabled = voiceBroadcastState == VoiceBroadcastState.STARTED ||
|
||||||
|
voiceBroadcastState == VoiceBroadcastState.RESUMED ||
|
||||||
|
voiceBroadcastState == VoiceBroadcastState.PAUSED
|
||||||
|
playButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Resume) }
|
||||||
|
pauseButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Pause) }
|
||||||
|
stopButton.setOnClickListener { attributes.callback?.onTimelineItemAction(RoomDetailAction.VoiceBroadcastAction.Stop) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getViewStubId() = STUB_ID
|
||||||
|
|
||||||
|
class Holder : AbsMessageLocationItem.Holder(STUB_ID) {
|
||||||
|
val currentStateText by bind<TextView>(R.id.currentStateText)
|
||||||
|
val playButton by bind<ImageButton>(R.id.playButton)
|
||||||
|
val pauseButton by bind<ImageButton>(R.id.pauseButton)
|
||||||
|
val stopButton by bind<ImageButton>(R.id.stopButton)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val STUB_ID = R.id.messageVoiceBroadcastStub
|
||||||
|
}
|
||||||
|
}
|
@ -47,6 +47,13 @@
|
|||||||
android:layout="@layout/item_timeline_event_audio_stub"
|
android:layout="@layout/item_timeline_event_audio_stub"
|
||||||
tools:visibility="gone" />
|
tools:visibility="gone" />
|
||||||
|
|
||||||
|
<ViewStub
|
||||||
|
android:id="@+id/messageVoiceBroadcastStub"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout="@layout/item_timeline_event_voice_broadcast_stub"
|
||||||
|
tools:visibility="gone" />
|
||||||
|
|
||||||
<ViewStub
|
<ViewStub
|
||||||
android:id="@+id/messageContentPollStub"
|
android:id="@+id/messageContentPollStub"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
@ -0,0 +1,62 @@
|
|||||||
|
<?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/messageRootLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="@dimen/layout_vertical_margin"
|
||||||
|
tools:viewBindingIgnore="true">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/currentStateText"
|
||||||
|
style="@style/Widget.Vector.TextView.HeadlineMedium"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/playButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="Voice Broadcast state: STARTED" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/playButton"
|
||||||
|
android:layout_width="@dimen/item_event_message_media_button_size"
|
||||||
|
android:layout_height="@dimen/item_event_message_media_button_size"
|
||||||
|
android:layout_marginTop="@dimen/layout_vertical_margin"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/a11y_play_voice_message"
|
||||||
|
android:src="@drawable/ic_play_pause_play"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/pauseButton"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/currentStateText"
|
||||||
|
app:tint="@color/vector_content_primary_tint_selector" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/pauseButton"
|
||||||
|
android:layout_width="@dimen/item_event_message_media_button_size"
|
||||||
|
android:layout_height="@dimen/item_event_message_media_button_size"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/a11y_pause_voice_message"
|
||||||
|
android:src="@drawable/ic_play_pause_pause"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/playButton"
|
||||||
|
app:layout_constraintEnd_toStartOf="@id/stopButton"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/playButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/playButton"
|
||||||
|
app:tint="@color/vector_content_primary_tint_selector" />
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/stopButton"
|
||||||
|
android:layout_width="@dimen/item_event_message_media_button_size"
|
||||||
|
android:layout_height="@dimen/item_event_message_media_button_size"
|
||||||
|
android:background="?android:attr/selectableItemBackground"
|
||||||
|
android:contentDescription="@string/a11y_stop_voice_message"
|
||||||
|
android:src="@drawable/ic_close_24dp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/pauseButton"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/pauseButton"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/playButton"
|
||||||
|
app:tint="@color/vector_content_primary_tint_selector" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
Loading…
x
Reference in New Issue
Block a user