Alibek Omarov 4 years ago
commit 82a22082f2
  1. 12
      app/schemas/com.keylesspalace.tusky.db.AppDatabase/25.json
  2. 1
      app/src/husky/res/values/strings.xml
  3. 22
      app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java
  4. 4
      app/src/main/java/com/keylesspalace/tusky/components/conversation/ConversationsFragment.kt
  5. 19
      app/src/main/java/com/keylesspalace/tusky/components/search/fragments/SearchStatusesFragment.kt
  6. 1
      app/src/main/java/com/keylesspalace/tusky/db/AppDatabase.java
  7. 2
      app/src/main/java/com/keylesspalace/tusky/db/TimelineDao.kt
  8. 3
      app/src/main/java/com/keylesspalace/tusky/db/TimelineStatusEntity.kt
  9. 12
      app/src/main/java/com/keylesspalace/tusky/entity/Status.kt
  10. 7
      app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java
  11. 10
      app/src/main/java/com/keylesspalace/tusky/fragment/SFragment.java
  12. 10
      app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java
  13. 7
      app/src/main/java/com/keylesspalace/tusky/fragment/ViewThreadFragment.java
  14. 1
      app/src/main/java/com/keylesspalace/tusky/interfaces/StatusActionListener.java
  15. 16
      app/src/main/java/com/keylesspalace/tusky/repository/TimelineRepository.kt
  16. 2
      app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java
  17. 1
      app/src/main/java/com/keylesspalace/tusky/view/StatusView.kt
  18. 40
      app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java
  19. 10
      app/src/main/res/drawable/ic_reply_18dp.xml
  20. 20
      app/src/main/res/layout/item_status.xml
  21. 18
      app/src/main/res/layout/item_status_detailed.xml
  22. 3
      app/src/main/res/menu/status_more.xml
  23. 3
      app/src/main/res/menu/status_more_for_user.xml

