Makes the main status of a thread appear as a more detailed view.

This commit is contained in:
Vavassor 2017-08-03 00:29:31 -04:00
parent 6b3dd30527
commit 309c89eefc
9 changed files with 565 additions and 38 deletions

View File

@ -51,7 +51,6 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
private View container; private View container;
private TextView displayName; private TextView displayName;
private TextView username; private TextView username;
private TextView sinceCreated;
private TextView content; private TextView content;
private ImageView avatar; private ImageView avatar;
private ImageView avatarReblog; private ImageView avatarReblog;
@ -74,12 +73,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
private TextView contentWarningDescription; private TextView contentWarningDescription;
private ToggleButton contentWarningButton; private ToggleButton contentWarningButton;
TextView timestamp;
StatusViewHolder(View itemView) { StatusViewHolder(View itemView) {
super(itemView); super(itemView);
container = itemView.findViewById(R.id.status_container); container = itemView.findViewById(R.id.status_container);
displayName = (TextView) itemView.findViewById(R.id.status_display_name); displayName = (TextView) itemView.findViewById(R.id.status_display_name);
username = (TextView) itemView.findViewById(R.id.status_username); username = (TextView) itemView.findViewById(R.id.status_username);
sinceCreated = (TextView) itemView.findViewById(R.id.status_since_created); timestamp = (TextView) itemView.findViewById(R.id.status_timestamp);
content = (TextView) itemView.findViewById(R.id.status_content); content = (TextView) itemView.findViewById(R.id.status_content);
avatar = (ImageView) itemView.findViewById(R.id.status_avatar); avatar = (ImageView) itemView.findViewById(R.id.status_avatar);
avatarReblog = (ImageView) itemView.findViewById(R.id.status_avatar_reblog); avatarReblog = (ImageView) itemView.findViewById(R.id.status_avatar_reblog);
@ -147,19 +148,21 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
.into(avatar); .into(avatar);
} }
if (hasReblog) { if (avatarReblog != null) {
avatarReblog.setVisibility(View.VISIBLE); if (hasReblog) {
Picasso.with(context) avatarReblog.setVisibility(View.VISIBLE);
.load(rebloggedUrl) Picasso.with(context)
.fit() .load(rebloggedUrl)
.transform(new RoundedTransformation(7, 0)) .fit()
.into(avatarReblog); .transform(new RoundedTransformation(7, 0))
} else { .into(avatarReblog);
avatarReblog.setVisibility(View.GONE); } else {
avatarReblog.setVisibility(View.GONE);
}
} }
} }
private void setCreatedAt(@Nullable Date createdAt) { protected void setCreatedAt(@Nullable Date createdAt) {
// This is the visible timestamp. // This is the visible timestamp.
String readout; String readout;
/* This one is for screen-readers. Frequently, they would mispronounce timestamps like "17m" /* This one is for screen-readers. Frequently, they would mispronounce timestamps like "17m"
@ -168,7 +171,7 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
if (createdAt != null) { if (createdAt != null) {
long then = createdAt.getTime(); long then = createdAt.getTime();
long now = new Date().getTime(); long now = new Date().getTime();
readout = DateUtils.getRelativeTimeSpanString(sinceCreated.getContext(), then, now); readout = DateUtils.getRelativeTimeSpanString(timestamp.getContext(), then, now);
readoutAloud = android.text.format.DateUtils.getRelativeTimeSpanString(then, now, readoutAloud = android.text.format.DateUtils.getRelativeTimeSpanString(then, now,
android.text.format.DateUtils.SECOND_IN_MILLIS, android.text.format.DateUtils.SECOND_IN_MILLIS,
android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE); android.text.format.DateUtils.FORMAT_ABBREV_RELATIVE);
@ -177,11 +180,14 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
readout = "?m"; readout = "?m";
readoutAloud = "? minutes"; readoutAloud = "? minutes";
} }
sinceCreated.setText(readout); timestamp.setText(readout);
sinceCreated.setContentDescription(readoutAloud); timestamp.setContentDescription(readoutAloud);
} }
private void setRebloggedByDisplayName(String name) { private void setRebloggedByDisplayName(String name) {
if (rebloggedByDisplayName == null || rebloggedBar == null) {
return;
}
Context context = rebloggedByDisplayName.getContext(); Context context = rebloggedByDisplayName.getContext();
String format = context.getString(R.string.status_boosted_format); String format = context.getString(R.string.status_boosted_format);
String boostedText = String.format(format, name); String boostedText = String.format(format, name);
@ -190,6 +196,9 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
} }
private void hideRebloggedByDisplayName() { private void hideRebloggedByDisplayName() {
if (rebloggedBar == null) {
return;
}
rebloggedBar.setVisibility(View.GONE); rebloggedBar.setVisibility(View.GONE);
} }
@ -529,11 +538,13 @@ public class StatusViewHolder extends RecyclerView.ViewHolder {
// I think it's not efficient to create new object every time we bind a holder. // I think it's not efficient to create new object every time we bind a holder.
// More efficient approach would be creating View.OnClickListener during holder creation // More efficient approach would be creating View.OnClickListener during holder creation
// and storing StatusActionListener in a variable after binding. // and storing StatusActionListener in a variable after binding.
rebloggedBar.setOnClickListener(new View.OnClickListener() { if (rebloggedBar != null) {
@Override rebloggedBar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) { @Override
listener.onOpenReblog(getAdapterPosition()); public void onClick(View v) {
} listener.onOpenReblog(getAdapterPosition());
}); }
});
}
} }
} }

View File

@ -15,42 +15,83 @@
package com.keylesspalace.tusky.adapter; package com.keylesspalace.tusky.adapter;
import android.content.Context;
import android.preference.PreferenceManager;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.TextView;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
import com.keylesspalace.tusky.entity.Status;
import com.keylesspalace.tusky.interfaces.StatusActionListener; import com.keylesspalace.tusky.interfaces.StatusActionListener;
import com.keylesspalace.tusky.util.CustomTabURLSpan;
import com.keylesspalace.tusky.viewdata.StatusViewData; import com.keylesspalace.tusky.viewdata.StatusViewData;
import java.text.DateFormat;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
public class ThreadAdapter extends RecyclerView.Adapter { public class ThreadAdapter extends RecyclerView.Adapter {
private static final int VIEW_TYPE_STATUS = 0;
private static final int VIEW_TYPE_STATUS_DETAILED = 1;
private List<StatusViewData> statuses; private List<StatusViewData> statuses;
private StatusActionListener statusActionListener; private StatusActionListener statusActionListener;
private boolean mediaPreviewEnabled; private boolean mediaPreviewEnabled;
private int detailedStatusPosition;
public ThreadAdapter(StatusActionListener listener) { public ThreadAdapter(StatusActionListener listener) {
this.statusActionListener = listener; this.statusActionListener = listener;
this.statuses = new ArrayList<>(); this.statuses = new ArrayList<>();
mediaPreviewEnabled = true; mediaPreviewEnabled = true;
detailedStatusPosition = RecyclerView.NO_POSITION;
} }
@Override @Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()) switch (viewType) {
.inflate(R.layout.item_status, parent, false); default:
return new StatusViewHolder(view); case VIEW_TYPE_STATUS: {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_status, parent, false);
return new StatusViewHolder(view);
}
case VIEW_TYPE_STATUS_DETAILED: {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_status_detailed, parent, false);
return new StatusDetailedViewHolder(view);
}
}
} }
@Override @Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) { public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
StatusViewHolder holder = (StatusViewHolder) viewHolder; if (position == detailedStatusPosition) {
StatusViewData status = statuses.get(position); StatusDetailedViewHolder holder = (StatusDetailedViewHolder) viewHolder;
holder.setupWithStatus(status, StatusViewData status = statuses.get(position);
statusActionListener, mediaPreviewEnabled); holder.setupWithStatus(status, statusActionListener, mediaPreviewEnabled);
} else {
StatusViewHolder holder = (StatusViewHolder) viewHolder;
StatusViewData status = statuses.get(position);
holder.setupWithStatus(status, statusActionListener, mediaPreviewEnabled);
}
}
@Override
public int getItemViewType(int position) {
if (position == detailedStatusPosition) {
return VIEW_TYPE_STATUS_DETAILED;
} else {
return VIEW_TYPE_STATUS;
}
} }
@Override @Override
@ -72,6 +113,7 @@ public class ThreadAdapter extends RecyclerView.Adapter {
public void clearItems() { public void clearItems() {
int oldSize = statuses.size(); int oldSize = statuses.size();
statuses.clear(); statuses.clear();
detailedStatusPosition = RecyclerView.NO_POSITION;
notifyItemRangeRemoved(0, oldSize); notifyItemRangeRemoved(0, oldSize);
} }
@ -88,15 +130,85 @@ public class ThreadAdapter extends RecyclerView.Adapter {
public void clear() { public void clear() {
statuses.clear(); statuses.clear();
detailedStatusPosition = RecyclerView.NO_POSITION;
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void setItem(int position, StatusViewData status, boolean notifyAdapter) { public void setItem(int position, StatusViewData status, boolean notifyAdapter) {
statuses.set(position, status); statuses.set(position, status);
if (notifyAdapter) notifyItemChanged(position); if (notifyAdapter) {
notifyItemChanged(position);
}
} }
public void setMediaPreviewEnabled(boolean enabled) { public void setMediaPreviewEnabled(boolean enabled) {
mediaPreviewEnabled = enabled; mediaPreviewEnabled = enabled;
} }
public void setDetailedStatusPosition(int position) {
if (position != detailedStatusPosition
&& detailedStatusPosition != RecyclerView.NO_POSITION) {
int prior = detailedStatusPosition;
detailedStatusPosition = position;
notifyItemChanged(prior);
} else {
detailedStatusPosition = position;
}
}
private static class StatusDetailedViewHolder extends StatusViewHolder {
private TextView reblogs;
private TextView favourites;
private TextView application;
StatusDetailedViewHolder(View view) {
super(view);
reblogs = (TextView) view.findViewById(R.id.status_reblogs);
favourites = (TextView) view.findViewById(R.id.status_favourites);
application = (TextView) view.findViewById(R.id.status_application);
}
@Override
protected void setCreatedAt(@Nullable Date createdAt) {
if (createdAt != null) {
DateFormat dateFormat = android.text.format.DateFormat.getMediumDateFormat(
timestamp.getContext());
timestamp.setText(dateFormat.format(createdAt));
} else {
timestamp.setText("");
}
}
private void setApplication(@Nullable Status.Application app) {
if (app == null) {
return;
}
if (app.website != null) {
URLSpan span;
Context context = application.getContext();
boolean useCustomTabs = PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean("customTabs", true);
if (useCustomTabs) {
span = new CustomTabURLSpan(app.website);
} else {
span = new URLSpan(app.website);
}
SpannableStringBuilder text = new SpannableStringBuilder(app.name);
text.setSpan(span, 0, app.name.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
application.setText(text);
application.setMovementMethod(LinkMovementMethod.getInstance());
} else {
application.setText(app.name);
}
}
@Override
void setupWithStatus(StatusViewData status, final StatusActionListener listener,
boolean mediaPreviewEnabled) {
super.setupWithStatus(status, listener, mediaPreviewEnabled);
reblogs.setText(status.getReblogsCount());
favourites.setText(status.getFavouritesCount());
setApplication(status.getApplication());
}
}
} }

View File

@ -100,6 +100,8 @@ public class Status {
public Mention[] mentions; public Mention[] mentions;
public Application application;
public static final int MAX_MEDIA_ATTACHMENTS = 4; public static final int MAX_MEDIA_ATTACHMENTS = 4;
@Override @Override
@ -172,4 +174,9 @@ public class Status {
@SerializedName("username") @SerializedName("username")
public String localUsername; public String localUsername;
} }
public static class Application {
public String name;
public String website;
}
} }

View File

@ -270,6 +270,7 @@ public class ViewThreadFragment extends SFragment implements
} }
} }
statusIndex = statuses.indexOf(status); statusIndex = statuses.indexOf(status);
adapter.setDetailedStatusPosition(statusIndex);
adapter.setStatuses(statuses.getPairedCopy()); adapter.setStatuses(statuses.getPairedCopy());
} }
@ -344,6 +345,7 @@ public class ViewThreadFragment extends SFragment implements
} }
int i = statusIndex; int i = statusIndex;
statuses.add(i, status); statuses.add(i, status);
adapter.setDetailedStatusPosition(i);
adapter.addItem(i, statuses.getPairedItem(i)); adapter.addItem(i, statuses.getPairedItem(i));
return i; return i;
} }
@ -362,6 +364,7 @@ public class ViewThreadFragment extends SFragment implements
// Insert newly fetched ancestors // Insert newly fetched ancestors
statusIndex = ancestors.size(); statusIndex = ancestors.size();
adapter.setDetailedStatusPosition(statusIndex);
statuses.addAll(0, ancestors); statuses.addAll(0, ancestors);
List<StatusViewData> ancestorsViewDatas = statuses.getPairedCopy().subList(0, statusIndex); List<StatusViewData> ancestorsViewDatas = statuses.getPairedCopy().subList(0, statusIndex);
if (BuildConfig.DEBUG && ancestors.size() != ancestorsViewDatas.size()) { if (BuildConfig.DEBUG && ancestors.size() != ancestorsViewDatas.size()) {

View File

@ -14,8 +14,8 @@ import android.view.View;
import com.keylesspalace.tusky.R; import com.keylesspalace.tusky.R;
class CustomTabURLSpan extends URLSpan { public class CustomTabURLSpan extends URLSpan {
CustomTabURLSpan(String url) { public CustomTabURLSpan(String url) {
super(url); super(url);
} }

View File

@ -26,6 +26,8 @@ public final class ViewDataUtils {
.setAvatar(visibleStatus.account.avatar) .setAvatar(visibleStatus.account.avatar)
.setContent(visibleStatus.content) .setContent(visibleStatus.content)
.setCreatedAt(visibleStatus.createdAt) .setCreatedAt(visibleStatus.createdAt)
.setReblogsCount(visibleStatus.reblogsCount)
.setFavouritesCount(visibleStatus.favouritesCount)
.setFavourited(visibleStatus.favourited) .setFavourited(visibleStatus.favourited)
.setReblogged(visibleStatus.reblogged) .setReblogged(visibleStatus.reblogged)
.setIsExpanded(false) .setIsExpanded(false)
@ -40,6 +42,7 @@ public final class ViewDataUtils {
.setVisibility(visibleStatus.visibility) .setVisibility(visibleStatus.visibility)
.setSenderId(visibleStatus.account.id) .setSenderId(visibleStatus.account.id)
.setRebloggingEnabled(visibleStatus.rebloggingAllowed()) .setRebloggingEnabled(visibleStatus.rebloggingAllowed())
.setApplication(visibleStatus.application)
.createStatusViewData(); .createStatusViewData();
} }

View File

@ -31,19 +31,23 @@ public final class StatusViewData {
private final String nickname; private final String nickname;
private final String avatar; private final String avatar;
private final Date createdAt; private final Date createdAt;
private final String reblogsCount;
private final String favouritesCount;
// I would rather have something else but it would be too much of a rewrite // I would rather have something else but it would be too much of a rewrite
@Nullable @Nullable
private final Status.Mention[] mentions; private final Status.Mention[] mentions;
private final String senderId; private final String senderId;
private final boolean rebloggingEnabled; private final boolean rebloggingEnabled;
private final Status.Application application;
public StatusViewData(String id, Spanned content, boolean reblogged, boolean favourited, public StatusViewData(String id, Spanned content, boolean reblogged, boolean favourited,
String spoilerText, Status.Visibility visibility, String spoilerText, Status.Visibility visibility,
Status.MediaAttachment[] attachments, String rebloggedByUsername, Status.MediaAttachment[] attachments, String rebloggedByUsername,
String rebloggedAvatar, boolean sensitive, boolean isExpanded, String rebloggedAvatar, boolean sensitive, boolean isExpanded,
boolean isShowingSensitiveWarning, String userFullName, String nickname, boolean isShowingSensitiveWarning, String userFullName, String nickname,
String avatar, Date createdAt, Status.Mention[] mentions, String avatar, Date createdAt, String reblogsCount,
String senderId, boolean rebloggingEnabled) { String favouritesCount, Status.Mention[] mentions, String senderId,
boolean rebloggingEnabled, Status.Application application) {
this.id = id; this.id = id;
this.content = content; this.content = content;
this.reblogged = reblogged; this.reblogged = reblogged;
@ -60,9 +64,12 @@ public final class StatusViewData {
this.nickname = nickname; this.nickname = nickname;
this.avatar = avatar; this.avatar = avatar;
this.createdAt = createdAt; this.createdAt = createdAt;
this.reblogsCount = reblogsCount;
this.favouritesCount = favouritesCount;
this.mentions = mentions; this.mentions = mentions;
this.senderId = senderId; this.senderId = senderId;
this.rebloggingEnabled = rebloggingEnabled; this.rebloggingEnabled = rebloggingEnabled;
this.application = application;
} }
public String getId() { public String getId() {
@ -132,6 +139,14 @@ public final class StatusViewData {
return createdAt; return createdAt;
} }
public String getReblogsCount() {
return reblogsCount;
}
public String getFavouritesCount() {
return favouritesCount;
}
public String getSenderId() { public String getSenderId() {
return senderId; return senderId;
} }
@ -145,6 +160,10 @@ public final class StatusViewData {
return mentions; return mentions;
} }
public Status.Application getApplication() {
return application;
}
public static class Builder { public static class Builder {
private String id; private String id;
private Spanned content; private Spanned content;
@ -162,9 +181,12 @@ public final class StatusViewData {
private String nickname; private String nickname;
private String avatar; private String avatar;
private Date createdAt; private Date createdAt;
private String reblogsCount;
private String favouritesCount;
private Status.Mention[] mentions; private Status.Mention[] mentions;
private String senderId; private String senderId;
private boolean rebloggingEnabled; private boolean rebloggingEnabled;
private Status.Application application;
public Builder() { public Builder() {
} }
@ -186,9 +208,12 @@ public final class StatusViewData {
nickname = viewData.nickname; nickname = viewData.nickname;
avatar = viewData.avatar; avatar = viewData.avatar;
createdAt = new Date(viewData.createdAt.getTime()); createdAt = new Date(viewData.createdAt.getTime());
reblogsCount = viewData.reblogsCount;
favouritesCount = viewData.favouritesCount;
mentions = viewData.mentions == null ? null : viewData.mentions.clone(); mentions = viewData.mentions == null ? null : viewData.mentions.clone();
senderId = viewData.senderId; senderId = viewData.senderId;
rebloggingEnabled = viewData.rebloggingEnabled; rebloggingEnabled = viewData.rebloggingEnabled;
application = viewData.application;
} }
public Builder setId(String id) { public Builder setId(String id) {
@ -271,6 +296,16 @@ public final class StatusViewData {
return this; return this;
} }
public Builder setReblogsCount(String reblogsCount) {
this.reblogsCount = reblogsCount;
return this;
}
public Builder setFavouritesCount(String favouritesCount) {
this.favouritesCount = favouritesCount;
return this;
}
public Builder setMentions(Status.Mention[] mentions) { public Builder setMentions(Status.Mention[] mentions) {
this.mentions = mentions; this.mentions = mentions;
return this; return this;
@ -286,11 +321,17 @@ public final class StatusViewData {
return this; return this;
} }
public Builder setApplication(Status.Application application) {
this.application = application;
return this;
}
public StatusViewData createStatusViewData() { public StatusViewData createStatusViewData() {
return new StatusViewData(id, content, reblogged, favourited, spoilerText, visibility, return new StatusViewData(id, content, reblogged, favourited, spoilerText, visibility,
attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded,
isShowingSensitiveContent, userFullName, nickname, avatar, createdAt, mentions, isShowingSensitiveContent, userFullName, nickname, avatar, createdAt,
senderId, rebloggingEnabled); reblogsCount, favouritesCount, mentions, senderId, rebloggingEnabled,
application);
} }
} }
} }

View File

@ -77,7 +77,7 @@
android:paddingTop="@dimen/status_avatar_padding"> android:paddingTop="@dimen/status_avatar_padding">
<TextView <TextView
android:id="@+id/status_since_created" android:id="@+id/status_timestamp"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
@ -93,8 +93,8 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_toStartOf="@id/status_since_created" android:layout_toStartOf="@id/status_timestamp"
android:layout_toLeftOf="@id/status_since_created"> android:layout_toLeftOf="@id/status_timestamp">
<TextView <TextView
android:id="@+id/status_display_name" android:id="@+id/status_display_name"

View File

@ -0,0 +1,350 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/status_container"
android:paddingLeft="16dp"
android:paddingRight="16dp">
<ImageView
android:layout_width="48dp"
android:layout_height="48dp"
android:scaleType="fitCenter"
android:id="@+id/status_avatar"
android:layout_marginTop="11dp"
android:layout_marginEnd="10dp"
android:layout_marginRight="10dp"
android:contentDescription="@string/action_view_profile"
tools:src="@drawable/avatar_default" />
<LinearLayout
android:id="@+id/status_name_bar"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_toRightOf="@+id/status_avatar"
android:layout_toEndOf="@+id/status_avatar"
android:layout_marginBottom="8dp"
android:layout_marginTop="11dp"
android:orientation="vertical">
<TextView
android:id="@+id/status_display_name"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"
android:textColor="?android:textColorPrimary"
android:textStyle="normal|bold"
android:ellipsize="end"
android:maxLines="1"
android:text="Name" />
<Space
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<TextView
android:id="@+id/status_username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorSecondary"
android:maxLines="1"
android:ellipsize="end"
android:text="Username is the slongest thing ever i am totally going" />
</LinearLayout>
<com.keylesspalace.tusky.view.FlowLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/status_content_warning_bar"
android:visibility="gone"
android:layout_toRightOf="@+id/status_avatar"
android:layout_toEndOf="@+id/status_avatar"
android:layout_below="@+id/status_name_bar"
android:layout_marginBottom="4dp"
app:paddingHorizontal="4dp"
android:focusable="true">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/status_content_warning_description"
android:text="Hello world"
android:textColor="?android:textColorPrimary"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium" />
<ToggleButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="0dp"
android:minHeight="0dp"
android:id="@+id/status_content_warning_button"
android:textOn="@string/status_content_warning_show_less"
android:textOff="@string/status_content_warning_show_more"
android:padding="3dp"
android:textAllCaps="true"
android:background="?attr/content_warning_button" />
</com.keylesspalace.tusky.view.FlowLayout>
<TextView
android:id="@+id/status_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Streaming from the shop, while I work on upcoming videos about electronics and reverse engineering."
android:textColor="?android:textColorPrimary"
android:textAppearance="@android:style/TextAppearance.DeviceDefault.Medium"
android:layout_marginBottom="4dp"
android:layout_toRightOf="@+id/status_avatar"
android:layout_toEndOf="@+id/status_avatar"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@+id/status_content_warning_bar"
android:focusable="true" />
<FrameLayout
android:id="@+id/status_media_preview_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/status_content"
android:layout_toEndOf="@+id/status_avatar"
android:layout_toRightOf="@+id/status_avatar">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_marginBottom="2dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/status_media_preview_0"
android:layout_width="wrap_content"
android:layout_height="@dimen/status_media_preview_height"
android:layout_weight="1"
android:layout_marginEnd="2dp"
android:layout_marginRight="2dp"
android:scaleType="centerCrop"
android:layout_marginTop="@dimen/status_media_preview_top_margin"
android:contentDescription="@string/action_view_media" />
<ImageView
android:id="@+id/status_media_preview_1"
android:layout_width="wrap_content"
android:layout_height="@dimen/status_media_preview_height"
android:layout_weight="1"
android:layout_marginStart="2dp"
android:layout_marginLeft="2dp"
android:scaleType="centerCrop"
android:layout_marginTop="@dimen/status_media_preview_top_margin"
android:contentDescription="@string/action_view_media" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_marginTop="2dp"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/status_media_preview_2"
android:layout_width="wrap_content"
android:layout_height="@dimen/status_media_preview_height"
android:layout_weight="1"
android:layout_marginEnd="2dp"
android:layout_marginRight="2dp"
android:scaleType="centerCrop"
android:contentDescription="@string/action_view_media" />
<ImageView
android:id="@+id/status_media_preview_3"
android:layout_width="wrap_content"
android:layout_height="@dimen/status_media_preview_height"
android:layout_marginStart="2dp"
android:layout_marginLeft="2dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:contentDescription="@string/action_view_media" />
</LinearLayout>
</LinearLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/status_video_indicator"
app:srcCompat="@drawable/ic_play_48dp"
android:alpha="0.5"
android:layout_centerInParent="true"
android:contentDescription="@null"
android:visibility="gone" />
</RelativeLayout>
<LinearLayout
android:id="@+id/status_sensitive_media_warning"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/status_media_preview_top_margin"
android:padding="8dp"
android:gravity="center"
android:orientation="vertical"
android:background="?attr/sensitive_media_warning_background_color"
android:visibility="gone">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="@string/status_sensitive_media_title"
android:textColor="@android:color/white"
android:textStyle="bold" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:text="@string/status_sensitive_media_directions"
android:textColor="@android:color/white" />
</LinearLayout>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/status_media_label"
android:visibility="gone"
android:gravity="center_vertical"
android:includeFontPadding="false" />
</FrameLayout>
<LinearLayout
android:id="@+id/status_info_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/status_media_preview_container"
android:layout_toEndOf="@id/status_avatar"
android:layout_toRightOf="@id/status_avatar"
android:layout_marginTop="8dp"
android:layout_marginBottom="4dp"
android:orientation="horizontal">
<TextView
android:id="@+id/status_timestamp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?android:textColorTertiary" />
<TextView
android:id="@+id/status_application"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="16dp" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/status_info_bar"
android:layout_toEndOf="@id/status_avatar"
android:layout_toRightOf="@id/status_avatar"
android:clipChildren="false"
android:clipToPadding="false"
android:gravity="center_vertical"
android:paddingBottom="2dp">
<ImageButton
app:srcCompat="@drawable/ic_reply_24dp"
android:id="@+id/status_reply"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="4dp"
style="?attr/image_button_style"
android:contentDescription="@string/action_reply" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<com.varunest.sparkbutton.SparkButton
android:id="@+id/status_reblog"
app:sparkbutton_activeImage="@drawable/reblog_active"
app:sparkbutton_inActiveImage="?attr/status_reblog_inactive_drawable"
app:sparkbutton_iconSize="28dp"
app:sparkbutton_primaryColor="@color/status_reblog_button_marked_dark"
app:sparkbutton_secondaryColor="@color/status_reblog_button_marked_light"
android:layout_width="40dp"
android:layout_height="40dp"
android:padding="4dp"
android:contentDescription="@string/action_reblog"
android:clipToPadding="false"/>
<TextView
android:id="@+id/status_reblogs"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="19" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<com.varunest.sparkbutton.SparkButton
android:layout_width="40dp"
android:layout_height="40dp"
app:sparkbutton_activeImage="?attr/status_favourite_active_drawable"
app:sparkbutton_inActiveImage="?attr/status_favourite_inactive_drawable"
app:sparkbutton_iconSize="28dp"
app:sparkbutton_primaryColor="@color/status_favourite_button_marked_dark"
app:sparkbutton_secondaryColor="@color/status_favourite_button_marked_light"
android:id="@+id/status_favourite"
android:padding="4dp"
android:contentDescription="@string/action_favourite"
android:clipToPadding="false"/>
<TextView
android:id="@+id/status_favourites"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="20" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
<ImageButton
app:srcCompat="@drawable/ic_more_horiz_24dp"
android:id="@+id/status_more"
android:layout_width="32dp"
android:layout_height="32dp"
android:padding="4dp"
style="?attr/image_button_style"
android:contentDescription="@string/action_more" />
<Space
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" />
</LinearLayout>
</RelativeLayout>