From 5739b2bf4bc674cc318e0631626c35259314bc69 Mon Sep 17 00:00:00 2001 From: Nite Date: Tue, 18 Aug 2020 21:24:24 +0200 Subject: [PATCH] Implemented file picker for cache folder settings --- .../ultrasonic/fragment/SettingsFragment.java | 50 ++- .../moire/ultrasonic/util/PermissionUtil.java | 74 ++++- .../filepicker/FilePickerAdapter.kt | 287 ++++++++++++++++++ .../ultrasonic/filepicker/FilePickerDialog.kt | 116 +++++++ .../ultrasonic/filepicker/FilePickerView.kt | 67 ++++ .../filepicker/OnFileSelectedListener.kt | 7 + .../ic_create_new_folder_dark.png | Bin 0 -> 2323 bytes .../ic_create_new_folder_light.png | Bin 0 -> 2093 bytes .../main/res/drawable-hdpi/ic_folder_dark.png | Bin 0 -> 1959 bytes .../res/drawable-hdpi/ic_folder_light.png | Bin 0 -> 1810 bytes .../res/drawable-hdpi/ic_sd_storage_dark.png | Bin 0 -> 2091 bytes .../res/drawable-hdpi/ic_sd_storage_light.png | Bin 0 -> 1920 bytes .../drawable-hdpi/ic_subdirectory_up_dark.png | Bin 0 -> 2232 bytes .../ic_subdirectory_up_light.png | Bin 0 -> 2127 bytes .../ic_create_new_folder_dark.png | Bin 0 -> 2153 bytes .../ic_create_new_folder_light.png | Bin 0 -> 1975 bytes .../main/res/drawable-ldpi/ic_folder_dark.png | Bin 0 -> 2031 bytes .../res/drawable-ldpi/ic_folder_light.png | Bin 0 -> 1821 bytes .../res/drawable-ldpi/ic_sd_storage_dark.png | Bin 0 -> 1972 bytes .../res/drawable-ldpi/ic_sd_storage_light.png | Bin 0 -> 2010 bytes .../drawable-ldpi/ic_subdirectory_up_dark.png | Bin 0 -> 2376 bytes .../ic_subdirectory_up_light.png | Bin 0 -> 2344 bytes .../ic_create_new_folder_dark.png | Bin 0 -> 1787 bytes .../ic_create_new_folder_light.png | Bin 0 -> 1747 bytes .../main/res/drawable-mdpi/ic_folder_dark.png | Bin 0 -> 1631 bytes .../res/drawable-mdpi/ic_folder_light.png | Bin 0 -> 1593 bytes .../res/drawable-mdpi/ic_sd_storage_dark.png | Bin 0 -> 1656 bytes .../res/drawable-mdpi/ic_sd_storage_light.png | Bin 0 -> 1658 bytes .../drawable-mdpi/ic_subdirectory_up_dark.png | Bin 0 -> 1752 bytes .../ic_subdirectory_up_light.png | Bin 0 -> 1763 bytes .../ic_create_new_folder_dark.png | Bin 0 -> 1984 bytes .../ic_create_new_folder_light.png | Bin 0 -> 1906 bytes .../res/drawable-xhdpi/ic_folder_dark.png | Bin 0 -> 1857 bytes .../res/drawable-xhdpi/ic_folder_light.png | Bin 0 -> 1762 bytes .../res/drawable-xhdpi/ic_sd_storage_dark.png | Bin 0 -> 1943 bytes .../drawable-xhdpi/ic_sd_storage_light.png | Bin 0 -> 1835 bytes .../ic_subdirectory_up_dark.png | Bin 0 -> 2233 bytes .../ic_subdirectory_up_light.png | Bin 0 -> 1990 bytes .../ic_create_new_folder_dark.png | Bin 0 -> 2011 bytes .../ic_create_new_folder_light.png | Bin 0 -> 1836 bytes .../res/drawable-xxhdpi/ic_folder_dark.png | Bin 0 -> 1915 bytes .../res/drawable-xxhdpi/ic_folder_light.png | Bin 0 -> 1784 bytes .../drawable-xxhdpi/ic_sd_storage_dark.png | Bin 0 -> 1928 bytes .../drawable-xxhdpi/ic_sd_storage_light.png | Bin 0 -> 1771 bytes .../ic_subdirectory_up_dark.png | Bin 0 -> 1957 bytes .../ic_subdirectory_up_light.png | Bin 0 -> 1863 bytes .../filepicker_dialog_create_folder.xml | 21 ++ .../res/layout/filepicker_dialog_main.xml | 43 +++ .../layout/filepicker_item_file_lister.xml | 26 ++ ultrasonic/src/main/res/values-de/strings.xml | 18 +- ultrasonic/src/main/res/values-es/strings.xml | 16 +- ultrasonic/src/main/res/values-fr/strings.xml | 18 +- ultrasonic/src/main/res/values-hu/strings.xml | 16 +- ultrasonic/src/main/res/values-nl/strings.xml | 18 +- ultrasonic/src/main/res/values-pl/strings.xml | 18 +- .../src/main/res/values-pt-rBR/strings.xml | 18 +- ultrasonic/src/main/res/values-pt/strings.xml | 18 +- ultrasonic/src/main/res/values/strings.xml | 18 +- ultrasonic/src/main/res/values/styles.xml | 5 + ultrasonic/src/main/res/values/themes.xml | 10 +- ultrasonic/src/main/res/xml/settings.xml | 2 +- 61 files changed, 830 insertions(+), 36 deletions(-) create mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerAdapter.kt create mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerDialog.kt create mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerView.kt create mode 100644 ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/OnFileSelectedListener.kt create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_sd_storage_dark.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_sd_storage_light.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_subdirectory_up_dark.png create mode 100644 ultrasonic/src/main/res/drawable-hdpi/ic_subdirectory_up_light.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_sd_storage_dark.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_sd_storage_light.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_subdirectory_up_dark.png create mode 100644 ultrasonic/src/main/res/drawable-ldpi/ic_subdirectory_up_light.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_create_new_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_create_new_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_dark.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_light.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_subdirectory_up_dark.png create mode 100644 ultrasonic/src/main/res/drawable-mdpi/ic_subdirectory_up_light.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_create_new_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_create_new_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_sd_storage_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_sd_storage_light.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_folder_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_folder_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_sd_storage_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_sd_storage_light.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_subdirectory_up_dark.png create mode 100644 ultrasonic/src/main/res/drawable-xxhdpi/ic_subdirectory_up_light.png create mode 100644 ultrasonic/src/main/res/layout/filepicker_dialog_create_folder.xml create mode 100644 ultrasonic/src/main/res/layout/filepicker_dialog_main.xml create mode 100644 ultrasonic/src/main/res/layout/filepicker_item_file_lister.xml diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java index d15d6a0e..b621d8d5 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/fragment/SettingsFragment.java @@ -15,6 +15,8 @@ import org.moire.ultrasonic.activity.ServerSettingsActivity; import org.moire.ultrasonic.activity.SubsonicTabActivity; import org.moire.ultrasonic.featureflags.Feature; import org.moire.ultrasonic.featureflags.FeatureStorage; +import org.moire.ultrasonic.filepicker.FilePickerDialog; +import org.moire.ultrasonic.filepicker.OnFileSelectedListener; import org.moire.ultrasonic.provider.SearchSuggestionProvider; import org.moire.ultrasonic.service.MediaPlayerController; import org.moire.ultrasonic.util.*; @@ -37,7 +39,7 @@ public class SettingsFragment extends PreferenceFragment private ListPreference maxBitrateWifi; private ListPreference maxBitrateMobile; private ListPreference cacheSize; - private EditTextPreference cacheLocation; + private Preference cacheLocation; private ListPreference preloadCount; private ListPreference bufferLength; private ListPreference incrementTime; @@ -85,7 +87,7 @@ public class SettingsFragment extends PreferenceFragment maxBitrateWifi = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_WIFI); maxBitrateMobile = (ListPreference) findPreference(Constants.PREFERENCES_KEY_MAX_BITRATE_MOBILE); cacheSize = (ListPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_SIZE); - cacheLocation = (EditTextPreference) findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); + cacheLocation = findPreference(Constants.PREFERENCES_KEY_CACHE_LOCATION); preloadCount = (ListPreference) findPreference(Constants.PREFERENCES_KEY_PRELOAD_COUNT); bufferLength = (ListPreference) findPreference(Constants.PREFERENCES_KEY_BUFFER_LENGTH); incrementTime = (ListPreference) findPreference(Constants.PREFERENCES_KEY_INCREMENT_TIME); @@ -113,6 +115,7 @@ public class SettingsFragment extends PreferenceFragment setupClearSearchPreference(); setupGaplessControlSettingsV14(); setupFeatureFlagsPreferences(); + setupCacheLocationPreference(); // After API26 foreground services must be used for music playback, and they must have a notification if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { @@ -155,8 +158,6 @@ public class SettingsFragment extends PreferenceFragment setHideMedia(sharedPreferences.getBoolean(key, false)); } else if (Constants.PREFERENCES_KEY_MEDIA_BUTTONS.equals(key)) { setMediaButtonsEnabled(sharedPreferences.getBoolean(key, true)); - } else if (Constants.PREFERENCES_KEY_CACHE_LOCATION.equals(key)) { - setCacheLocation(sharedPreferences.getString(key, "")); } else if (Constants.PREFERENCES_KEY_SEND_BLUETOOTH_NOTIFICATIONS.equals(key)) { setBluetoothPreferences(sharedPreferences.getBoolean(key, true)); } else if (Constants.PREFERENCES_KEY_IMAGE_LOADER_CONCURRENCY.equals(key)) { @@ -164,6 +165,40 @@ public class SettingsFragment extends PreferenceFragment } } + private void setupCacheLocationPreference() { + cacheLocation.setSummary(settings.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, + FileUtil.getDefaultMusicDirectory(getActivity()).getPath())); + + cacheLocation.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + // If the user tries to change the cache location, we must first check to see if we have write access. + PermissionUtil.requestInitialPermission(getActivity(), new PermissionUtil.PermissionRequestFinishedCallback() { + @Override + public void onPermissionRequestFinished(boolean hasPermission) { + if (hasPermission) { + FilePickerDialog filePickerDialog = FilePickerDialog.Companion.createFilePickerDialog(getActivity()); + filePickerDialog.setDefaultDirectory(FileUtil.getDefaultMusicDirectory(getActivity()).getPath()); + filePickerDialog.setInitialDirectory(cacheLocation.getSummary().toString()); + filePickerDialog.setOnFileSelectedListener(new OnFileSelectedListener() { + @Override + public void onFileSelected(File file, String path) { + SharedPreferences.Editor editor = cacheLocation.getEditor(); + editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, path); + editor.commit(); + + setCacheLocation(path); + } + }); + filePickerDialog.show(); + } + } + }); + return true; + } + }); + } + private void setupClearSearchPreference() { Preference clearSearchPreference = findPreference(Constants.PREFERENCES_KEY_CLEAR_SEARCH_HISTORY); @@ -315,7 +350,6 @@ public class SettingsFragment extends PreferenceFragment maxBitrateWifi.setSummary(maxBitrateWifi.getEntry()); maxBitrateMobile.setSummary(maxBitrateMobile.getEntry()); cacheSize.setSummary(cacheSize.getEntry()); - cacheLocation.setSummary(cacheLocation.getText()); preloadCount.setSummary(preloadCount.getEntry()); bufferLength.setSummary(bufferLength.getEntry()); incrementTime.setSummary(incrementTime.getEntry()); @@ -396,14 +430,16 @@ public class SettingsFragment extends PreferenceFragment if (!FileUtil.ensureDirectoryExistsAndIsReadWritable(dir)) { PermissionUtil.handlePermissionFailed(getActivity(), new PermissionUtil.PermissionRequestFinishedCallback() { @Override - public void onPermissionRequestFinished() { + public void onPermissionRequestFinished(boolean hasPermission) { String currentPath = settings.getString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory(getActivity()).getPath()); cacheLocation.setSummary(currentPath); - cacheLocation.setText(currentPath); } }); } + else { + cacheLocation.setSummary(path); + } // Clear download queue. mediaPlayerControllerLazy.getValue().clear(); diff --git a/ultrasonic/src/main/java/org/moire/ultrasonic/util/PermissionUtil.java b/ultrasonic/src/main/java/org/moire/ultrasonic/util/PermissionUtil.java index 938466cf..74868160 100644 --- a/ultrasonic/src/main/java/org/moire/ultrasonic/util/PermissionUtil.java +++ b/ultrasonic/src/main/java/org/moire/ultrasonic/util/PermissionUtil.java @@ -5,6 +5,8 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import androidx.appcompat.app.AlertDialog; @@ -34,7 +36,7 @@ public class PermissionUtil { private static final String TAG = FileUtil.class.getSimpleName(); public interface PermissionRequestFinishedCallback { - void onPermissionRequestFinished(); + void onPermissionRequestFinished(boolean hasPermission); } /** @@ -55,27 +57,79 @@ public class PermissionUtil { if (currentCachePath.compareTo(defaultCachePath) == 0) return; // We must get the context of the Main Activity for the dialogs, as this function may be called from a background thread where displaying dialogs is not available - Context mainContext = MainActivity.getInstance(); + final Context mainContext = MainActivity.getInstance(); if ((PermissionChecker.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PERMISSION_DENIED) || (PermissionChecker.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) == PERMISSION_DENIED)) { // While we request permission, the Music Directory is temporarily reset to its default location setCacheLocation(context, FileUtil.getDefaultMusicDirectory(context).getPath()); - requestPermission(mainContext, currentCachePath, callback); + requestFailedPermission(mainContext, currentCachePath, callback); } else { setCacheLocation(context, FileUtil.getDefaultMusicDirectory(context).getPath()); - showWarning(mainContext, context.getString(R.string.permissions_message_box_title), context.getString(R.string.permissions_access_error), null); - callback.onPermissionRequestFinished(); + new Handler(Looper.getMainLooper()).post(new Runnable() { + @Override + public void run() { + showWarning(mainContext, context.getString(R.string.permissions_message_box_title), context.getString(R.string.permissions_access_error), null); + } + }); + callback.onPermissionRequestFinished(false); } } + /** + * This function requests permission to access the filesystem. + * It can be used to request the permission initially, e.g. when the user decides to use a non-default folder for the cache + * @param context context for the operation + * @param callback callback function to execute after the permission request is finished + */ + public static void requestInitialPermission(final Context context, final PermissionRequestFinishedCallback callback) { + Dexter.withContext(context) + .withPermissions( + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE) + .withListener(new MultiplePermissionsListener() { + @Override + public void onPermissionsChecked(MultiplePermissionsReport report) { + if (report.areAllPermissionsGranted()) { + Log.i(TAG, "Permission granted to read / write external storage"); + if (callback != null) callback.onPermissionRequestFinished(true); + return; + } + + if (report.isAnyPermissionPermanentlyDenied()) { + Log.i(TAG, "Found permanently denied permission to read / write external storage, offering settings"); + showSettingsDialog(context); + if (callback != null) callback.onPermissionRequestFinished(false); + return; + } + + Log.i(TAG, "At least one permission is missing to read / write external storage"); + showWarning(context, context.getString(R.string.permissions_message_box_title), + context.getString(R.string.permissions_rationale_description_initial), null); + if (callback != null) callback.onPermissionRequestFinished(false); + } + + @Override + public void onPermissionRationaleShouldBeShown(List permissions, PermissionToken token) { + showWarning(context, context.getString(R.string.permissions_rationale_title), + context.getString(R.string.permissions_rationale_description_initial), token); + } + }).withErrorListener(new PermissionRequestErrorListener() { + @Override + public void onError(DexterError error) { + Log.e(TAG, String.format("An error has occurred during checking permissions with Dexter: %s", error.toString())); + } + }) + .check(); + } + private static void setCacheLocation(Context context, String cacheLocation) { Util.getPreferences(context).edit() .putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, cacheLocation) .apply(); } - private static void requestPermission(final Context context, final String cacheLocation, final PermissionRequestFinishedCallback callback) { + private static void requestFailedPermission(final Context context, final String cacheLocation, final PermissionRequestFinishedCallback callback) { Dexter.withContext(context) .withPermissions( Manifest.permission.WRITE_EXTERNAL_STORAGE, @@ -86,14 +140,14 @@ public class PermissionUtil { if (report.areAllPermissionsGranted()) { Log.i(TAG, String.format("Permission granted to use cache directory %s", cacheLocation)); setCacheLocation(context, cacheLocation); - if (callback != null) callback.onPermissionRequestFinished(); + if (callback != null) callback.onPermissionRequestFinished(true); return; } if (report.isAnyPermissionPermanentlyDenied()) { Log.i(TAG, String.format("Found permanently denied permission to use cache directory %s, offering settings", cacheLocation)); showSettingsDialog(context); - if (callback != null) callback.onPermissionRequestFinished(); + if (callback != null) callback.onPermissionRequestFinished(false); return; } @@ -101,13 +155,13 @@ public class PermissionUtil { setCacheLocation(context, FileUtil.getDefaultMusicDirectory(context).getPath()); showWarning(context, context.getString(R.string.permissions_message_box_title), context.getString(R.string.permissions_permission_missing), null); - if (callback != null) callback.onPermissionRequestFinished(); + if (callback != null) callback.onPermissionRequestFinished(false); } @Override public void onPermissionRationaleShouldBeShown(List permissions, PermissionToken token) { showWarning(context, context.getString(R.string.permissions_rationale_title), - context.getString(R.string.permissions_rationale_description), token); + context.getString(R.string.permissions_rationale_description_failed), token); } }).withErrorListener(new PermissionRequestErrorListener() { @Override diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerAdapter.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerAdapter.kt new file mode 100644 index 00000000..442187ba --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerAdapter.kt @@ -0,0 +1,287 @@ +package org.moire.ultrasonic.filepicker + +import android.content.Context +import android.graphics.drawable.Drawable +import android.os.Environment +import android.text.TextUtils +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.widget.AppCompatEditText +import androidx.recyclerview.widget.RecyclerView +import java.io.File +import java.util.LinkedList +import kotlin.Comparator +import org.moire.ultrasonic.R +import org.moire.ultrasonic.util.Util + +/** + * Adapter for the RecyclerView which handles listing, navigating and picking files + * @author this implementation is loosely based on the work of Yogesh Sundaresan, + * original license: http://www.apache.org/licenses/LICENSE-2.0 + */ +internal class FilePickerAdapter : RecyclerView.Adapter { + + private var data: MutableList = LinkedList() + var defaultDirectory: File = Environment.getExternalStorageDirectory() + var initialDirectory: File = Environment.getExternalStorageDirectory() + lateinit var selectedDirectoryChanged: (String, Boolean) -> Unit + var selectedDirectory: File = defaultDirectory + private set + + private var context: Context? = null + private var listerView: FilePickerView? = null + private var isRealDirectory: Boolean = false + + private val physicalPaths: Array + get() = arrayOf( + "/storage/sdcard0", "/storage/sdcard1", "/storage/extsdcard", + "/storage/sdcard0/external_sdcard", "/mnt/extsdcard", "/mnt/sdcard/external_sd", + "/mnt/external_sd", "/mnt/media_rw/sdcard1", "/removable/microsd", "/mnt/emmc", + "/storage/external_SD", "/storage/ext_sd", "/storage/removable/sdcard1", + "/data/sdext", "/data/sdext2", "/data/sdext3", "/data/sdext4", "/sdcard1", + "/sdcard2", "/storage/microsd", "/data/user" + ) + + private var folderIcon: Drawable? = null + private var upIcon: Drawable? = null + private var sdIcon: Drawable? = null + + constructor(defaultDir: File, view: FilePickerView) : this(view) { + this.defaultDirectory = defaultDir + selectedDirectory = defaultDir + } + + constructor(view: FilePickerView) { + this.context = view.context + listerView = view + + upIcon = Util.getDrawableFromAttribute(context, R.attr.filepicker_subdirectory_up) + folderIcon = Util.getDrawableFromAttribute(context, R.attr.filepicker_folder) + sdIcon = Util.getDrawableFromAttribute(context, R.attr.filepicker_sd_card) + } + + fun start() { + fileLister(initialDirectory) + } + + private fun fileLister(currentDirectory: File) { + var fileList = LinkedList() + var storages: List? = null + var storagePaths: List? = null + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + storages = context!!.getExternalFilesDirs(null).filterNotNull() + storagePaths = storages.map { i -> i.absolutePath } + } + + if (currentDirectory.absolutePath == "/" || + currentDirectory.absolutePath == "/storage" || + currentDirectory.absolutePath == "/storage/emulated" || + currentDirectory.absolutePath == "/mnt" + ) { + isRealDirectory = false + fileList = if ( + android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT + ) { + getKitKatStorageItems(storages!!) + } else { + getStorageItems() + } + } else { + isRealDirectory = true + val files = currentDirectory.listFiles() + files?.forEach { file -> + if (file.isDirectory) { + fileList.add(FileListItem(file, file.name, folderIcon!!)) + } + } + } + + data = LinkedList(fileList) + + data.sortWith( + Comparator { f1, f2 -> + if (f1.file!!.isDirectory && f2.file!!.isDirectory) + f1.name.compareTo(f2.name, ignoreCase = true) + else if (f1.file!!.isDirectory && !f2.file!!.isDirectory) + -1 + else if (!f1.file!!.isDirectory && f2.file!!.isDirectory) + 1 + else if (!f1.file!!.isDirectory && !f2.file!!.isDirectory) + f1.name.compareTo(f2.name, ignoreCase = true) + else + 0 + } + ) + + selectedDirectory = currentDirectory + selectedDirectoryChanged.invoke( + if (isRealDirectory) selectedDirectory.absolutePath + else context!!.getString(R.string.filepicker_available_drives), + isRealDirectory + ) + + // Add the "Up" navigation to the list + if (currentDirectory.absolutePath != "/" && isRealDirectory) { + // If we are on KitKat or later, only the default App folder is usable, so we can't + // navigate the SD card. Jump to the root if "Up" is selected. + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { + if (storagePaths!!.indexOf(currentDirectory.absolutePath) > 0) + data.add(0, FileListItem(File("/"), "..", upIcon!!)) + else + data.add(0, FileListItem(selectedDirectory.parentFile!!, "..", upIcon!!)) + } else { + data.add(0, FileListItem(selectedDirectory.parentFile!!, "..", upIcon!!)) + } + } + + notifyDataSetChanged() + listerView!!.scrollToPosition(0) + } + + private fun getStorageItems(): LinkedList { + val fileList = LinkedList() + var s = System.getenv("EXTERNAL_STORAGE") + if (!TextUtils.isEmpty(s)) { + val f = File(s!!) + fileList.add(FileListItem(f, f.name, sdIcon!!)) + } else { + val paths = physicalPaths + for (path in paths) { + val f = File(path) + if (f.exists()) + fileList.add(FileListItem(f, f.name, sdIcon!!)) + } + } + s = System.getenv("SECONDARY_STORAGE") + if (s != null && !TextUtils.isEmpty(s)) { + val rawSecondaryStorages = + s.split(File.pathSeparator.toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray() + for (path in rawSecondaryStorages) { + val f = File(path) + if (f.exists()) + fileList.add(FileListItem(f, f.name, sdIcon!!)) + } + } + return fileList + } + + private fun getKitKatStorageItems(storages: List): LinkedList { + val fileList = LinkedList() + if (storages.isNotEmpty()) { + for ((index, file) in storages.withIndex()) { + var path = file.absolutePath + path = path.replace("/Android/data/([a-zA-Z_][.\\w]*)/files".toRegex(), "") + if (index == 0) { + fileList.add( + FileListItem( + File(path), + context!!.getString(R.string.filepicker_internal, path), + sdIcon!! + ) + ) + } else { + fileList.add( + FileListItem( + file, + context!!.getString(R.string.filepicker_default_app_folder, path), + sdIcon!! + ) + ) + } + } + } + return fileList + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FileListHolder { + return FileListHolder( + LayoutInflater.from(context).inflate( + R.layout.filepicker_item_file_lister, listerView, false + ) + ) + } + + override fun onBindViewHolder(holder: FileListHolder, position: Int) { + val actualFile = data[position] + + holder.name.text = actualFile.name + holder.icon.setImageDrawable(actualFile.icon) + } + + override fun getItemCount(): Int { + return data.size + } + + fun goToDefault() { + fileLister(defaultDirectory) + } + + fun createNewFolder() { + val view = View.inflate(context, R.layout.filepicker_dialog_create_folder, null) + val editText = view.findViewById(R.id.edittext) + val builder = AlertDialog.Builder(context!!) + .setView(view) + .setTitle(context!!.getString(R.string.filepicker_enter_folder_name)) + .setPositiveButton(context!!.getString(R.string.filepicker_create)) { _, _ -> } + val dialog = builder.create() + dialog.show() + + dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + val name = editText.text!!.toString() + + if (TextUtils.isEmpty(name)) { + Util.toast(context!!, context!!.getString(R.string.filepicker_name_invalid)) + } else { + val file = File(selectedDirectory, name) + + if (file.exists()) { + Util.toast(context!!, context!!.getString(R.string.filepicker_already_exists)) + } else { + dialog.dismiss() + if (file.mkdirs()) { + fileLister(file) + } else { + Util.toast( + context!!, + context!!.getString(R.string.filepicker_create_folder_failed) + ) + } + } + } + } + } + + internal inner class FileListItem( + fileParameter: File, + nameParameter: String, + iconParameter: Drawable + ) { + var file: File? = fileParameter + var name: String = nameParameter + var icon: Drawable? = iconParameter + } + + internal inner class FileListHolder( + itemView: View + ) : RecyclerView.ViewHolder(itemView), View.OnClickListener { + + var name: TextView = itemView.findViewById(R.id.name) + var icon: ImageView = itemView.findViewById(R.id.icon) + + init { + itemView.findViewById(R.id.layout).setOnClickListener(this) + } + + override fun onClick(v: View) { + val clickedFile = data[adapterPosition] + selectedDirectory = clickedFile.file!! + fileLister(clickedFile.file!!) + Log.d("FileLister", clickedFile.file!!.absolutePath) + } + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerDialog.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerDialog.kt new file mode 100644 index 00000000..5c743136 --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerDialog.kt @@ -0,0 +1,116 @@ +package org.moire.ultrasonic.filepicker + +import android.content.Context +import android.content.DialogInterface.BUTTON_NEGATIVE +import android.content.DialogInterface.BUTTON_NEUTRAL +import android.content.DialogInterface.BUTTON_POSITIVE +import android.view.LayoutInflater +import android.widget.Button +import android.widget.TextView +import androidx.appcompat.app.AlertDialog +import org.moire.ultrasonic.R + +/** + * This dialog can be used to pick a file / folder from the filesystem. + * Currently only supports folders. + * @author this implementation is loosely based on the work of Yogesh Sundaresan, + * original license: http://www.apache.org/licenses/LICENSE-2.0 + */ +class FilePickerDialog { + + private var alertDialog: AlertDialog? = null + private var filePickerView: FilePickerView? = null + private var onFileSelectedListener: OnFileSelectedListener? = null + private var currentPath: TextView? = null + private var newFolderButton: Button? = null + + private constructor(context: Context) { + alertDialog = AlertDialog.Builder(context).create() + initialize(context) + } + + private constructor(context: Context, themeResId: Int) { + alertDialog = AlertDialog.Builder(context, themeResId).create() + initialize(context) + } + + private fun initialize(context: Context) { + val view = LayoutInflater.from(context).inflate(R.layout.filepicker_dialog_main, null) + + alertDialog!!.setView(view) + filePickerView = view.findViewById(R.id.file_list_view) + currentPath = view.findViewById(R.id.current_path) + + newFolderButton = view.findViewById(R.id.filepicker_create_folder) + newFolderButton!!.setOnClickListener { filePickerView!!.createNewFolder() } + + alertDialog!!.setTitle(context.getString(R.string.filepicker_select_folder)) + + alertDialog!!.setButton(BUTTON_POSITIVE, context.getString(R.string.filepicker_select)) { + dialogInterface, _ -> + dialogInterface.dismiss() + if (onFileSelectedListener != null) + onFileSelectedListener!!.onFileSelected( + filePickerView!!.selected, filePickerView!!.selected.absolutePath + ) + } + alertDialog!!.setButton(BUTTON_NEUTRAL, context.getString(R.string.filepicker_default)) { + _, _ -> + filePickerView!!.goToDefaultDirectory() + } + alertDialog!!.setButton(BUTTON_NEGATIVE, context.getString(R.string.common_cancel)) { + dialogInterface, _ -> + dialogInterface.dismiss() + } + } + + /** + * Display the FilePickerDialog + */ + fun show() { + filePickerView!!.start { currentDirectory, isRealPath -> + run { + currentPath?.text = currentDirectory + newFolderButton!!.isEnabled = isRealPath + } + } + alertDialog!!.show() + alertDialog!!.getButton(BUTTON_NEUTRAL).setOnClickListener { + filePickerView!!.goToDefaultDirectory() + } + } + + /** + * Listener to know which file/directory is selected + * + * @param onFileSelectedListener Instance of the Listener + */ + fun setOnFileSelectedListener(onFileSelectedListener: OnFileSelectedListener) { + this.onFileSelectedListener = onFileSelectedListener + } + + /** + * Set the initial directory to show the list of files in that directory + * + * @param path String denoting to the directory + */ + fun setDefaultDirectory(path: String) { + filePickerView!!.setDefaultDirectory(path) + } + + fun setInitialDirectory(path: String) { + filePickerView!!.setInitialDirectory(path) + } + + companion object { + /** + * Creates a default instance of FilePickerDialog + * + * @param context Context of the App + * @return Instance of FileListerDialog + */ + fun createFilePickerDialog(context: Context): FilePickerDialog { + return FilePickerDialog(context) + } + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerView.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerView.kt new file mode 100644 index 00000000..a94f86be --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/FilePickerView.kt @@ -0,0 +1,67 @@ +package org.moire.ultrasonic.filepicker + +import android.content.Context +import android.util.AttributeSet +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import java.io.File + +/** + * RecyclerView containing the file list of a directory + * @author this implementation is loosely based on the work of Yogesh Sundaresan, + * original license: http://www.apache.org/licenses/LICENSE-2.0 + */ +internal class FilePickerView : RecyclerView { + + private var adapter: FilePickerAdapter? = null + + val selected: File + get() = adapter!!.selectedDirectory + + constructor(context: Context) : super(context) { + initialize() + } + + constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) { + initialize() + } + + constructor( + context: Context, + attrs: AttributeSet?, + defStyle: Int + ) : super(context, attrs, defStyle) { + initialize() + } + + private fun initialize() { + layoutManager = LinearLayoutManager(context, VERTICAL, false) + adapter = FilePickerAdapter(this) + } + + fun start(selectedDirectoryChangedListener: (String, Boolean) -> Unit) { + setAdapter(adapter) + adapter?.selectedDirectoryChanged = selectedDirectoryChangedListener + adapter!!.start() + } + + fun setDefaultDirectory(file: File) { + adapter!!.defaultDirectory = file + } + + fun setDefaultDirectory(path: String) { + setDefaultDirectory(File(path)) + } + + fun setInitialDirectory(path: String) { + adapter!!.initialDirectory = File(path) + } + + fun goToDefaultDirectory() { + adapter!!.goToDefault() + } + + fun createNewFolder() { + adapter!!.createNewFolder() + } +} diff --git a/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/OnFileSelectedListener.kt b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/OnFileSelectedListener.kt new file mode 100644 index 00000000..54d3b5de --- /dev/null +++ b/ultrasonic/src/main/kotlin/org/moire/ultrasonic/filepicker/OnFileSelectedListener.kt @@ -0,0 +1,7 @@ +package org.moire.ultrasonic.filepicker + +import java.io.File + +interface OnFileSelectedListener { + fun onFileSelected(file: File?, path: String?) +} diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_dark.png b/ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..958d9941a7aaa1310b398bf282f3ea59382cfb6b GIT binary patch literal 2323 zcmV+u3GDWXP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+T~YUk|ZY#{O1%t0+JAj07(5-Md%h%o>9bA>DFXh3mCv2A@dMLhGuvgyW@!Uwr`6j1yDXQ}}$koboQ`@De zUlWfh*OeY--Malhybu(4X($#F<|!l*cb3Znxm}LSa3?X$BN2>QG@R~k2^{j`^X`3& z&mHu_$@fus?fu8-mGjvzxxDgazI=qiHy@C`lFMTmenp4NB7XV6DV8^%b6sl*dK`Rj7yR)Ve?V0rsK?EQ5A@h>Dw@(0x8&d~ zn5XD(Aw;2!O95PjwH3yY0D+iElrqS`T!`RD13(~$ArQC$0aE1wBRPp=4uugiSR3yY zI&)b$^A;mF0SJ{W1=v(^fR&PhKP4GB1OTd&;* z4;e@kBabp{)ZvrDM5dT&>ddoDn|1mE*Osibbmdi+t-Aby+J)+y_6gMJLX8hndtP~< z25Bheu7Y+t(Ty1p<3vEbYy?1P-k3$Blz1bzF^iQE6v{ACH#T9=Mhp<9Nvw+=*gYZl zA>4x6hj8N`As04uUx8czbZ>F{25MvPbNwK8i^A>GD2P7HakhX9X_4($`~SS6zS?Y5 z^US~$EQosxonXocX|UQ@y%m+l;_xXIS%7=GjM+dN_!LCMrd}wu{TCdwzHF;{7SJZ>NDl?Eb~Q=^soR)2S>{AALu6tE`6}G(ETEUJ<0V#xQ1gPDnt=bv(za z2?YlN5ngTW<1VA{Ngw|Ht89m!upKEA6{J4_^e@8%0cKZ7V)b93i8Az?}1G zUtvzgmR;jgK&_9IGqrTkn!NRatV1>@kEuqdHnEhfC+fBnL@XmW_x+xPsw)m0kbEI6 z4CE?o8&*+?rfdndHFiU6aLHu!xROuzm$|MZ+29~B0*`-!N9YV2C^9DvM(VgRg2hJk zmeUm1jm*X*e33yX)qebi%?j{gQv~F=5#>+>WzCnEqyH~ON+@bjUk%SZXE#)C9f#f3 zRHx%fQPeVAFsZ6dQR`lDSXwx)V@oXqWea$&pe-sbNv+<(rtWQUCzG94K;rks;d9g9 z7l$K9O$RD~u!z#7mRiBtx#8Hn3jta5l3W2rF?JJVVUz5XQfhOt$XqphVtr4n(H)& z5XTY{NJ4;w8p^1^M3h#Q6ay*RkGc24=GxZD8-o-|Px zZOKQ|TPOhUXY@@up#K&Kt~tH6_Hp_EWT>m<8{ps&7%fuvy34x*oxS~grq$mM$4PR@ z@mO|P00006VoOIv0RI600RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliru zSsPq5;0uV_=K~!ko?byF+R6!KS@z3NBYQPjB8iEECOGzOJzJ*{BK^uGD zz)}=^0};y03CE4t;@Fpz7-E}v+cXtExgIg^3?r^@tIlq~6 zC@Lx{DjGtm+lz>p$0FtiSTFEBrL;FufQYz)o4AORy+AXy@d}$MrTvKjM8rDoV{L%I zJGGCec$QN7-88^V7W@Kk3=urc;tp;{#HpqM^88-JHO}J}uHqryb*+IZRaDO=U5#{4*Ipe~4ZhbyIO6Z>_&lz%&JfX}##?dtam9^>4o&Vg~Ll~QU|w%r=( zNqiht04A-bY9M!;&YNo8?X^|oHhsBMQvkW!9D;TB2`Q!Rh}ftJv~PE6(uEG)rl+yj zG(Lm4Q>lR->#kOPb!U3C@bzHVBVrb3vp53F{l?Z5z%m}y^a5XSue#&I5*}c+CNq{M z2{4N@b#;-Y?M(IEksGLTkQIO_b)kOT$slesEdaSY_3bv(0?^H!2DxMPtbu*}nc|fH ziQQfRJJ_0HfGzy!1@H?m@X2uFz$UKeAMr9D7Va{sJ70i(IdML@NLQ002ovPDHLkV1gt1I_m%c literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_light.png b/ultrasonic/src/main/res/drawable-hdpi/ic_create_new_folder_light.png new file mode 100644 index 0000000000000000000000000000000000000000..96f975e8596002fabe299e1ea4cf0a563e5d55f6 GIT binary patch literal 2093 zcmV+|2-5e7P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ujwB}x{m&_K1Z-n$j>D&v8|3(TR8{xP^z3Y= zlUAgawon0WT*mm>#vSHgf3ENc9wv$*sd+9rM?9&d!W9#b=TnZJVmkWck!uORKhVQ{ zfkBctPOBGx1zq1hxa~phBR%-F!hQ*&yWmrUz4M-r_ez4!C!NwIsLXSci`#ou+a;)9 zjE5@Mo9=3z!~PvU5DZotij9PM3Q0uIa%mvvTk$%25(giNV9r9}Al)>9K|UPsHpckg zKp%{Jn}tW~-)9fT=X%lQ!It^55hg!eAbp_AeH(sohf5>=xB&I-({ZkMt>J6U^K><3 zSTtWAbr_p&V!+s7aydTBXogo0(YqBik2Q8cK4Omzty3WeDl1T;L6sKGW9-zSV&ch$ zk+}nqO>;3W+-2jGcB926MFtRL={y7AOTu?u=-9U$`*m{cJP53arjCvI>lS{t_)H6H z^=%@Gezz6$;_cTvsDa$>!398QUAXCC;9I-kkMH~kt_lS8Ftg);HMUbkQ+o3)IdB&6 zDaJE|DA>3Jz(m+vp$rKSh?ztwQ#58Hf*l8Wea-MaVE>);^+ zX=3DI!$%o)QkcjTGfka&+VojwUGTLfD=l4l+45CZy`y%a`l&sE8eORIfz;-+J8GZ? zvzrLo=|neXK#UUsaoY&Mp?PB#ol@eB+{P>xMo=h2N!{3lK^rkZm?p6fgeR{|ULUp?d{#0nmNM?FXoheb4m+u`>#{O`{i%pO17C~d~8F4kUJK_&%ms9N1 zsOwSC?N4@1^mz#<-;nA4J+Dq|GWQ1>CHlfTr_`7?e=@ zX$?QQcb*y_1eG%*;_u2rl>p64lsqTO6&0*%Gn&zGjm1XCJ$U~(yhNQ}TF^qNRl?u? z5vz8L+7ONa00D(*LqkwWLqi~Na&Km7Y-Iodc$|HaJxIeq9K~N-rKMB^?I7Y1p*mR* z6%i+?Vi7EqwnD28CYOFelZGV4#ZhoAIQX$xb#QUk)xlK|1V2EW9Gw(hq{ROvg%&X$ z9QWhhy~o`5l3W2rF?JJVVUz5XQfhOt$XqphVtr4n(H)&5XTY{NJ4;w8p^1^ zM3h#Q6ay*RkGc24=GxZD8-o-|PxZOKQ|TPOhUXY@@u zp#K&Kt~tH6_Hp_EWT>m<8{ps&7%fuvy34x*oxS~grq$mM$4PR@@mO|P00006VoOIv z0RI600RN!9r;`8x010qNS#tmY3ljhU3ljkVnw%H_000McNliruGpcPLer^f9j}^~yJ8vG17Z>RWKzook*daHQ%FQM zfFqziqXmkMuwCx|1$+m-0bQF&a}F8{9G|fcyaTp@Q{ac4uT@8EejQ-P=(JV@l3(+c zsZF&cfC;`iPYq<%iA*bZwb7z+1DpVTbNtk}-m|(8h>fR*#4n>?glGmSfW4dgURZ4n7lG|<0q zH$|jj(#2lLR@oY80f#B#>;oUn9v@&0cyCD93$RuufrcTG=0brLXv?L6@`cP3sBk5o z#GNK~o2n47-DzUCsS1HCcbb_7BH*sVDL(*)c?52Os|pjiG9=OosOlf!0=UL~960OE z;ZNX;JuuE1ufJt9UVmQF_Xo!lM#J8+YefhQRJF?5^ziWTs4M;f XtrUxCmKiBY00000NkvXXu0mjfJx#q% literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_folder_dark.png b/ultrasonic/src/main/res/drawable-hdpi/ic_folder_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..fe3ed46caa77addad687f5634dd0e08e8e54e136 GIT binary patch literal 1959 zcmV;Y2Uz%tP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ea`iR{eb*|w1OWo1<>+^&JLvLzWc%JEH_6we zw-0S6)>x7eMwo*Dhxy0vEBuCwNpnc**@{`jl}ajHG0E|~%F$CyM}J&$E#dhMJ=_-< zBzfWVdhu7#_2q@z9@O5_L%voxUxMf^_|#zUyyxS!lA!ZRr*sJ_^PE`8{#w;`3F;T) zp~`iqyISY4pTir1!%9Q3kuXmoiRf7_4dlEl?u?!!gO5Zo7fIn*uuB*W^5*kyV~np2 z^v1}yS$MSmefD5{t`}V%Y-yK`F!^wS^not-ZTP_*E{*tM!K1(Xoah4zEp{m~fFMif88&pncU|b%w;cO*%Gh}jSeYP<@XDtx{A%$#Ev(hI zi74i~t)LfgzlItcx!r>cfY7>d)5E~GcEKNC`43zb2!Z3D5Fja6Om%3sne#bV-^eJP$)x5-PnXd8!?!i_fH@f0Ns1sK0s~kJl7Az&QrK;8U?2hJe7069V5DD$N#*bzS?Y5Y#K0y z7sQ=HCp=|@G{m}S#A0>$haQVQHTp>2hHd|jmX+f`Brlfn2>d7m=Up%$<`~G~1NvY% z+Z<_w0hdRZu{?U=WI}l|oP;ZtYMZ+2medzgcHHqR=`Jds8pGdt5pI-P(j)D3M9Bti z13Yl6Yulc?O8WAM<50)!1*Z!~p@&p)f?C#v`iOEzzQAWA#MU+nuR65iEGj(Oxh>8p zb~3FgDbhYqFVe&J)cAb-k|1DIVnbmiG`1BILeY+P+hn?{KaAlvd3O8}^dsm;(EmV? z;;*lv4jI*W&Yn@>bo>;qriy&fc%cYQ)leT4MWoZ*QDX#Z({|=r4UEV;6~geNfg0lq zIgD)4@gIuVoKP*wC*<%w_Rq=Tq9X$C-$$p~Cz9!zFCUWW{y5Z4$arS0HPlKo9r@Je zDgnPaN^@!T=Q3M(J~jTE1R)8oQBY(539w$kZD=8qGynhrg=s@WP)S2WAaHVTW@&6? z004NLeUUv#!$2IxUt6U`D~fgy>5!p1Sr8R*lqwd%LTM|s>R@u|7c^-|Qd}Gb*Mfr| zi&X~~XI&j!1wrrw#L3Y~(M3x9Us7lh ze(*o|-K|lWnskzaF`)a!vOY!u|1Qw1Th{lnWi?L#-!pKfw*A!xF#Ab*y{$!#fc|aZ z;<~L#d%)!mF#M#6x@b#2n%+VIct4|W$^k>SK+l@fTWcSu4?u>xTD}1e4uP>EWv{!u zJJ8wNzh_$g{Qy+Wa+|8O#QXpN00v@9M??Vs0RI60puMM)00009a7bBm000XU000XU z0RWnu7ytkO2XskIMF->v5(^>-E?ou^0004INkl|Sm_dNF~k@2B4RKTfy{h` z13bS&;x`%K2p=Ni@3aM$TFI|r7aR9X9v)yHdzra9ZGm=uujBOu;;uCkGPBq8#(ha- zL=0~&q0D@SLp+(#0S%iq&h=;bhOhV;5!rPIrct6xW5#%jJ#6DWevIsaIVGF*5^vjm zwFm+?bA8kF=|T!59%Fe?1^z#DVvz;9Ut}dv0wquaB~St-Py!`T0wquabN*S`DKNml zITkoazf0f`j^|k5xRDqsaDh)aHQqRI8l`iB&+UQnsPX!a>+$*vtue+7=;IeYM#T5_ tX4emnN3MrRvu^YO&Lg6)D2k$(G*>~xR1KFPvQ+>8002ovPDHLkV1hI3j#U5v literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_folder_light.png b/ultrasonic/src/main/res/drawable-hdpi/ic_folder_light.png new file mode 100644 index 0000000000000000000000000000000000000000..55b9ebf2a13bc92a4261d3c41087617520b192a8 GIT binary patch literal 1810 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 VoM>V*zWD$E002ovPDHLkV1ldfya50J literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-hdpi/ic_sd_storage_light.png b/ultrasonic/src/main/res/drawable-hdpi/ic_sd_storage_light.png new file mode 100644 index 0000000000000000000000000000000000000000..7367e397d04f4283f630f802095c4679ddb63394 GIT binary patch literal 1920 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 FV1f$Q>dgQE literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_dark.png b/ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ccf8e98767b6779f9ad7ede39edfa8df82def9be GIT binary patch literal 2153 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 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_light.png b/ultrasonic/src/main/res/drawable-ldpi/ic_create_new_folder_light.png new file mode 100644 index 0000000000000000000000000000000000000000..19678649fc00685e0f9e9c5942c56e1dc0c8fc34 GIT binary patch literal 1975 zcmV;o2T1sdP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ua^xrs{m&`(2uMOm9EZ=UxxpTPAGW)bPI@Mj zWd3Z`m@;62g?LX$c9{SESm7UBOp-!U^IUR{xKc@lD>@#}s~k1Obkyg=ZHyk};Xc3+ z30gTHtzPph~~NXYq=Q@RwDd3JJfdu?jF6!mN3 zVaj!n&Z{%`chF>o%cZ>LOfL643+qv$whOafx-PM$V zXudq^0Gn=VFtGu0IbO>shFj6MqZAa6HFi)wVvh}_Qz1BZT!9h|sBYC?;8`$F z(Vj<$f{jZ7Ai~-TV@SY2%p^*gqA?p0aC8t@S&=rNma9&deEXZOHNsH&X#wOt0tCAEt{EJvFhT< z)w7$s7q5kjAO>p5#fq0wYUNO|P=&6F`4y7JOw@= zBet5$Y&&2?9QC9-L+i6P{A}P=J1f}Jn#QzIz0d4B<+sO4;Ug_{cm{TaD5{9{@ImYv z9B(59?vnbTQgPO>_X5l^)}eftzZJtvC6(qIzKO>7o6aZV_&Cu z^(C6?Y-^~m8iuA5k#G8T_}Ys^4fN&GbCJ_S!uL<@Bi>oPDL|WUq=LU}|k|~lM{v@l8zAaxV>`{C$We78po~I)te?H=dKNPaxC=z^`75Kz|u=LN)@x|Ai0004nX+uL$ zNkc;*aB^>EX>4Tx0C=2zkv&MmKpe$iTcxE`1nnT=5TQC*5ET(8sbUcwvW#V(+gyEO`v6HZbn26Vqz*2f6o-vyd=%lbaHtmX;edj_u5w!hi{ zWT(>o854hX`2A(ug7j4N$(_1J2?`QN)IiUX*2(CH3wf1rP0A#4E zy{D4^000Sa zNLh0L01FcU01FcV0GgZ_00007bV*G`2jmD63l=Lk5QLWi00B2iL_t(Y$L-ZgN<=Xb z2H?*gzyX^EMVI0k0xs2+9zri5-oq<+0q@{K5L`>ZTL>zMy>MuIaFYjFM7v+Vtv`em z8S1b4Q=$0B3@lYf2%(K0x`lHS3}TGKg$P0jE$ra{YlU-T+~YRJ_*sXblja@{vHQo_ zBP@jwZc;|SVTwtNahhkajdN_z2xu~g^G96cA;vgq)s(cAvi@y!v4dl*R~Ht+6r(hz zg}qfQ=WkFK&$vwX8MX=}nh;bOC}dEqqIsQ;lbuU5%E;RJ->OSc$?}x_4Y)}2R!Ocp z1a0(_<1t>-dOzE1H<751)8zaGS84qOn;D5F8Ej0?oXN-iZ? zN(4iEE+|(C@A%3I-f)L~tTgN~AIaCCPQ$5#@6?>e|NVR}`~Y5YOu{(C0fPVl002ov JPDHLkV1f zaB^>EX>4U6ba`-PAZ2)IW&i+q+SONElH@21{O1&V1SBDlj>9uzZ?MPT#CBD8SI_i2 zW@Am*P#8m!DG61W|NOneU$~ephNQ)^=Nxe*PtFw$i|6IXlVUoa=a1Vvdf6ZDFBn~d zTF#%PUgInJ_34BAJndzFuj-Rc;h z6ZC@QTPr-We{VgI&-Ln;2QKr)5gNaILHf`y_htC`!g5E%FJFM<@@hNRz1Fa`=DE9? zG8oO5MIB_{7}^6HD3{~2j8bqb+T|#YVzI^!$w%z5p>%R$sImej8dPb~JnBvz5ED-> zsF^#<(PvWFxy#lm?Lv!-xC|)B(s_n0o$wtC9qanBUWe6>I0!?TFd5;K-as zR^Jp+v^!V8#oMj{V=K3x7zIISUApN(@U2|($7l8fQ-y+h&}`UXjqRMGDLvVi96Afe zDeBXOD3ozc0E)1-0t^Whh?ztwQ!LDd2s|1DszAZC9cDQ22F^DNV*&$?i1OIBLC@+!-guXBjFV7q)aips{ZQ=m!p&(Ecpt`8wtzcEJic51;fdh3$(v~$ zgT29W)~k`>vulHYt=9U?3#NupF>r>Kl>#_aoh{7@bEUMGQ%Xu7sO`kJV42B7OGqiQ zXoiu1e#>i>wrYgS&%PxbFx zG0{PzxR;)Et)2Rj@j!~vhL+utWT&CCtyC6e#En);UKvgvM+bpD=foL7XrEw4!+dES zeS|4vw%*$$cyYHfkLl{tyz2pZ+u)4tY6Y2|{u`%d@iiwr6WguZdkCau*di348E)!}FGyq@TjIG*b8Gk9(j zeHq779ex1M0V8}5$4}VN10CUeIKFO2&u}37Ma?@5t_c31ML?-98jqKx%^6LXp8xSg3puQZe*vcl9__U8u;>5)0flKp zLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ#a~;cMJtMS5b2PiI$01Eag-_+!9r;(wCZ4T z=@&FMg=CKw5p^SNYQ@G#Xn;E zljM@fRR$x+0;*6T+J5jq_}#5hn3{Bwf-#``#j-v|0sk)0tXtOiv1K(+0N*okrMCUm z1~B_cdcCbhj)4Ac;NrTiNqfNM4lw+riMnV@KAPS_0eC;7Z^{8fw?NOD(_3pFrw>4e zx>~*g4i15_B4w|;ygSg@+rMX8{rvz`&2pQnw8Z=X000JJOGiWi{{a60|De66lK=n! z32;bRa{vGf6951U69E94oEQKA00(qQO+^Rf2oeh-HFh;h0{{R3(Md!>R7l6|)iFu~ zK@`UE-&=wy3<}X!?DZn{B6gn18(7!~dIBp?;t5P+hy+>o*-Rklx-lkJ?gzt6@y+|s zH^qDOTA^4RGIM}2hAqAZlZcrA3Xqu<&TxUf7GI4=+(pD}9l)UMhq%OPhxZCqX5N-W z-ziZ?L@p;d#x;&sJg6yYx{5#J22T;uRBL`|g`JKy#7RjzUR>C=68qTwE5Mh?J)j5t zQ$T(O%rV^};1zGn-Sh zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|ecJn9lZ;-%l(zi}yw<#|t|kMb zc6!tSHeJ48?Bhn3z8=;lDaxDPgU? zA)=UXSivsdeho7=bNh)=AcWS*n;rmP%SnH{^B=e>7}Nvij0M)%E-ISRn{Ua%vtXQ} zzHA{1K28OI2y-ipAprx?NR*7CGdmG*%pj=3a+bsm43H`h7|BV*I5=a=U~YWlbc|(X z<1I#P0ud@E4sME6kd>0ce>`RQP*u^Ss-~_vXwhn7$<)l;c95$so?PABJ$vz*C8w;} zvge#ju7!&r25Pb5C6`ia!Z3D5Fja6Om%3sne#;6E$R)=Q+oJnYb6k9S!+77_BgWh3??qshY)#0;_s9uZ7YSm{;rA2Q8j$;Vnd)isy zN0MyMVHxXzXBS|i&+-q&d3jme+e*)u-UIU;2y6Hm@mq&+!6X114ohI*QT`P%%g8=z z)r>Ps02FzHpptZXTEq4TOW0h9)v0&v1M$%bZjrar@haFa)}Je4f}52zfxLdft%APh zcfX2$75ysuz9Jlyey%Hg??c+r7-_Bbwo^n-7RHPNX`b2|bM+m$5Jc0?W3SB+zPlFQ z|8_W3%!${Af03qKT`Nw>`v>w8)AmVd$i%-Q{%VRJsROaC#GPA^RSs3Mg=CKw5p^SNYQ@G z#Xn;EljM@fRR$x+0;*6T+J5jq_}#5hn3{Bwf-#``#j-v|0sk)0tXtOiv1K(+0N*ok zrMCUm1~B_cdcCbhj)4Ac;NrTiNqfNM4lw+riMnV@KAPS_0eC;7Z^{8fw?NOD(_3pF zrw>4ex>~*g4i15_B4w|;ygSg@+rMX8{rvz`&2pQnw8Z=X000JJOGiWi{{a60|De66 zlK=n!32;bRa{vGf6951U69E94oEQKA00(qQO+^Rf2oeh(GMl2NUjP6A%Sl8*R7l6| z)xAmsK@`RDU)Cr}Fr}9I4geE?H`-FM*PmgDULtAt+SOri3 z1@Hs-#QPuCeZ_Kpn$B^b$Mw;`;%~XuqU*z%Vt*iDg+)Zvinh@ghiETfv3&u}00000 LNkvXXu0mjfr`lH5 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-ldpi/ic_sd_storage_dark.png b/ultrasonic/src/main/res/drawable-ldpi/ic_sd_storage_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..c783e281f0e792ae5f650dbd6ec49d731d8d6ad1 GIT binary patch literal 1972 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 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-ldpi/ic_subdirectory_up_dark.png b/ultrasonic/src/main/res/drawable-ldpi/ic_subdirectory_up_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..58fb230dd7f1ebf09147d2ddc5ffdbe5d3de7d3f GIT binary patch literal 2376 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 O0000 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 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_folder_light.png b/ultrasonic/src/main/res/drawable-mdpi/ic_folder_light.png new file mode 100644 index 0000000000000000000000000000000000000000..0e5cacd4e2728b2bae3a13d42e8b54692f487488 GIT binary patch literal 1593 zcmV-92FCe`P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=HYZrnHwhX3mndjydbMd~=RK7ih!$KO}B$C;TV zP1*)nED#G8Wr`+gKC_%hJrji-c81M zU!aE~-$voN`q${G_*_rDJk>IvHNxP{3DPIMTw(Y=uv{7O!Y%K%@Tl$e+a;t|GfY3a->0aPlJMqW6^@F7fg1VR4@qjgMhl@?=Wo^mMSzxD- z$16m^`sn~ALTp7cBp?toiBhI$%tnMdIsjE<&XRZo0aE3TBsqy>4#s$85F7Ux?Y69( zd8x5C0fb5x1Dhfhuu@X2A4`rkR8=&oYF1MZTC`@#DQnKz^4jF8i6v9ZX69C`x_EN+ z?B?#pYvCf;1GVI0#Y-u*a;OMY;j6;FLbLHETiSHXn{B?8tu`#5mYTNQta&S~cJ9)# zP4wKYdoR5X3IjXENJB>+Hhh#(C)V1OnWoM>ZTc*;Uer#iui9@=qmvr%q?Vms)SwM! zHy5ZNH-QUXpxg(zVdam*M!avF2 zZ%<@RJ++$gn;_#In+F*_GWe`~%Tex>#(EUml1lxAs@D>3E|xyV@yF#3f6wdN(YK>- zN8gTqZCFQF{&=4ZU$W8Gsrao?`hu^~dbBV3to^r+1ius|{0qe?q#kRpf*k+=0flKp zLr_UWLm+T+Z)Rz1WdHzpoPCi!NW(xJ#a~;cMJtMS5b2PiI$01Eag-_+!9r;(wCZ4T z=@&FMg=CKw5p^SNYQ@G#Xn;E zljM@fRR$x+0;*6T+J5jq_}#5hn3{Bwf-#``#j-v|0sk)0tXtOiv1K(+0N*okrMCUm z1~B_cdcCbhj)4Ac;NrTiNqfNM4lw+riMnV@KAPS_0eC;7Z^{8fw?NOD(_3pFrw>4e zx>~*g4i15_B4w|;ygSg@+rMX8{rvz`&2pQnw8Z=X000JJOGiWi{{a60|De66lK=n! z32;bRa{vGf6951U69E94oEQKA00(qQO+^Rf2oeh(9;tfDyZ`_I?@2^KR9M69)-g)O zKokYglc08j;8!cbPW$P#bpvidT%nyJf(w}1N)fRXOF{Ym*d!3cS4R?!=v)Yd1ac2A z2|RNCdy4Lb5JG`+-n}{%W--QUa6kxQ6}y;x0Dvo;4}mCJ<;yt2_9x}d6pnEgV|?xd zSZJMZVk@D%f$!JwlNywgsynsz1Og5_C<&8DEuZ2Vr?`wU&eR`U-&a^B9!uE40oIxa zlq39k6KsqLD6lvt;7u|h12P~3GT>JMp78Pmol`u{1Kid}^^N5fZgBVBQo4>ktR${x rUoC&YMU3&j&syFGFxWbu^LO$J&dxiwpZ`e400000NkvXXu0mjfJQ?IZ literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_dark.png b/ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..2a9cbaf9f23ee2cc6734dd32896685cea9693b8f GIT binary patch literal 1656 zcmV-;28a2HP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KHmgFW3hTmC5mVhLL#B#WpbFzahKR>q1T~*yP znaWi1)aG!pkR@3k;Ht3w_2&$K;G*I=BsI?^=ZGtnRJdZ`@wm#~QcQchUwlsC{y`qD z35H0}%W-S<)US~1#{)MX)E?!*&l&d95XA@AvOKTxxDOI?KID{6LuES#xwzej+D=3L zRNO;3Yr4WZx^*8O1codPg(G3!ge0P6IU|sxR#Znz;?N@zjFWIc$8w7V33+(ETOZ?n zf*z858-?fWU!$kwb3Ntql*@eP2!k&tNT1|#x#4@qaz(_C6W(s7J|}t3;d5@s+trkj z(R{9`J=t_K1I31v%l=qKF;vCa_EJzh*4Tl3#2y<;r$P)WGf<*Il_qU_->DgTP?HzgyzXj_XOX{i9g=0A1qZ6)IH6P7p$=zCYsX6+LE2KKu^&h zTZn><(*RNg--=*JKp#}m@ zCC1qV5Gq*=Y>HICN=dPPEIHOtRnerXSxr4?(V8WvtT|`P>yWD^mP{?1nOm{y;>p#s zo4XgUg^S<})RK!8FQwGVp~6vxtqT1LN#iChHEp?B^Hy5zSUx> zdD!q#M%^fEI4QQY>6SO!d@Ea>SZh;enmY5e>9fpwQ9G%ADlbr@lN#@&mY!YIAPr_W z6SR&KUCcm?6M?ub0$9+zm_?_Qc#&JoVqt6wWdx~pRzXV#h9AIgNtd2c60uP-8^%yZwJ{sE^7m)fa4qCjoKE zj?~AfuZ0!Mg=CKw5p^SNYQ@G#Xn;EljM@fRR$x+ z0;*6T+J5jq_}#5hn3{Bwf-#``#j-v|0sk)0tXtOiv1K(+0N*okrMCUm1~B_cdcCbh zj)4Ac;NrTiNqfNM4lw+riMnV@KAPS_0eC;7Z^{8fw?NOD(_3pFrw>4ex>~*g4i15_ zB4w|;ygSg@+rMX8{rvz`&2pQnw8Z=X000JJOGiWi{{a60|De66lK=n!32;bRa{vGf z6951U69E94oEQKA00(qQO+^Rf2oeh_8H_Zn=l}o#Hc3Q5R9M69m%T~@K@^3*Gg%=~ zJ6n525IbMMN3gIkAXxYkR-(R(2>Jy26wyL^K^qalMw1+y5klB(cJiZzbDQO`d-tC2 za%Y%<{~k(Bu-yW-faRJg@4%y^x3ZT-V(|d%18tyLCk6Nf?rfh*dLI5DBouD~hrkig z8iLRWEno@Q26k<0q7FpzHgFKBE`Ux1H~}sz^jUna0u7*>)PWLm106{>z%9@pqg_=i zB#?)Btb$?;c{`Gac`d{6SL7o*5GQr7f?U9+?H_79 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_light.png b/ultrasonic/src/main/res/drawable-mdpi/ic_sd_storage_light.png new file mode 100644 index 0000000000000000000000000000000000000000..a766925fd616ce393cbe298327f126f9fb3185e8 GIT binary patch literal 1658 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 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-mdpi/ic_subdirectory_up_light.png b/ultrasonic/src/main/res/drawable-mdpi/ic_subdirectory_up_light.png new file mode 100644 index 0000000000000000000000000000000000000000..2f758b8319e95fc96fd7c57edc402536f94628e2 GIT binary patch literal 1763 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 SD-&=40000 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 WbfWDP)CVbdYtZ0C%4Oc2i{D1J{E`pq?`Gb$34- z@iOBtQZrKmsH{0wh2JBtQZrKmsH{0wh2J zBtQZrKmsH{0wh2JBtQZrpm=_wk-30&G{&7a@Et)q* zR{z}0Vt2r(+vG0kZdN)1mI$HjV d2q8p#{s5Ucf~$*i05$*s002ovPDHLkV1n;PX>R}k literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xhdpi/ic_sd_storage_light.png b/ultrasonic/src/main/res/drawable-xhdpi/ic_sd_storage_light.png new file mode 100644 index 0000000000000000000000000000000000000000..ddf6a4c42efe08d45971fdd4f7e11efbbe6737cf GIT binary patch literal 1835 zcmV+`2h{k9P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KZlH)iChX3mndjtbQpyTMXYHzT|-&c<9PSQQw znVzZHKW&vQ1<8PUu!zI>=kFQ*!oeGJh-#j4N*j)tW9EW^Z?_}wSK8u!-H&)o;rD|) zToVkDpqJZEE64f*xxU?S+MxO<4}Q$BAByNwydSbGuW`S35^}!D>F^}vaT}!UcJFFE z6t&Z3e>>yl*73Ob9UcURD0PJ)VID%V;mUG&Ah)yNbX-Xs>qrD+ksNl>=?Mbz@OWpx zZTA6s2=X}!&(Xg|Pr>JM$mJ=P>4*^qA5M@y$>lP`_lD*2h#x1)JXO69@|@l09Ji+{ zF(IPq$f!NobgIF^ijd2GTS7COim~l2qxn|02IPHfTSaS>i9uxsiqxslq_Ovn8eEJ# z*jD0mW7%ac#+jQePH{DwY?7seAWP#BfG!GOzR+$r@AeuwEO)|ECMYA^^1~MXYw~AW zn6s@A(dJjI;1{pFh8v6Ax?&Z8&^);59^kVb__w?KL8^kF?qPO3VA<+TMOAvsE!jB> z)+zeiD@4Kip#UL*ZG|%=Ah0D8r9_)C8xi8@094>POXLayq{;==9aCv zcy#sT=I+@`<}BC)HK%OZbIzr3C@@r@t6+VBq;i!StJYMldd;;oq)&@YTWZ$4DVTE>ejvIUIvAMonpkHBMloq@+cFzHf6@CGfkU5^DGy&gX+8X6V&LS#yhFC&Ms<@ z2D4KIt?fh?GZ5oQAa08Q5}FsY%_&A+0$P z{UvVv8M&~~{SI;g=-zYtfLdR5uIEX>4Tx0C=2zkv&MmKpe$iTct%Sigpm`kfAzR5EXHhDi*;)X)Cnq zU~=gfG-*guTpR`0f`cE6RRFSdL}hb93mEq9V~S)E9naH zG;u^$RLb{e9hNz7aaJld*19KuVKA?*q`6Krj5wB%KoSBZ)KEqRCZe>eq!>uie$2%` zV*8WilE_sCBgX=&P$1fV@IUz7tx=eobdrKGp!>zLK1KomF3_x7*7vbxHBSKFGjOH0 z{nZ9A`$>AetwoN2{%zpmx~)ljz~v4w{G^GxXiGkt-a-L*KcjET0YkSy&zjR)Yagc% zK!&y{D4^ z000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jmD63nvfFPG|H000FB>L_t(|+U=Xa zO2a@L$3G2G(8WQW+;nm3a`*y5Cqcv~@Ev>(adPk#>NAL|gFl2$qFVg$z$$RyoU50@0Yf9d7dY0pz=@f43v)n{`N7DC z)*7%p?#Xe$%zpyy5luEd)ep3glwttZyLXPjPSn1!g{zqAAFHCdD~s zer6mHVx2Fa1FD*NFAk`3<}*8>>Y4Z9fJ$e6Vh2o1<|lp`a?Y&-hZ!c$P+Q>$I5M*v z-*doxQhp``usGsjebyJZ6P&qaPyhr#00ck)1V8`;KmY_l00ck)1V8`;KmY_l00ck) z1V8`;KmY_l00dx~0rc_zt$!Z+0>1MA&`nC&)df0v0C)l(DgfXfc=is!%szk%pjYC~ zcYt#<8`}YCzxTOJj{Cq;iROeF@Cuv(*J&H3mUC_e*a9|yxq>_2HjRk|aqQ ZU%x+!X66w{DHH$z002ovPDHLkV1kWnRLcMW literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_dark.png b/ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..ad0bb6fe3318890ef80aa32ddbad92b25cc4b156 GIT binary patch literal 2233 zcmV;q2uAmbP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|clI$i7{bvzz@@{h5 z?g4rL`PK{1=wH1j@VTCPdBRdpjL`XTfYOs*u4(vwV!0yX$AO$Sd$*kPp40Q3<5*pd z3PknHs2yy&xq)E=-<6U}Xl1#`UZ?y`7_tI=eWA`S*wI*$PQqVN?9?ems>zD^l4JHeC*&Iq4;+QL_Z-)Uja zz96D4Usxe7UU`i$7IW(fD-c5SCGz0mlr2Dk5iz+`s^(#Eu|2iYNzTY#GdrZ;W>PFCNwZ?HxuYrHeH?CfF< z+F*8bL93jk#TgjmNMPI+14w9IoNbw6Td;@3f$CZna=B981-M|Bx4 zP4F#@#G4??bFFTsZEA7&8SbqNFUY4RF;PtGH_au(v*M@n$VZ_ObBZ7-wa{nQ~-x+30a4pULq0zRcUu1FER%&1=!SO%%Q=TR7fjMZV4-$$ONa z=70F!j{5EBWr=?adKNz<=_=!^9(|zwMERBf@QYUV+tL5j(ZmTEX>4Tx0C=2zkv&MmKpe$iTct%Sigpm`kfAzR5EXHhDi*;) zX)CnqU~=gfG-*guTpR`0f`cE6RRFSdL}hb93mEq9V~S) zE9naHG;u^$RLb{e9hNz7aaJld*19KuVKA?*q`6Krj5wB%KoSBZ)KEqRCZe>eq!>ui ze$2%`V*8WilE_sCBgX=&P$1fV@IUz7tx=eobdrKGp!>zLK1KomF3_x7*7vbxHBSKF zGjOH0{nZ9A`$>AetwoN2{%zpmx~)ljz~v4w{G^GxXiGkt-a-L*KcjET0YkSy&zjR) zYagc%K!& zy{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jmD63obV_j$|VM00J>dL_t(| z+U=RWY7|izhM#ZP#>T=Q^bTzO4Jf3t@KU@8-AJ;Cpp7XMwU13;Q^+C#JF93E%b-^v z5`xJx(ZakI9$^_~vNL9Wj@j>lsm|=o`JV4*c6PyW9LI4S$8j9TsTWD}lCI8b@N<&Z zC5o5xOoq&Z*! zoSt&(*H8(cVi1tjnE3&4ro`#zf%~z{1Z%M8rxC?Wu!eiSjD${Sg0;}|#5@y{273N` zII`>k>j}m-F!pn)7VBua1;ognX zE4j&SNlW1=@b0LY&yyf&2%G>e0ZV4K)5Z|&RoLW?q{Z<4 zxX~ArKkd+3@U{IO@IT`MT!0I30WQD=xBwU60$hL#m`!>u-s_sA&6bjS+sxj31-Jkg z(Af;I4&^3P_}AN-*ny-Az{!pT7_en#yEu;HIF92uP9eVmRQT!n6-B!f00000NkvXX Hu0mjfU4b0b literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_light.png b/ultrasonic/src/main/res/drawable-xhdpi/ic_subdirectory_up_light.png new file mode 100644 index 0000000000000000000000000000000000000000..94e65383f37c89004fc466604eb1764b6f08c15f GIT binary patch literal 1990 zcmV;%2RZnOP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U-|aawI7X{pS>O1SBB@$6<|_8}#w#k(+Dr*e-WZ z#C$l3M3f*U@t#m-x$*1o>HfmSKC%mHDdreGu8>3KfD@KK zPzj{$Kdl_=3-tQ-!0ChPz22o`hSOn)F2ma;%kvud+aRImT~9|OE{}Z>bF$k|>tU#! zA*Z)HTwxvC#cy|~Frd^Gj)Zv#iAT?JL?HWJa3}O63F}A%;~>F7sGM5@Aa~n4rT4c0 z-GO|L+#~we=mC5#hh84Aj0Z*-ygNbqpqI-H-#V5nBEFyKcA9zydCs2Z9Q*D{h(I(R z8MT2;rx`4)fLyl6BHA*l7~9q|TJps=P~Ls>6|GSw1}oE1piYG*jZHRc2r=+rgJfZ1iDKX;O95FSDDuZbLJk!b4XPT|G&#*$qQnq2#%OUBxng3$)S{Us%T|)4kTk_) zDW#lB<}9dznq#({a?Yi&D{xd`t6+VBrgD`Us@7PorkZPMNS_v(w%DwtmRsrErK3#r z*sZ6Ydl}>gD#ZvxM;tcN$fHc;+LRfl&NywRnP<6JJ6L^cFR(@jYrHYF*4f1xw9f1_ zL93kT;tY&&ATVx=0VFgp&U~T}crmv)^O2!nmV2L0 zqRHq1m276Ib;LHT7i1L*9amg~b4+-NQLWSq3UXXV%KCn}mF`jTU3qH=B6_^8%v#TF zt~wo7s*ahfd)gk3>c9$Mqy;BB#nCLnntm59_X3_Dz`3*b!T!IFxBDKx&v3fW z@C zD&4CO{22N%^ke9MWXLAIgYbXc{R74brloHQ+&=&S0flKpLr_UWLm+T+Z)Rz1WdHzp zoPCi!NW(xJ#a~;cMJtMS5b2PiI$01Eag-_+!9r;(wCZ4T=@&FMg=CKw5p^SNYQ@G#Xn;EljM@fRR$x+0;*6T+J5jq z_}#5hn3{Bwf-#``#j-v|0sk)0tXtOiv1K(+0N*okrMCUm1~B_cdcCbhj)4Ac;NrTi zNqfNM4lw+riMnV@KAPS_0eC;7Z^{8fw?NOD(_3pFrw>4ex>~*g4i15_B4w|;ygSg@ z+rMX8{rvz`&2pQnw8Z=X000JJOGiWi{{a60|De66lK=n!32;bRa{vGf6951U69E94 zoEQKA00(qQO+^Rf2oeh{HwL%{p#T5^BuPX;RCwC$mO*P1K@`V-=|riDt%|3)S6d79 z@W5}QSoQ1p0lc)(gD6^P#hZe~Lg~Q=)=RyK^{}UUP;9J9;$?(o*<_R0*&UkqJ7zXJ z^M3RGF9E|a48t%C!!V2q#KnBMh%9;UFJ)PFIB^0*WC6Gf-1Odm&a&+5#0U_PrBM6~ za2{Cj-hWB46I_Ji7jwn`;~a1!bi(1O6_C66izUm`z@qp5ASDSdLgr@%JT?u?r!*5> zgv?iw)J$-ZGG9e9Gr>j7d=*K|1Q$8;!$@d!Cb$Th{{j34&K5rJ0DpipDa{0T!kIq; zo`8(o|CS?+qMPx210paHF^=bQ`z!P9sReM$MQq?Z79isB9!_9Zc z-8|O`FG?irhtHc8psL@172pHV%4L50e~K?ic%7RGt+3Zh*t_{57!I-qyw7F6ds2re z%!EB)t&ZYH`WaN!@4)J~nIB;$tcJa6p*`XuJ24LvBpfCCPw+Hi0!)AjFaajO1egF5 zU;<2l37AaUHSRSpB9Cgi)Q772(K^5cn1IG+K&wHytrP@211>apu?HB2VHk#C7{);U Y0@_67D>?9;&j0`b07*qoM6N<$f<=X$_W%F@ literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_dark.png b/ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..a7a92c6c3dffb29f9a51e47284dec7d3fbdd550a GIT binary patch literal 2011 zcmV<12PF83P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+TE5}lH@83MgLhvF9Au2VL6x~qId9?|1KE2a_p+C ztdEX1Vapb>5IO?ewEup0^9u)C_Qq+5K6!6(xa1ON+(f${X6zVYaT7&RNRNz5?Zv`79g*-*bS{vA_kRi$Wf(Co!XRz3PN<;I6yKN zmZ^&pIB}7|$&E&xgCwaS$Wpi&Fmu9ZEHuYWbG$+kBUgec6PyuVdD_gMI$vp~_cBsM zHlDdcTs-O;VGMHP3M&AizPRa3@X;22dr?0qRS?vf=7Dz`wY#-n`~~=&2M3gTiS9#`4m^Q_!3GispQI4 zDz=I0YpAiNnj4vhouav>&9~5EOD%WQT9@v+cHcvfJ@tH2TU77b3)E;)<4J1Rg_9bz zCWONUjqOASGZ14(ARYz*6f_TJHj;BZ$PH#TF&2d~g4DsrR2sy9&^2Q1bh7&(_a$yd zp{(A{%;K&_7NT$#l7RXB2L1*;D>nWMpJEiUiMf60-IkF}EX91H#d zuxBgXX?NvIuFdHQJ;ob||!-7EXT)6w;MDP2r$RDj>T zz7)$If_Wzv8B1!fKuk@Z;F!y9uL2A-R9D$OkUW^$_h{WwvuD}8nw?#mcSv1k%e+JC z5|nv2mP49P4W9>cCC&F3{gk6)+evdroKEX>4Tx0C=2zkv&MmKpe$iTcxE`1nnT=5TQC*5ET(8 zsbUcwvW#V(+gyEO`v6HZbn26Vqz*2f6o-vyd=%lbaH ztmX;edj_u5w!hi{WT(>o854hX`2A(ug7j4N$(_1J2?`QN)IiUX* z2(CH3wf1rP0A#4Ey{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2jmD63m7Ocn)sst00JLL zL_t(|+U?x2Y7{{nfbs8th9FuP40s?mf*@GiMU9{c7QR4y0c|8*dOI5t8~YT#f{;Q5 zlP*{aVqv8cP>`S?VjPRxq)cWno11m+`#}hVP1u_+Gq<}T1Ck_3k|arzB&l}M=HQgl z0Js2L0~UZGaOQ~5@hR{;BL37EV5Y_3p8%GD8^GM|mnU$J_nObEQ#%8i!G8!`FLNjo=HoPQ z7g$Lt9XCKZcYymTr7%D_w}JBpC}+O8hcZAxR}4`0jrptr${HG=f=3ZDK)q&ae}NHk zdEa-+!jD><0WLuXkO2%J0~kOCFn|nT08P+;_blk3XFEsz^SXX^u~=jECU!o1~7mOU;r7w05X69w5R(259s?=3(f!o7(hJ_u;Va|?Q0hSwj9T? z1n{Mc0PD2eVOM)Lx(Kia{B$f^`_5MPkASyE$R7OH zz>|phn{#mP9pxOb!f4m@lk{^d%hChC4ZH##N5qfZZ)$T}KMPy}ZZX=7Xb2pe@`2w0 tJ~iw88t}f>t@b5Jk|arzBuUbE{sE4?b(`6Vt9$?e002ovPDHLkV1iU;nUMeh literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_light.png b/ultrasonic/src/main/res/drawable-xxhdpi/ic_create_new_folder_light.png new file mode 100644 index 0000000000000000000000000000000000000000..38ae0196e007d4860de9798d20a63cfc7f69aad0 GIT binary patch literal 1836 zcmV+{2h;e8P) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KHlI$i7hTmC5mVhLL#Bwm0s_Y=k&kv?O-F+@O zr;?XcH53;MEXn!=JrmBq{v6>C6e^iRQuADLjwq?5!W9#bS1GHfm{z|^-b;9Xk%xPM zArg#oJzCxSE9Cn1!ovm~ukzq~g?%fcTk$F~Ezfy>b`o;FnDKJPKc_#B{@ zAU|f|J^J_TE%;owT;5{2X$4HayFmITm)i_K8olkt-Y+Ad5Up2 z0R#?^7}yl4fR&OWe=Iq2sH$jE)vTr-v}nzeQ`Vfb<$1|f6HBI+&CIP>b@Alt+0EUH z*TO|`2WrX1ikDJqU*g99 zL@rEp{{^`Kbl-CO4z)gi=h`B6ox&N@C^&sXxUvVd7}5RP@uTRY=%eVP=%eVP=%eWW zuSf>|c)≶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 literal 0 HcmV?d00001 diff --git a/ultrasonic/src/main/res/drawable-xxhdpi/ic_subdirectory_up_dark.png b/ultrasonic/src/main/res/drawable-xxhdpi/ic_subdirectory_up_dark.png new file mode 100644 index 0000000000000000000000000000000000000000..dec22e7c16aff8176e112fcffe5f8a5e34071a3b GIT binary patch literal 1957 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 + + + + + + + + \ No newline at end of file diff --git a/ultrasonic/src/main/res/layout/filepicker_dialog_main.xml b/ultrasonic/src/main/res/layout/filepicker_dialog_main.xml new file mode 100644 index 00000000..aed2057e --- /dev/null +++ b/ultrasonic/src/main/res/layout/filepicker_dialog_main.xml @@ -0,0 +1,43 @@ + + + + + + + +