From 7ccb9ac5d2d063509ddb6412e63578c3a42c9742 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Fri, 13 Mar 2020 18:54:27 +0300 Subject: [PATCH] Better handling of muted users and conversations, add option Hide muted users like in PleromaFE --- .../tusky/PreferencesActivity.kt | 2 +- .../tusky/adapter/NotificationsAdapter.java | 16 +++---- .../tusky/adapter/StatusViewHolder.java | 2 +- .../tusky/adapter/TimelineAdapter.java | 4 +- .../com/keylesspalace/tusky/entity/Status.kt | 4 ++ .../tusky/fragment/NotificationsFragment.java | 4 +- .../tusky/fragment/TimelineFragment.java | 7 +-- .../tusky/util/ViewDataUtils.java | 2 +- .../tusky/viewdata/StatusViewData.java | 46 +++++++++---------- app/src/main/res/values/husky.xml | 1 + app/src/main/res/xml/preferences.xml | 6 +++ 11 files changed, 53 insertions(+), 41 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt index 4adfc4e9..1af0f478 100644 --- a/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt @@ -129,7 +129,7 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference } "statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars", - "useBlurhash", "showCardsInTimelines", "confirmReblogs" -> { + "useBlurhash", "showCardsInTimelines", "confirmReblogs", "hideMutedUsers" -> { restartActivitiesOnExit = true } "language" -> { diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java index 8939b010..6c6d55af 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java @@ -262,7 +262,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter { switch (concrete.getType()) { case MENTION: case POLL: { - if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isThreadMuted()) + if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isMuted()) return VIEW_TYPE_MUTED_STATUS; return VIEW_TYPE_STATUS; } @@ -493,13 +493,13 @@ public class NotificationsAdapter extends RecyclerView.Adapter { if(icon != null) { icon.setColorFilter(ContextCompat.getColor(context, R.color.tusky_green), PorterDuff.Mode.SRC_ATOP); - } - - String format = context.getString(R.string.notification_emoji_format); - String emojiCode = notificationViewData.getEmoji(); - wholeMessage = String.format(format, displayName, emojiCode); - break; - } + } + + String format = context.getString(R.string.notification_emoji_format); + String emojiCode = notificationViewData.getEmoji(); + wholeMessage = String.format(format, displayName, emojiCode); + break; + } } message.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); final SpannableStringBuilder str = new SpannableStringBuilder(wholeMessage); diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java index 96bb7302..b189ce16 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java @@ -71,7 +71,7 @@ public class StatusViewHolder extends StatusBaseViewHolder { statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition())); } - if(status.isThreadMutedOnBackend()) { + if(status.isUserMuted() || status.isThreadMuted()) { toggleVisibility.setVisibility(View.VISIBLE); toggleVisibility.setOnClickListener(v -> listener.onMute(getAdapterPosition(), true)); } else { diff --git a/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java b/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java index 4375dfac..b1167de9 100644 --- a/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java +++ b/app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java @@ -111,7 +111,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter { holder.setup(statusListener, ((StatusViewData.Placeholder) status).isLoading()); } else if (status instanceof StatusViewData.Concrete) { StatusViewData.Concrete concrete = (StatusViewData.Concrete)status; - if(concrete.isThreadMuted()) { + if(concrete.isMuted()) { MutedStatusViewHolder holder = (MutedStatusViewHolder) viewHolder; holder.setupWithStatus(concrete, statusListener, statusDisplayOptions, payloads != null && !payloads.isEmpty() ? payloads.get(0) : null); @@ -134,7 +134,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter { return VIEW_TYPE_PLACEHOLDER; } else { StatusViewData.Concrete concrete = (StatusViewData.Concrete)dataSource.getItemAt(position); - if(concrete.isThreadMuted()) { + if(concrete.isMuted()) { return VIEW_TYPE_STATUS_MUTED; } else { return VIEW_TYPE_STATUS; 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 d4abf98c..270bba01 100644 --- a/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt +++ b/app/src/main/java/com/keylesspalace/tusky/entity/Status.kt @@ -126,6 +126,10 @@ data class Status( ) } + fun isMuted(): Boolean { + return muted + } + fun isUserMuted(): Boolean { return muted && !isThreadMuted() } diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java b/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java index faba2b65..0fdcf908 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java @@ -626,7 +626,7 @@ public class NotificationsFragment extends SFragment implements (NotificationViewData.Concrete) notifications.getPairedItem(position); StatusViewData.Concrete statusViewData = new StatusViewData.Builder(old.getStatusViewData()) - .setThreadMuted(isMuted) + .setMuted(isMuted) .createStatusViewData(); NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(), old.getId(), old.getAccount(), statusViewData, old.isExpanded(), old.getEmoji()); @@ -641,7 +641,7 @@ public class NotificationsFragment extends SFragment implements StatusViewData.Builder viewDataBuilder = new StatusViewData.Builder(viewdata.getStatusViewData()); viewDataBuilder.setThreadMuted(muted); - viewDataBuilder.setThreadMutedOnBackend(muted); + viewDataBuilder.setMuted(muted); NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete( viewdata.getType(), viewdata.getId(), viewdata.getAccount(), diff --git a/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java b/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java index d608271c..a4e737f1 100644 --- a/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java +++ b/app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java @@ -675,7 +675,7 @@ public class TimelineFragment extends SFragment implements public void onMute(int position, boolean isMuted) { StatusViewData.Concrete statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position)) - .setThreadMuted(isMuted) + .setMuted(isMuted) .createStatusViewData(); statuses.setPairedItem(position, statusViewData); updateAdapter(); @@ -685,8 +685,8 @@ public class TimelineFragment extends SFragment implements status.setThreadMuted(muted); StatusViewData.Builder statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position)); + statusViewData.setMuted(muted); statusViewData.setThreadMuted(muted); - statusViewData.setThreadMutedOnBackend(muted); statuses.setPairedItem(position, statusViewData.createStatusViewData()); } @@ -993,7 +993,8 @@ public class TimelineFragment extends SFragment implements private Call> getFetchCallByTimelineType(Kind kind, String tagOrId, String fromId, String uptoId) { MastodonApi api = mastodonApi; - boolean withMuted = true; // TODO: configurable + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); + boolean withMuted = !preferences.getBoolean("hideMutedUsers", false); switch (kind) { default: case HOME: 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 c435f426..12ff0639 100644 --- a/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java +++ b/app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java @@ -65,9 +65,9 @@ public final class ViewDataUtils { .setPoll(visibleStatus.getPoll()) .setCard(visibleStatus.getCard()) .setIsBot(visibleStatus.getAccount().getBot()) + .setMuted(visibleStatus.isMuted()) .setUserMuted(visibleStatus.isUserMuted()) .setThreadMuted(visibleStatus.isThreadMuted()) - .setThreadMutedOnBackend(visibleStatus.isThreadMuted()) .setConversationId(visibleStatus.getConversationId()) .setEmojiReactions(visibleStatus.getEmojiReactions()) .createStatusViewData(); 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 3f2fbaed..4475d221 100644 --- a/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java +++ b/app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java @@ -92,9 +92,9 @@ public abstract class StatusViewData { @Nullable private final PollViewData poll; private final boolean isBot; - private final boolean isThreadMuted; /* toggle for showing thread */ - private final boolean isUserMuted; - private final boolean isThreadMutedOnBackend; /* thread_muted state got from backend */ + private final boolean isMuted; /* user toggle */ + private final boolean isThreadMuted; /* thread_muted state got from backend */ + private final boolean isUserMuted; /* muted state got from backend */ private final int conversationId; @Nullable private final List emojiReactions; @@ -106,8 +106,8 @@ public abstract class StatusViewData { Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId, @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 isThreadMuted, - boolean isUserMuted, boolean isThreadMutedOnBackend, int conversationId, @Nullable List emojiReactions) { + boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isMuted, boolean isThreadMuted, + boolean isUserMuted, int conversationId, @Nullable List emojiReactions) { this.id = id; if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) { @@ -147,8 +147,8 @@ public abstract class StatusViewData { this.isCollapsed = isCollapsed; this.poll = poll; this.isBot = isBot; + this.isMuted = isMuted; this.isThreadMuted = isThreadMuted; - this.isThreadMutedOnBackend = isThreadMutedOnBackend; this.isUserMuted = isUserMuted; this.conversationId = conversationId; this.emojiReactions = emojiReactions; @@ -304,12 +304,12 @@ public abstract class StatusViewData { return isThreadMuted; } - public boolean isThreadMutedOnBackend() { - return isThreadMutedOnBackend; + public boolean isMuted() { + return isMuted; } public boolean isUserMuted() { - return isUserMuted; + return isUserMuted; } @Nullable @@ -351,9 +351,9 @@ public abstract class StatusViewData { Objects.equals(card, concrete.card) && Objects.equals(poll, concrete.poll) && isCollapsed == concrete.isCollapsed && + isMuted == concrete.isMuted && isThreadMuted == concrete.isThreadMuted && isUserMuted == concrete.isUserMuted && - isThreadMutedOnBackend == concrete.isThreadMutedOnBackend && conversationId == concrete.conversationId && Objects.equals(emojiReactions, concrete.emojiReactions); } @@ -462,8 +462,8 @@ public abstract class StatusViewData { private boolean isCollapsed; /** Whether the status is shown partially or fully */ private PollViewData poll; private boolean isBot; + private boolean isMuted; private boolean isThreadMuted; - private boolean isThreadMutedOnBackend; private boolean isUserMuted; private int conversationId; private List emojiReactions; @@ -503,9 +503,9 @@ public abstract class StatusViewData { isCollapsed = viewData.isCollapsed(); poll = viewData.poll; isBot = viewData.isBot(); + isMuted = viewData.isMuted; isThreadMuted = viewData.isThreadMuted; isUserMuted = viewData.isUserMuted; - isThreadMutedOnBackend = viewData.isThreadMutedOnBackend; emojiReactions = viewData.emojiReactions; } @@ -677,27 +677,27 @@ public abstract class StatusViewData { this.poll = PollViewDataKt.toViewData(poll); return this; } - + + public Builder setMuted(Boolean isMuted) { + this.isMuted = isMuted; + return this; + } + public Builder setUserMuted(Boolean isUserMuted) { this.isUserMuted = isUserMuted; return this; } - + public Builder setThreadMuted(Boolean isThreadMuted) { this.isThreadMuted = isThreadMuted; return this; } - - public Builder setThreadMutedOnBackend(Boolean isThreadMutedOnBackend) { - this.isThreadMutedOnBackend = isThreadMutedOnBackend; - return this; - } - + public Builder setConversationId(int conversationId) { this.conversationId = conversationId; return this; } - + public Builder setEmojiReactions(List emojiReactions) { this.emojiReactions = emojiReactions; return this; @@ -712,8 +712,8 @@ public abstract class StatusViewData { visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded, isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount, favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application, - statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isThreadMuted, - isUserMuted, isThreadMutedOnBackend, conversationId, emojiReactions); + statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isMuted, isThreadMuted, + isUserMuted, conversationId, emojiReactions); } } } diff --git a/app/src/main/res/values/husky.xml b/app/src/main/res/values/husky.xml index 6ca25ec3..e0954b82 100644 --- a/app/src/main/res/values/husky.xml +++ b/app/src/main/res/values/husky.xml @@ -23,5 +23,6 @@ Notifications about new emoji reactions my posts are reacted with emojis + Hide muted users diff --git a/app/src/main/res/xml/preferences.xml b/app/src/main/res/xml/preferences.xml index b04ccacc..6e75a611 100644 --- a/app/src/main/res/xml/preferences.xml +++ b/app/src/main/res/xml/preferences.xml @@ -84,6 +84,12 @@ android:title="@string/pref_title_confirm_reblogs" app:singleLineTitle="false" /> + +