mirror of
https://github.com/oxen-io/session-android.git
synced 2024-12-26 01:37:43 +00:00
feat: wiring up click listeners in AlbumThumbnailView.kt
This commit is contained in:
parent
4a8c5f5946
commit
21835800ff
@ -1,27 +1,27 @@
|
|||||||
package org.thoughtcrime.securesms.components;
|
package org.thoughtcrime.securesms.components;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import androidx.annotation.ColorInt;
|
|
||||||
import androidx.annotation.IdRes;
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import network.loki.messenger.R;
|
import androidx.annotation.ColorInt;
|
||||||
|
import androidx.annotation.IdRes;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView;
|
import org.session.libsession.utilities.Stub;
|
||||||
|
import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView;
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||||
|
|
||||||
import org.thoughtcrime.securesms.mms.Slide;
|
import org.thoughtcrime.securesms.mms.Slide;
|
||||||
import org.thoughtcrime.securesms.mms.SlideClickListener;
|
import org.thoughtcrime.securesms.mms.SlideClickListener;
|
||||||
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
|
import org.thoughtcrime.securesms.mms.SlidesClickedListener;
|
||||||
import org.session.libsession.utilities.Stub;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import network.loki.messenger.R;
|
||||||
|
|
||||||
public class AlbumThumbnailView extends FrameLayout {
|
public class AlbumThumbnailView extends FrameLayout {
|
||||||
|
|
||||||
private @Nullable SlideClickListener thumbnailClickListener;
|
private @Nullable SlideClickListener thumbnailClickListener;
|
||||||
@ -149,7 +149,7 @@ public class AlbumThumbnailView extends FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setSlide(@NonNull GlideRequests glideRequests, @NonNull Slide slide, @IdRes int id) {
|
private void setSlide(@NonNull GlideRequests glideRequests, @NonNull Slide slide, @IdRes int id) {
|
||||||
ThumbnailView cell = findViewById(id);
|
KThumbnailView cell = findViewById(id);
|
||||||
cell.setImageResource(glideRequests, slide, false, false);
|
cell.setImageResource(glideRequests, slide, false, false);
|
||||||
cell.setThumbnailClickListener(defaultThumbnailClickListener);
|
cell.setThumbnailClickListener(defaultThumbnailClickListener);
|
||||||
cell.setOnLongClickListener(defaultLongClickListener);
|
cell.setOnLongClickListener(defaultLongClickListener);
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
@ -11,21 +12,27 @@ import kotlinx.android.synthetic.main.album_thumbnail_view.view.*
|
|||||||
import network.loki.messenger.R
|
import network.loki.messenger.R
|
||||||
import org.thoughtcrime.securesms.components.CornerMask
|
import org.thoughtcrime.securesms.components.CornerMask
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
import org.thoughtcrime.securesms.conversation.v2.utilities.KThumbnailView
|
||||||
import org.thoughtcrime.securesms.conversation.v2.utilities.ThumbnailView
|
|
||||||
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
|
||||||
import org.thoughtcrime.securesms.mms.GlideRequests
|
import org.thoughtcrime.securesms.mms.GlideRequests
|
||||||
|
import org.thoughtcrime.securesms.mms.Slide
|
||||||
|
import org.thoughtcrime.securesms.mms.SlideClickListener
|
||||||
|
import org.thoughtcrime.securesms.mms.SlidesClickedListener
|
||||||
|
|
||||||
class AlbumThumbnailView: FrameLayout {
|
class AlbumThumbnailView: FrameLayout, SlideClickListener, SlidesClickedListener, View.OnClickListener {
|
||||||
|
|
||||||
// region Lifecycle
|
// region Lifecycle
|
||||||
constructor(context: Context) : super(context) { initialize() }
|
constructor(context: Context) : super(context) { initialize() }
|
||||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
|
||||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
|
||||||
|
|
||||||
|
private var slideClickListener: ((Slide) -> Unit)? = null
|
||||||
|
private var downloadClickListener: ((Slide) -> Unit)? = null
|
||||||
|
private var readMoreListener: (() -> Unit)? = null
|
||||||
private val cornerMask by lazy { CornerMask(this) }
|
private val cornerMask by lazy { CornerMask(this) }
|
||||||
|
|
||||||
private fun initialize() {
|
private fun initialize() {
|
||||||
LayoutInflater.from(context).inflate(R.layout.album_thumbnail_view, this)
|
LayoutInflater.from(context).inflate(R.layout.album_thumbnail_view, this)
|
||||||
|
albumCellBodyTextReadMore.setOnClickListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun dispatchDraw(canvas: Canvas?) {
|
override fun dispatchDraw(canvas: Canvas?) {
|
||||||
@ -37,7 +44,34 @@ class AlbumThumbnailView: FrameLayout {
|
|||||||
|
|
||||||
// region Interaction
|
// region Interaction
|
||||||
|
|
||||||
fun bind(glideRequests: GlideRequests, message: MmsMessageRecord, isStart: Boolean, isEnd: Boolean) {
|
override fun onClick(v: View?) {
|
||||||
|
// clicked the view or one of its children
|
||||||
|
if (v === albumCellBodyTextReadMore) {
|
||||||
|
readMoreListener?.invoke()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?, slide: Slide?) {
|
||||||
|
// slide thumbnail clicked
|
||||||
|
if (slide==null) return
|
||||||
|
slideClickListener?.invoke(slide)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onClick(v: View?, slides: MutableList<Slide>?) {
|
||||||
|
// slide download clicked
|
||||||
|
if (slides.isNullOrEmpty()) return
|
||||||
|
slides.firstOrNull().let { slide ->
|
||||||
|
if (slide == null) return@let
|
||||||
|
downloadClickListener?.invoke(slide)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bind(glideRequests: GlideRequests, message: MmsMessageRecord,
|
||||||
|
clickListener: (Slide)->Unit, downloadClickListener: (Slide)->Unit, readMoreListener: ()->Unit,
|
||||||
|
isStart: Boolean, isEnd: Boolean) {
|
||||||
|
this.slideClickListener = clickListener
|
||||||
|
this.downloadClickListener = downloadClickListener
|
||||||
|
this.readMoreListener = readMoreListener
|
||||||
// TODO: optimize for same size
|
// TODO: optimize for same size
|
||||||
val slides = message.slideDeck.thumbnailSlides
|
val slides = message.slideDeck.thumbnailSlides
|
||||||
if (slides.isEmpty()) {
|
if (slides.isEmpty()) {
|
||||||
@ -49,10 +83,21 @@ class AlbumThumbnailView: FrameLayout {
|
|||||||
LayoutInflater.from(context).inflate(layoutRes(slides.size), albumCellContainer)
|
LayoutInflater.from(context).inflate(layoutRes(slides.size), albumCellContainer)
|
||||||
// iterate
|
// iterate
|
||||||
slides.take(5).forEachIndexed { position, slide ->
|
slides.take(5).forEachIndexed { position, slide ->
|
||||||
val imageResource = getThumbnailView(position).setImageResource(glideRequests, slide, showControls = false, isPreview = false)
|
val thumbnailView = getThumbnailView(position)
|
||||||
|
thumbnailView.thumbnailClickListener = this
|
||||||
|
thumbnailView.setImageResource(glideRequests, slide, showControls = false, isPreview = false)
|
||||||
|
thumbnailView.setDownloadClickListener(this)
|
||||||
}
|
}
|
||||||
albumCellBodyParent.isVisible = message.body.isNotEmpty()
|
albumCellBodyParent.isVisible = message.body.isNotEmpty()
|
||||||
albumCellBodyText.text = message.body
|
albumCellBodyText.text = message.body
|
||||||
|
post {
|
||||||
|
// post to await layout of text
|
||||||
|
albumCellBodyText.layout?.let { layout ->
|
||||||
|
val maxEllipsis = (0 until layout.lineCount).maxByOrNull { lineNum -> layout.getEllipsisCount(lineNum) } ?: 0
|
||||||
|
// show read more text if at least one line is ellipsized
|
||||||
|
albumCellBodyTextReadMore.isVisible = maxEllipsis > 0
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Context
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.widget.LinearLayout
|
import android.widget.LinearLayout
|
||||||
@ -88,7 +89,22 @@ class VisibleMessageContentView : LinearLayout {
|
|||||||
mainContainer.addView(albumThumbnailView)
|
mainContainer.addView(albumThumbnailView)
|
||||||
// isStart and isEnd of cluster needed for calculating the mask for full bubble image groups
|
// isStart and isEnd of cluster needed for calculating the mask for full bubble image groups
|
||||||
// bind after add view because views are inflated and calculated during bind
|
// bind after add view because views are inflated and calculated during bind
|
||||||
albumThumbnailView.bind(glide, message, isStartOfMessageCluster, isEndOfMessageCluster)
|
albumThumbnailView.bind(
|
||||||
|
glideRequests = glide,
|
||||||
|
message = message,
|
||||||
|
isStart = isStartOfMessageCluster,
|
||||||
|
isEnd = isEndOfMessageCluster,
|
||||||
|
clickListener = { slide ->
|
||||||
|
Log.d("Loki-UI","clicked to display the slide $slide")
|
||||||
|
},
|
||||||
|
downloadClickListener = { slide ->
|
||||||
|
// trigger download of content?
|
||||||
|
Log.d("Loki-UI","clicked to download the slide $slide")
|
||||||
|
},
|
||||||
|
readMoreListener = {
|
||||||
|
Log.d("Loki-UI", "clicked to read more the message $message")
|
||||||
|
}
|
||||||
|
)
|
||||||
} else if (message.isOpenGroupInvitation) {
|
} else if (message.isOpenGroupInvitation) {
|
||||||
val openGroupInvitationView = OpenGroupInvitationView(context)
|
val openGroupInvitationView = OpenGroupInvitationView(context)
|
||||||
openGroupInvitationView.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
openGroupInvitationView.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
||||||
|
@ -5,6 +5,7 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
import android.widget.FrameLayout
|
import android.widget.FrameLayout
|
||||||
import android.widget.ProgressBar
|
import android.widget.ProgressBar
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
@ -26,7 +27,7 @@ import org.thoughtcrime.securesms.components.TransferControlView
|
|||||||
import org.thoughtcrime.securesms.mms.*
|
import org.thoughtcrime.securesms.mms.*
|
||||||
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
|
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
|
||||||
|
|
||||||
open class KThumbnailView: FrameLayout {
|
open class KThumbnailView: FrameLayout, View.OnClickListener {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val WIDTH = 0
|
private const val WIDTH = 0
|
||||||
@ -65,9 +66,9 @@ open class KThumbnailView: FrameLayout {
|
|||||||
|
|
||||||
typedArray.recycle()
|
typedArray.recycle()
|
||||||
}
|
}
|
||||||
|
setOnClickListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// region Lifecycle
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
val adjustedDimens = dimensDelegate.resourceSize()
|
val adjustedDimens = dimensDelegate.resourceSize()
|
||||||
if (adjustedDimens[WIDTH] == 0 && adjustedDimens[HEIGHT] == 0) {
|
if (adjustedDimens[WIDTH] == 0 && adjustedDimens[HEIGHT] == 0) {
|
||||||
@ -85,10 +86,16 @@ open class KThumbnailView: FrameLayout {
|
|||||||
|
|
||||||
private fun getDefaultWidth() = maxOf(layoutParams?.width ?: 0, 0)
|
private fun getDefaultWidth() = maxOf(layoutParams?.width ?: 0, 0)
|
||||||
private fun getDefaultHeight() = maxOf(layoutParams?.height ?: 0, 0)
|
private fun getDefaultHeight() = maxOf(layoutParams?.height ?: 0, 0)
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
// region Interaction
|
// region Interaction
|
||||||
|
|
||||||
|
override fun onClick(v: View?) {
|
||||||
|
if (v === this) {
|
||||||
|
thumbnailClickListener?.onClick(v, slide)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun setImageResource(glide: GlideRequests, slide: Slide, showControls: Boolean, isPreview: Boolean): ListenableFuture<Boolean> {
|
fun setImageResource(glide: GlideRequests, slide: Slide, showControls: Boolean, isPreview: Boolean): ListenableFuture<Boolean> {
|
||||||
return setImageResource(glide, slide, showControls, isPreview, 0, 0)
|
return setImageResource(glide, slide, showControls, isPreview, 0, 0)
|
||||||
}
|
}
|
||||||
@ -216,7 +223,11 @@ open class KThumbnailView: FrameLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun setDownloadClickListener(listener: SlidesClickedListener) {
|
fun setDownloadClickListener(listener: SlidesClickedListener) {
|
||||||
|
transferControls.setDownloadClickListener {
|
||||||
|
slide?.let { slide ->
|
||||||
|
listener.onClick(it, listOf(slide))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<merge
|
<merge xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content">
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
@ -17,7 +18,8 @@
|
|||||||
android:layout_gravity="center"
|
android:layout_gravity="center"
|
||||||
android:layout="@layout/transfer_controls_stub" />
|
android:layout="@layout/transfer_controls_stub" />
|
||||||
|
|
||||||
<FrameLayout
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
tools:visibility="visible"
|
||||||
android:visibility="gone"
|
android:visibility="gone"
|
||||||
android:layout_gravity="bottom"
|
android:layout_gravity="bottom"
|
||||||
android:id="@+id/albumCellBodyParent"
|
android:id="@+id/albumCellBodyParent"
|
||||||
@ -27,23 +29,43 @@
|
|||||||
android:id="@+id/albumCellShade"
|
android:id="@+id/albumCellShade"
|
||||||
android:src="@drawable/image_shade"
|
android:src="@drawable/image_shade"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintTop_toTopOf="@+id/albumCellBodyTextParent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
/>
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/albumCellBodyTextParent"
|
||||||
|
android:padding="@dimen/small_spacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@+id/albumCellBodyTextReadMore"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
<View
|
<View
|
||||||
android:layout_margin="@dimen/small_spacing"
|
android:layout_marginStart="@dimen/small_spacing"
|
||||||
android:layout_width="@dimen/small_spacing"
|
android:layout_width="@dimen/accent_line_thickness"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:background="@color/accent"/>
|
android:background="@color/accent"/>
|
||||||
<TextView
|
<TextView
|
||||||
|
android:maxLines="4"
|
||||||
|
android:ellipsize="end"
|
||||||
android:id="@+id/albumCellBodyText"
|
android:id="@+id/albumCellBodyText"
|
||||||
android:textColor="@color/core_white"
|
android:textColor="@color/core_white"
|
||||||
android:layout_margin="@dimen/small_spacing"
|
android:layout_margin="@dimen/small_spacing"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"/>
|
android:layout_height="wrap_content"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
<TextView
|
||||||
|
tools:visibility="visible"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
android:id="@+id/albumCellBodyTextReadMore"
|
||||||
|
android:textColor="@color/core_white"
|
||||||
|
android:padding="@dimen/small_spacing"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/ConversationItem_read_more"/>
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
</merge>
|
</merge>
|
Loading…
x
Reference in New Issue
Block a user