@ -2,7 +2,7 @@
"formatVersion": 1,
"database": {
"version": 25,
"identityHash": "ce7a96213f9e12e00a6ec21f3efaf547",
"identityHash": "0a5f8f196d357a01b8b571098ea32431",
"entities": [
{
"tableName": "TootEntity",
@ -364,7 +364,7 @@
},
{
"tableName": "TimelineStatusEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `url` TEXT, `timelineUserId` INTEGER NOT NULL, `authorServerId` TEXT, `inReplyToId` TEXT, `inReplyToAccountId` TEXT, `content` TEXT, `createdAt` INTEGER NOT NULL, `emojis` TEXT, `reblogsCount` INTEGER NOT NULL, `favouritesCount` INTEGER NOT NULL, `reblogged` INTEGER NOT NULL, `bookmarked` INTEGER NOT NULL, `favourited` INTEGER NOT NULL, `sensitive` INTEGER NOT NULL, `spoilerText` TEXT, `visibility` INTEGER, `attachments` TEXT, `mentions` TEXT, `application` TEXT, `reblogServerId` TEXT, `reblogAccountId` TEXT, `poll` TEXT, PRIMARY KEY(`serverId`, `timelineUserId`), FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`serverId` TEXT NOT NULL, `url` TEXT, `timelineUserId` INTEGER NOT NULL, `authorServerId` TEXT, `inReplyToId` TEXT, `inReplyToAccountId` TEXT, `content` TEXT, `createdAt` INTEGER NOT NULL, `emojis` TEXT, `reblogsCount` INTEGER NOT NULL, `favouritesCount` INTEGER NOT NULL, `reblogged` INTEGER NOT NULL, `bookmarked` INTEGER NOT NULL, `favourited` INTEGER NOT NULL, `sensitive` INTEGER NOT NULL, `spoilerText` TEXT, `visibility` INTEGER, `attachments` TEXT, `mentions` TEXT, `application` TEXT, `reblogServerId` TEXT, `reblogAccountId` TEXT, `poll` TEXT, `pleroma` TEXT, PRIMARY KEY(`serverId`, `timelineUserId`), FOREIGN KEY(`authorServerId`, `timelineUserId`) REFERENCES `TimelineAccountEntity`(`serverId`, `timelineUserId`) ON UPDATE NO ACTION ON DELETE NO ACTION )",
"fields": [
{
"fieldPath": "serverId",
@ -503,6 +503,12 @@
"columnName": "poll",
"affinity": "TEXT",
"notNull": false
},
{
"fieldPath": "pleroma",
"columnName": "pleroma",
"affinity": "TEXT",
"notNull": false
}
],
"primaryKey": {
@ -885,7 +891,7 @@
"views": [],
"setupQueries": [
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ce7a96213f9e12e00a6ec21f3efaf547')"
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '0a5f8f196d357a01b8b571098ea32431')"
]
}
}

@ -98,6 +98,7 @@
<string name="status_share_content">Share content of post</string>
<string name="status_share_link">Share link to post</string>
<string name="status_boosted_format">%s repeated</string>
<string name="status_replied_to_format">Reply to %s</string>
<string name="title_scheduled_toot">Scheduled posts</string>
<string name="title_reblogged_by">Repeated by</string>

@ -17,6 +17,7 @@ import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.util.Log;
import android.graphics.Paint;
import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
@ -69,6 +70,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
private TextView displayName;
private TextView username;
private TextView replyInfo;
private ImageButton replyButton;
private SparkButton reblogButton;
private SparkButton favouriteButton;
@ -121,6 +123,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
timestampInfo = itemView.findViewById(R.id.status_timestamp_info);
content = itemView.findViewById(R.id.status_content);
avatar = itemView.findViewById(R.id.status_avatar);
replyInfo = itemView.findViewById(R.id.reply_info);
replyButton = itemView.findViewById(R.id.status_reply);
reblogButton = itemView.findViewById(R.id.status_inset);
favouriteButton = itemView.findViewById(R.id.status_favourite);
@ -379,6 +382,24 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
}
protected void setReplyInfo(StatusViewData.Concrete status, StatusActionListener listener) {
if (status.getInReplyToId() != null) {
Context context = replyInfo.getContext();
String replyToAccount = status.getInReplyToAccountAcct();
replyInfo.setText(context.getString(R.string.status_replied_to_format, replyToAccount));
if (status.getParentVisible() == false)
replyInfo.setPaintFlags(replyInfo.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
else
replyInfo.setPaintFlags(replyInfo.getPaintFlags() & (~Paint.STRIKE_THRU_TEXT_FLAG));
replyInfo.setOnClickListener(v -> listener.onViewReplyTo(getAdapterPosition()));
replyInfo.setVisibility(View.VISIBLE);
} else {
replyInfo.setVisibility(View.GONE);
}
}
private void setReblogged(boolean reblogged) {
reblogButton.setChecked(reblogged);
}
@ -757,6 +778,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder {
setUsername(status.getNickname());
setCreatedAt(status.getCreatedAt(), statusDisplayOptions);
setIsReply(status.getInReplyToId() != null);
setReplyInfo(status, listener);
setAvatar(status.getAvatar(), status.getRebloggedAvatar(), status.isBot(), statusDisplayOptions);
setReblogged(status.isReblogged());
setFavourited(status.isFavourited());

@ -138,6 +138,10 @@ class ConversationsFragment : SFragment(), StatusActionListener, Injectable, Res
}
}
override fun onViewReplyTo(position: Int) {
// there are no Reply to labels in conversations
}
override fun onOpenReblog(position: Int) {
// there are no reblogs in search results
}

