Merge branch 'develop' of https://github.com/FWGS/Husky into develop

main
Alibek Omarov 5 years ago
commit 78cf552a32
  1. 1
      .travis.yml
  2. 1
      app/build.gradle
  3. 2
      app/src/main/java/com/keylesspalace/tusky/PreferencesActivity.kt
  4. 26
      app/src/main/java/com/keylesspalace/tusky/adapter/NotificationsAdapter.java
  5. 2
      app/src/main/java/com/keylesspalace/tusky/adapter/StatusViewHolder.java
  6. 4
      app/src/main/java/com/keylesspalace/tusky/adapter/TimelineAdapter.java
  7. 6
      app/src/main/java/com/keylesspalace/tusky/entity/Status.kt
  8. 4
      app/src/main/java/com/keylesspalace/tusky/fragment/NotificationsFragment.java
  9. 18
      app/src/main/java/com/keylesspalace/tusky/fragment/TimelineFragment.java
  10. 3
      app/src/main/java/com/keylesspalace/tusky/fragment/preference/AccountPreferencesFragment.kt
  11. 4
      app/src/main/java/com/keylesspalace/tusky/service/SendTootService.kt
  12. 18
      app/src/main/java/com/keylesspalace/tusky/util/NotificationHelper.java
  13. 2
      app/src/main/java/com/keylesspalace/tusky/util/ViewDataUtils.java
  14. 48
      app/src/main/java/com/keylesspalace/tusky/viewdata/StatusViewData.java
  15. 4
      app/src/main/res/layout/view_background_message.xml
  16. 1
      app/src/main/res/values/husky.xml
  17. 10
      app/src/main/res/xml/notification_preferences.xml
  18. 6
      app/src/main/res/xml/preferences.xml

@ -9,6 +9,7 @@ before_script:
- export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk-bundle - export ANDROID_NDK_ROOT=$ANDROID_HOME/ndk-bundle
- export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT - export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT
- sed -i "s/blue {}//" app/build.gradle - sed -i "s/blue {}//" app/build.gradle
- sed -i "s/\/\/abortOnError/abortOnError/" app/build.gradle
# - sed -i "s/debug {}//" app/build.gradle # - sed -i "s/debug {}//" app/build.gradle
before_cache: before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock

