feat: AlbumThumbnailView.kt view visible and binding to thumbnail slides

This commit is contained in:
jubb 2021-06-24 16:15:13 +10:00
parent 19f2546d81
commit 277c741851
12 changed files with 409 additions and 28 deletions

View File

@ -11,6 +11,8 @@ import android.widget.FrameLayout;
import android.widget.TextView; import android.widget.TextView;
import network.loki.messenger.R; import network.loki.messenger.R;
import org.thoughtcrime.securesms.components.v2.ThumbnailView;
import org.thoughtcrime.securesms.mms.GlideRequests; import org.thoughtcrime.securesms.mms.GlideRequests;
import org.thoughtcrime.securesms.mms.Slide; import org.thoughtcrime.securesms.mms.Slide;
@ -149,7 +151,6 @@ 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); ThumbnailView cell = findViewById(id);
cell.setImageResource(glideRequests, slide, false, false); cell.setImageResource(glideRequests, slide, false, false);
cell.setLoadIndicatorVisibile(slide.isInProgress());
cell.setThumbnailClickListener(defaultThumbnailClickListener); cell.setThumbnailClickListener(defaultThumbnailClickListener);
cell.setOnLongClickListener(defaultLongClickListener); cell.setOnLongClickListener(defaultLongClickListener);
} }

View File

@ -72,7 +72,6 @@ public class ConversationItemThumbnail extends FrameLayout {
} }
} }
@SuppressWarnings("SuspiciousNameCombination")
@Override @Override
protected void dispatchDraw(Canvas canvas) { protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas); super.dispatchDraw(canvas);

View File

@ -0,0 +1,99 @@
package org.thoughtcrime.securesms.components.v2
import android.content.Context
import android.graphics.Canvas
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.FrameLayout
import kotlinx.android.synthetic.main.album_thumbnail_view.view.*
import network.loki.messenger.R
import org.thoughtcrime.securesms.components.CornerMask
import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.mms.GlideRequests
class AlbumThumbnailView: FrameLayout {
// region Lifecycle
constructor(context: Context) : super(context) { initialize() }
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize() }
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize() }
private val albumCellContainer by lazy { album_cell_container }
private lateinit var cornerMask: CornerMask
private fun initialize() {
LayoutInflater.from(context).inflate(R.layout.album_thumbnail_view, this)
cornerMask = CornerMask(this)
cornerMask.setRadius(80)
}
override fun dispatchDraw(canvas: Canvas?) {
super.dispatchDraw(canvas)
cornerMask.mask(canvas)
}
// endregion
// region Interaction
fun bind(glideRequests: GlideRequests, message: MmsMessageRecord, isStart: Boolean, isEnd: Boolean) {
// TODO: optimize for same size
val slides = message.slideDeck.thumbnailSlides
if (slides.isEmpty()) {
// this should never be encountered because it's checked by parent
return
}
calculateRadius(isStart, isEnd, message.isOutgoing)
albumCellContainer.removeAllViews()
LayoutInflater.from(context).inflate(layoutRes(slides.size), albumCellContainer)
// iterate
slides.take(5).forEachIndexed { position, slide ->
getThumbnailView(position).setImageResource(glideRequests, slide, showControls = false, isPreview = false)
}
}
// endregion
fun layoutRes(slideCount: Int) = when (slideCount) {
1 -> R.layout.album_thumbnail_1 // single
2 -> R.layout.album_thumbnail_2// two sidebyside
3 -> R.layout.album_thumbnail_3// three stacked
4 -> R.layout.album_thumbnail_4// four square
5 -> R.layout.album_thumbnail_5//
else -> R.layout.album_thumbnail_many// five or more
}
fun getThumbnailView(position: Int): ThumbnailView = when (position) {
0 -> albumCellContainer.findViewById<ViewGroup>(R.id.album_cell_container).findViewById(R.id.album_cell_1)
1 -> albumCellContainer.findViewById<ViewGroup>(R.id.album_cell_container).findViewById(R.id.album_cell_2)
2 -> albumCellContainer.findViewById<ViewGroup>(R.id.album_cell_container).findViewById(R.id.album_cell_3)
3 -> albumCellContainer.findViewById<ViewGroup>(R.id.album_cell_container).findViewById(R.id.album_cell_4)
4 -> albumCellContainer.findViewById<ViewGroup>(R.id.album_cell_container).findViewById(R.id.album_cell_5)
else -> throw Exception("Can't get thumbnail view for non-existent thumbnail at position: $position")
}
fun calculateRadius(isStart: Boolean, isEnd: Boolean, outgoing: Boolean) {
val roundedDimen = context.resources.getDimension(R.dimen.message_corner_radius).toInt()
val collapsedDimen = context.resources.getDimension(R.dimen.message_corner_collapse_radius).toInt()
val (startTop, endTop, startBottom, endBottom) = when {
// single message, consistent dimen
isStart && isEnd -> intArrayOf(roundedDimen, roundedDimen, roundedDimen, roundedDimen)
// start of message cluster, collapsed BL
isStart -> intArrayOf(roundedDimen, roundedDimen, collapsedDimen, roundedDimen)
// end of message cluster, collapsed TL
isEnd -> intArrayOf(collapsedDimen, roundedDimen, roundedDimen, roundedDimen)
// else in the middle, no rounding left side
else -> intArrayOf(collapsedDimen, roundedDimen, collapsedDimen, roundedDimen)
}
// TL, TR, BR, BL (CW direction)
cornerMask.setRadii(
if (!outgoing) startTop else endTop, // TL
if (!outgoing) endTop else startTop, // TR
if (!outgoing) endBottom else startBottom, // BR
if (!outgoing) startBottom else endBottom // BL
)
}
}

