1
0
mirror of https://github.com/ultrasonic/ultrasonic synced 2025-02-26 16:37:58 +01:00

Merge pull request #649 from ultrasonic/ready/dialogs

Unify error dialog handling
This commit is contained in:
Nite 2021-12-20 09:52:51 +01:00 committed by GitHub
commit adf72d6460
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 145 additions and 169 deletions

View File

@ -212,7 +212,7 @@ public class PlaylistsFragment extends Fragment {
private void deletePlaylist(final Playlist playlist)
{
new AlertDialog.Builder(getContext()).setIcon(android.R.drawable.ic_dialog_alert).setTitle(R.string.common_confirm).setMessage(getResources().getString(R.string.delete_playlist, playlist.getName())).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
new AlertDialog.Builder(getContext()).setIcon(R.drawable.ic_baseline_warning).setTitle(R.string.common_confirm).setMessage(getResources().getString(R.string.delete_playlist, playlist.getName())).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
@ -263,7 +263,7 @@ public class PlaylistsFragment extends Fragment {
textView.setText(message);
textView.setMovementMethod(LinkMovementMethod.getInstance());
new AlertDialog.Builder(getContext()).setTitle(playlist.getName()).setCancelable(true).setIcon(android.R.drawable.ic_dialog_info).setView(textView).show();
new AlertDialog.Builder(getContext()).setTitle(playlist.getName()).setCancelable(true).setIcon(R.drawable.ic_baseline_info).setView(textView).show();
}
private void updatePlaylistInfo(final Playlist playlist)
@ -294,7 +294,7 @@ public class PlaylistsFragment extends Fragment {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
alertDialog.setIcon(R.drawable.ic_baseline_warning);
alertDialog.setTitle(R.string.playlist_update_info);
alertDialog.setView(dialogView);
alertDialog.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()

View File

@ -185,7 +185,7 @@ public class SharesFragment extends Fragment {
private void deleteShare(final Share share)
{
new AlertDialog.Builder(getContext()).setIcon(android.R.drawable.ic_dialog_alert).setTitle(R.string.common_confirm).setMessage(getResources().getString(R.string.delete_playlist, share.getName())).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
new AlertDialog.Builder(getContext()).setIcon(R.drawable.ic_baseline_warning).setTitle(R.string.common_confirm).setMessage(getResources().getString(R.string.delete_playlist, share.getName())).setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialog, int which)
@ -240,7 +240,7 @@ public class SharesFragment extends Fragment {
textView.setText(message);
textView.setMovementMethod(LinkMovementMethod.getInstance());
new AlertDialog.Builder(getContext()).setTitle("Share Details").setCancelable(true).setIcon(android.R.drawable.ic_dialog_info).setView(textView).show();
new AlertDialog.Builder(getContext()).setTitle("Share Details").setCancelable(true).setIcon(R.drawable.ic_baseline_info).setView(textView).show();
}
private void updateShareInfo(final Share share)
@ -278,7 +278,7 @@ public class SharesFragment extends Fragment {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(getContext());
alertDialog.setIcon(android.R.drawable.ic_dialog_alert);
alertDialog.setIcon(R.drawable.ic_baseline_warning);
alertDialog.setTitle(R.string.playlist_update_info);
alertDialog.setView(dialogView);
alertDialog.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()

View File

@ -1,71 +0,0 @@
/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see <http://www.gnu.org/licenses/>.
Copyright 2009 (C) Sindre Mehus
*/
package org.moire.ultrasonic.util;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import org.moire.ultrasonic.R;
/**
* @author Sindre Mehus
*/
public class ErrorDialog
{
public ErrorDialog(Activity activity, int messageId, boolean finishActivityOnCancel)
{
this(activity, activity.getResources().getString(messageId), finishActivityOnCancel);
}
public ErrorDialog(final Activity activity, CharSequence message, final boolean finishActivityOnClose)
{
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setTitle(R.string.error_label);
builder.setMessage(message);
builder.setCancelable(true);
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialogInterface)
{
if (finishActivityOnClose)
{
activity.finish();
}
}
});
builder.setPositiveButton(R.string.common_ok, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
if (finishActivityOnClose)
{
activity.finish();
}
}
});
builder.create().show();
}
}

View File