@ -64,6 +64,7 @@ android {
} }
lintOptions { lintOptions {
//abortOnError false
disable 'MissingTranslation' disable 'MissingTranslation'
disable 'ExtraTranslation' disable 'ExtraTranslation'
disable 'AppCompatCustomView' // I don't care about AppCompat bloat disable 'AppCompatCustomView' // I don't care about AppCompat bloat

@ -129,7 +129,7 @@ class PreferencesActivity : BaseActivity(), SharedPreferences.OnSharedPreference
} }
"statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars", "statusTextSize", "absoluteTimeView", "showBotOverlay", "animateGifAvatars",
"useBlurhash", "showCardsInTimelines", "confirmReblogs" -> { "useBlurhash", "showCardsInTimelines", "confirmReblogs", "hideMutedUsers" -> {
restartActivitiesOnExit = true restartActivitiesOnExit = true
} }
"language" -> { "language" -> {

@ -154,14 +154,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) { public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @NonNull List payloads) {
bindViewHolder(viewHolder, position, payloads); bindViewHolder(viewHolder, position, payloads);
} }
private void fixupHiddenUsers(StatusViewData.Concrete status, View v) {
if(status.isUserMuted()) {
v.setVisibility(View.GONE);
} else {
v.setVisibility(View.VISIBLE);
}
}
private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List payloads) { private void bindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int position, @Nullable List payloads) {
Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null; Object payloadForHolder = payloads != null && !payloads.isEmpty() ? payloads.get(0) : null;
@ -188,7 +180,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
} else { } else {
holder.hideStatusInfo(); holder.hideStatusInfo();
} }
fixupHiddenUsers(status, holder.itemView);
break; break;
} }
case VIEW_TYPE_MUTED_STATUS: { case VIEW_TYPE_MUTED_STATUS: {
@ -196,7 +187,6 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
StatusViewData.Concrete status = concreteNotificaton.getStatusViewData(); StatusViewData.Concrete status = concreteNotificaton.getStatusViewData();
holder.setupWithStatus(status, holder.setupWithStatus(status,
statusListener, statusDisplayOptions, payloadForHolder); statusListener, statusDisplayOptions, payloadForHolder);
fixupHiddenUsers(status, holder.itemView);
break; break;
} }
case VIEW_TYPE_STATUS_NOTIFICATION: { case VIEW_TYPE_STATUS_NOTIFICATION: {
@ -272,7 +262,7 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
switch (concrete.getType()) { switch (concrete.getType()) {
case MENTION: case MENTION:
case POLL: { case POLL: {
if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isThreadMuted()) if(concrete.getStatusViewData() != null && concrete.getStatusViewData().isMuted())
return VIEW_TYPE_MUTED_STATUS; return VIEW_TYPE_MUTED_STATUS;
return VIEW_TYPE_STATUS; return VIEW_TYPE_STATUS;
} }
@ -503,13 +493,13 @@ public class NotificationsAdapter extends RecyclerView.Adapter {
if(icon != null) { if(icon != null) {
icon.setColorFilter(ContextCompat.getColor(context, icon.setColorFilter(ContextCompat.getColor(context,
R.color.tusky_green), PorterDuff.Mode.SRC_ATOP); R.color.tusky_green), PorterDuff.Mode.SRC_ATOP);
} }
String format = context.getString(R.string.notification_emoji_format); String format = context.getString(R.string.notification_emoji_format);
String emojiCode = notificationViewData.getEmoji(); String emojiCode = notificationViewData.getEmoji();
wholeMessage = String.format(format, displayName, emojiCode); wholeMessage = String.format(format, displayName, emojiCode);
break; break;
} }
} }
message.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); message.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
final SpannableStringBuilder str = new SpannableStringBuilder(wholeMessage); final SpannableStringBuilder str = new SpannableStringBuilder(wholeMessage);