View File

@ -0,0 +1,91 @@
package org.thoughtcrime.securesms.components.v2
class ThumbnailDimensDelegate {
companion object {
// dimens array constants
private const val WIDTH = 0
private const val HEIGHT = 1
private const val DIMENS_ARRAY_SIZE = 2
// bounds array constants
private const val MIN_WIDTH = 0
private const val MIN_HEIGHT = 1
private const val MAX_WIDTH = 2
private const val MAX_HEIGHT = 3
private const val BOUNDS_ARRAY_SIZE = 4
// const zero int array
private val EMPTY_DIMENS = intArrayOf(0,0)
}
private val measured: IntArray = IntArray(DIMENS_ARRAY_SIZE)
private val dimens: IntArray = IntArray(DIMENS_ARRAY_SIZE)
private val bounds: IntArray = IntArray(BOUNDS_ARRAY_SIZE)
fun resourceSize(): IntArray {
if (dimens.all { it == 0 }) {
// dimens are (0, 0), don't go any further
return EMPTY_DIMENS
}
val naturalWidth = dimens[WIDTH].toDouble()
val naturalHeight = dimens[HEIGHT].toDouble()
val minWidth = dimens[MIN_WIDTH]
val maxWidth = dimens[MAX_WIDTH]
val minHeight = dimens[MIN_HEIGHT]
val maxHeight = dimens[MAX_HEIGHT]
// calculate actual measured
var measuredWidth: Double = naturalWidth
var measuredHeight: Double = naturalHeight
val widthInBounds = measuredWidth >= minWidth && measuredWidth <= maxWidth
val heightInBounds = measuredHeight >= minHeight && measuredHeight <= maxHeight
if (!widthInBounds || !heightInBounds) {
val minWidthRatio: Double = naturalWidth / minWidth
val maxWidthRatio: Double = naturalWidth / maxWidth
val minHeightRatio: Double = naturalHeight / minHeight
val maxHeightRatio: Double = naturalHeight / maxHeight
if (maxWidthRatio > 1 || maxHeightRatio > 1) {
if (maxWidthRatio >= maxHeightRatio) {
measuredWidth /= maxWidthRatio
measuredHeight /= maxWidthRatio
} else {
measuredWidth /= maxHeightRatio
measuredHeight /= maxHeightRatio
}
measuredWidth = Math.max(measuredWidth, minWidth.toDouble())
measuredHeight = Math.max(measuredHeight, minHeight.toDouble())
} else if (minWidthRatio < 1 || minHeightRatio < 1) {
if (minWidthRatio <= minHeightRatio) {
measuredWidth /= minWidthRatio
measuredHeight /= minWidthRatio
} else {
measuredWidth /= minHeightRatio
measuredHeight /= minHeightRatio
}
measuredWidth = Math.min(measuredWidth, maxWidth.toDouble())
measuredHeight = Math.min(measuredHeight, maxHeight.toDouble())
}
}
measured[WIDTH] = measuredWidth.toInt()
measured[HEIGHT] = measuredHeight.toInt()
return measured
}
fun setBounds(minWidth: Int, minHeight: Int, maxWidth: Int, maxHeight: Int) {
bounds[MIN_WIDTH] = minWidth
bounds[MIN_HEIGHT] = minHeight
bounds[MAX_WIDTH] = maxWidth
bounds[MAX_HEIGHT] = maxHeight
}
fun setDimens(width: Int, height: Int) {
dimens[WIDTH] = width
dimens[HEIGHT] = height
}
}