@ -155,6 +155,13 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
}
}
override fun onViewReplyTo(position: Int) {
searchAdapter.getItem(position)?.first?.let { status ->
val actionableStatus = status.actionableStatus
bottomSheetActivity?.viewThread(actionableStatus.inReplyToId!!, null)
}
}
override fun onOpenReblog(position: Int) {
searchAdapter.getItem(position)?.first?.let { status ->
bottomSheetActivity?.viewAccount(status.account.id)
@ -195,10 +202,6 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
}
}
private fun onShowReplyTo(replyToId: String) {
bottomSheetActivity?.viewThread(replyToId, null)
}
companion object {
fun newInstance() = SearchStatusesFragment()
}
@ -272,10 +275,6 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
}
openAsItem.title = openAsTitle
if(status.inReplyToId == null) {
popup.menu.findItem(R.id.status_reply_to)?.isVisible = false
}
popup.setOnMenuItemClickListener { item ->
when (item.itemId) {
R.id.status_share_content -> {
@ -309,10 +308,6 @@ class SearchStatusesFragment : SearchFragment<Pair<Status, StatusViewData.Concre
LinkHelper.openLinkInBrowser(Uri.parse(statusUrl), context);
return@setOnMenuItemClickListener true
}
R.id.status_reply_to -> {
onShowReplyTo(status.inReplyToId!!)
return@setOnMenuItemClickListener true
}
R.id.status_open_as -> {
showOpenAsDialog(statusUrl!!, item.title)
return@setOnMenuItemClickListener true

@ -373,6 +373,7 @@ public abstract class AppDatabase extends RoomDatabase {
database.execSQL("ALTER TABLE `InstanceEntity` ADD COLUMN `chatLimit` INTEGER");
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `notificationsChatMessages` INTEGER NOT NULL DEFAULT 1");
database.execSQL("ALTER TABLE `AccountEntity` ADD COLUMN `notificationsStreamingEnabled` INTEGER NOT NULL DEFAULT 1");
database.execSQL("ALTER TABLE `TimelineStatusEntity` ADD COLUMN `pleroma` TEXT");
}
};
}

@ -26,7 +26,7 @@ SELECT s.serverId, s.url, s.timelineUserId,
s.authorServerId, s.inReplyToId, s.inReplyToAccountId, s.createdAt,
s.emojis, s.reblogsCount, s.favouritesCount, s.reblogged, s.favourited, s.bookmarked, s.sensitive,
s.spoilerText, s.visibility, s.mentions, s.application, s.reblogServerId,s.reblogAccountId,
s.content, s.attachments, s.poll,
s.content, s.attachments, s.poll, s.pleroma,
a.serverId as 'a_serverId', a.timelineUserId as 'a_timelineUserId',
a.localUsername as 'a_localUsername', a.username as 'a_username',
a.displayName as 'a_displayName', a.url as 'a_url', a.avatar as 'a_avatar',

@ -51,7 +51,8 @@ data class TimelineStatusEntity(
val application: String?,
val reblogServerId: String?, // if it has a reblogged status, it's id is stored here
val reblogAccountId: String?,
val poll: String?
val poll: String?,
val pleroma: String?
)
@Entity(

@ -151,6 +151,14 @@ data class Status(
return pleroma?.emojiReactions;
}
fun getInReplyToAccountAcct(): String? {
return pleroma?.inReplyToAccountAcct;
}
fun getParentVisible(): Boolean {
return pleroma?.parentVisible ?: true;
}
private fun getEditableText(): String {
val builder = SpannableStringBuilder(content)
for (span in content.getSpans(0, content.length, URLSpan::class.java)) {
@ -182,7 +190,9 @@ data class Status(
data class PleromaStatus(
@SerializedName("thread_muted") var threadMuted: Boolean?,
@SerializedName("conversation_id") val conversationId: Int?,
@SerializedName("emoji_reactions") val emojiReactions: List<EmojiReaction>?
@SerializedName("emoji_reactions") val emojiReactions: List<EmojiReaction>?,
@SerializedName("in_reply_to_account_acct") val inReplyToAccountAcct: String?,
@SerializedName("parent_visible") val parentVisible: Boolean?
)
data class Mention (

@ -591,6 +591,13 @@ public class NotificationsFragment extends SFragment implements
super.viewThread(notification.getStatus());
}
@Override
public void onViewReplyTo(int position) {
Notification notification = notifications.get(position).asRightOrNull();
if (notification == null) return;
super.onShowReplyTo(notification.getStatus().getInReplyToId());
}
@Override
public void onOpenReblog(int position) {
Notification notification = notifications.get(position).asRight();

@ -267,12 +267,6 @@ public abstract class SFragment extends BaseFragment implements Injectable {
}
openAsItem.setTitle(openAsTitle);
if(status.getInReplyToId() == null) {
MenuItem replyToItem = menu.findItem(R.id.status_reply_to);
replyToItem.setVisible(false);
}
// maybe not a best check
if(status.getPleroma() != null) {
boolean showMute = true; // predict state
@ -325,10 +319,6 @@ public abstract class SFragment extends BaseFragment implements Injectable {
LinkHelper.openLinkInBrowser(Uri.parse(statusUrl), getContext());
return true;
}
case R.id.status_reply_to: {
onShowReplyTo(status.getInReplyToId());
return true;
}
case R.id.status_open_as: {
showOpenAsDialog(statusUrl, item.getTitle());
return true;

@ -848,6 +848,16 @@ public class TimelineFragment extends SFragment implements
super.viewThread(statuses.get(position).asRight());
}
@Override
public void onViewReplyTo(int position) {
Status status = statuses.get(position).asRightOrNull();
if (status == null) return;
String replyToId = status.getReblog() == null ? status.getInReplyToId() : status.getReblog().getInReplyToId();
if (replyToId == null) return;
super.onShowReplyTo(replyToId);
}
@Override
public void onViewTag(String tag) {
if (kind == Kind.TAG && tags.size() == 1 && tags.contains(tag)) {

@ -315,6 +315,13 @@ public final class ViewThreadFragment extends SFragment implements
super.viewThread(status);
}
@Override
public void onViewReplyTo(int position) {
Status status = statuses.get(position);
if (thisThreadsStatusId.equals(status.getInReplyToId())) return;
super.onShowReplyTo(status.getInReplyToId());
}
@Override
public void onOpenReblog(int position) {
// there should be no reblogs in the thread but let's implement it to be sure

@ -31,6 +31,7 @@ public interface StatusActionListener extends LinkListener {
void onMore(@NonNull View view, final int position);
void onViewMedia(int position, int attachmentIndex, @Nullable View view);
void onViewThread(int position);
void onViewReplyTo(int position);
/**
* Open reblog author for the status.

@ -208,6 +208,7 @@ class TimelineRepositoryImpl(
val emojis: List<Emoji> = gson.fromJson(status.emojis,
object : TypeToken<List<Emoji>>() {}.type) ?: listOf()
val poll: Poll? = gson.fromJson(status.poll, Poll::class.java)
val pleroma = gson.fromJson(status.pleroma, Status.PleromaStatus::class.java)
val reblog = status.reblogServerId?.let { id ->
Status(
@ -233,7 +234,8 @@ class TimelineRepositoryImpl(
application = application,
pinned = false,
poll = poll,
card = null
card = null,
pleroma = pleroma
)
}
val status = if (reblog != null) {
@ -260,7 +262,8 @@ class TimelineRepositoryImpl(
application = null,
pinned = false,
poll = null,
card = null
card = null,
pleroma = null
)
} else {
Status(
@ -286,7 +289,8 @@ class TimelineRepositoryImpl(
application = application,
pinned = false,
poll = poll,
card = null
card = null,
pleroma = pleroma
)
}
return Either.Right(status)
@ -356,7 +360,8 @@ fun Placeholder.toEntity(timelineUserId: Long): TimelineStatusEntity {
application = null,
reblogServerId = null,
reblogAccountId = null,
poll = null
poll = null,
pleroma = null
)
}
@ -386,7 +391,8 @@ fun Status.toEntity(timelineUserId: Long,
application = actionable.application.let(gson::toJson),
reblogServerId = reblog?.id,
reblogAccountId = reblog?.let { this.account.id },
poll = actionable.poll.let(gson::toJson)
poll = actionable.poll.let(gson::toJson),
pleroma = actionable.pleroma.let(gson::toJson)
)
}

@ -46,6 +46,7 @@ public final class ViewDataUtils {
.setReblogsCount(visibleStatus.getReblogsCount())
.setFavouritesCount(visibleStatus.getFavouritesCount())
.setInReplyToId(visibleStatus.getInReplyToId())
.setInReplyToAccountAcct(visibleStatus.getInReplyToAccountAcct())
.setFavourited(visibleStatus.getFavourited())
.setBookmarked(visibleStatus.getBookmarked())
.setReblogged(visibleStatus.getReblogged())
@ -75,6 +76,7 @@ public final class ViewDataUtils {
.setThreadMuted(visibleStatus.isThreadMuted())
.setConversationId(visibleStatus.getConversationId())
.setEmojiReactions(visibleStatus.getEmojiReactions())
.setParentVisible(visibleStatus.getParentVisible())
.createStatusViewData();
}

@ -58,6 +58,7 @@ class StatusView @JvmOverloads constructor(
override fun onMore(view: View, position: Int) { }
override fun onViewMedia(position: Int, attachmentIndex: Int, view: View?) { }
override fun onViewThread(position: Int) { }
override fun onViewReplyTo(position: Int) { }
override fun onOpenReblog(position: Int) { }
override fun onExpandedChange(expanded: Boolean, position: Int) { }
override fun onContentHiddenChange(isShowing: Boolean, position: Int) { }

@ -77,6 +77,8 @@ public abstract class StatusViewData {
private final int favouritesCount;
@Nullable
private final String inReplyToId;
@Nullable
private final String inReplyToAccountAcct;
// I would rather have something else but it would be too much of a rewrite
@Nullable
private final Status.Mention[] mentions;
@ -98,16 +100,17 @@ public abstract class StatusViewData {
private final int conversationId;
@Nullable
private final List<EmojiReaction> emojiReactions;
private final boolean parentVisible;
public Concrete(String id, Spanned content, boolean reblogged, boolean favourited, boolean bookmarked,
@Nullable String spoilerText, Status.Visibility visibility, List<Attachment> attachments,
@Nullable String rebloggedByUsername, @Nullable String rebloggedAvatar, boolean sensitive, boolean isExpanded,
boolean isShowingContent, String userFullName, String nickname, String avatar,
Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId,
@Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
@Nullable String inReplyToAccountAcct, @Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isMuted, boolean isThreadMuted,
boolean isUserMuted, int conversationId, @Nullable List<EmojiReaction> emojiReactions) {
boolean isUserMuted, int conversationId, @Nullable List<EmojiReaction> emojiReactions, boolean parentVisible) {
this.id = id;
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
@ -136,6 +139,7 @@ public abstract class StatusViewData {
this.reblogsCount = reblogsCount;
this.favouritesCount = favouritesCount;
this.inReplyToId = inReplyToId;
this.inReplyToAccountAcct = inReplyToAccountAcct;
this.mentions = mentions;
this.senderId = senderId;
this.rebloggingEnabled = rebloggingEnabled;
@ -152,6 +156,7 @@ public abstract class StatusViewData {
this.isUserMuted = isUserMuted;
this.conversationId = conversationId;
this.emojiReactions = emojiReactions;
this.parentVisible = parentVisible;
}
public String getId() {
@ -240,6 +245,11 @@ public abstract class StatusViewData {
return inReplyToId;
}
@Nullable
public String getInReplyToAccountAcct() {
return inReplyToAccountAcct;
}
public String getSenderId() {
return senderId;
}
@ -265,6 +275,10 @@ public abstract class StatusViewData {
return accountEmojis;
}
public boolean getParentVisible() {
return parentVisible;
}
@Nullable
public Card getCard() {
return card;
@ -343,6 +357,7 @@ public abstract class StatusViewData {
Objects.equals(avatar, concrete.avatar) &&
Objects.equals(createdAt, concrete.createdAt) &&
Objects.equals(inReplyToId, concrete.inReplyToId) &&
Objects.equals(inReplyToAccountAcct, concrete.inReplyToAccountAcct) &&
Arrays.equals(mentions, concrete.mentions) &&
Objects.equals(senderId, concrete.senderId) &&
Objects.equals(application, concrete.application) &&
@ -355,7 +370,8 @@ public abstract class StatusViewData {
isThreadMuted == concrete.isThreadMuted &&
isUserMuted == concrete.isUserMuted &&
conversationId == concrete.conversationId &&
Objects.equals(emojiReactions, concrete.emojiReactions);
Objects.equals(emojiReactions, concrete.emojiReactions) &&
parentVisible == concrete.parentVisible;
}
static Spanned replaceCrashingCharacters(Spanned content) {
@ -451,6 +467,7 @@ public abstract class StatusViewData {
private int reblogsCount;
private int favouritesCount;
private String inReplyToId;
private String inReplyToAccountAcct;
private Status.Mention[] mentions;
private String senderId;
private boolean rebloggingEnabled;
@ -467,6 +484,7 @@ public abstract class StatusViewData {
private boolean isUserMuted;
private int conversationId;
private List<EmojiReaction> emojiReactions;
private boolean parentVisible;
public Builder() {
}
@ -492,6 +510,7 @@ public abstract class StatusViewData {
reblogsCount = viewData.reblogsCount;
favouritesCount = viewData.favouritesCount;
inReplyToId = viewData.inReplyToId;
inReplyToAccountAcct = viewData.inReplyToAccountAcct;
mentions = viewData.mentions == null ? null : viewData.mentions.clone();
senderId = viewData.senderId;
rebloggingEnabled = viewData.rebloggingEnabled;
@ -507,6 +526,7 @@ public abstract class StatusViewData {
isThreadMuted = viewData.isThreadMuted;
isUserMuted = viewData.isUserMuted;
emojiReactions = viewData.emojiReactions;
parentVisible = viewData.parentVisible;
}
public Builder setId(String id) {
@ -614,6 +634,11 @@ public abstract class StatusViewData {
return this;
}
public Builder setInReplyToAccountAcct(String inReplyToAccountAcct) {
this.inReplyToAccountAcct = inReplyToAccountAcct;
return this;
}
public Builder setMentions(Status.Mention[] mentions) {
this.mentions = mentions;
return this;
@ -644,6 +669,11 @@ public abstract class StatusViewData {
return this;
}
public Builder setParentVisible(boolean parentVisible) {
this.parentVisible = parentVisible;
return this;
}
public Builder setCard(Card card) {
this.card = card;
return this;
@ -711,9 +741,9 @@ public abstract class StatusViewData {
return new StatusViewData.Concrete(id, content, reblogged, favourited, bookmarked, spoilerText,
visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded,
isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount,
favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application,
favouritesCount, inReplyToId, inReplyToAccountAcct, mentions, senderId, rebloggingEnabled, application,
statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isMuted, isThreadMuted,
isUserMuted, conversationId, emojiReactions);
isUserMuted, conversationId, emojiReactions, parentVisible);
}
}
}

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="18dp"
android:height="18dp"
android:autoMirrored="true"
android:viewportHeight="24.0"
android:viewportWidth="24.0">
<path
android:fillColor="?android:attr/textColorTertiary"
android:pathData="M10,9V5l-7,7 7,7v-4.1c5,0 8.5,1.6 11,5.1 -1,-5 -4,-10 -11,-11z" />
</vector>

@ -115,6 +115,22 @@
app:layout_constraintBaseline_toBaselineOf="@id/status_display_name"
tools:text="13:37" />
<TextView
android:id="@+id/reply_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:drawablePadding="6dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorTertiary"
android:textSize="?attr/status_text_medium"
app:drawableStartCompat="@drawable/ic_reply_18dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@+id/status_display_name"
app:layout_constraintTop_toBottomOf="@+id/status_display_name"
tools:text="Reply to a1batross" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/status_content_warning_description"
android:layout_width="0dp"
@ -126,8 +142,8 @@
android:textSize="?attr/status_text_medium"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/status_display_name"
app:layout_constraintTop_toBottomOf="@id/status_display_name"
app:layout_constraintStart_toStartOf="@+id/status_display_name"
app:layout_constraintTop_toBottomOf="@+id/reply_info"
tools:text="content warning which is very long and it doesn't fit"
tools:visibility="visible" />

@ -79,6 +79,22 @@
app:layout_constraintTop_toBottomOf="@id/status_display_name"
tools:text="\@ConnyDuck\@mastodon.social" />
<TextView
android:id="@+id/reply_info"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:drawablePadding="6dp"
android:ellipsize="end"
android:maxLines="1"
android:textColor="?android:textColorTertiary"
android:textSize="?attr/status_text_medium"
app:drawableStartCompat="@drawable/ic_reply_18dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="@id/status_avatar"
app:layout_constraintTop_toBottomOf="@+id/status_avatar"
tools:text="Reply to a1batross" />
<androidx.emoji.widget.EmojiTextView
android:id="@+id/status_content_warning_description"
android:layout_width="wrap_content"
@ -90,7 +106,7 @@
android:textColor="?android:textColorPrimary"
android:textSize="?attr/status_text_large"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/status_avatar"
app:layout_constraintTop_toBottomOf="@id/reply_info"
tools:text="CW this is a long long long long long long long long content warning" />
<com.google.android.material.button.MaterialButton

@ -12,9 +12,6 @@
android:title="@string/status_share_content" />
</menu>
</item>
<item
android:id="@+id/status_reply_to"
android:title="@string/action_reply_to" />
<item
android:id="@+id/status_copy_link"
android:title="@string/action_copy_link" />

@ -12,9 +12,6 @@
android:title="@string/status_share_content" />
</menu>
</item>
<item
android:id="@+id/status_reply_to"
android:title="@string/action_reply_to" />
<item
android:id="@+id/status_copy_link"
android:title="@string/action_copy_link" />

Loading…
Cancel
Save