@ -71,7 +71,7 @@ public class StatusViewHolder extends StatusBaseViewHolder {
statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition())); statusInfo.setOnClickListener(v -> listener.onOpenReblog(getAdapterPosition()));
} }
if(status.isThreadMutedOnBackend()) { if(status.isUserMuted() || status.isThreadMuted()) {
toggleVisibility.setVisibility(View.VISIBLE); toggleVisibility.setVisibility(View.VISIBLE);
toggleVisibility.setOnClickListener(v -> listener.onMute(getAdapterPosition(), true)); toggleVisibility.setOnClickListener(v -> listener.onMute(getAdapterPosition(), true));
} else { } else {

@ -111,7 +111,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter {
holder.setup(statusListener, ((StatusViewData.Placeholder) status).isLoading()); holder.setup(statusListener, ((StatusViewData.Placeholder) status).isLoading());
} else if (status instanceof StatusViewData.Concrete) { } else if (status instanceof StatusViewData.Concrete) {
StatusViewData.Concrete concrete = (StatusViewData.Concrete)status; StatusViewData.Concrete concrete = (StatusViewData.Concrete)status;
if(concrete.isThreadMuted()) { if(concrete.isMuted()) {
MutedStatusViewHolder holder = (MutedStatusViewHolder) viewHolder; MutedStatusViewHolder holder = (MutedStatusViewHolder) viewHolder;
holder.setupWithStatus(concrete, statusListener, statusDisplayOptions, holder.setupWithStatus(concrete, statusListener, statusDisplayOptions,
payloads != null && !payloads.isEmpty() ? payloads.get(0) : null); payloads != null && !payloads.isEmpty() ? payloads.get(0) : null);
@ -134,7 +134,7 @@ public final class TimelineAdapter extends RecyclerView.Adapter {
return VIEW_TYPE_PLACEHOLDER; return VIEW_TYPE_PLACEHOLDER;
} else { } else {
StatusViewData.Concrete concrete = (StatusViewData.Concrete)dataSource.getItemAt(position); StatusViewData.Concrete concrete = (StatusViewData.Concrete)dataSource.getItemAt(position);
if(concrete.isThreadMuted()) { if(concrete.isMuted()) {
return VIEW_TYPE_STATUS_MUTED; return VIEW_TYPE_STATUS_MUTED;
} else { } else {
return VIEW_TYPE_STATUS; return VIEW_TYPE_STATUS;

@ -126,10 +126,14 @@ data class Status(
) )
} }
fun isUserMuted(): Boolean { fun isMuted(): Boolean {
return muted return muted
} }
fun isUserMuted(): Boolean {
return muted && !isThreadMuted()
}
fun isThreadMuted(): Boolean { fun isThreadMuted(): Boolean {
return pleroma?.threadMuted ?: false return pleroma?.threadMuted ?: false
} }

@ -626,7 +626,7 @@ public class NotificationsFragment extends SFragment implements
(NotificationViewData.Concrete) notifications.getPairedItem(position); (NotificationViewData.Concrete) notifications.getPairedItem(position);
StatusViewData.Concrete statusViewData = StatusViewData.Concrete statusViewData =
new StatusViewData.Builder(old.getStatusViewData()) new StatusViewData.Builder(old.getStatusViewData())
.setThreadMuted(isMuted) .setMuted(isMuted)
.createStatusViewData(); .createStatusViewData();
NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(), NotificationViewData notificationViewData = new NotificationViewData.Concrete(old.getType(),
old.getId(), old.getAccount(), statusViewData, old.isExpanded(), old.getEmoji()); 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()); StatusViewData.Builder viewDataBuilder = new StatusViewData.Builder(viewdata.getStatusViewData());
viewDataBuilder.setThreadMuted(muted); viewDataBuilder.setThreadMuted(muted);
viewDataBuilder.setThreadMutedOnBackend(muted); viewDataBuilder.setMuted(muted);
NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete( NotificationViewData.Concrete newViewData = new NotificationViewData.Concrete(
viewdata.getType(), viewdata.getId(), viewdata.getAccount(), viewdata.getType(), viewdata.getId(), viewdata.getAccount(),

@ -152,7 +152,6 @@ public class TimelineFragment extends SFragment implements
private EndlessOnScrollListener scrollListener; private EndlessOnScrollListener scrollListener;
private boolean filterRemoveReplies; private boolean filterRemoveReplies;
private boolean filterRemoveReblogs; private boolean filterRemoveReblogs;
private boolean filterRemoveMutedUsers;
private boolean hideFab; private boolean hideFab;
private boolean bottomLoading; private boolean bottomLoading;
@ -353,11 +352,6 @@ public class TimelineFragment extends SFragment implements
filter = preferences.getBoolean("tabFilterHomeBoosts", true); filter = preferences.getBoolean("tabFilterHomeBoosts", true);
filterRemoveReblogs = kind == Kind.HOME && !filter; filterRemoveReblogs = kind == Kind.HOME && !filter;
filterRemoveMutedUsers = kind != Kind.USER &&
kind != Kind.USER_PINNED &&
kind != Kind.USER_WITH_REPLIES &&
kind != Kind.BOOKMARKS;
reloadFilters(false); reloadFilters(false);
} }
@ -681,7 +675,7 @@ public class TimelineFragment extends SFragment implements
public void onMute(int position, boolean isMuted) { public void onMute(int position, boolean isMuted) {
StatusViewData.Concrete statusViewData = StatusViewData.Concrete statusViewData =
new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position)) new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position))
.setThreadMuted(isMuted) .setMuted(isMuted)
.createStatusViewData(); .createStatusViewData();
statuses.setPairedItem(position, statusViewData); statuses.setPairedItem(position, statusViewData);
updateAdapter(); updateAdapter();
@ -691,8 +685,8 @@ public class TimelineFragment extends SFragment implements
status.setThreadMuted(muted); status.setThreadMuted(muted);
StatusViewData.Builder statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position)); StatusViewData.Builder statusViewData = new StatusViewData.Builder((StatusViewData.Concrete)statuses.getPairedItem(position));
statusViewData.setMuted(muted);
statusViewData.setThreadMuted(muted); statusViewData.setThreadMuted(muted);
statusViewData.setThreadMutedOnBackend(muted);
statuses.setPairedItem(position, statusViewData.createStatusViewData()); statuses.setPairedItem(position, statusViewData.createStatusViewData());
} }
@ -999,7 +993,8 @@ public class TimelineFragment extends SFragment implements
private Call<List<Status>> getFetchCallByTimelineType(Kind kind, String tagOrId, String fromId, private Call<List<Status>> getFetchCallByTimelineType(Kind kind, String tagOrId, String fromId,
String uptoId) { String uptoId) {
MastodonApi api = mastodonApi; MastodonApi api = mastodonApi;
boolean withMuted = true; // TODO: configurable SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
boolean withMuted = !preferences.getBoolean("hideMutedUsers", false);
switch (kind) { switch (kind) {
default: default:
case HOME: case HOME:
@ -1175,9 +1170,8 @@ public class TimelineFragment extends SFragment implements
while (it.hasNext()) { while (it.hasNext()) {
Status status = it.next().asRightOrNull(); Status status = it.next().asRightOrNull();
if (status != null if (status != null
&& ((filterRemoveReplies && status.getInReplyToId() != null) && ((status.getInReplyToId() != null && filterRemoveReplies)
|| (filterRemoveReblogs && status.getReblog() != null) || (status.getReblog() != null && filterRemoveReblogs)
|| (filterRemoveMutedUsers && status.isUserMuted())
|| shouldFilterStatus(status))) { || shouldFilterStatus(status))) {
it.remove(); it.remove();
} }

@ -35,6 +35,7 @@ import com.keylesspalace.tusky.entity.Filter
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.ThemeUtils import com.keylesspalace.tusky.util.ThemeUtils
import com.keylesspalace.tusky.util.NotificationHelper
import com.mikepenz.google_material_typeface_library.GoogleMaterial import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable import com.mikepenz.iconics.IconicsDrawable
import retrofit2.Call import retrofit2.Call
@ -171,7 +172,7 @@ class AccountPreferencesFragment : PreferenceFragmentCompat(),
return when (preference) { return when (preference) {
notificationPreference -> { notificationPreference -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
val intent = Intent() val intent = Intent()
intent.action = "android.settings.APP_NOTIFICATION_SETTINGS" intent.action = "android.settings.APP_NOTIFICATION_SETTINGS"
intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID) intent.putExtra("android.provider.extra.APP_PACKAGE", BuildConfig.APPLICATION_ID)

@ -26,6 +26,7 @@ import com.keylesspalace.tusky.entity.NewStatus
import com.keylesspalace.tusky.entity.Status import com.keylesspalace.tusky.entity.Status
import com.keylesspalace.tusky.network.MastodonApi import com.keylesspalace.tusky.network.MastodonApi
import com.keylesspalace.tusky.util.SaveTootHelper import com.keylesspalace.tusky.util.SaveTootHelper
import com.keylesspalace.tusky.util.NotificationHelper
import dagger.android.AndroidInjection import dagger.android.AndroidInjection
import kotlinx.android.parcel.Parcelize import kotlinx.android.parcel.Parcelize
import retrofit2.Call import retrofit2.Call
@ -72,10 +73,9 @@ class SendTootService : Service(), Injectable {
val tootToSend = intent.getParcelableExtra<TootToSend>(KEY_TOOT) val tootToSend = intent.getParcelableExtra<TootToSend>(KEY_TOOT)
?: throw IllegalStateException("SendTootService started without $KEY_TOOT extra") ?: throw IllegalStateException("SendTootService started without $KEY_TOOT extra")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NotificationHelper.NOTIFICATION_USE_CHANNELS) {
val channel = NotificationChannel(CHANNEL_ID, getString(R.string.send_toot_notification_channel_name), NotificationManager.IMPORTANCE_LOW) val channel = NotificationChannel(CHANNEL_ID, getString(R.string.send_toot_notification_channel_name), NotificationManager.IMPORTANCE_LOW)
notificationManager.createNotificationChannel(channel) notificationManager.createNotificationChannel(channel)
} }
var notificationText = tootToSend.warningText var notificationText = tootToSend.warningText

@ -124,6 +124,12 @@ public class NotificationHelper {
*/ */
private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15; private static final int NOTIFICATION_CHECK_INTERVAL_MINUTES = 15;
/**
* by setting this as false, it's possible to test legacy notification channels on newer devices
*/
//public static final boolean NOTIFICATION_USE_CHANNELS = false;
public static final boolean NOTIFICATION_USE_CHANNELS = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
/** /**
* Takes a given Mastodon notification and either creates a new Android notification or updates * Takes a given Mastodon notification and either creates a new Android notification or updates
@ -353,7 +359,7 @@ public class NotificationHelper {
} }
public static void createNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) { public static void createNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -411,7 +417,7 @@ public class NotificationHelper {
} }
public static void deleteNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) { public static void deleteNotificationChannelsForAccount(@NonNull AccountEntity account, @NonNull Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -422,7 +428,7 @@ public class NotificationHelper {
} }
public static void deleteLegacyNotificationChannels(@NonNull Context context, @NonNull AccountManager accountManager) { public static void deleteLegacyNotificationChannels(@NonNull Context context, @NonNull AccountManager accountManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -441,7 +447,7 @@ public class NotificationHelper {
} }
public static boolean areNotificationsEnabled(@NonNull Context context, @NonNull AccountManager accountManager) { public static boolean areNotificationsEnabled(@NonNull Context context, @NonNull AccountManager accountManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
// on Android >= O, notifications are enabled, if at least one channel is enabled // on Android >= O, notifications are enabled, if at least one channel is enabled
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
@ -505,7 +511,7 @@ public class NotificationHelper {
private static boolean filterNotification(AccountEntity account, Notification notification, private static boolean filterNotification(AccountEntity account, Notification notification,
Context context) { Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String channelId = getChannelId(account, notification); String channelId = getChannelId(account, notification);
@ -559,7 +565,7 @@ public class NotificationHelper {
private static void setupPreferences(AccountEntity account, private static void setupPreferences(AccountEntity account,
NotificationCompat.Builder builder) { NotificationCompat.Builder builder) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { if (NOTIFICATION_USE_CHANNELS) {
return; //do nothing on Android O or newer, the system uses the channel settings anyway return; //do nothing on Android O or newer, the system uses the channel settings anyway
} }

@ -65,9 +65,9 @@ public final class ViewDataUtils {
.setPoll(visibleStatus.getPoll()) .setPoll(visibleStatus.getPoll())
.setCard(visibleStatus.getCard()) .setCard(visibleStatus.getCard())
.setIsBot(visibleStatus.getAccount().getBot()) .setIsBot(visibleStatus.getAccount().getBot())
.setMuted(visibleStatus.isMuted())
.setUserMuted(visibleStatus.isUserMuted()) .setUserMuted(visibleStatus.isUserMuted())
.setThreadMuted(visibleStatus.isThreadMuted()) .setThreadMuted(visibleStatus.isThreadMuted())
.setThreadMutedOnBackend(visibleStatus.isThreadMuted())
.setConversationId(visibleStatus.getConversationId()) .setConversationId(visibleStatus.getConversationId())
.setEmojiReactions(visibleStatus.getEmojiReactions()) .setEmojiReactions(visibleStatus.getEmojiReactions())
.createStatusViewData(); .createStatusViewData();

@ -92,9 +92,9 @@ public abstract class StatusViewData {
@Nullable @Nullable
private final PollViewData poll; private final PollViewData poll;
private final boolean isBot; private final boolean isBot;
private final boolean isThreadMuted; /* toggle for showing thread */ private final boolean isMuted; /* user toggle */
private final boolean isUserMuted; private final boolean isThreadMuted; /* thread_muted state got from backend */
private final boolean isThreadMutedOnBackend; /* thread_muted state got from backend */ private final boolean isUserMuted; /* muted state got from backend */
private final int conversationId; private final int conversationId;
@Nullable @Nullable
private final List<EmojiReaction> emojiReactions; private final List<EmojiReaction> emojiReactions;
@ -106,11 +106,11 @@ public abstract class StatusViewData {
Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId, Date createdAt, int reblogsCount, int favouritesCount, @Nullable String inReplyToId,
@Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled, @Nullable Status.Mention[] mentions, String senderId, boolean rebloggingEnabled,
Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card, Status.Application application, List<Emoji> statusEmojis, List<Emoji> accountEmojis, @Nullable Card card,
boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isThreadMuted, boolean isCollapsible, boolean isCollapsed, @Nullable PollViewData poll, boolean isBot, boolean isMuted, boolean isThreadMuted,
boolean isUserMuted, boolean isThreadMutedOnBackend, int conversationId, @Nullable List<EmojiReaction> emojiReactions) { boolean isUserMuted, int conversationId, @Nullable List<EmojiReaction> emojiReactions) {
this.id = id; this.id = id;
if (Build.VERSION.SDK_INT == 23) { if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
// https://github.com/tuskyapp/Tusky/issues/563 // https://github.com/tuskyapp/Tusky/issues/563
this.content = replaceCrashingCharacters(content); this.content = replaceCrashingCharacters(content);
this.spoilerText = spoilerText == null ? null : replaceCrashingCharacters(spoilerText).toString(); this.spoilerText = spoilerText == null ? null : replaceCrashingCharacters(spoilerText).toString();
@ -147,8 +147,8 @@ public abstract class StatusViewData {
this.isCollapsed = isCollapsed; this.isCollapsed = isCollapsed;
this.poll = poll; this.poll = poll;
this.isBot = isBot; this.isBot = isBot;
this.isMuted = isMuted;
this.isThreadMuted = isThreadMuted; this.isThreadMuted = isThreadMuted;
this.isThreadMutedOnBackend = isThreadMutedOnBackend;
this.isUserMuted = isUserMuted; this.isUserMuted = isUserMuted;
this.conversationId = conversationId; this.conversationId = conversationId;
this.emojiReactions = emojiReactions; this.emojiReactions = emojiReactions;
@ -304,12 +304,12 @@ public abstract class StatusViewData {
return isThreadMuted; return isThreadMuted;
} }
public boolean isThreadMutedOnBackend() { public boolean isMuted() {
return isThreadMutedOnBackend; return isMuted;
} }
public boolean isUserMuted() { public boolean isUserMuted() {
return isUserMuted; return isUserMuted;
} }
@Nullable @Nullable
@ -351,9 +351,9 @@ public abstract class StatusViewData {
Objects.equals(card, concrete.card) && Objects.equals(card, concrete.card) &&
Objects.equals(poll, concrete.poll) && Objects.equals(poll, concrete.poll) &&
isCollapsed == concrete.isCollapsed && isCollapsed == concrete.isCollapsed &&
isMuted == concrete.isMuted &&
isThreadMuted == concrete.isThreadMuted && isThreadMuted == concrete.isThreadMuted &&
isUserMuted == concrete.isUserMuted && isUserMuted == concrete.isUserMuted &&
isThreadMutedOnBackend == concrete.isThreadMutedOnBackend &&
conversationId == concrete.conversationId && conversationId == concrete.conversationId &&
Objects.equals(emojiReactions, concrete.emojiReactions); 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 boolean isCollapsed; /** Whether the status is shown partially or fully */
private PollViewData poll; private PollViewData poll;
private boolean isBot; private boolean isBot;
private boolean isMuted;
private boolean isThreadMuted; private boolean isThreadMuted;
private boolean isThreadMutedOnBackend;
private boolean isUserMuted; private boolean isUserMuted;
private int conversationId; private int conversationId;
private List<EmojiReaction> emojiReactions; private List<EmojiReaction> emojiReactions;
@ -503,9 +503,9 @@ public abstract class StatusViewData {
isCollapsed = viewData.isCollapsed(); isCollapsed = viewData.isCollapsed();
poll = viewData.poll; poll = viewData.poll;
isBot = viewData.isBot(); isBot = viewData.isBot();
isMuted = viewData.isMuted;
isThreadMuted = viewData.isThreadMuted; isThreadMuted = viewData.isThreadMuted;
isUserMuted = viewData.isUserMuted; isUserMuted = viewData.isUserMuted;
isThreadMutedOnBackend = viewData.isThreadMutedOnBackend;
emojiReactions = viewData.emojiReactions; emojiReactions = viewData.emojiReactions;
} }
@ -677,27 +677,27 @@ public abstract class StatusViewData {
this.poll = PollViewDataKt.toViewData(poll); this.poll = PollViewDataKt.toViewData(poll);
return this; return this;
} }
public Builder setMuted(Boolean isMuted) {
this.isMuted = isMuted;
return this;
}
public Builder setUserMuted(Boolean isUserMuted) { public Builder setUserMuted(Boolean isUserMuted) {
this.isUserMuted = isUserMuted; this.isUserMuted = isUserMuted;
return this; return this;
} }
public Builder setThreadMuted(Boolean isThreadMuted) { public Builder setThreadMuted(Boolean isThreadMuted) {
this.isThreadMuted = isThreadMuted; this.isThreadMuted = isThreadMuted;
return this; return this;
} }
public Builder setThreadMutedOnBackend(Boolean isThreadMutedOnBackend) {
this.isThreadMutedOnBackend = isThreadMutedOnBackend;
return this;
}
public Builder setConversationId(int conversationId) { public Builder setConversationId(int conversationId) {
this.conversationId = conversationId; this.conversationId = conversationId;
return this; return this;
} }
public Builder setEmojiReactions(List<EmojiReaction> emojiReactions) { public Builder setEmojiReactions(List<EmojiReaction> emojiReactions) {
this.emojiReactions = emojiReactions; this.emojiReactions = emojiReactions;
return this; return this;
@ -712,8 +712,8 @@ public abstract class StatusViewData {
visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded, visibility, attachments, rebloggedByUsername, rebloggedAvatar, isSensitive, isExpanded,
isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount, isShowingContent, userFullName, nickname, avatar, createdAt, reblogsCount,
favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application, favouritesCount, inReplyToId, mentions, senderId, rebloggingEnabled, application,
statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isThreadMuted, statusEmojis, accountEmojis, card, isCollapsible, isCollapsed, poll, isBot, isMuted, isThreadMuted,
isUserMuted, isThreadMutedOnBackend, conversationId, emojiReactions); isUserMuted, conversationId, emojiReactions);
} }
} }
} }

@ -7,8 +7,8 @@
<ImageView <ImageView
android:id="@+id/imageView" android:id="@+id/imageView"
android:layout_width="match_parent" android:layout_width="wrap_content"
android:layout_height="0dp" android:layout_height="wrap_content"
android:layout_marginTop="4dp" android:layout_marginTop="4dp"
android:layout_weight="1" android:layout_weight="1"
android:contentDescription="@null" android:contentDescription="@null"

@ -23,5 +23,6 @@
<string name="notification_emoji_description">Notifications about new emoji reactions</string> <string name="notification_emoji_description">Notifications about new emoji reactions</string>
<string name="pref_title_notification_filter_emoji">my posts are reacted with emojis</string> <string name="pref_title_notification_filter_emoji">my posts are reacted with emojis</string>
<string name="pref_title_hide_muted_users">Hide muted users</string>
</resources> </resources>

@ -41,14 +41,14 @@
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="notificationFilterPolls" android:key="notificationFilterEmojis"
android:title="@string/pref_title_notification_filter_poll" android:title="@string/pref_title_notification_filter_emoji"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
<SwitchPreferenceCompat <SwitchPreferenceCompat
android:defaultValue="true" android:defaultValue="true"
android:key="notificationFilterEmojiReactons" android:key="notificationFilterPolls"
android:title="@string/pref_title_notification_filter_emoji" android:title="@string/pref_title_notification_filter_poll"
app:iconSpaceReserved="false" /> app:iconSpaceReserved="false" />
</PreferenceCategory> </PreferenceCategory>

@ -84,6 +84,12 @@
android:title="@string/pref_title_confirm_reblogs" android:title="@string/pref_title_confirm_reblogs"
app:singleLineTitle="false" /> app:singleLineTitle="false" />
<SwitchPreferenceCompat
android:defaultValue="false"
android:key="hideMutedUsers"
android:title="@string/pref_title_hide_muted_users"
app:singleLineTitle="false" />
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:title="@string/pref_title_browser_settings"> <PreferenceCategory android:title="@string/pref_title_browser_settings">

Loading…
Cancel
Save