View File

@ -0,0 +1,174 @@
package org.thoughtcrime.securesms.components.v2
import android.content.Context
import android.graphics.Bitmap
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.widget.FrameLayout
import android.widget.ProgressBar
import androidx.core.view.isVisible
import com.bumptech.glide.load.engine.DiskCacheStrategy
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
import com.bumptech.glide.request.RequestOptions
import kotlinx.android.synthetic.main.thumbnail_view.view.*
import network.loki.messenger.R
import org.session.libsession.messaging.sending_receiving.attachments.AttachmentTransferProgress
import org.session.libsession.utilities.Util.equals
import org.session.libsession.utilities.ViewUtil
import org.thoughtcrime.securesms.components.TransferControlView
import org.thoughtcrime.securesms.mms.DecryptableStreamUriLoader.DecryptableUri
import org.thoughtcrime.securesms.mms.GlideRequest
import org.thoughtcrime.securesms.mms.GlideRequests
import org.thoughtcrime.securesms.mms.Slide
import org.thoughtcrime.securesms.mms.SlideClickListener
class ThumbnailView: FrameLayout {
companion object {
private const val WIDTH = 0
private const val HEIGHT = 1
}
// region Lifecycle
constructor(context: Context) : super(context) { initialize(null) }
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) { initialize(attrs) }
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) { initialize(attrs) }
private val image by lazy { thumbnail_image }
private val playOverlay by lazy { play_overlay }
private val captionIcon by lazy { thumbnail_caption_icon }
val loadIndicator: ProgressBar by lazy { thumbnail_load_indicator }
private val transferControls by lazy { ViewUtil.inflateStub<TransferControlView>(this, R.id.transfer_controls_stub) }
private val dimensDelegate = ThumbnailDimensDelegate()
var thumbnailClickListener: SlideClickListener? = null
private var slide: Slide? = null
private fun initialize(attrs: AttributeSet?) {
inflate(context, R.layout.thumbnail_view, this)
if (attrs != null) {
val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.ThumbnailView, 0, 0)
dimensDelegate.setBounds(typedArray.getDimensionPixelSize(R.styleable.ConversationItemThumbnail_conversationThumbnail_minWidth, 0),
typedArray.getDimensionPixelSize(R.styleable.ConversationItemThumbnail_conversationThumbnail_minHeight, 0),
typedArray.getDimensionPixelSize(R.styleable.ConversationItemThumbnail_conversationThumbnail_maxWidth, 0),
typedArray.getDimensionPixelSize(R.styleable.ConversationItemThumbnail_conversationThumbnail_maxHeight, 0))
typedArray.recycle()
}
}
// region Lifecycle
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val adjustedDimens = dimensDelegate.resourceSize()
if (adjustedDimens[WIDTH] == 0 && adjustedDimens[HEIGHT] == 0) {
return super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
val finalWidth: Int = adjustedDimens[WIDTH] + paddingLeft + paddingRight
val finalHeight: Int = adjustedDimens[HEIGHT] + paddingTop + paddingBottom
super.onMeasure(
MeasureSpec.makeMeasureSpec(finalWidth, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(finalHeight, MeasureSpec.EXACTLY)
)
}
private fun getDefaultWidth() = maxOf(layoutParams?.width ?: 0, 0)
private fun getDefaultHeight() = maxOf(layoutParams?.height ?: 0, 0)
// endregion
// region Interaction
fun setImageResource(glide: GlideRequests, slide: Slide, showControls: Boolean, isPreview: Boolean) {
return setImageResource(glide, slide, showControls, isPreview, 0, 0)
}
fun setImageResource(glide: GlideRequests, slide: Slide,
showControls: Boolean, isPreview: Boolean,
naturalWidth: Int, naturalHeight: Int) {
val currentSlide = this.slide
if (showControls) {
transferControls.setSlide(slide)
// transferControls.setDownloadClickListener() TODO: re-add this
} else {
transferControls.isVisible = false
}
playOverlay.isVisible = (slide.thumbnailUri != null && slide.hasPlayOverlay() &&
(slide.transferState == AttachmentTransferProgress.TRANSFER_PROGRESS_DONE || isPreview))
if (equals(currentSlide, slide)) {
// don't re-load slide
return
}
if (currentSlide != null && currentSlide.fastPreflightId != null && currentSlide.fastPreflightId == slide.fastPreflightId) {
// not reloading slide for fast preflight
this.slide = slide
}
this.slide = slide
captionIcon.isVisible = slide.caption.isPresent
loadIndicator.isVisible = slide.isInProgress
dimensDelegate.setDimens(naturalWidth, naturalHeight)
invalidate()
when {
slide.thumbnailUri != null -> {
buildThumbnailGlideRequest(glide, slide).into(image)
}
slide.hasPlaceholder() -> {
buildPlaceholderGlideRequest(glide, slide).into(image)
}
else -> {
glide.clear(image)
}
}
}
fun buildThumbnailGlideRequest(glide: GlideRequests, slide: Slide): GlideRequest<Drawable> {
val dimens = dimensDelegate.resourceSize()
val request = glide.load(DecryptableUri(slide.thumbnailUri!!))
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
.let { request ->
if (dimens[WIDTH] == 0 || dimens[HEIGHT] == 0) {
request.override(getDefaultWidth(), getDefaultHeight())
} else {
request.override(dimens[WIDTH], dimens[HEIGHT])
}
}
.transition(DrawableTransitionOptions.withCrossFade())
.centerCrop()
return if (slide.isInProgress) request else request.apply(RequestOptions.errorOf(R.drawable.ic_missing_thumbnail_picture))
}
fun buildPlaceholderGlideRequest(glide: GlideRequests, slide: Slide): GlideRequest<Bitmap> {
val dimens = dimensDelegate.resourceSize()
return glide.asBitmap()
.load(slide.getPlaceholderRes(context.theme))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.let { request ->
if (dimens[WIDTH] == 0 || dimens[HEIGHT] == 0) {
request.override(getDefaultWidth(), getDefaultHeight())
} else {
request.override(dimens[WIDTH], dimens[HEIGHT])
}
}
.fitCenter()
}
// endregion
}

