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:
commit
adf72d6460
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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, _ ->
|
||||
|
@ -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, _ ->
|
||||
|
@ -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, _ ->
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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 {
|
||||
|
10
ultrasonic/src/main/res/drawable/ic_baseline_info.xml
Normal file
10
ultrasonic/src/main/res/drawable/ic_baseline_info.xml
Normal 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>
|
10
ultrasonic/src/main/res/drawable/ic_baseline_warning.xml
Normal file
10
ultrasonic/src/main/res/drawable/ic_baseline_warning.xml
Normal 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>
|
Loading…
x
Reference in New Issue
Block a user