diff --git a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java index 6b41c41f3..9ad711637 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java +++ b/mastodon/src/main/java/org/joinmastodon/android/api/session/AccountLocalPreferences.java @@ -13,7 +13,6 @@ import org.joinmastodon.android.model.TimelineDefinition; import java.lang.reflect.Type; import java.util.ArrayList; -import java.util.List; public class AccountLocalPreferences{ private final SharedPreferences prefs; @@ -39,7 +38,7 @@ public class AccountLocalPreferences{ public boolean keepOnlyLatestNotification; public boolean emojiReactionsEnabled; - public boolean emojiReactionsInTimelines; + public ShowEmojiReactions showEmojiReactions; private final static Type recentLanguagesType = new TypeToken>() {}.getType(); private final static Type timelinesType = new TypeToken>() {}.getType(); @@ -66,7 +65,7 @@ public class AccountLocalPreferences{ timelineReplyVisibility=prefs.getString("timelineReplyVisibility", null); keepOnlyLatestNotification=prefs.getBoolean("keepOnlyLatestNotification", false); emojiReactionsEnabled=prefs.getBoolean("emojiReactionsEnabled", session.getInstance().isPresent() && session.getInstance().get().isAkkoma()); - emojiReactionsInTimelines=prefs.getBoolean("emojiReactionsInTimelines", true); + showEmojiReactions=ShowEmojiReactions.valueOf(prefs.getString("showEmojiReactions", ShowEmojiReactions.HIDE_EMPTY.name())); } public long getNotificationsPauseEndTime(){ @@ -99,7 +98,13 @@ public class AccountLocalPreferences{ .putString("timelineReplyVisibility", timelineReplyVisibility) .putBoolean("keepOnlyLatestNotification", keepOnlyLatestNotification) .putBoolean("emojiReactionsEnabled", emojiReactionsEnabled) - .putBoolean("emojiReactionsInTimelines", emojiReactionsInTimelines) + .putString("showEmojiReactions", showEmojiReactions.name()) .apply(); } + + public enum ShowEmojiReactions{ + HIDE_EMPTY, + ONLY_OPENED, + ALWAYS + } } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java index 47be8cab7..c58d761d7 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java @@ -1,5 +1,7 @@ package org.joinmastodon.android.fragments; +import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ONLY_OPENED; + import android.content.res.Configuration; import android.os.Bundle; @@ -7,6 +9,7 @@ import com.squareup.otto.Subscribe; import org.joinmastodon.android.E; import org.joinmastodon.android.GlobalUserPreferences; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.events.EmojiReactionsUpdatedEvent; import org.joinmastodon.android.events.PollUpdatedEvent; @@ -38,9 +41,10 @@ public abstract class StatusListFragment extends BaseStatusListFragment protected List buildDisplayItems(Status s){ boolean isMainThreadStatus = this instanceof ThreadFragment t && s.id.equals(t.mainStatus.id); int flags = 0; + AccountLocalPreferences lp=getLocalPrefs(); if (GlobalUserPreferences.spectatorMode) flags |= StatusDisplayItem.FLAG_NO_FOOTER; - if (!getLocalPrefs().emojiReactionsInTimelines) + if (!lp.emojiReactionsEnabled || lp.showEmojiReactions==ONLY_OPENED) flags |= StatusDisplayItem.FLAG_NO_EMOJI_REACTIONS; return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, getFilterContext(), isMainThreadStatus ? 0 : flags); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsInstanceFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsInstanceFragment.java index e7b28d398..93542823e 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsInstanceFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/settings/SettingsInstanceFragment.java @@ -2,10 +2,14 @@ package org.joinmastodon.android.fragments.settings; import android.os.Bundle; +import androidx.annotation.StringRes; + +import org.joinmastodon.android.E; import org.joinmastodon.android.R; import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSession; import org.joinmastodon.android.api.session.AccountSessionManager; +import org.joinmastodon.android.events.StatusDisplaySettingsChangedEvent; import org.joinmastodon.android.fragments.HasAccountID; import org.joinmastodon.android.model.ContentType; import org.joinmastodon.android.model.viewmodel.CheckableListItem; @@ -15,12 +19,13 @@ import org.joinmastodon.android.ui.utils.UiUtils; import java.util.Arrays; import java.util.List; +import java.util.stream.IntStream; import me.grishka.appkit.Nav; public class SettingsInstanceFragment extends BaseSettingsFragment implements HasAccountID{ - private CheckableListItem contentTypesItem, emojiReactionsItem, emojiReactionsInTimelinesItem, localOnlyItem, glitchModeItem; - private ListItem defaultContentTypeItem; + private CheckableListItem contentTypesItem, emojiReactionsItem, localOnlyItem, glitchModeItem; + private ListItem defaultContentTypeItem, showEmojiReactionsItem; private AccountLocalPreferences lp; @Override @@ -37,14 +42,14 @@ public class SettingsInstanceFragment extends BaseSettingsFragment impleme contentTypesItem=new CheckableListItem<>(R.string.sk_settings_content_types, R.string.sk_settings_content_types_explanation, CheckableListItem.Style.SWITCH, lp.contentTypesEnabled, R.drawable.ic_fluent_text_edit_style_24_regular, this::onContentTypeClick), defaultContentTypeItem=new ListItem<>(R.string.sk_settings_default_content_type, lp.defaultContentType.getName(), R.drawable.ic_fluent_text_bold_24_regular, this::onDefaultContentTypeClick, 0, true), emojiReactionsItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions, R.string.sk_settings_emoji_reactions_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsEnabled, R.drawable.ic_fluent_emoji_laugh_24_regular, this::onEmojiReactionsClick), - emojiReactionsInTimelinesItem=new CheckableListItem<>(R.string.sk_settings_emoji_reactions_in_lists, R.string.sk_settings_emoji_reactions_in_lists_explanation, CheckableListItem.Style.SWITCH, lp.emojiReactionsInTimelines, R.drawable.ic_fluent_emoji_24_regular, ()->toggleCheckableItem(emojiReactionsInTimelinesItem), true), + showEmojiReactionsItem=new ListItem<>(R.string.sk_settings_show_emoji_reactions, getShowEmojiReactionsString(), R.drawable.ic_fluent_emoji_24_regular, this::onShowEmojiReactionsClick, 0, true), localOnlyItem=new CheckableListItem<>(R.string.sk_settings_support_local_only, R.string.sk_settings_local_only_explanation, CheckableListItem.Style.SWITCH, lp.localOnlySupported, R.drawable.ic_fluent_eye_24_regular, this::onLocalOnlyClick), glitchModeItem=new CheckableListItem<>(R.string.sk_settings_glitch_instance, R.string.sk_settings_glitch_mode_explanation, CheckableListItem.Style.SWITCH, lp.glitchInstance, R.drawable.ic_fluent_eye_24_filled, ()->toggleCheckableItem(glitchModeItem)) )); contentTypesItem.checkedChangeListener=checked->onContentTypeClick(); defaultContentTypeItem.isEnabled=contentTypesItem.checked; emojiReactionsItem.checkedChangeListener=checked->onEmojiReactionsClick(); - emojiReactionsInTimelinesItem.isEnabled=emojiReactionsItem.checked; + showEmojiReactionsItem.isEnabled=emojiReactionsItem.checked; localOnlyItem.checkedChangeListener=checked->onLocalOnlyClick(); glitchModeItem.isEnabled=localOnlyItem.checked; } @@ -57,10 +62,10 @@ public class SettingsInstanceFragment extends BaseSettingsFragment impleme super.onHidden(); lp.contentTypesEnabled=contentTypesItem.checked; lp.emojiReactionsEnabled=emojiReactionsItem.checked; - lp.emojiReactionsInTimelines=emojiReactionsInTimelinesItem.checked; lp.localOnlySupported=localOnlyItem.checked; lp.glitchInstance=glitchModeItem.checked; lp.save(); + E.post(new StatusDisplaySettingsChangedEvent(accountID)); } private void onServerClick(){ @@ -107,10 +112,34 @@ public class SettingsInstanceFragment extends BaseSettingsFragment impleme .show(); } + private void onShowEmojiReactionsClick(){ + int selected=lp.showEmojiReactions.ordinal(); + int[] newSelected={selected}; + new M3AlertDialogBuilder(getActivity()) + .setTitle(R.string.sk_settings_show_emoji_reactions) + .setSingleChoiceItems((String[]) IntStream.of(R.string.sk_settings_show_emoji_reactions_hide_empty, R.string.sk_settings_show_emoji_reactions_only_opened, R.string.sk_settings_show_emoji_reactions_always).mapToObj(this::getString).toArray(String[]::new), + selected, (dlg, item)->newSelected[0]=item) + .setPositiveButton(R.string.ok, (dlg, item)->{ + lp.showEmojiReactions=AccountLocalPreferences.ShowEmojiReactions.values()[newSelected[0]]; + showEmojiReactionsItem.subtitleRes=getShowEmojiReactionsString(); + rebindItem(showEmojiReactionsItem); + }) + .setNegativeButton(R.string.cancel, null) + .show(); + } + + private @StringRes int getShowEmojiReactionsString(){ + return switch(lp.showEmojiReactions){ + case HIDE_EMPTY -> R.string.sk_settings_show_emoji_reactions_hide_empty; + case ONLY_OPENED -> R.string.sk_settings_show_emoji_reactions_only_opened; + case ALWAYS -> R.string.sk_settings_show_emoji_reactions_always; + }; + } + private void onEmojiReactionsClick(){ toggleCheckableItem(emojiReactionsItem); - emojiReactionsInTimelinesItem.checked=emojiReactionsInTimelinesItem.isEnabled=emojiReactionsItem.checked; - rebindItem(emojiReactionsInTimelinesItem); + showEmojiReactionsItem.isEnabled=emojiReactionsItem.checked; + rebindItem(showEmojiReactionsItem); } private void onLocalOnlyClick(){ diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java index 2e81f0735..e17b1f49a 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java @@ -1,5 +1,8 @@ package org.joinmastodon.android.ui.displayitems; +import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ALWAYS; +import static org.joinmastodon.android.api.session.AccountLocalPreferences.ShowEmojiReactions.ONLY_OPENED; + import android.app.Activity; import android.app.Fragment; import android.content.Context; @@ -12,6 +15,7 @@ import android.view.ViewGroup; import org.joinmastodon.android.GlobalUserPreferences; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.session.AccountLocalPreferences; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.fragments.BaseStatusListFragment; import org.joinmastodon.android.fragments.HashtagTimelineFragment; @@ -277,10 +281,12 @@ public abstract class StatusDisplayItem{ if(contentItems!=items && statusForContent.spoilerRevealed){ items.addAll(contentItems); } - if((flags & FLAG_NO_EMOJI_REACTIONS)==0 && fragment.getLocalPrefs().emojiReactionsEnabled && - (fragment.getLocalPrefs().emojiReactionsInTimelines || fragment instanceof ThreadFragment)){ + AccountLocalPreferences lp=fragment.getLocalPrefs(); + if((flags & FLAG_NO_EMOJI_REACTIONS)==0 && lp.emojiReactionsEnabled && + (lp.showEmojiReactions!=ONLY_OPENED || fragment instanceof ThreadFragment)){ boolean isMainStatus=fragment instanceof ThreadFragment t && t.getMainStatus().id.equals(statusForContent.id); - items.add(new EmojiReactionsStatusDisplayItem(parentID, fragment, statusForContent, accountID, !isMainStatus, false)); + boolean showAddButton=lp.showEmojiReactions==ALWAYS || isMainStatus; + items.add(new EmojiReactionsStatusDisplayItem(parentID, fragment, statusForContent, accountID, !showAddButton, false)); } FooterStatusDisplayItem footer=null; if((flags & FLAG_NO_FOOTER)==0){ diff --git a/mastodon/src/main/res/values/strings_sk.xml b/mastodon/src/main/res/values/strings_sk.xml index 6ae21451e..950285895 100644 --- a/mastodon/src/main/res/values/strings_sk.xml +++ b/mastodon/src/main/res/values/strings_sk.xml @@ -352,8 +352,10 @@ Show tab labels in the navigation bar Enable emoji reactions Displays emoji reactions to posts and lets you interact with them. Some modified versions of Mastodon support this, but Mastodon doesn\'t. - Show emoji reactions in timelines - Whether emoji reactions should be displayed on timelines. If this option is off, emoji reactions will only be displayed when viewing a thread. + Show emoji reactions in timelines + Hide empty emoji reactions + Only when post is opened + Always show add button One user reacted with %2$s %1$,d users reacted with %2$s