mirror of
https://github.com/element-hq/element-android
synced 2024-11-27 20:06:51 +03:00
Gif support
This commit is contained in:
parent
4a2a6d34ae
commit
2d4a728af4
6 changed files with 127 additions and 12 deletions
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2020 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.riotx.attachment_viewer
|
||||
|
||||
import android.graphics.drawable.Animatable
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.ProgressBar
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import com.bumptech.glide.request.target.CustomViewTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.github.chrisbanes.photoview.PhotoView
|
||||
|
||||
class AnimatedImageViewHolder constructor(itemView: View) :
|
||||
BaseViewHolder(itemView) {
|
||||
|
||||
val touchImageView: ImageView = itemView.findViewById(R.id.imageView)
|
||||
val imageLoaderProgress: ProgressBar = itemView.findViewById(R.id.imageLoaderProgress)
|
||||
|
||||
val customTargetView = object : CustomViewTarget<ImageView, Drawable>(touchImageView) {
|
||||
|
||||
override fun onResourceLoading(placeholder: Drawable?) {
|
||||
imageLoaderProgress.isVisible = true
|
||||
}
|
||||
|
||||
override fun onLoadFailed(errorDrawable: Drawable?) {
|
||||
imageLoaderProgress.isVisible = false
|
||||
}
|
||||
|
||||
override fun onResourceCleared(placeholder: Drawable?) {
|
||||
touchImageView.setImageDrawable(placeholder)
|
||||
}
|
||||
|
||||
override fun onResourceReady(resource: Drawable, transition: Transition<in Drawable>?) {
|
||||
imageLoaderProgress.isVisible = false
|
||||
// Glide mess up the view size :/
|
||||
touchImageView.updateLayoutParams {
|
||||
width = LinearLayout.LayoutParams.MATCH_PARENT
|
||||
height = LinearLayout.LayoutParams.MATCH_PARENT
|
||||
}
|
||||
touchImageView.setImageDrawable(resource)
|
||||
if (resource is Animatable) {
|
||||
resource.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun bind(attachmentInfo: AttachmentInfo) {
|
||||
}
|
||||
}
|
|
@ -18,6 +18,7 @@ package im.vector.riotx.attachment_viewer
|
|||
|
||||
sealed class AttachmentInfo {
|
||||
data class Image(val url: String, val data: Any?) : AttachmentInfo()
|
||||
data class AnimatedImage(val url: String, val data: Any?) : AttachmentInfo()
|
||||
data class Video(val url: String, val data: Any) : AttachmentInfo()
|
||||
data class Audio(val url: String, val data: Any) : AttachmentInfo()
|
||||
data class File(val url: String, val data: Any) : AttachmentInfo()
|
||||
|
@ -32,5 +33,6 @@ interface AttachmentSourceProvider {
|
|||
|
||||
fun getAttachmentInfoAt(position: Int): AttachmentInfo
|
||||
|
||||
fun loadImage(holder: ImageViewHolder, info: AttachmentInfo.Image)
|
||||
fun loadImage(holder: ZoomableImageViewHolder, info: AttachmentInfo.Image)
|
||||
fun loadImage(holder: AnimatedImageViewHolder, info: AttachmentInfo.AnimatedImage)
|
||||
}
|
||||
|
|
|
@ -60,7 +60,8 @@ class AttachmentsAdapter() : RecyclerView.Adapter<BaseViewHolder>() {
|
|||
val inflater = LayoutInflater.from(parent.context)
|
||||
val itemView = inflater.inflate(viewType, parent, false)
|
||||
return when (viewType) {
|
||||
R.layout.item_image_attachment -> ImageViewHolder(itemView)
|
||||
R.layout.item_image_attachment -> ZoomableImageViewHolder(itemView)
|
||||
R.layout.item_animated_image_attachment -> AnimatedImageViewHolder(itemView)
|
||||
else -> AttachmentViewHolder(itemView)
|
||||
}
|
||||
}
|
||||
|
@ -70,6 +71,7 @@ class AttachmentsAdapter() : RecyclerView.Adapter<BaseViewHolder>() {
|
|||
return when (info) {
|
||||
is AttachmentInfo.Image -> R.layout.item_image_attachment
|
||||
is AttachmentInfo.Video -> R.layout.item_video_attachment
|
||||
is AttachmentInfo.AnimatedImage -> R.layout.item_animated_image_attachment
|
||||
is AttachmentInfo.Audio -> TODO()
|
||||
is AttachmentInfo.File -> TODO()
|
||||
}
|
||||
|
@ -83,15 +85,22 @@ class AttachmentsAdapter() : RecyclerView.Adapter<BaseViewHolder>() {
|
|||
override fun onBindViewHolder(holder: BaseViewHolder, position: Int) {
|
||||
attachmentSourceProvider?.getAttachmentInfoAt(position)?.let {
|
||||
holder.bind(it)
|
||||
if (it is AttachmentInfo.Image) {
|
||||
attachmentSourceProvider?.loadImage(holder as ImageViewHolder, it)
|
||||
when(it) {
|
||||
is AttachmentInfo.Image -> {
|
||||
attachmentSourceProvider?.loadImage(holder as ZoomableImageViewHolder, it)
|
||||
}
|
||||
is AttachmentInfo.AnimatedImage -> {
|
||||
attachmentSourceProvider?.loadImage(holder as AnimatedImageViewHolder, it)
|
||||
}
|
||||
else -> {}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun isScaled(position: Int): Boolean {
|
||||
val holder = recyclerView?.findViewHolderForAdapterPosition(position)
|
||||
if (holder is ImageViewHolder) {
|
||||
if (holder is ZoomableImageViewHolder) {
|
||||
return holder.touchImageView.attacher.scale > 1f
|
||||
}
|
||||
return false
|
||||
|
|
|
@ -27,7 +27,7 @@ import com.bumptech.glide.request.target.CustomViewTarget
|
|||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.github.chrisbanes.photoview.PhotoView
|
||||
|
||||
class ImageViewHolder constructor(itemView: View) :
|
||||
class ZoomableImageViewHolder constructor(itemView: View) :
|
||||
BaseViewHolder(itemView) {
|
||||
|
||||
val touchImageView: PhotoView = itemView.findViewById(R.id.touchImageView)
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView"
|
||||
android:visibility="visible"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<ProgressBar
|
||||
android:layout_centerInParent="true"
|
||||
android:id="@+id/imageLoaderProgress"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:visibility="visible"
|
||||
tools:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
|
@ -24,9 +24,10 @@ import im.vector.matrix.android.api.session.room.model.message.MessageWithAttach
|
|||
import im.vector.matrix.android.api.session.room.model.message.getFileUrl
|
||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||
import im.vector.matrix.android.internal.crypto.attachments.toElementToDecrypt
|
||||
import im.vector.riotx.attachment_viewer.AnimatedImageViewHolder
|
||||
import im.vector.riotx.attachment_viewer.AttachmentInfo
|
||||
import im.vector.riotx.attachment_viewer.AttachmentSourceProvider
|
||||
import im.vector.riotx.attachment_viewer.ImageViewHolder
|
||||
import im.vector.riotx.attachment_viewer.ZoomableImageViewHolder
|
||||
import javax.inject.Inject
|
||||
|
||||
class RoomAttachmentProvider(
|
||||
|
@ -53,14 +54,27 @@ class RoomAttachmentProvider(
|
|||
width = null,
|
||||
height = null
|
||||
)
|
||||
AttachmentInfo.Image(
|
||||
content?.url ?: "",
|
||||
data
|
||||
)
|
||||
if (content?.mimeType == "image/gif") {
|
||||
AttachmentInfo.AnimatedImage(
|
||||
content.url ?: "",
|
||||
data
|
||||
)
|
||||
} else {
|
||||
AttachmentInfo.Image(
|
||||
content?.url ?: "",
|
||||
data
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadImage(holder: ImageViewHolder, info: AttachmentInfo.Image) {
|
||||
override fun loadImage(holder: ZoomableImageViewHolder, info: AttachmentInfo.Image) {
|
||||
(info.data as? ImageContentRenderer.Data)?.let {
|
||||
imageContentRenderer.render(it, holder.touchImageView, holder.customTargetView as CustomViewTarget<*, Drawable>)
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadImage(holder: AnimatedImageViewHolder, info: AttachmentInfo.AnimatedImage) {
|
||||
(info.data as? ImageContentRenderer.Data)?.let {
|
||||
imageContentRenderer.render(it, holder.touchImageView, holder.customTargetView as CustomViewTarget<*, Drawable>)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue