diff --git a/app/src/main/java/eu/faircode/email/FragmentDialogUnsubscribe.java b/app/src/main/java/eu/faircode/email/FragmentDialogUnsubscribe.java index f1afab5497..42b8280a98 100644 --- a/app/src/main/java/eu/faircode/email/FragmentDialogUnsubscribe.java +++ b/app/src/main/java/eu/faircode/email/FragmentDialogUnsubscribe.java @@ -25,6 +25,8 @@ import android.content.DialogInterface; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; +import android.widget.Button; +import android.widget.ProgressBar; import android.widget.TextView; import android.widget.Toast; @@ -33,6 +35,7 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AlertDialog; import java.io.IOException; +import java.io.InputStream; import java.net.URL; import javax.net.ssl.HttpsURLConnection; @@ -52,65 +55,86 @@ public class FragmentDialogUnsubscribe extends FragmentDialogBase { View view = LayoutInflater.from(context).inflate(R.layout.dialog_unsubscribe, null); final TextView tvSender = view.findViewById(R.id.tvSender); final TextView tvUri = view.findViewById(R.id.tvUri); + final Button btnUnsubscribe = view.findViewById(R.id.btnUnsubscribe); + final ProgressBar pbUnsubscribe = view.findViewById(R.id.pbUnsubscribe); tvSender.setText(from); tvUri.setText(uri); + pbUnsubscribe.setVisibility(View.GONE); - AlertDialog.Builder builder = new AlertDialog.Builder(context) + AlertDialog dialog = new AlertDialog.Builder(context) .setView(view) - .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { + .setNeutralButton(android.R.string.cancel, null) + .create(); + + btnUnsubscribe.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + new SimpleTask() { @Override - public void onClick(DialogInterface dialog, int which) { - new SimpleTask() { - @Override - protected String onExecute(Context context, Bundle args) throws Throwable { - final String uri = args.getString("uri"); - final String request = "List-Unsubscribe=One-Click"; - - // https://datatracker.ietf.org/doc/html/rfc8058 - - URL url = new URL(uri); - HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); - connection.setRequestMethod("POST"); - connection.setDoInput(true); - connection.setDoOutput(true); - connection.setReadTimeout(UNSUBSCRIBE_TIMEOUT); - connection.setConnectTimeout(UNSUBSCRIBE_TIMEOUT); - ConnectionHelper.setUserAgent(context, connection); - connection.setRequestProperty("Content-Length", Integer.toString(request.length())); - connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); - connection.connect(); - - try { - connection.getOutputStream().write(request.getBytes()); - - int status = connection.getResponseCode(); - if (status != HttpsURLConnection.HTTP_OK) { - String error = "Error " + status + ": " + connection.getResponseMessage(); - String detail = Helper.readStream(connection.getErrorStream()); - throw new IOException(error + " " + detail); - } - - return Helper.readStream(connection.getInputStream()); - } finally { - connection.disconnect(); - } - } + protected void onPreExecute(Bundle args) { + btnUnsubscribe.setEnabled(false); + pbUnsubscribe.setVisibility(View.VISIBLE); + } - @Override - protected void onExecuted(Bundle args, String output) { - ToastEx.makeText(context, R.string.title_completed, Toast.LENGTH_LONG).show(); - } + @Override + protected void onPostExecute(Bundle args) { + btnUnsubscribe.setEnabled(true); + pbUnsubscribe.setVisibility(View.GONE); + } - @Override - protected void onException(Bundle args, Throwable ex) { - Log.unexpectedError(getParentFragment(), ex); + @Override + protected String onExecute(Context context, Bundle args) throws Throwable { + final String uri = args.getString("uri"); + final String request = "List-Unsubscribe=One-Click"; + + // https://datatracker.ietf.org/doc/html/rfc8058 + + URL url = new URL(uri); + HttpsURLConnection connection = (HttpsURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoInput(true); + connection.setDoOutput(true); + connection.setReadTimeout(UNSUBSCRIBE_TIMEOUT); + connection.setConnectTimeout(UNSUBSCRIBE_TIMEOUT); + ConnectionHelper.setUserAgent(context, connection); + connection.setRequestProperty("Content-Length", Integer.toString(request.length())); + connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); + connection.connect(); + + try { + connection.getOutputStream().write(request.getBytes()); + + int status = connection.getResponseCode(); + if (status < 200 || status > 299) { + String error = "Error " + status + ": " + connection.getResponseMessage(); + InputStream stream = connection.getErrorStream(); + String detail = (stream == null ? null : Helper.readStream(stream)); + throw new IOException(error + " " + detail); } - }.execute(FragmentDialogUnsubscribe.this, args, "unsubscribe"); + + return Helper.readStream(connection.getInputStream()); + } finally { + connection.disconnect(); + } } - }) - .setNegativeButton(android.R.string.cancel, null); - return builder.create(); + @Override + protected void onExecuted(Bundle args, String output) { + ToastEx.makeText(context, R.string.title_completed, Toast.LENGTH_LONG).show(); + dialog.dismiss(); + } + + @Override + protected void onException(Bundle args, Throwable ex) { + dialog.dismiss(); + Log.unexpectedError(getParentFragmentManager(), ex); + } + }.execute(FragmentDialogUnsubscribe.this, args, "unsubscribe"); + } + }); + + + return dialog; } } diff --git a/app/src/main/res/layout/dialog_unsubscribe.xml b/app/src/main/res/layout/dialog_unsubscribe.xml index 32186e4d3b..b1530fe504 100644 --- a/app/src/main/res/layout/dialog_unsubscribe.xml +++ b/app/src/main/res/layout/dialog_unsubscribe.xml @@ -41,5 +41,29 @@ android:textAppearance="@style/TextAppearance.AppCompat.Small" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/tvSender" /> + +