feat: change mute duration (#751)

* feat: add mute timer

* fix: missing ressources

* refactor(add-mute-timer): change of the mute timer popup layout

* tweak mute dialog

---------

Co-authored-by: LucasGGamerM <lucassggabriel@gmail.com>
Co-authored-by: sk <sk22@mailbox.org>
This commit is contained in:
FineFindus
2023-08-05 20:17:40 +02:00
committed by GitHub
parent df1a6cf764
commit 0269756b52
7 changed files with 139 additions and 23 deletions

View File

@@ -121,13 +121,13 @@ public abstract class MastodonAPIRequest<T> extends APIRequest<T>{
.orElseGet(() -> this.execNoAuth(domain)); .orElseGet(() -> this.execNoAuth(domain));
} }
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable){ public MastodonAPIRequest<T> wrapProgress(Context context, @StringRes int message, boolean cancelable){
return wrapProgress(activity, message, cancelable, null); return wrapProgress(context, message, cancelable, null);
} }
public MastodonAPIRequest<T> wrapProgress(Activity activity, @StringRes int message, boolean cancelable, Consumer<ProgressDialog> transform){ public MastodonAPIRequest<T> wrapProgress(Context context, @StringRes int message, boolean cancelable, Consumer<ProgressDialog> transform){
progressDialog=new ProgressDialog(activity); progressDialog=new ProgressDialog(context);
progressDialog.setMessage(activity.getString(message)); progressDialog.setMessage(context.getString(message));
progressDialog.setCancelable(cancelable); progressDialog.setCancelable(cancelable);
if (transform != null) transform.accept(progressDialog); if (transform != null) transform.accept(progressDialog);
if(cancelable){ if(cancelable){

View File

@@ -4,8 +4,15 @@ import org.joinmastodon.android.api.MastodonAPIRequest;
import org.joinmastodon.android.model.Relationship; import org.joinmastodon.android.model.Relationship;
public class SetAccountMuted extends MastodonAPIRequest<Relationship>{ public class SetAccountMuted extends MastodonAPIRequest<Relationship>{
public SetAccountMuted(String id, boolean muted){ public SetAccountMuted(String id, boolean muted, long duration){
super(HttpMethod.POST, "/accounts/"+id+"/"+(muted ? "mute" : "unmute"), Relationship.class); super(HttpMethod.POST, "/accounts/"+id+"/"+(muted ? "mute" : "unmute"), Relationship.class);
setRequestBody(new Object()); setRequestBody(new Request(duration));
}
private static class Request{
public long duration;
public Request(long duration){
this.duration=duration;
}
} }
} }

View File

@@ -45,7 +45,9 @@ import android.transition.TransitionManager;
import android.transition.TransitionSet; import android.transition.TransitionSet;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
import android.view.Gravity;
import android.view.HapticFeedbackConstants; import android.view.HapticFeedbackConstants;
import android.view.LayoutInflater;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.view.SubMenu; import android.view.SubMenu;
@@ -106,7 +108,6 @@ import org.joinmastodon.android.model.ScheduledStatus;
import org.joinmastodon.android.model.SearchResults; import org.joinmastodon.android.model.SearchResults;
import org.joinmastodon.android.model.Searchable; import org.joinmastodon.android.model.Searchable;
import org.joinmastodon.android.model.Status; import org.joinmastodon.android.model.Status;
import org.joinmastodon.android.model.StatusPrivacy;
import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.M3AlertDialogBuilder;
import org.joinmastodon.android.ui.text.CustomEmojiSpan; import org.joinmastodon.android.ui.text.CustomEmojiSpan;
import org.joinmastodon.android.ui.text.HtmlParser; import org.joinmastodon.android.ui.text.HtmlParser;
@@ -118,6 +119,7 @@ import java.lang.reflect.Method;
import java.net.IDN; import java.net.IDN;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.time.Duration;
import java.time.Instant; import java.time.Instant;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
@@ -135,6 +137,7 @@ import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.BiPredicate; import java.util.function.BiPredicate;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@@ -531,31 +534,70 @@ public class UiUtils {
.exec(accountID); .exec(accountID);
}); });
} }
public static void confirmToggleMuteUser(Context context, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback){
View durationView=LayoutInflater.from(context).inflate(R.layout.mute_user_dialog, null);
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
params.setMargins(0, V.dp(-12), 0, 0);
durationView.setLayoutParams(params);
Button button=durationView.findViewById(R.id.button);
((TextView) durationView.findViewById(R.id.message)).setText(context.getString(R.string.confirm_mute, account.displayName));
public static void confirmToggleMuteUser(Activity activity, String accountID, Account account, boolean currentlyMuted, Consumer<Relationship> resultCallback) { AtomicReference<Duration> muteDuration=new AtomicReference<>(Duration.ZERO);
showConfirmationAlert(activity, activity.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title),
activity.getString(currentlyMuted ? R.string.confirm_unmute : R.string.confirm_mute, account.displayName), PopupMenu popupMenu=new PopupMenu(context, button, Gravity.CENTER_HORIZONTAL);
activity.getString(currentlyMuted ? R.string.do_unmute : R.string.do_mute), popupMenu.inflate(R.menu.mute_duration);
currentlyMuted ? R.drawable.ic_fluent_speaker_0_28_regular : R.drawable.ic_fluent_speaker_off_28_regular, popupMenu.setOnMenuItemClickListener(item->{
() -> { int id=item.getItemId();
new SetAccountMuted(account.id, !currentlyMuted) if(id==R.id.duration_indefinite)
.setCallback(new Callback<>() { muteDuration.set(Duration.ZERO);
else if(id==R.id.duration_minutes_5){
muteDuration.set(Duration.ofMinutes(5));
}else if(id==R.id.duration_minutes_30){
muteDuration.set(Duration.ofMinutes(30));
}else if(id==R.id.duration_hours_1){
muteDuration.set(Duration.ofHours(1));
}else if(id==R.id.duration_hours_6){
muteDuration.set(Duration.ofHours(6));
}else if(id==R.id.duration_days_1){
muteDuration.set(Duration.ofDays(1));
}else if(id==R.id.duration_days_3){
muteDuration.set(Duration.ofDays(3));
}else if(id==R.id.duration_days_7){
muteDuration.set(Duration.ofDays(7));
}
button.setText(item.getTitle());
return true;
});
button.setOnTouchListener(popupMenu.getDragToOpenListener());
button.setOnClickListener(v->popupMenu.show());
button.setText(popupMenu.getMenu().getItem(0).getTitle());
new M3AlertDialogBuilder(context)
.setTitle(context.getString(currentlyMuted ? R.string.confirm_unmute_title : R.string.confirm_mute_title))
.setMessage(currentlyMuted ? context.getString(R.string.confirm_unmute, account.displayName) : null)
.setView(currentlyMuted ? null : durationView)
.setPositiveButton(context.getString(currentlyMuted ? R.string.do_unmute : R.string.do_mute), (dlg, i)->{
new SetAccountMuted(account.id, !currentlyMuted, muteDuration.get().getSeconds())
.setCallback(new Callback<>(){
@Override @Override
public void onSuccess(Relationship result) { public void onSuccess(Relationship result){
resultCallback.accept(result); resultCallback.accept(result);
if (!currentlyMuted) { if(!currentlyMuted){
E.post(new RemoveAccountPostsEvent(accountID, account.id, false)); E.post(new RemoveAccountPostsEvent(accountID, account.id, false));
} }
} }
@Override @Override
public void onError(ErrorResponse error) { public void onError(ErrorResponse error){
error.showToast(activity); error.showToast(context);
} }
}) })
.wrapProgress(activity, R.string.loading, false) .wrapProgress(context, R.string.loading, false)
.exec(accountID); .exec(accountID);
}); })
.setNegativeButton(R.string.cancel, null)
.setIcon(currentlyMuted ? R.drawable.ic_fluent_speaker_0_28_regular : R.drawable.ic_fluent_speaker_off_28_regular)
.show();
} }
public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback) { public static void confirmDeletePost(Activity activity, String accountID, Status status, Consumer<Status> resultCallback) {

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="24dp">
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="16dp"
android:gravity="center_vertical"
android:textColor="?android:textColorPrimary"
android:text="@string/confirm_mute"
android:textSize="16sp"/>
<org.joinmastodon.android.ui.views.AutoOrientationLinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layoutDirection="locale">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:paddingVertical="8dp"
android:gravity="center_vertical"
android:textColor="?android:textColorPrimary"
android:text="@string/sk_mute_label"
android:textSize="16sp"/>
<Button
android:id="@+id/button"
style="@style/Widget.Mastodon.M3.Button.Outlined"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/bg_button_m3_tonal"
android:ellipsize="none"
android:singleLine="true"
android:stateListAnimator="@null"
android:textColor="?android:textColorPrimary"
android:textSize="16sp" />
</org.joinmastodon.android.ui.views.AutoOrientationLinearLayout>
</LinearLayout>

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/duration_indefinite" android:title="@string/sk_duration_indefinite" />
<item android:id="@+id/duration_minutes_5" android:title="@string/sk_duration_minutes_5"/>
<item android:id="@+id/duration_minutes_30" android:title="@string/sk_duration_minutes_30"/>
<item android:id="@+id/duration_hours_1" android:title="@string/sk_duration_hours_1"/>
<item android:id="@+id/duration_hours_6" android:title="@string/sk_duration_hours_6"/>
<item android:id="@+id/duration_days_1" android:title="@string/sk_duration_days_1"/>
<item android:id="@+id/duration_days_3" android:title="@string/sk_duration_days_3"/>
<item android:id="@+id/duration_days_7" android:title="@string/sk_duration_days_7"/>
</menu>

View File

@@ -348,5 +348,14 @@
<string name="sk_tab_notifications">Notifications</string> <string name="sk_tab_notifications">Notifications</string>
<string name="sk_tab_profile">Profile</string> <string name="sk_tab_profile">Profile</string>
<string name="sk_settings_show_labels_in_navigation_bar">Show tab labels in the navigation bar</string> <string name="sk_settings_show_labels_in_navigation_bar">Show tab labels in the navigation bar</string>
<string name="sk_mute_label">Duration</string>
<string name="sk_duration_indefinite">Indefinite</string>
<string name="sk_duration_minutes_5">5 minutes</string>
<string name="sk_duration_minutes_30">30 minutes</string>
<string name="sk_duration_hours_1">1 hour</string>
<string name="sk_duration_hours_6">6 hours</string>
<string name="sk_duration_days_1">1 day</string>
<string name="sk_duration_days_3">3 days</string>
<string name="sk_duration_days_7">7 days</string>
<string name="sk_notification_mention">You were mentioned by %s</string> <string name="sk_notification_mention">You were mentioned by %s</string>
</resources> </resources>

View File

@@ -293,7 +293,7 @@
<style name="alert_title"> <style name="alert_title">
<item name="android:textSize">24sp</item> <item name="android:textSize">24sp</item>
<item name="android:minHeight">38dp</item> <item name="android:minHeight">38dp</item>
<item name="android:gravity">bottom</item> <item name="android:gravity">center_vertical</item>
<item name="android:maxLines">2</item> <item name="android:maxLines">2</item>
<item name="android:singleLine">false</item> <item name="android:singleLine">false</item>
<item name="android:textColor">?colorM3OnSurface</item> <item name="android:textColor">?colorM3OnSurface</item>