@ -20,11 +20,11 @@ package org.moire.ultrasonic.util;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import timber.log.Timber;
import org.moire.ultrasonic.R;
import timber.log.Timber;
/**
* @author Sindre Mehus
*/
@ -49,27 +49,11 @@ public abstract class ModalBackgroundTask<T> extends BackgroundTask<T>
private AlertDialog createProgressDialog()
{
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setIcon(android.R.drawable.ic_dialog_info);
AlertDialog.Builder builder = new InfoDialog.Builder(getActivity());
builder.setTitle(R.string.background_task_wait);
builder.setMessage(R.string.background_task_loading);
builder.setCancelable(true);
builder.setOnCancelListener(new DialogInterface.OnCancelListener()
{
@Override
public void onCancel(DialogInterface dialogInterface)
{
cancel();
}
});
builder.setPositiveButton(R.string.common_cancel, new DialogInterface.OnClickListener()
{
@Override
public void onClick(DialogInterface dialogInterface, int i)
{
cancel();
}
});
builder.setOnCancelListener(dialogInterface -> cancel());
builder.setPositiveButton(R.string.common_cancel, (dialogInterface, i) -> cancel());
return builder.create();
}
@ -165,19 +149,12 @@ public abstract class ModalBackgroundTask<T> extends BackgroundTask<T>
protected void error(Throwable error)
{
Timber.w(error);
new ErrorDialog(getActivity(), getErrorMessage(error), finishActivityOnCancel);
new ErrorDialog(getActivity(), getErrorMessage(error), getActivity(), finishActivityOnCancel);
}
@Override
public void updateProgress(final String message)
{
getHandler().post(new Runnable()
{
@Override
public void run()
{
progressDialog.setMessage(message);
}
});
getHandler().post(() -> progressDialog.setMessage(message));
}
}

View File

@ -1,6 +1,11 @@
/*
* NavigationActivity.kt
* Copyright (C) 2009-2021 Ultrasonic developers
*
* Distributed under terms of the GNU GPLv3 license.
*/
package org.moire.ultrasonic.activity
import android.app.AlertDialog
import android.app.SearchManager
import android.content.Intent
import android.content.res.ColorStateList
@ -47,6 +52,7 @@ import org.moire.ultrasonic.service.MediaPlayerLifecycleSupport
import org.moire.ultrasonic.service.RxBus
import org.moire.ultrasonic.subsonic.ImageLoaderProvider
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.InfoDialog
import org.moire.ultrasonic.util.ServerColor
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Storage
@ -358,8 +364,7 @@ class NavigationActivity : AppCompatActivity() {
if (!infoDialogDisplayed) {
infoDialogDisplayed = true
AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_info)
InfoDialog.Builder(this)
.setTitle(R.string.main_welcome_title)
.setMessage(R.string.main_welcome_text_demo)
.setNegativeButton(R.string.main_welcome_cancel) { dialog, _ ->

View File

@ -1,6 +1,5 @@
package org.moire.ultrasonic.fragment
import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -37,6 +36,7 @@ import org.moire.ultrasonic.model.ServerSettingsModel
import org.moire.ultrasonic.service.MusicServiceFactory
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.ErrorDialog
import org.moire.ultrasonic.util.InfoDialog
import org.moire.ultrasonic.util.ModalBackgroundTask
import org.moire.ultrasonic.util.ServerColor
import org.moire.ultrasonic.util.Util
@ -470,24 +470,22 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
)
}
Util.showDialog(
context = requireActivity(),
titleId = R.string.settings_testing_ok,
message = dialogText
)
InfoDialog.Builder(requireActivity())
.setTitle(R.string.settings_testing_ok)
.setMessage(dialogText)
.show()
}
override fun error(error: Throwable) {
Timber.w(error)
ErrorDialog(
activity,
String.format(
context = activity,
message = String.format(
"%s %s",
resources.getString(R.string.settings_connection_failure),
getErrorMessage(error)
),
false
)
)
).show()
}
}
task.execute()
@ -508,8 +506,7 @@ class EditServerFragment : Fragment(), OnBackPressedHandler {
*/
private fun finishActivity() {
if (areFieldsChanged()) {
AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
ErrorDialog.Builder(context)
.setTitle(R.string.common_confirm)
.setMessage(R.string.server_editor_leave_confirmation)
.setPositiveButton(R.string.common_ok) { dialog, _ ->

View File

@ -1,6 +1,5 @@
package org.moire.ultrasonic.fragment
import android.app.AlertDialog
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
@ -20,6 +19,7 @@ import org.moire.ultrasonic.data.ActiveServerProvider
import org.moire.ultrasonic.fragment.EditServerFragment.Companion.EDIT_SERVER_INTENT_INDEX
import org.moire.ultrasonic.model.ServerSettingsModel
import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.util.ErrorDialog
import org.moire.ultrasonic.util.Util
import timber.log.Timber
@ -133,8 +133,7 @@ class ServerSelectorFragment : Fragment() {
* This Callback handles the deletion of a Server Setting
*/
private fun onServerDeleted(index: Int) {
AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
ErrorDialog.Builder(context)
.setTitle(R.string.server_menu_delete)
.setMessage(R.string.server_selector_delete_confirmation)
.setPositiveButton(R.string.common_delete) { dialog, _ ->

View File

@ -37,8 +37,10 @@ import org.moire.ultrasonic.provider.SearchSuggestionProvider
import org.moire.ultrasonic.service.MediaPlayerController
import org.moire.ultrasonic.service.RxBus
import org.moire.ultrasonic.util.Constants
import org.moire.ultrasonic.util.ErrorDialog
import org.moire.ultrasonic.util.FileUtil.defaultMusicDirectory
import org.moire.ultrasonic.util.FileUtil.ultrasonicDirectory
import org.moire.ultrasonic.util.InfoDialog
import org.moire.ultrasonic.util.MediaSessionHandler
import org.moire.ultrasonic.util.Settings
import org.moire.ultrasonic.util.Settings.preferences
@ -178,8 +180,12 @@ class SettingsFragment :
val write = (resultData.flags and Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0
val persist = (resultData.flags and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0
// TODO Should we show an error?
if (!read || !write || !persist) return
if (!read || !write || !persist) {
ErrorDialog.Builder(context)
.setMessage(R.string.settings_cache_location_error)
.show()
return
}
// The result data contains a URI for the document or directory that
// the user selected.
@ -461,9 +467,8 @@ class SettingsFragment :
)
val keep = R.string.settings_debug_log_keep
val delete = R.string.settings_debug_log_delete
AlertDialog.Builder(activity)
InfoDialog.Builder(activity)
.setMessage(message)
.setIcon(android.R.drawable.ic_dialog_info)
.setNegativeButton(keep) { dIf: DialogInterface, _: Int ->
dIf.cancel()
}

View File

@ -647,7 +647,7 @@ class MediaPlayerService : Service() {
4 -> {
keycode = KeyEvent.KEYCODE_MEDIA_STOP
label = getString(R.string.buttons_stop)
icon = R.drawable.ic_baseline_close_24
icon = R.drawable.ic_baseline_close
}
else -> return null
}

View File

@ -6,7 +6,6 @@
*/
package org.moire.ultrasonic.util
import android.app.AlertDialog
import android.content.Context
import android.os.Handler
import android.os.Looper
@ -45,13 +44,10 @@ object CommunicationError {
if (context == null) return
AlertDialog.Builder(context)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle(R.string.error_label)
.setMessage(getErrorMessage(error!!, context))
.setCancelable(true)
.setPositiveButton(R.string.common_ok) { _, _ -> }
.create().show()
ErrorDialog(
context = context,
message = getErrorMessage(error!!, context)
).show()
}
@JvmStatic

View File

@ -0,0 +1,78 @@
/*
* Dialogs.kt
* Copyright (C) 2009-2021 Ultrasonic developers
*
* Distributed under terms of the GNU GPLv3 license.
*/
package org.moire.ultrasonic.util
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import org.moire.ultrasonic.R
open class InfoDialog(
context: Context,
message: CharSequence?,
private val activity: Activity? = null,
private val finishActivityOnClose: Boolean = false
) {
open var builder: AlertDialog.Builder = Builder(activity ?: context, message)
fun show() {
builder.setOnCancelListener {
if (finishActivityOnClose) {
activity!!.finish()
}
}
builder.setPositiveButton(R.string.common_ok) { _, _ ->
if (finishActivityOnClose) {
activity!!.finish()
}
}
builder.create().show()
}
class Builder(context: Context?) : AlertDialog.Builder(context) {
constructor(context: Context, message: CharSequence?) : this(context) {
setMessage(message)
}
init {
setIcon(R.drawable.ic_baseline_info)
setTitle(R.string.common_confirm)
setCancelable(true)
setPositiveButton(R.string.common_ok) { _, _ ->
// Just close it
}
}
}
}
class ErrorDialog(
context: Context,
message: CharSequence?,
activity: Activity? = null,
finishActivityOnClose: Boolean = false
) : InfoDialog(context, message, activity, finishActivityOnClose) {
override var builder: AlertDialog.Builder = Builder(activity ?: context, message)
class Builder(context: Context?) : AlertDialog.Builder(context) {
constructor(context: Context, message: CharSequence?) : this(context) {
setMessage(message)
}
init {
setIcon(R.drawable.ic_baseline_warning)
setTitle(R.string.error_label)
setCancelable(true)
setPositiveButton(R.string.common_ok) { _, _ ->
// Just close it
}
}
}
}

View File

@ -9,11 +9,9 @@ package org.moire.ultrasonic.util
import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.PendingIntent
import android.content.ContentResolver
import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
@ -364,34 +362,6 @@ object Util {
fun isExternalStoragePresent(): Boolean =
Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()
// The AlertDialog requires an Activity context, app context is not enough
// See https://stackoverflow.com/questions/5436822/
fun createDialog(
context: Context?,
icon: Int = android.R.drawable.ic_dialog_info,
title: String,
message: String?
): AlertDialog.Builder {
return AlertDialog.Builder(context)
.setIcon(icon)
.setTitle(title)
.setMessage(message)
.setPositiveButton(R.string.common_ok) {
dialog: DialogInterface,
_: Int ->
dialog.dismiss()
}
}
fun showDialog(
context: Context,
icon: Int = android.R.drawable.ic_dialog_info,
titleId: Int,
message: String?
) {
createDialog(context, icon, context.getString(titleId, ""), message).show()
}
@JvmStatic
fun sleepQuietly(millis: Long) {
try {

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
</vector>

View File

@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
android:fillColor="@android:color/white"
android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
</vector>