View File

@ -1,11 +1,9 @@
package org.thoughtcrime.securesms.conversation.v2.messages package org.thoughtcrime.securesms.conversation.v2.messages
import android.content.Context import android.content.Context
import android.content.res.ColorStateList
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
@ -17,11 +15,10 @@ import androidx.core.graphics.BlendModeColorFilterCompat
import androidx.core.graphics.BlendModeCompat import androidx.core.graphics.BlendModeCompat
import kotlinx.android.synthetic.main.view_visible_message_content.view.* import kotlinx.android.synthetic.main.view_visible_message_content.view.*
import network.loki.messenger.R import network.loki.messenger.R
import org.session.libsession.messaging.utilities.UpdateMessageData
import org.session.libsession.messaging.utilities.UpdateMessageData.Companion.fromJSON
import org.session.libsession.utilities.ThemeUtil import org.session.libsession.utilities.ThemeUtil
import org.session.libsession.utilities.ViewUtil import org.session.libsession.utilities.ViewUtil
import org.session.libsession.utilities.recipients.Recipient import org.session.libsession.utilities.recipients.Recipient
import org.thoughtcrime.securesms.components.v2.AlbumThumbnailView
import org.thoughtcrime.securesms.database.model.MessageRecord import org.thoughtcrime.securesms.database.model.MessageRecord
import org.thoughtcrime.securesms.database.model.MmsMessageRecord import org.thoughtcrime.securesms.database.model.MmsMessageRecord
import org.thoughtcrime.securesms.loki.utilities.UiMode import org.thoughtcrime.securesms.loki.utilities.UiMode
@ -89,9 +86,10 @@ class VisibleMessageContentView : LinearLayout {
documentView.bind(message, VisibleMessageContentView.getTextColor(context, message)) documentView.bind(message, VisibleMessageContentView.getTextColor(context, message))
mainContainer.addView(documentView) mainContainer.addView(documentView)
} else if (message is MmsMessageRecord && message.slideDeck.asAttachments().isNotEmpty()) { } else if (message is MmsMessageRecord && message.slideDeck.asAttachments().isNotEmpty()) {
val dummyTextView = TextView(context) val albumThumbnailView = AlbumThumbnailView(context)
dummyTextView.text = "asifuygaihsfo" mainContainer.addView(albumThumbnailView)
mainContainer.addView(dummyTextView) // isStart and isEnd of cluster needed for calculating the mask for full bubble image groups
albumThumbnailView.bind(glide, message, isStartOfMessageCluster, isEndOfMessageCluster)
} 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))

