diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java index d2a1cc024..a331bddc8 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/HashtagTimelineFragment.java @@ -11,7 +11,6 @@ import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageButton; import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -32,21 +31,21 @@ import org.joinmastodon.android.model.FilterAction; import org.joinmastodon.android.api.session.AccountSessionManager; import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.FilterKeyword; -import org.joinmastodon.android.api.session.AccountSessionManager; -import org.joinmastodon.android.model.FilterContext; import org.joinmastodon.android.model.Hashtag; import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.TimelineDefinition; +import org.joinmastodon.android.ui.Snackbar; +import org.joinmastodon.android.ui.sheets.MuteHashtagConfirmationSheet; import org.joinmastodon.android.ui.text.SpacerSpan; import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.views.ProgressBarButton; import org.parceler.Parcels; -import java.util.ArrayList; +import java.time.Duration; import java.util.EnumSet; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; +import java.util.concurrent.atomic.AtomicReference; import me.grishka.appkit.Nav; import me.grishka.appkit.api.Callback; @@ -110,15 +109,35 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{ followMenuItem.setIcon(following ? R.drawable.ic_fluent_person_delete_24_filled : R.drawable.ic_fluent_person_add_24_regular); } - private void showMuteDialog(boolean mute) { - UiUtils.showConfirmationAlert(getContext(), - mute ? R.string.mo_unmute_hashtag : R.string.mo_mute_hashtag, - mute ? R.string.mo_confirm_to_unmute_hashtag : R.string.mo_confirm_to_mute_hashtag, - mute ? R.string.do_unmute : R.string.do_mute, - mute ? R.drawable.ic_fluent_speaker_2_28_regular : R.drawable.ic_fluent_speaker_off_28_regular, - mute ? this::unmuteHashtag : this::muteHashtag - ); + private void showMuteDialog(boolean currentlyMuted) { + if (currentlyMuted) { + unmuteHashtag(); + return; + } + + //pass a references, so they can be changed inside the confirmation sheet + AtomicReference muteDuration=new AtomicReference<>(Duration.ZERO); + new MuteHashtagConfirmationSheet(getContext(), null, muteDuration, hashtag, (onSuccess, onError)->{ + FilterKeyword hashtagFilter=new FilterKeyword(); + hashtagFilter.wholeWord=true; + hashtagFilter.keyword="#"+hashtagName; + new CreateFilter("#"+hashtagName, EnumSet.of(FilterContext.HOME), FilterAction.HIDE, (int) muteDuration.get().getSeconds(), List.of(hashtagFilter)).setCallback(new Callback<>(){ + @Override + public void onSuccess(Filter result){ + filter=Optional.of(result); + updateMuteState(true); + onSuccess.run(); + } + + @Override + public void onError(ErrorResponse error){ + error.showToast(getContext()); + onError.run(); + } + }).exec(accountID); + }).show(); } + private void unmuteHashtag() { //safe to get, this only called if filter is present new DeleteFilter(filter.get().id).setCallback(new Callback<>(){ @@ -126,24 +145,9 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{ public void onSuccess(Void result){ filter=Optional.empty(); updateMuteState(false); - } - - @Override - public void onError(ErrorResponse error){ - error.showToast(getContext()); - } - }).exec(accountID); - } - - private void muteHashtag() { - FilterKeyword hashtagFilter=new FilterKeyword(); - hashtagFilter.wholeWord=true; - hashtagFilter.keyword="#"+hashtagName; - new CreateFilter("#"+hashtagName, EnumSet.of(FilterContext.HOME), FilterAction.HIDE, 0 , List.of(hashtagFilter)).setCallback(new Callback<>(){ - @Override - public void onSuccess(Filter result){ - filter=Optional.of(result); - updateMuteState(true); + new Snackbar.Builder(getContext()) + .setText(getContext().getString(R.string.unmuted_user_x, '#'+hashtagName)) + .show(); } @Override diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/AccountRestrictionConfirmationSheet.java b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/AccountRestrictionConfirmationSheet.java index 7f293f734..93cdfa28b 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/AccountRestrictionConfirmationSheet.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/AccountRestrictionConfirmationSheet.java @@ -1,5 +1,6 @@ package org.joinmastodon.android.ui.sheets; +import android.app.AlertDialog; import android.content.Context; import android.content.res.ColorStateList; import android.graphics.drawable.ColorDrawable; @@ -15,6 +16,7 @@ import android.widget.TextView; import org.joinmastodon.android.R; import org.joinmastodon.android.model.Account; +import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.drawables.EmptyDrawable; import org.joinmastodon.android.ui.utils.UiUtils; import org.joinmastodon.android.ui.views.AutoOrientationLinearLayout; @@ -23,6 +25,11 @@ import org.joinmastodon.android.ui.views.ProgressBarButton; import androidx.annotation.DrawableRes; import androidx.annotation.NonNull; import androidx.annotation.StringRes; + +import java.time.Duration; +import java.util.List; +import java.util.concurrent.atomic.AtomicReference; + import me.grishka.appkit.utils.V; import me.grishka.appkit.views.BottomSheet; @@ -108,6 +115,51 @@ public abstract class AccountRestrictionConfirmationSheet extends BottomSheet{ addRow(icon, getContext().getString(text)); } + public void addDurationRow(@NonNull Context context, AtomicReference muteDuration) { + //Moshidon: add row to choose a duration, e.g. for muting accounts + Button muteDurationBtn=new Button(getContext()); + muteDurationBtn.setOnClickListener(v->getMuteDurationDialog(context, muteDuration, muteDurationBtn).show()); + muteDurationBtn.setText(R.string.sk_duration_indefinite); + addRow(R.drawable.ic_fluent_clock_20_regular, R.string.sk_mute_label, muteDurationBtn); + } + + @NonNull + private M3AlertDialogBuilder getMuteDurationDialog(@NonNull Context context, AtomicReference muteDuration, Button button){ + M3AlertDialogBuilder builder=new M3AlertDialogBuilder(context); + builder.setTitle(R.string.sk_mute_label); + builder.setIcon(R.drawable.ic_fluent_clock_20_regular); + List durations =List.of(Duration.ZERO, + Duration.ofMinutes(5), + Duration.ofMinutes(30), + Duration.ofHours(1), + Duration.ofHours(6), + Duration.ofDays(1), + Duration.ofDays(3), + Duration.ofDays(7), + Duration.ofDays(7)); + + String[] choices = {context.getString(R.string.sk_duration_indefinite), + context.getString(R.string.sk_duration_minutes_5), + context.getString(R.string.sk_duration_minutes_30), + context.getString(R.string.sk_duration_hours_1), + context.getString(R.string.sk_duration_hours_6), + context.getString(R.string.sk_duration_days_1), + context.getString(R.string.sk_duration_days_3), + context.getString(R.string.sk_duration_days_7)}; + + builder.setSingleChoiceItems(choices, durations.indexOf(muteDuration.get()), (dialog, which) -> {}); + + builder.setPositiveButton(R.string.ok, (dialog, which)->{ + int selected = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); + muteDuration.set(durations.get(selected)); + button.setText(choices[selected]); + }); + builder.setNegativeButton(R.string.cancel, null); + + return builder; + } + + public interface ConfirmCallback{ void onConfirmed(Runnable onSuccess, Runnable onError); } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteAccountConfirmationSheet.java b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteAccountConfirmationSheet.java index 6a1172e13..100ce9222 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteAccountConfirmationSheet.java +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteAccountConfirmationSheet.java @@ -1,17 +1,13 @@ package org.joinmastodon.android.ui.sheets; -import android.app.AlertDialog; import android.content.Context; import android.view.View; -import android.widget.Button; import org.joinmastodon.android.R; import org.joinmastodon.android.model.Account; -import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.views.M3Switch; import java.time.Duration; -import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; @@ -39,47 +35,6 @@ public class MuteAccountConfirmationSheet extends AccountRestrictionConfirmation addRow(R.drawable.ic_fluent_alert_off_24_regular, R.string.mo_mute_notifications, m3Switch); // add mute duration (Moshidon) - Button muteDurationBtn=new Button(getContext()); - muteDurationBtn.setOnClickListener(v->getMuteDurationDialog(context, muteDuration, muteDurationBtn).show()); - muteDurationBtn.setText(R.string.sk_duration_indefinite); - addRow(R.drawable.ic_fluent_clock_20_regular, R.string.sk_mute_label, muteDurationBtn); + addDurationRow(context, muteDuration); } - - @NonNull - private M3AlertDialogBuilder getMuteDurationDialog(@NonNull Context context, AtomicReference muteDuration, Button button){ - M3AlertDialogBuilder builder=new M3AlertDialogBuilder(context); - builder.setTitle(R.string.sk_mute_label); - builder.setIcon(R.drawable.ic_fluent_clock_20_regular); - List durations =List.of(Duration.ZERO, - Duration.ofMinutes(5), - Duration.ofMinutes(30), - Duration.ofHours(1), - Duration.ofHours(6), - Duration.ofDays(1), - Duration.ofDays(3), - Duration.ofDays(7), - Duration.ofDays(7)); - - String[] choices = {context.getString(R.string.sk_duration_indefinite), - context.getString(R.string.sk_duration_minutes_5), - context.getString(R.string.sk_duration_minutes_30), - context.getString(R.string.sk_duration_hours_1), - context.getString(R.string.sk_duration_hours_6), - context.getString(R.string.sk_duration_days_1), - context.getString(R.string.sk_duration_days_3), - context.getString(R.string.sk_duration_days_7)}; - - builder.setSingleChoiceItems(choices, durations.indexOf(muteDuration.get()), (dialog, which) -> {}); - - builder.setPositiveButton(R.string.ok, (dialog, which)->{ - int selected = ((AlertDialog) dialog).getListView().getCheckedItemPosition(); - muteDuration.set(durations.get(selected)); - button.setText(choices[selected]); - }); - builder.setNegativeButton(R.string.cancel, null); - - return builder; - } - - } diff --git a/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteHashtagConfirmationSheet.java b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteHashtagConfirmationSheet.java new file mode 100644 index 000000000..33955572c --- /dev/null +++ b/mastodon/src/main/java/org/joinmastodon/android/ui/sheets/MuteHashtagConfirmationSheet.java @@ -0,0 +1,30 @@ +package org.joinmastodon.android.ui.sheets; + +import android.content.Context; +import android.view.View; + +import androidx.annotation.NonNull; + +import org.joinmastodon.android.R; +import org.joinmastodon.android.model.Account; +import org.joinmastodon.android.model.Hashtag; + +import java.time.Duration; +import java.util.concurrent.atomic.AtomicReference; + + +// MOSHIDON +public class MuteHashtagConfirmationSheet extends AccountRestrictionConfirmationSheet{ + public MuteHashtagConfirmationSheet(@NonNull Context context, Account user, AtomicReference muteDuration, Hashtag hashtag, ConfirmCallback confirmCallback){ + super(context, user, confirmCallback); + titleView.setText(R.string.mo_mute_hashtag); + confirmBtn.setText(R.string.do_mute); + secondaryBtn.setVisibility(View.GONE); + icon.setImageResource(R.drawable.ic_fluent_speaker_off_24_regular); + subtitleView.setText("#"+hashtag.name); + addRow(R.drawable.ic_fluent_number_symbol_24_regular, R.string.mo_mute_hashtag_explanation_muted_home); + addRow(R.drawable.ic_fluent_eye_off_24_regular, R.string.mo_mute_hashtag_explanation_discreet); + addRow(R.drawable.ic_fluent_search_24_regular, R.string.mo_mute_hashtag_explanation_search); + addDurationRow(context, muteDuration); + } +} diff --git a/mastodon/src/main/res/values/strings_mo.xml b/mastodon/src/main/res/values/strings_mo.xml index c490abb98..ded512896 100644 --- a/mastodon/src/main/res/values/strings_mo.xml +++ b/mastodon/src/main/res/values/strings_mo.xml @@ -45,6 +45,9 @@ Are you sure you want to mute this conversation? Are you sure you want to unmute this conversation? Mute hashtag + You won’t see posts mentioning this hashtag in your Home timeline. + Others won’t know that you’ve muted this hashtag. + You can still find posts with this hashtag on other timelines or through search. Unmute hashtag Are you sure you want to mute this hashtag? Are you sure you want to unmute this hashtag?