kopia lustrzana https://github.com/ryukoposting/Signal-Android
Story Status for landing page and my stories.
rodzic
1ac8701ada
commit
1f82ceecc6
|
@ -236,7 +236,7 @@ class MediaSelectionRepository(context: Context) {
|
||||||
if (isStory && preUploadResults.size > 1) {
|
if (isStory && preUploadResults.size > 1) {
|
||||||
preUploadResults.forEach {
|
preUploadResults.forEach {
|
||||||
val list = storyMessages[it] ?: mutableListOf()
|
val list = storyMessages[it] ?: mutableListOf()
|
||||||
list.add(OutgoingSecureMediaMessage(message))
|
list.add(OutgoingSecureMediaMessage(message).withSentTimestamp(System.currentTimeMillis()))
|
||||||
storyMessages[it] = list
|
storyMessages[it] = list
|
||||||
|
|
||||||
// XXX We must do this to avoid sending out messages to the same recipient with the same
|
// XXX We must do this to avoid sending out messages to the same recipient with the same
|
||||||
|
|
|
@ -58,4 +58,20 @@ public class OutgoingSecureMediaMessage extends OutgoingMediaMessage {
|
||||||
getLinkPreviews(),
|
getLinkPreviews(),
|
||||||
getMentions());
|
getMentions());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public @NonNull OutgoingSecureMediaMessage withSentTimestamp(long sentTimestamp) {
|
||||||
|
return new OutgoingSecureMediaMessage(getRecipient(),
|
||||||
|
getBody(),
|
||||||
|
getAttachments(),
|
||||||
|
sentTimestamp,
|
||||||
|
getDistributionType(),
|
||||||
|
getExpiresIn(),
|
||||||
|
isViewOnce(),
|
||||||
|
getStoryType(),
|
||||||
|
getParentStoryId(),
|
||||||
|
getOutgoingQuote(),
|
||||||
|
getSharedContacts(),
|
||||||
|
getLinkPreviews(),
|
||||||
|
getMentions());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package org.thoughtcrime.securesms.stories.landing
|
package org.thoughtcrime.securesms.stories.landing
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.drawable.ColorDrawable
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.avatar.view.AvatarView
|
import org.thoughtcrime.securesms.avatar.view.AvatarView
|
||||||
import org.thoughtcrime.securesms.components.ThumbnailView
|
import org.thoughtcrime.securesms.components.ThumbnailView
|
||||||
|
@ -17,6 +16,7 @@ import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||||
import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
|
import org.thoughtcrime.securesms.stories.dialogs.StoryContextMenu
|
||||||
import org.thoughtcrime.securesms.util.Base64
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
import org.thoughtcrime.securesms.util.DateUtils
|
import org.thoughtcrime.securesms.util.DateUtils
|
||||||
|
import org.thoughtcrime.securesms.util.SpanUtil
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
||||||
|
@ -27,6 +27,9 @@ import java.util.Locale
|
||||||
* Items displaying a preview and metadata for a story from a user, allowing them to launch into the story viewer.
|
* Items displaying a preview and metadata for a story from a user, allowing them to launch into the story viewer.
|
||||||
*/
|
*/
|
||||||
object StoriesLandingItem {
|
object StoriesLandingItem {
|
||||||
|
|
||||||
|
private const val STATUS_CHANGE = 0
|
||||||
|
|
||||||
fun register(mappingAdapter: MappingAdapter) {
|
fun register(mappingAdapter: MappingAdapter) {
|
||||||
mappingAdapter.registerFactory(Model::class.java, LayoutFactory(::ViewHolder, R.layout.stories_landing_item))
|
mappingAdapter.registerFactory(Model::class.java, LayoutFactory(::ViewHolder, R.layout.stories_landing_item))
|
||||||
}
|
}
|
||||||
|
@ -48,8 +51,30 @@ object StoriesLandingItem {
|
||||||
override fun areContentsTheSame(newItem: Model): Boolean {
|
override fun areContentsTheSame(newItem: Model): Boolean {
|
||||||
return data.storyRecipient.hasSameContent(newItem.data.storyRecipient) &&
|
return data.storyRecipient.hasSameContent(newItem.data.storyRecipient) &&
|
||||||
data == newItem.data &&
|
data == newItem.data &&
|
||||||
|
!hasStatusChange(newItem) &&
|
||||||
super.areContentsTheSame(newItem)
|
super.areContentsTheSame(newItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getChangePayload(newItem: Model): Any? {
|
||||||
|
return if (isSameRecord(newItem) && hasStatusChange(newItem)) {
|
||||||
|
STATUS_CHANGE
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isSameRecord(newItem: Model): Boolean {
|
||||||
|
return data.primaryStory.messageRecord.id == newItem.data.primaryStory.messageRecord.id
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasStatusChange(newItem: Model): Boolean {
|
||||||
|
val oldRecord = data.primaryStory.messageRecord
|
||||||
|
val newRecord = newItem.data.primaryStory.messageRecord
|
||||||
|
|
||||||
|
return oldRecord.isOutgoing &&
|
||||||
|
newRecord.isOutgoing &&
|
||||||
|
(oldRecord.isPending != newRecord.isPending || oldRecord.isSent != newRecord.isSent || oldRecord.isFailed != newRecord.isFailed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ViewHolder(itemView: View) : MappingViewHolder<Model>(itemView) {
|
private class ViewHolder(itemView: View) : MappingViewHolder<Model>(itemView) {
|
||||||
|
@ -64,19 +89,20 @@ object StoriesLandingItem {
|
||||||
private val sender: TextView = itemView.findViewById(R.id.sender)
|
private val sender: TextView = itemView.findViewById(R.id.sender)
|
||||||
private val date: TextView = itemView.findViewById(R.id.date)
|
private val date: TextView = itemView.findViewById(R.id.date)
|
||||||
private val icon: ImageView = itemView.findViewById(R.id.icon)
|
private val icon: ImageView = itemView.findViewById(R.id.icon)
|
||||||
|
private val errorIndicator: View = itemView.findViewById(R.id.error_indicator)
|
||||||
|
|
||||||
override fun bind(model: Model) {
|
override fun bind(model: Model) {
|
||||||
itemView.setOnClickListener { model.onRowClick(model) }
|
|
||||||
|
presentDateOrStatus(model)
|
||||||
|
setUpClickListeners(model)
|
||||||
|
|
||||||
|
if (payload.contains(STATUS_CHANGE)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (model.data.storyRecipient.isMyStory) {
|
if (model.data.storyRecipient.isMyStory) {
|
||||||
itemView.setOnLongClickListener(null)
|
|
||||||
avatarView.displayProfileAvatar(Recipient.self())
|
avatarView.displayProfileAvatar(Recipient.self())
|
||||||
} else {
|
} else {
|
||||||
itemView.setOnLongClickListener {
|
|
||||||
displayContext(model)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
avatarView.displayProfileAvatar(model.data.storyRecipient)
|
avatarView.displayProfileAvatar(model.data.storyRecipient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +137,6 @@ object StoriesLandingItem {
|
||||||
else -> model.data.storyRecipient.getDisplayName(context)
|
else -> model.data.storyRecipient.getDisplayName(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
date.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), model.data.dateInMilliseconds)
|
|
||||||
icon.visible = model.data.hasReplies || model.data.hasRepliesFromSelf
|
icon.visible = model.data.hasReplies || model.data.hasRepliesFromSelf
|
||||||
// TODO [stories] -- Set actual image resource
|
// TODO [stories] -- Set actual image resource
|
||||||
icon.setImageDrawable(ColorDrawable(Color.RED))
|
icon.setImageDrawable(ColorDrawable(Color.RED))
|
||||||
|
@ -121,6 +146,32 @@ object StoriesLandingItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun presentDateOrStatus(model: Model) {
|
||||||
|
if (model.data.primaryStory.messageRecord.isOutgoing && (model.data.primaryStory.messageRecord.isPending || model.data.primaryStory.messageRecord.isMediaPending)) {
|
||||||
|
errorIndicator.visible = false
|
||||||
|
date.setText(R.string.StoriesLandingItem__sending)
|
||||||
|
} else if (model.data.primaryStory.messageRecord.isOutgoing && model.data.primaryStory.messageRecord.isFailed) {
|
||||||
|
errorIndicator.visible = true
|
||||||
|
date.text = SpanUtil.color(ContextCompat.getColor(context, R.color.signal_alert_primary), context.getString(R.string.StoriesLandingItem__couldnt_send))
|
||||||
|
} else {
|
||||||
|
errorIndicator.visible = false
|
||||||
|
date.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), model.data.dateInMilliseconds)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setUpClickListeners(model: Model) {
|
||||||
|
itemView.setOnClickListener { model.onRowClick(model) }
|
||||||
|
|
||||||
|
if (model.data.storyRecipient.isMyStory) {
|
||||||
|
itemView.setOnLongClickListener(null)
|
||||||
|
} else {
|
||||||
|
itemView.setOnLongClickListener {
|
||||||
|
displayContext(model)
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun getGroupPresentation(model: Model): String {
|
private fun getGroupPresentation(model: Model): String {
|
||||||
return context.getString(
|
return context.getString(
|
||||||
R.string.StoryViewerPageFragment__s_to_s,
|
R.string.StoryViewerPageFragment__s_to_s,
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.thoughtcrime.securesms.stories.my
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
import org.thoughtcrime.securesms.R
|
import org.thoughtcrime.securesms.R
|
||||||
import org.thoughtcrime.securesms.components.ThumbnailView
|
import org.thoughtcrime.securesms.components.ThumbnailView
|
||||||
import org.thoughtcrime.securesms.components.menu.ActionItem
|
import org.thoughtcrime.securesms.components.menu.ActionItem
|
||||||
|
@ -16,13 +17,17 @@ import org.thoughtcrime.securesms.mms.Slide
|
||||||
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
import org.thoughtcrime.securesms.stories.StoryTextPostModel
|
||||||
import org.thoughtcrime.securesms.util.Base64
|
import org.thoughtcrime.securesms.util.Base64
|
||||||
import org.thoughtcrime.securesms.util.DateUtils
|
import org.thoughtcrime.securesms.util.DateUtils
|
||||||
|
import org.thoughtcrime.securesms.util.SpanUtil
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
import org.thoughtcrime.securesms.util.adapter.mapping.LayoutFactory
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingAdapter
|
||||||
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
import org.thoughtcrime.securesms.util.adapter.mapping.MappingViewHolder
|
||||||
|
import org.thoughtcrime.securesms.util.visible
|
||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
|
|
||||||
object MyStoriesItem {
|
object MyStoriesItem {
|
||||||
|
|
||||||
|
private const val STATUS_CHANGE = 0
|
||||||
|
|
||||||
fun register(mappingAdapter: MappingAdapter) {
|
fun register(mappingAdapter: MappingAdapter) {
|
||||||
mappingAdapter.registerFactory(Model::class.java, LayoutFactory(::ViewHolder, R.layout.stories_my_stories_item))
|
mappingAdapter.registerFactory(Model::class.java, LayoutFactory(::ViewHolder, R.layout.stories_my_stories_item))
|
||||||
}
|
}
|
||||||
|
@ -40,7 +45,30 @@ object MyStoriesItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun areContentsTheSame(newItem: Model): Boolean {
|
override fun areContentsTheSame(newItem: Model): Boolean {
|
||||||
return distributionStory == newItem.distributionStory && super.areContentsTheSame(newItem)
|
return distributionStory == newItem.distributionStory &&
|
||||||
|
!hasStatusChange(newItem) &&
|
||||||
|
super.areContentsTheSame(newItem)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getChangePayload(newItem: Model): Any? {
|
||||||
|
return if (isSameRecord(newItem) && hasStatusChange(newItem)) {
|
||||||
|
STATUS_CHANGE
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isSameRecord(newItem: Model): Boolean {
|
||||||
|
return distributionStory.messageRecord.id == newItem.distributionStory.messageRecord.id
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hasStatusChange(newItem: Model): Boolean {
|
||||||
|
val oldRecord = distributionStory.messageRecord
|
||||||
|
val newRecord = newItem.distributionStory.messageRecord
|
||||||
|
|
||||||
|
return oldRecord.isOutgoing &&
|
||||||
|
newRecord.isOutgoing &&
|
||||||
|
(oldRecord.isPending != newRecord.isPending || oldRecord.isSent != newRecord.isSent || oldRecord.isFailed != newRecord.isFailed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +79,23 @@ object MyStoriesItem {
|
||||||
private val storyPreview: ThumbnailView = itemView.findViewById(R.id.story)
|
private val storyPreview: ThumbnailView = itemView.findViewById(R.id.story)
|
||||||
private val viewCount: TextView = itemView.findViewById(R.id.view_count)
|
private val viewCount: TextView = itemView.findViewById(R.id.view_count)
|
||||||
private val date: TextView = itemView.findViewById(R.id.date)
|
private val date: TextView = itemView.findViewById(R.id.date)
|
||||||
|
private val errorIndicator: View = itemView.findViewById(R.id.error_indicator)
|
||||||
|
|
||||||
override fun bind(model: Model) {
|
override fun bind(model: Model) {
|
||||||
itemView.setOnClickListener { model.onClick(model) }
|
itemView.setOnClickListener { model.onClick(model) }
|
||||||
downloadTarget.setOnClickListener { model.onSaveClick(model) }
|
downloadTarget.setOnClickListener { model.onSaveClick(model) }
|
||||||
moreTarget.setOnClickListener { showContextMenu(model) }
|
moreTarget.setOnClickListener { showContextMenu(model) }
|
||||||
viewCount.text = context.resources.getQuantityString(R.plurals.MyStories__d_views, model.distributionStory.messageRecord.readReceiptCount, model.distributionStory.messageRecord.readReceiptCount)
|
presentDateOrStatus(model)
|
||||||
date.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), model.distributionStory.messageRecord.dateSent)
|
|
||||||
|
viewCount.text = context.resources.getQuantityString(
|
||||||
|
R.plurals.MyStories__d_views,
|
||||||
|
model.distributionStory.messageRecord.readReceiptCount,
|
||||||
|
model.distributionStory.messageRecord.readReceiptCount
|
||||||
|
)
|
||||||
|
|
||||||
|
if (STATUS_CHANGE in payload) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val record: MmsMessageRecord = model.distributionStory.messageRecord as MmsMessageRecord
|
val record: MmsMessageRecord = model.distributionStory.messageRecord as MmsMessageRecord
|
||||||
val thumbnail: Slide? = record.slideDeck.thumbnailSlide
|
val thumbnail: Slide? = record.slideDeck.thumbnailSlide
|
||||||
|
@ -72,6 +110,19 @@ object MyStoriesItem {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun presentDateOrStatus(model: Model) {
|
||||||
|
if (model.distributionStory.messageRecord.isPending || model.distributionStory.messageRecord.isMediaPending) {
|
||||||
|
errorIndicator.visible = false
|
||||||
|
date.setText(R.string.StoriesLandingItem__sending)
|
||||||
|
} else if (model.distributionStory.messageRecord.isFailed) {
|
||||||
|
errorIndicator.visible = true
|
||||||
|
date.text = SpanUtil.color(ContextCompat.getColor(context, R.color.signal_alert_primary), context.getString(R.string.StoriesLandingItem__couldnt_send))
|
||||||
|
} else {
|
||||||
|
errorIndicator.visible = false
|
||||||
|
date.text = DateUtils.getBriefRelativeTimeSpanString(context, Locale.getDefault(), model.distributionStory.messageRecord.dateSent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showContextMenu(model: Model) {
|
private fun showContextMenu(model: Model) {
|
||||||
SignalContextMenu.Builder(itemView, itemView.rootView as ViewGroup)
|
SignalContextMenu.Builder(itemView, itemView.rootView as ViewGroup)
|
||||||
.preferredHorizontalPosition(SignalContextMenu.HorizontalPosition.END)
|
.preferredHorizontalPosition(SignalContextMenu.HorizontalPosition.END)
|
||||||
|
|
|
@ -40,18 +40,33 @@
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
tools:text="My Stories" />
|
tools:text="My Stories" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/error_indicator"
|
||||||
|
android:layout_width="14dp"
|
||||||
|
android:layout_height="14dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/date"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/avatar"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/date"
|
||||||
|
app:srcCompat="@drawable/ic_error_outline_24"
|
||||||
|
app:tint="@color/signal_alert_primary"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/date"
|
android:id="@+id/date"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="7dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||||
android:textColor="@color/signal_text_secondary"
|
android:textColor="@color/signal_text_secondary"
|
||||||
app:layout_constraintBottom_toTopOf="@id/icon"
|
app:layout_constraintBottom_toTopOf="@id/icon"
|
||||||
app:layout_constraintEnd_toStartOf="@id/story"
|
app:layout_constraintEnd_toStartOf="@id/story"
|
||||||
app:layout_constraintStart_toEndOf="@id/avatar"
|
app:layout_constraintStart_toEndOf="@id/error_indicator"
|
||||||
app:layout_constraintTop_toBottomOf="@id/sender"
|
app:layout_constraintTop_toBottomOf="@id/sender"
|
||||||
|
app:layout_goneMarginStart="16dp"
|
||||||
tools:text="10m" />
|
tools:text="10m" />
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:background="?selectableItemBackground"
|
||||||
android:paddingStart="@dimen/dsl_settings_gutter"
|
android:paddingStart="@dimen/dsl_settings_gutter"
|
||||||
android:paddingEnd="@dimen/dsl_settings_gutter"
|
android:paddingEnd="@dimen/dsl_settings_gutter">
|
||||||
android:background="?selectableItemBackground">
|
|
||||||
|
|
||||||
<org.thoughtcrime.securesms.components.OutlinedThumbnailView
|
<org.thoughtcrime.securesms.components.OutlinedThumbnailView
|
||||||
android:id="@+id/story"
|
android:id="@+id/story"
|
||||||
|
@ -35,16 +35,31 @@
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
app:layout_constraintVertical_chainStyle="packed"
|
||||||
tools:text="12 views" />
|
tools:text="12 views" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
|
android:id="@+id/error_indicator"
|
||||||
|
android:layout_width="14dp"
|
||||||
|
android:layout_height="14dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:importantForAccessibility="no"
|
||||||
|
android:visibility="gone"
|
||||||
|
app:layout_constraintBottom_toBottomOf="@id/date"
|
||||||
|
app:layout_constraintStart_toEndOf="@id/story"
|
||||||
|
app:layout_constraintTop_toTopOf="@id/date"
|
||||||
|
app:srcCompat="@drawable/ic_error_outline_24"
|
||||||
|
app:tint="@color/signal_alert_primary"
|
||||||
|
tools:visibility="visible" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/date"
|
android:id="@+id/date"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="7dp"
|
||||||
android:layout_marginEnd="16dp"
|
android:layout_marginEnd="16dp"
|
||||||
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
android:textAppearance="@style/TextAppearance.Signal.Body2"
|
||||||
android:textColor="@color/signal_text_secondary"
|
android:textColor="@color/signal_text_secondary"
|
||||||
app:layout_constraintStart_toEndOf="@id/story"
|
app:layout_constraintStart_toEndOf="@id/error_indicator"
|
||||||
app:layout_constraintTop_toBottomOf="@id/view_count"
|
app:layout_constraintTop_toBottomOf="@id/view_count"
|
||||||
|
app:layout_goneMarginStart="16dp"
|
||||||
tools:text="10m" />
|
tools:text="10m" />
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|
|
@ -4381,6 +4381,10 @@
|
||||||
<string name="StoriesLandingItem__share">Share…</string>
|
<string name="StoriesLandingItem__share">Share…</string>
|
||||||
<!-- Context menu option to go to story chat -->
|
<!-- Context menu option to go to story chat -->
|
||||||
<string name="StoriesLandingItem__go_to_chat">Go to chat</string>
|
<string name="StoriesLandingItem__go_to_chat">Go to chat</string>
|
||||||
|
<!-- Label when a story is pending sending -->
|
||||||
|
<string name="StoriesLandingItem__sending">Sending…</string>
|
||||||
|
<!-- Label when a story fails to send -->
|
||||||
|
<string name="StoriesLandingItem__couldnt_send">Couldn\'t send</string>
|
||||||
<!-- Title of dialog confirming decision to hide a story -->
|
<!-- Title of dialog confirming decision to hide a story -->
|
||||||
<string name="StoriesLandingFragment__hide_story">Hide story?</string>
|
<string name="StoriesLandingFragment__hide_story">Hide story?</string>
|
||||||
<!-- Message of dialog confirming decision to hide a story -->
|
<!-- Message of dialog confirming decision to hide a story -->
|
||||||
|
|
Ładowanie…
Reference in New Issue