View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/album_thumbnail_root"
android:layout_width="@dimen/media_bubble_default_dimens"
android:layout_height="@dimen/media_bubble_default_dimens">
<org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:conversationThumbnail_minWidth="@dimen/media_bubble_min_width"
app:conversationThumbnail_maxWidth="@dimen/media_bubble_max_width"
app:conversationThumbnail_minHeight="@dimen/media_bubble_min_height"
app:conversationThumbnail_maxHeight="@dimen/media_bubble_max_height"
app:thumbnail_radius="1dp"/>
</FrameLayout>

View File

@ -7,13 +7,13 @@
android:layout_width="@dimen/album_total_width" android:layout_width="@dimen/album_total_width"
android:layout_height="@dimen/album_2_total_height"> android:layout_height="@dimen/album_2_total_height">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1" android:id="@+id/album_cell_1"
android:layout_width="@dimen/album_2_cell_width" android:layout_width="@dimen/album_2_cell_width"
android:layout_height="@dimen/album_2_total_height" android:layout_height="@dimen/album_2_total_height"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_2" android:id="@+id/album_cell_2"
android:layout_width="@dimen/album_2_cell_width" android:layout_width="@dimen/album_2_cell_width"
android:layout_height="@dimen/album_2_total_height" android:layout_height="@dimen/album_2_total_height"

View File

@ -6,20 +6,20 @@
android:layout_width="@dimen/album_total_width" android:layout_width="@dimen/album_total_width"
android:layout_height="@dimen/album_3_total_height"> android:layout_height="@dimen/album_3_total_height">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1" android:id="@+id/album_cell_1"
android:layout_width="@dimen/album_3_cell_width_big" android:layout_width="@dimen/album_3_cell_width_big"
android:layout_height="@dimen/album_3_total_height" android:layout_height="@dimen/album_3_total_height"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_2" android:id="@+id/album_cell_2"
android:layout_width="@dimen/album_3_cell_size_small" android:layout_width="@dimen/album_3_cell_size_small"
android:layout_height="@dimen/album_3_cell_size_small" android:layout_height="@dimen/album_3_cell_size_small"
android:layout_gravity="right|end|top" android:layout_gravity="right|end|top"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_3" android:id="@+id/album_cell_3"
android:layout_width="@dimen/album_3_cell_size_small" android:layout_width="@dimen/album_3_cell_size_small"
android:layout_height="@dimen/album_3_cell_size_small" android:layout_height="@dimen/album_3_cell_size_small"

View File

@ -6,27 +6,27 @@
android:layout_width="@dimen/album_total_width" android:layout_width="@dimen/album_total_width"
android:layout_height="@dimen/album_4_total_height"> android:layout_height="@dimen/album_4_total_height">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1" android:id="@+id/album_cell_1"
android:layout_width="@dimen/album_4_cell_size" android:layout_width="@dimen/album_4_cell_size"
android:layout_height="@dimen/album_4_cell_size" android:layout_height="@dimen/album_4_cell_size"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_2" android:id="@+id/album_cell_2"
android:layout_width="@dimen/album_4_cell_size" android:layout_width="@dimen/album_4_cell_size"
android:layout_height="@dimen/album_4_cell_size" android:layout_height="@dimen/album_4_cell_size"
android:layout_gravity="right|end|top" android:layout_gravity="right|end|top"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_3" android:id="@+id/album_cell_3"
android:layout_width="@dimen/album_4_cell_size" android:layout_width="@dimen/album_4_cell_size"
android:layout_height="@dimen/album_4_cell_size" android:layout_height="@dimen/album_4_cell_size"
android:layout_gravity="left|start|bottom" android:layout_gravity="left|start|bottom"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_4" android:id="@+id/album_cell_4"
android:layout_width="@dimen/album_4_cell_size" android:layout_width="@dimen/album_4_cell_size"
android:layout_height="@dimen/album_4_cell_size" android:layout_height="@dimen/album_4_cell_size"

