diff --git a/app/src/husky/res/values/strings.xml b/app/src/husky/res/values/strings.xml index 56ad4784..81d7ddcb 100644 --- a/app/src/husky/res/values/strings.xml +++ b/app/src/husky/res/values/strings.xml @@ -95,6 +95,7 @@ Share content of post Share link to post %s repeated + Reply to %s Scheduled posts Repeated by diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java index 64a59bfe..d49b189b 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusBaseViewHolder.java @@ -69,6 +69,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 +122,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 +381,17 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { } + protected void setReplyInfo(StatusViewData.Concrete status) { + if (status.getInReplyToId() != null) { + Context context = replyInfo.getContext(); + String replyToAccount = status.getInReplyToAccountAcct(); + replyInfo.setText(context.getString(R.string.status_replied_to_format, replyToAccount)); + replyInfo.setVisibility(View.VISIBLE); + } else { + replyInfo.setVisibility(View.GONE); + } + } + private void setReblogged(boolean reblogged) { reblogButton.setChecked(reblogged); } @@ -757,6 +770,7 @@ public abstract class StatusBaseViewHolder extends RecyclerView.ViewHolder { setUsername(status.getNickname()); setCreatedAt(status.getCreatedAt(), statusDisplayOptions); setIsReply(status.getInReplyToId() != null); + setReplyInfo(status); setAvatar(status.getAvatar(), status.getRebloggedAvatar(), status.isBot(), statusDisplayOptions); setReblogged(status.isReblogged()); setFavourited(status.isFavourited()); diff --git a/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt b/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt index 566d75bf..a6c42151 100644 --- a/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt +++ b/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt @@ -151,6 +151,10 @@ data class Status( return pleroma?.emojiReactions; } + fun getInReplyToAccountAcct(): String? { + return pleroma?.inReplyToAccountAcct; + } + private fun getEditableText(): String { val builder = SpannableStringBuilder(content) for (span in content.getSpans(0, content.length, URLSpan::class.java)) { @@ -182,7 +186,8 @@ data class Status( data class PleromaStatus( @SerializedName("thread_muted") var threadMuted: Boolean?, @SerializedName("conversation_id") val conversationId: Int?, - @SerializedName("emoji_reactions") val emojiReactions: List? + @SerializedName("emoji_reactions") val emojiReactions: List?, + @SerializedName("in_reply_to_account_acct") val inReplyToAccountAcct: String? ) data class Mention ( diff --git a/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java b/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java index ef649496..8c3b3c4e 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java +++ b/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java @@ -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()) diff --git a/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java b/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java index 4475d221..289402c1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java +++ b/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java @@ -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; @@ -104,7 +106,7 @@ public abstract class StatusViewData { @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 statusEmojis, List accountEmojis, @Nullable Card card, boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isMuted, boolean isThreadMuted, boolean isUserMuted, int conversationId, @Nullable List emojiReactions) { @@ -136,6 +138,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; @@ -240,6 +243,11 @@ public abstract class StatusViewData { return inReplyToId; } + @Nullable + public String getInReplyToAccountAcct() { + return inReplyToAccountAcct; + } + public String getSenderId() { return senderId; } @@ -343,6 +351,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) && @@ -451,6 +460,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; @@ -492,6 +502,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; @@ -614,6 +625,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; @@ -711,7 +727,7 @@ 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); } diff --git a/app/src/main/res/drawable/ic_reply_18dp.xml b/app/src/main/res/drawable/ic_reply_18dp.xml new file mode 100644 index 00000000..234bc07d --- /dev/null +++ b/app/src/main/res/drawable/ic_reply_18dp.xml @@ -0,0 +1,10 @@ + + + diff --git a/app/src/main/res/layout/item_status.xml b/app/src/main/res/layout/item_status.xml index 82488ac7..3bc36369 100644 --- a/app/src/main/res/layout/item_status.xml +++ b/app/src/main/res/layout/item_status.xml @@ -115,6 +115,22 @@ app:layout_constraintBaseline_toBaselineOf="@id/status_display_name" tools:text="13:37" /> + + diff --git a/app/src/main/res/layout/item_status_detailed.xml b/app/src/main/res/layout/item_status_detailed.xml index 832e6133..61244772 100644 --- a/app/src/main/res/layout/item_status_detailed.xml +++ b/app/src/main/res/layout/item_status_detailed.xml @@ -79,6 +79,22 @@ app:layout_constraintTop_toBottomOf="@id/status_display_name" tools:text="\@ConnyDuck\@mastodon.social" /> + +