Timeline : start to handle video media. Probably to amend
This commit is contained in:
parent
657f4d3e9c
commit
2c83ba0824
|
@ -24,8 +24,11 @@ import im.vector.matrix.android.api.session.content.ContentAttachmentData
|
|||
import im.vector.matrix.android.api.session.events.model.Event
|
||||
import im.vector.matrix.android.api.session.events.model.toContent
|
||||
import im.vector.matrix.android.api.session.events.model.toModel
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageAudioContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageFileContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageImageContent
|
||||
import im.vector.matrix.android.api.session.room.model.message.MessageVideoContent
|
||||
import im.vector.matrix.android.internal.di.MatrixKoinComponent
|
||||
import im.vector.matrix.android.internal.session.room.send.SendEventWorker
|
||||
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
||||
|
@ -69,6 +72,9 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
|
|||
val messageContent: MessageContent = event.content.toModel() ?: return event
|
||||
val updatedContent = when (messageContent) {
|
||||
is MessageImageContent -> messageContent.update(url)
|
||||
is MessageVideoContent -> messageContent.update(url)
|
||||
is MessageFileContent -> messageContent.update(url)
|
||||
is MessageAudioContent -> messageContent.update(url)
|
||||
else -> messageContent
|
||||
}
|
||||
return event.copy(content = updatedContent.toContent())
|
||||
|
@ -78,6 +84,18 @@ internal class UploadContentWorker(context: Context, params: WorkerParameters)
|
|||
return copy(url = url)
|
||||
}
|
||||
|
||||
private fun MessageVideoContent.update(url: String): MessageVideoContent {
|
||||
return copy(url = url)
|
||||
}
|
||||
|
||||
private fun MessageFileContent.update(url: String): MessageFileContent {
|
||||
return copy(url = url)
|
||||
}
|
||||
|
||||
private fun MessageAudioContent.update(url: String): MessageAudioContent {
|
||||
return copy(url = url)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@ dependencies {
|
|||
implementation "com.github.piasy:GlideImageViewFactory:$big_image_viewer_version"
|
||||
implementation "com.github.bumptech.glide:glide:$glide_version"
|
||||
kapt "com.github.bumptech.glide:compiler:$glide_version"
|
||||
implementation 'com.danikula:videocache:2.7.1'
|
||||
|
||||
// Badge for compatibility
|
||||
implementation 'me.leolin:ShortcutBadger:1.1.2@aar'
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
|
||||
<activity android:name=".features.home.HomeActivity" />
|
||||
<activity android:name=".features.login.LoginActivity" />
|
||||
<activity android:name=".features.media.MediaViewerActivity" />
|
||||
<activity android:name=".features.media.ImageMediaViewerActivity" />
|
||||
<activity
|
||||
android:name=".features.rageshake.BugReportActivity"
|
||||
android:label="@string/title_activity_bug_report" />
|
||||
|
@ -37,6 +37,7 @@
|
|||
android:name=".features.settings.VectorSettingsActivity"
|
||||
android:label="@string/title_activity_settings"
|
||||
android:windowSoftInputMode="adjustResize" />
|
||||
<activity android:name=".features.media.VideoMediaViewerActivity" />
|
||||
|
||||
<service
|
||||
android:name=".core.services.CallService"
|
||||
|
|
|
@ -70,7 +70,9 @@ import im.vector.riotredesign.features.home.room.detail.timeline.TimelineEventCo
|
|||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.EndlessRecyclerViewScrollListener
|
||||
import im.vector.riotredesign.features.html.PillImageSpan
|
||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||
import im.vector.riotredesign.features.media.MediaViewerActivity
|
||||
import im.vector.riotredesign.features.media.ImageMediaViewerActivity
|
||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||
import im.vector.riotredesign.features.media.VideoMediaViewerActivity
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
import kotlinx.android.synthetic.main.fragment_room_detail.*
|
||||
import org.koin.android.ext.android.inject
|
||||
|
@ -384,12 +386,13 @@ class RoomDetailFragment : VectorBaseFragment(), TimelineEventController.Callbac
|
|||
}
|
||||
|
||||
override fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View) {
|
||||
val intent = MediaViewerActivity.newIntent(vectorBaseActivity, mediaData)
|
||||
val intent = ImageMediaViewerActivity.newIntent(vectorBaseActivity, mediaData)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: ImageContentRenderer.Data, view: View) {
|
||||
vectorBaseActivity.notImplemented()
|
||||
override fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View) {
|
||||
val intent = VideoMediaViewerActivity.newIntent(vectorBaseActivity, mediaData)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
override fun onFileMessageClicked(messageFileContent: MessageFileContent) {
|
||||
|
|
|
@ -42,6 +42,7 @@ import im.vector.riotredesign.features.home.room.detail.timeline.helper.Timeline
|
|||
import im.vector.riotredesign.features.home.room.detail.timeline.helper.nextDisplayableEvent
|
||||
import im.vector.riotredesign.features.home.room.detail.timeline.item.DaySeparatorItem_
|
||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||
|
||||
class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
||||
private val timelineItemFactory: TimelineItemFactory,
|
||||
|
@ -53,7 +54,7 @@ class TimelineEventController(private val dateFormatter: TimelineDateFormatter,
|
|||
fun onEventVisible(event: TimelineEvent)
|
||||
fun onUrlClicked(url: String)
|
||||
fun onImageMessageClicked(messageImageContent: MessageImageContent, mediaData: ImageContentRenderer.Data, view: View)
|
||||
fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: ImageContentRenderer.Data, view: View)
|
||||
fun onVideoMessageClicked(messageVideoContent: MessageVideoContent, mediaData: VideoContentRenderer.Data, view: View)
|
||||
fun onFileMessageClicked(messageFileContent: MessageFileContent)
|
||||
fun onAudioMessageClicked(messageAudioContent: MessageAudioContent)
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTex
|
|||
import im.vector.riotredesign.features.home.room.detail.timeline.item.MessageTextItem_
|
||||
import im.vector.riotredesign.features.html.EventHtmlRenderer
|
||||
import im.vector.riotredesign.features.media.ImageContentRenderer
|
||||
import im.vector.riotredesign.features.media.VideoContentRenderer
|
||||
import me.gujun.android.span.span
|
||||
|
||||
class MessageItemFactory(private val colorProvider: ColorProvider,
|
||||
|
@ -157,7 +158,7 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||
callback: TimelineEventController.Callback?): MessageImageVideoItem? {
|
||||
|
||||
val (maxWidth, maxHeight) = timelineMediaSizeProvider.getMaxSize()
|
||||
val data = ImageContentRenderer.Data(
|
||||
val thumbnailData = ImageContentRenderer.Data(
|
||||
filename = messageContent.body,
|
||||
url = messageContent.info?.thumbnailUrl,
|
||||
height = messageContent.info?.height,
|
||||
|
@ -165,11 +166,18 @@ class MessageItemFactory(private val colorProvider: ColorProvider,
|
|||
width = messageContent.info?.width,
|
||||
maxWidth = maxWidth
|
||||
)
|
||||
|
||||
val videoData = VideoContentRenderer.Data(
|
||||
filename = messageContent.body,
|
||||
videoUrl = messageContent.url,
|
||||
thumbnailMediaData = thumbnailData
|
||||
)
|
||||
|
||||
return MessageImageVideoItem_()
|
||||
.playable(true)
|
||||
.informationData(informationData)
|
||||
.mediaData(data)
|
||||
.clickListener { view -> callback?.onVideoMessageClicked(messageContent, data, view) }
|
||||
.mediaData(thumbnailData)
|
||||
.clickListener { view -> callback?.onVideoMessageClicked(messageContent, videoData, view) }
|
||||
}
|
||||
|
||||
private fun buildTextMessageItem(messageContent: MessageTextContent,
|
||||
|
|
|
@ -25,22 +25,22 @@ import androidx.appcompat.widget.Toolbar
|
|||
import com.github.piasy.biv.indicator.progresspie.ProgressPieIndicator
|
||||
import com.github.piasy.biv.view.GlideImageViewFactory
|
||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||
import kotlinx.android.synthetic.main.activity_media_viewer.*
|
||||
import kotlinx.android.synthetic.main.activity_image_media_viewer.*
|
||||
|
||||
|
||||
class MediaViewerActivity : VectorBaseActivity() {
|
||||
class ImageMediaViewerActivity : VectorBaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(im.vector.riotredesign.R.layout.activity_media_viewer)
|
||||
setContentView(im.vector.riotredesign.R.layout.activity_image_media_viewer)
|
||||
val mediaData = intent.getParcelableExtra<ImageContentRenderer.Data>(EXTRA_MEDIA_DATA)
|
||||
if (mediaData.url.isNullOrEmpty()) {
|
||||
finish()
|
||||
} else {
|
||||
configureToolbar(mediaViewerToolbar, mediaData)
|
||||
mediaViewerImageView.setImageViewFactory(GlideImageViewFactory())
|
||||
mediaViewerImageView.setProgressIndicator(ProgressPieIndicator())
|
||||
ImageContentRenderer.render(mediaData, mediaViewerImageView)
|
||||
configureToolbar(imageMediaViewerToolbar, mediaData)
|
||||
imageMediaViewerImageView.setImageViewFactory(GlideImageViewFactory())
|
||||
imageMediaViewerImageView.setProgressIndicator(ProgressPieIndicator())
|
||||
ImageContentRenderer.render(mediaData, imageMediaViewerImageView)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ class MediaViewerActivity : VectorBaseActivity() {
|
|||
private const val EXTRA_MEDIA_DATA = "EXTRA_MEDIA_DATA"
|
||||
|
||||
fun newIntent(context: Context, mediaData: ImageContentRenderer.Data): Intent {
|
||||
return Intent(context, MediaViewerActivity::class.java).apply {
|
||||
return Intent(context, ImageMediaViewerActivity::class.java).apply {
|
||||
putExtra(EXTRA_MEDIA_DATA, mediaData)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.riotredesign.features.media
|
||||
|
||||
import android.os.Parcelable
|
||||
import android.widget.ImageView
|
||||
import android.widget.VideoView
|
||||
import im.vector.matrix.android.api.Matrix
|
||||
import kotlinx.android.parcel.Parcelize
|
||||
|
||||
object VideoContentRenderer {
|
||||
|
||||
@Parcelize
|
||||
data class Data(
|
||||
val filename: String,
|
||||
val videoUrl: String?,
|
||||
val thumbnailMediaData: ImageContentRenderer.Data
|
||||
) : Parcelable
|
||||
|
||||
fun render(data: Data, thumbnailView: ImageView, videoView: VideoView) {
|
||||
val contentUrlResolver = Matrix.getInstance().currentSession!!.contentUrlResolver()
|
||||
val resolvedUrl = contentUrlResolver.resolveFullSize(data.videoUrl)
|
||||
videoView.setVideoPath(resolvedUrl)
|
||||
videoView.start()
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.riotredesign.features.media
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import im.vector.riotredesign.core.platform.VectorBaseActivity
|
||||
import kotlinx.android.synthetic.main.activity_video_media_viewer.*
|
||||
|
||||
|
||||
class VideoMediaViewerActivity : VectorBaseActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(im.vector.riotredesign.R.layout.activity_video_media_viewer)
|
||||
val mediaData = intent.getParcelableExtra<VideoContentRenderer.Data>(EXTRA_MEDIA_DATA)
|
||||
if (mediaData.videoUrl.isNullOrEmpty()) {
|
||||
finish()
|
||||
} else {
|
||||
configureToolbar(videoMediaViewerToolbar, mediaData)
|
||||
VideoContentRenderer.render(mediaData, videoMediaViewerThumbnailView, videoMediaViewerVideoView)
|
||||
}
|
||||
}
|
||||
|
||||
private fun configureToolbar(toolbar: Toolbar, mediaData: VideoContentRenderer.Data) {
|
||||
setSupportActionBar(toolbar)
|
||||
supportActionBar?.apply {
|
||||
title = mediaData.filename
|
||||
setHomeButtonEnabled(true)
|
||||
setDisplayHomeAsUpEnabled(true)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val EXTRA_MEDIA_DATA = "EXTRA_MEDIA_DATA"
|
||||
|
||||
fun newIntent(context: Context, mediaData: VideoContentRenderer.Data): Intent {
|
||||
return Intent(context, VideoMediaViewerActivity::class.java).apply {
|
||||
putExtra(EXTRA_MEDIA_DATA, mediaData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/mediaViewerToolbar"
|
||||
android:id="@+id/imageMediaViewerToolbar"
|
||||
style="@style/VectorToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
|
@ -15,7 +15,7 @@
|
|||
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<com.github.piasy.biv.view.BigImageView
|
||||
android:id="@+id/mediaViewerImageView"
|
||||
android:id="@+id/imageMediaViewerImageView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:failureImageInitScaleType="center"
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
~ 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.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/videoMediaViewerToolbar"
|
||||
style="@style/VectorToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:background="?attr/colorPrimary"
|
||||
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
|
||||
app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/videoMediaViewerThumbnailView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<VideoView
|
||||
android:id="@+id/videoMediaViewerVideoView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
</LinearLayout>
|
Loading…
Reference in New Issue