View File

@ -6,34 +6,34 @@
android:layout_width="@dimen/album_total_width" android:layout_width="@dimen/album_total_width"
android:layout_height="@dimen/album_5_total_height"> android:layout_height="@dimen/album_5_total_height">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1" android:id="@+id/album_cell_1"
android:layout_width="@dimen/album_5_cell_size_big" android:layout_width="@dimen/album_5_cell_size_big"
android:layout_height="@dimen/album_5_cell_size_big" android:layout_height="@dimen/album_5_cell_size_big"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_2" android:id="@+id/album_cell_2"
android:layout_width="@dimen/album_5_cell_size_big" android:layout_width="@dimen/album_5_cell_size_big"
android:layout_height="@dimen/album_5_cell_size_big" android:layout_height="@dimen/album_5_cell_size_big"
android:layout_gravity="right|end|top" android:layout_gravity="right|end|top"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_3" android:id="@+id/album_cell_3"
android:layout_width="@dimen/album_5_cell_size_small" android:layout_width="@dimen/album_5_cell_size_small"
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"
android:layout_gravity="left|start|bottom" android:layout_gravity="left|start|bottom"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_4" android:id="@+id/album_cell_4"
android:layout_width="@dimen/album_5_cell_size_small" android:layout_width="@dimen/album_5_cell_size_small"
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"
android:layout_gravity="center_horizontal|bottom" android:layout_gravity="center_horizontal|bottom"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_5" android:id="@+id/album_cell_5"
android:layout_width="@dimen/album_5_cell_size_small" android:layout_width="@dimen/album_5_cell_size_small"
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"

View File

@ -7,27 +7,27 @@
android:layout_width="@dimen/album_total_width" android:layout_width="@dimen/album_total_width"
android:layout_height="@dimen/album_5_total_height"> android:layout_height="@dimen/album_5_total_height">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_1" android:id="@+id/album_cell_1"
android:layout_width="@dimen/album_5_cell_size_big" android:layout_width="@dimen/album_5_cell_size_big"
android:layout_height="@dimen/album_5_cell_size_big" android:layout_height="@dimen/album_5_cell_size_big"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_2" android:id="@+id/album_cell_2"
android:layout_width="@dimen/album_5_cell_size_big" android:layout_width="@dimen/album_5_cell_size_big"
android:layout_height="@dimen/album_5_cell_size_big" android:layout_height="@dimen/album_5_cell_size_big"
android:layout_gravity="right|end|top" android:layout_gravity="right|end|top"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_3" android:id="@+id/album_cell_3"
android:layout_width="@dimen/album_5_cell_size_small" android:layout_width="@dimen/album_5_cell_size_small"
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"
android:layout_gravity="left|start|bottom" android:layout_gravity="left|start|bottom"
app:thumbnail_radius="0dp"/> app:thumbnail_radius="0dp"/>
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_4" android:id="@+id/album_cell_4"
android:layout_width="@dimen/album_5_cell_size_small" android:layout_width="@dimen/album_5_cell_size_small"
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"
@ -39,7 +39,7 @@
android:layout_height="@dimen/album_5_cell_size_small" android:layout_height="@dimen/album_5_cell_size_small"
android:layout_gravity="right|end|bottom"> android:layout_gravity="right|end|bottom">
<org.thoughtcrime.securesms.components.ThumbnailView <org.thoughtcrime.securesms.components.v2.ThumbnailView
android:id="@+id/album_cell_5" android:id="@+id/album_cell_5"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_width="match_parent" android:layout_width="match_parent"