feat: Add countdown confirmation for "hide icon"

This commit is contained in:
deltazefiro
2025-11-26 16:25:40 +08:00
parent bb18e00aaa
commit 8e023c8be7
3 changed files with 168 additions and 5 deletions
@@ -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());
+3
View File
@@ -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>