feat(Timeline/Hashtag): show confirmation sheet when muting
Shows a MuteHashtagConfirmationSheet when muting a hashtag, similar to the MuteAccountConfirmationSheet. This also adds the option for the mute to expire.
This commit is contained in:
parent
5427b21365
commit
b0f8cbb2e3
5 changed files with 116 additions and 79 deletions
|
@ -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,20 @@ 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.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;
|
||||
|
@ -105,14 +103,33 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
|
|||
muteMenuItem.setIcon(newMute ? R.drawable.ic_fluent_speaker_2_24_regular : R.drawable.ic_fluent_speaker_off_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<Duration> 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
|
||||
|
@ -130,26 +147,6 @@ public class HashtagTimelineFragment extends PinnableStatusListFragment{
|
|||
}).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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(ErrorResponse error){
|
||||
error.showToast(getContext());
|
||||
}
|
||||
}).exec(accountID);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
protected TimelineDefinition makeTimelineDefinition() {
|
||||
return TimelineDefinition.ofHashtag(hashtagName);
|
||||
|
|
|
@ -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<Duration> 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<Duration> 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<Duration> 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);
|
||||
}
|
||||
|
|
|
@ -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<Duration> 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<Duration> 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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -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<Duration> 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);
|
||||
}
|
||||
}
|
|
@ -45,6 +45,9 @@
|
|||
<string name="mo_confirm_to_mute_conversation">Are you sure you want to mute this conversation?</string>
|
||||
<string name="mo_confirm_to_unmute_conversation">Are you sure you want to unmute this conversation?</string>
|
||||
<string name="mo_mute_hashtag">Mute hashtag</string>
|
||||
<string name="mo_mute_hashtag_explanation_muted_home">You won’t see posts mentioning this hashtag in your Home timeline.</string>
|
||||
<string name="mo_mute_hashtag_explanation_discreet">Others won’t know that you’ve muted this hashtag.</string>
|
||||
<string name="mo_mute_hashtag_explanation_search">You can still find posts with this hashtag on other timelines or through search.</string>
|
||||
<string name="mo_unmute_hashtag">Unmute hashtag</string>
|
||||
<string name="mo_confirm_to_mute_hashtag">Are you sure you want to mute this hashtag?</string>
|
||||
<string name="mo_confirm_to_unmute_hashtag">Are you sure you want to unmute this hashtag?</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue