feat: Add countdown confirmation for "hide icon"
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
package deltazero.amarok.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import deltazero.amarok.R;
|
||||
|
||||
public class CountdownConfirmDialog {
|
||||
|
||||
private final Context context;
|
||||
private final String title;
|
||||
private final String message;
|
||||
private final int countdownSeconds;
|
||||
private final Runnable onConfirmAction;
|
||||
private final Runnable onCancelAction;
|
||||
|
||||
private CountdownConfirmDialog(Builder builder) {
|
||||
this.context = builder.context;
|
||||
this.title = builder.title;
|
||||
this.message = builder.message;
|
||||
this.countdownSeconds = builder.countdownSeconds;
|
||||
this.onConfirmAction = builder.onConfirmAction;
|
||||
this.onCancelAction = builder.onCancelAction;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
MaterialAlertDialogBuilder dialogBuilder = new MaterialAlertDialogBuilder(context);
|
||||
dialogBuilder.setTitle(title);
|
||||
dialogBuilder.setMessage(message);
|
||||
|
||||
// Positive button (initially disabled)
|
||||
dialogBuilder.setPositiveButton(android.R.string.ok, (d, which) -> {
|
||||
if (onConfirmAction != null) {
|
||||
onConfirmAction.run();
|
||||
}
|
||||
});
|
||||
|
||||
// Negative button
|
||||
dialogBuilder.setNegativeButton(android.R.string.cancel, (d, which) -> {
|
||||
if (onCancelAction != null) {
|
||||
onCancelAction.run();
|
||||
}
|
||||
});
|
||||
|
||||
var dialog = dialogBuilder.create();
|
||||
dialog.show();
|
||||
|
||||
// Disable the positive button initially and set countdown text
|
||||
var positiveButton = dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE);
|
||||
if (positiveButton != null) {
|
||||
positiveButton.setEnabled(false);
|
||||
positiveButton.setText(context.getString(R.string.confirm_with_countdown, countdownSeconds));
|
||||
}
|
||||
|
||||
// Start countdown
|
||||
final var finalDialog = dialog;
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
final int[] countdown = {countdownSeconds};
|
||||
|
||||
Runnable countdownRunnable = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (countdown[0] > 0 && finalDialog.isShowing()) {
|
||||
countdown[0]--;
|
||||
var button = finalDialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE);
|
||||
if (button != null) {
|
||||
if (countdown[0] > 0) {
|
||||
button.setText(context.getString(R.string.confirm_with_countdown, countdown[0]));
|
||||
} else {
|
||||
button.setText(context.getString(R.string.confirm));
|
||||
button.setEnabled(true);
|
||||
}
|
||||
}
|
||||
if (countdown[0] > 0) {
|
||||
handler.postDelayed(this, 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
handler.postDelayed(countdownRunnable, 1000);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final Context context;
|
||||
private String title = "";
|
||||
private String message = "";
|
||||
private int countdownSeconds = 5;
|
||||
private Runnable onConfirmAction;
|
||||
private Runnable onCancelAction;
|
||||
|
||||
public Builder(@NonNull Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public Builder setTitle(String title) {
|
||||
this.title = title;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setTitle(int titleResId) {
|
||||
this.title = context.getString(titleResId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMessage(String message) {
|
||||
this.message = message;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setMessage(int messageResId) {
|
||||
this.message = context.getString(messageResId);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setCountdownSeconds(int seconds) {
|
||||
this.countdownSeconds = seconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setOnConfirmAction(Runnable action) {
|
||||
this.onConfirmAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setOnCancelAction(Runnable action) {
|
||||
this.onCancelAction = action;
|
||||
return this;
|
||||
}
|
||||
|
||||
public CountdownConfirmDialog build() {
|
||||
return new CountdownConfirmDialog(this);
|
||||
}
|
||||
|
||||
public void show() {
|
||||
build().show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import androidx.preference.PreferenceScreen;
|
||||
|
||||
import deltazero.amarok.PrefMgr;
|
||||
import deltazero.amarok.R;
|
||||
import deltazero.amarok.ui.CountdownConfirmDialog;
|
||||
import deltazero.amarok.ui.SetPasswordFragment;
|
||||
import deltazero.amarok.utils.HashUtil;
|
||||
import deltazero.amarok.utils.LauncherIconController;
|
||||
@@ -81,16 +82,30 @@ public class PrivacyCategory extends BaseCategory {
|
||||
hideAmarokIconPref.setOnPreferenceChangeListener((preference, newValue) -> {
|
||||
boolean hideIcon = (boolean) newValue;
|
||||
if (hideIcon) {
|
||||
// When hiding icon, disable disguise and turn it off
|
||||
disguisePref.setChecked(false);
|
||||
disguisePref.setEnabled(false);
|
||||
LauncherIconController.setIconState(activity, LauncherIconController.IconState.HIDDEN);
|
||||
// Show countdown dialog before hiding icon
|
||||
new CountdownConfirmDialog.Builder(activity)
|
||||
.setTitle(R.string.hide_amarok_icon_dialog_title)
|
||||
.setMessage(R.string.hide_amarok_icon_dialog_message)
|
||||
.setCountdownSeconds(10)
|
||||
.setOnConfirmAction(() -> {
|
||||
// When hiding icon, disable disguise and turn it off
|
||||
disguisePref.setChecked(false);
|
||||
disguisePref.setEnabled(false);
|
||||
LauncherIconController.setIconState(activity, LauncherIconController.IconState.HIDDEN);
|
||||
hideAmarokIconPref.setChecked(true);
|
||||
})
|
||||
.setOnCancelAction(() -> {
|
||||
// User cancelled, revert the switch state
|
||||
hideAmarokIconPref.setChecked(false);
|
||||
})
|
||||
.show();
|
||||
return false; // Don't change the preference yet
|
||||
} else {
|
||||
// When showing icon, re-enable disguise option
|
||||
disguisePref.setEnabled(true);
|
||||
LauncherIconController.setIconState(activity, LauncherIconController.IconState.VISIBLE);
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
// Set initial state: if icon is hidden, disable disguise option
|
||||
disguisePref.setEnabled(!PrefMgr.getHideAmarokIcon());
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
<string name="remove_hide_path">Remove hidden folder?</string>
|
||||
<string name="remove_hide_path_description">Remove folder \'%s\' from hidden list?</string>
|
||||
<string name="confirm">Confirm</string>
|
||||
<string name="confirm_with_countdown">Confirm (%1$ds)</string>
|
||||
<string name="not_local_storage">Unsupported directory</string>
|
||||
<string name="not_local_storage_description">Please ensure it is local file and not a virtual one.</string>
|
||||
<string name="help">Help</string>
|
||||
@@ -205,4 +206,6 @@
|
||||
<string name="dhizuku_failed_to_set_delegated_scopes">Dhizuku: Failed to grant `DELEGATION_PACKAGE_ACCESS`. Please try reactivating Dhizuku.</string>
|
||||
<string name="hide_from_recents">Hide from Recents</string>
|
||||
<string name="hide_from_recents_description">Hide Amarok from the recent apps screen.</string>
|
||||
<string name="hide_amarok_icon_dialog_title">Hide Amarok Icon</string>
|
||||
<string name="hide_amarok_icon_dialog_message">This action will hide Amarok from the launcher. You can dial *#*#262765#*#* (262765 spells \"amarok\" on T9 keypad) to access Amarok again.</string>
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user