mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 20:15:21 +00:00
feat: AlbumThumbnailView.kt view visible and binding to thumbnail slides
This commit is contained in:
parent
19f2546d81
commit
277c741851
@ -11,6 +11,8 @@ import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import network.loki.messenger.R;
|
||||
|
||||
import org.thoughtcrime.securesms.components.v2.ThumbnailView;
|
||||
import org.thoughtcrime.securesms.mms.GlideRequests;
|
||||
|
||||
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) {
|
||||
ThumbnailView cell = findViewById(id);
|
||||
cell.setImageResource(glideRequests, slide, false, false);
|
||||
cell.setLoadIndicatorVisibile(slide.isInProgress());
|
||||
cell.setThumbnailClickListener(defaultThumbnailClickListener);
|
||||
cell.setOnLongClickListener(defaultLongClickListener);
|
||||
}
|
||||
|
@ -72,7 +72,6 @@ public class ConversationItemThumbnail extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
@Override
|
||||
protected void dispatchDraw(Canvas canvas) {
|
||||
super.dispatchDraw(canvas);
|
||||
|
@ -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
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
}
|
||||
|
||||
}
|
@ -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
|
||||
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
package org.thoughtcrime.securesms.conversation.v2.messages
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.text.util.Linkify
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.LinearLayout
|
||||
@ -17,11 +15,10 @@ import androidx.core.graphics.BlendModeColorFilterCompat
|
||||
import androidx.core.graphics.BlendModeCompat
|
||||
import kotlinx.android.synthetic.main.view_visible_message_content.view.*
|
||||
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.ViewUtil
|
||||
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.MmsMessageRecord
|
||||
import org.thoughtcrime.securesms.loki.utilities.UiMode
|
||||
@ -89,9 +86,10 @@ class VisibleMessageContentView : LinearLayout {
|
||||
documentView.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
||||
mainContainer.addView(documentView)
|
||||
} else if (message is MmsMessageRecord && message.slideDeck.asAttachments().isNotEmpty()) {
|
||||
val dummyTextView = TextView(context)
|
||||
dummyTextView.text = "asifuygaihsfo"
|
||||
mainContainer.addView(dummyTextView)
|
||||
val albumThumbnailView = AlbumThumbnailView(context)
|
||||
mainContainer.addView(albumThumbnailView)
|
||||
// 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) {
|
||||
val openGroupInvitationView = OpenGroupInvitationView(context)
|
||||
openGroupInvitationView.bind(message, VisibleMessageContentView.getTextColor(context, message))
|
||||
|
19
app/src/main/res/layout/album_thumbnail_1.xml
Normal file
19
app/src/main/res/layout/album_thumbnail_1.xml
Normal 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>
|
@ -7,13 +7,13 @@
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
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:layout_width="@dimen/album_2_cell_width"
|
||||
android:layout_height="@dimen/album_2_total_height"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_2_cell_width"
|
||||
android:layout_height="@dimen/album_2_total_height"
|
||||
|
@ -6,20 +6,20 @@
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
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:layout_width="@dimen/album_3_cell_width_big"
|
||||
android:layout_height="@dimen/album_3_total_height"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_3_cell_size_small"
|
||||
android:layout_height="@dimen/album_3_cell_size_small"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_3_cell_size_small"
|
||||
android:layout_height="@dimen/album_3_cell_size_small"
|
||||
|
@ -6,27 +6,27 @@
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
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:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@dimen/album_4_cell_size"
|
||||
android:layout_height="@dimen/album_4_cell_size"
|
||||
|
@ -6,34 +6,34 @@
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
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:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="center_horizontal|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_5"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
|
@ -7,27 +7,27 @@
|
||||
android:layout_width="@dimen/album_total_width"
|
||||
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:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_2"
|
||||
android:layout_width="@dimen/album_5_cell_size_big"
|
||||
android:layout_height="@dimen/album_5_cell_size_big"
|
||||
android:layout_gravity="right|end|top"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_3"
|
||||
android:layout_width="@dimen/album_5_cell_size_small"
|
||||
android:layout_height="@dimen/album_5_cell_size_small"
|
||||
android:layout_gravity="left|start|bottom"
|
||||
app:thumbnail_radius="0dp"/>
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_4"
|
||||
android:layout_width="@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_gravity="right|end|bottom">
|
||||
|
||||
<org.thoughtcrime.securesms.components.ThumbnailView
|
||||
<org.thoughtcrime.securesms.components.v2.ThumbnailView
|
||||
android:id="@+id/album_cell_5"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="match_parent"
|
||||
|
Loading…
Reference in New Issue
Block a user