From a5d3de55a2cbdf86152e1750510e6c6545cb05d2 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Wed, 14 Apr 2021 22:52:00 +0200 Subject: [PATCH] Add support for selecting SVG icons through the file selection dialog Fixes #724 --- .../aegis/ui/EditEntryActivity.java | 69 +++++++++++++++---- .../ImportExportPreferencesFragment.java | 3 +- .../aegis/ui/tasks/ImportFileTask.java | 36 ++++++++-- 3 files changed, 88 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java index a5265f29..52e5ec82 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/EditEntryActivity.java @@ -26,6 +26,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; +import androidx.documentfile.provider.DocumentFile; import com.amulyakhare.textdrawable.TextDrawable; import com.avito.android.krop.KropView; @@ -47,6 +48,7 @@ import com.beemdevelopment.aegis.otp.TotpInfo; import com.beemdevelopment.aegis.ui.dialogs.Dialogs; import com.beemdevelopment.aegis.ui.dialogs.IconPickerDialog; import com.beemdevelopment.aegis.ui.glide.IconLoader; +import com.beemdevelopment.aegis.ui.tasks.ImportFileTask; import com.beemdevelopment.aegis.ui.views.IconAdapter; import com.beemdevelopment.aegis.util.Cloner; import com.beemdevelopment.aegis.util.IOUtils; @@ -61,6 +63,7 @@ import com.google.android.material.textfield.TextInputEditText; import com.google.android.material.textfield.TextInputLayout; import java.io.ByteArrayOutputStream; +import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.ArrayList; @@ -439,18 +442,7 @@ public class EditEntryActivity extends AegisActivity { BottomSheetDialog dialog = IconPickerDialog.create(this, iconPacks, _textIssuer.getText().toString(), new IconAdapter.Listener() { @Override public void onIconSelected(IconPack.Icon icon) { - _selectedIcon = icon; - _hasCustomIcon = true; - _hasChangedIcon = true; - - IconViewHelper.setLayerType(_iconView, icon.getIconType()); - Glide.with(EditEntryActivity.this) - .asDrawable() - .load(icon.getFile()) - .set(IconLoader.ICON_TYPE, icon.getIconType()) - .diskCacheStrategy(DiskCacheStrategy.NONE) - .skipMemoryCache(false) - .into(_iconView); + selectIcon(icon); } @Override @@ -461,6 +453,21 @@ public class EditEntryActivity extends AegisActivity { Dialogs.showSecureDialog(dialog); } + private void selectIcon(IconPack.Icon icon) { + _selectedIcon = icon; + _hasCustomIcon = true; + _hasChangedIcon = true; + + IconViewHelper.setLayerType(_iconView, icon.getIconType()); + Glide.with(EditEntryActivity.this) + .asDrawable() + .load(icon.getFile()) + .set(IconLoader.ICON_TYPE, icon.getIconType()) + .diskCacheStrategy(DiskCacheStrategy.NONE) + .skipMemoryCache(false) + .into(_iconView); + } + private void startEditingIcon(Uri data) { Glide.with(this) .asBitmap() @@ -546,7 +553,21 @@ public class EditEntryActivity extends AegisActivity { @Override protected void onActivityResult(int requestCode, final int resultCode, Intent data) { if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) { - startEditingIcon(data.getData()); + DocumentFile file = DocumentFile.fromSingleUri(this, data.getData()); + if (file.getType().equals(IconType.SVG.toMimeType())) { + ImportFileTask.Params params = new ImportFileTask.Params(data.getData(), "icon", null); + ImportFileTask task = new ImportFileTask(this, result -> { + if (result.getException() == null) { + CustomSvgIcon icon = new CustomSvgIcon(result.getFile()); + selectIcon(icon); + } else { + Dialogs.showErrorDialog(this, R.string.reading_file_error, result.getException()); + } + }); + task.execute(getLifecycle(), params); + } else { + startEditingIcon(data.getData()); + } } super.onActivityResult(requestCode, resultCode, data); @@ -641,8 +662,7 @@ public class EditEntryActivity extends AegisActivity { try (FileInputStream inStream = new FileInputStream(_selectedIcon.getFile())){ iconBytes = IOUtils.readFile(inStream); } catch (IOException e) { - // TODO: show dialog - throw new RuntimeException(e); + throw new ParseException(e.getMessage()); } entry.setIcon(iconBytes, _selectedIcon.getIconType()); @@ -714,4 +734,23 @@ public class EditEntryActivity extends AegisActivity { super(message); } } + + private static class CustomSvgIcon extends IconPack.Icon { + private final File _file; + + protected CustomSvgIcon(File file) { + super(file.getAbsolutePath(), null, null); + _file = file; + } + + @Nullable + public File getFile() { + return _file; + } + + @Override + public IconType getIconType() { + return IconType.SVG; + } + } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/ImportExportPreferencesFragment.java b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/ImportExportPreferencesFragment.java index 1019fa3f..4ad46db7 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/ImportExportPreferencesFragment.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/fragments/ImportExportPreferencesFragment.java @@ -112,6 +112,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment { return; } + ImportFileTask.Params params = new ImportFileTask.Params(uri, "import", null); ImportFileTask task = new ImportFileTask(getContext(), result -> { if (result.getException() == null) { startImportEntriesActivity(_importerType, result.getFile()); @@ -119,7 +120,7 @@ public class ImportExportPreferencesFragment extends PreferencesFragment { Dialogs.showErrorDialog(getContext(), R.string.reading_file_error, result.getException()); } }); - task.execute(getLifecycle(), uri); + task.execute(getLifecycle(), params); } private void startImportEntriesActivity(Class importerType, File file) { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportFileTask.java b/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportFileTask.java index 602de544..f62960e8 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportFileTask.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/tasks/ImportFileTask.java @@ -15,7 +15,7 @@ import java.io.InputStream; * ImportFileTask reads an SAF file from a background thread and * writes it to a temporary file in the cache directory. */ -public class ImportFileTask extends ProgressDialogTask { +public class ImportFileTask extends ProgressDialogTask { private final Callback _cb; public ImportFileTask(Context context, Callback cb) { @@ -24,11 +24,15 @@ public class ImportFileTask extends ProgressDialogTask