From 0bfb952365b1a96b7667314159f55e004fe4f725 Mon Sep 17 00:00:00 2001 From: Hardcore Sushi Date: Wed, 5 Aug 2020 14:06:54 +0200 Subject: [PATCH] Take Photo feature --- app/build.gradle | 23 +-- app/src/main/AndroidManifest.xml | 33 +++-- .../sushi/hardcore/droidfs/CameraActivity.kt | 89 ++++++++++++ .../adapters/ExplorerElementAdapter.kt | 11 -- .../droidfs/adapters/IconTextDialogAdapter.kt | 32 +++++ .../droidfs/adapters/OpenAsDialogAdapter.kt | 36 ++--- .../droidfs/adapters/SavedVolumesAdapter.kt | 65 +++++---- .../droidfs/explorers/BaseExplorerActivity.kt | 30 ++-- .../droidfs/explorers/ExplorerActivity.kt | 136 ++++++++++-------- .../droidfs/explorers/ExplorerActivityDrop.kt | 5 + .../droidfs/explorers/ExplorerElement.kt | 9 +- .../droidfs/file_viewers/ImageViewer.kt | 21 +-- .../provider/RestrictedFileProvider.kt | 13 +- .../hardcore/droidfs/util/GocryptfsVolume.kt | 2 +- .../sushi/hardcore/droidfs/util/MiscUtils.kt | 18 +++ .../droidfs/widgets/ColoredBorderListView.kt | 9 +- .../hardcore/droidfs/widgets/ColoredButton.kt | 18 --- .../droidfs/widgets/ColoredCheckBox.kt | 9 +- .../droidfs/widgets/ColoredEditText.kt | 9 +- .../hardcore/droidfs/widgets/ColoredFAB.kt | 17 ++- .../hardcore/droidfs/widgets/ColoredFAM.kt | 19 --- .../droidfs/widgets/ColoredImageButton.kt | 9 +- .../droidfs/widgets/ColoredImageView.kt | 9 +- .../droidfs/widgets/ColoredSeekBar.kt | 21 --- .../NonScrollableColoredBorderListView.kt | 21 +-- .../droidfs/widgets/TakePhotoButton.kt | 27 ++++ .../main/res/drawable/button_background.xml | 9 ++ .../res/drawable/fab_label_background.xml | 11 -- app/src/main/res/drawable/icon_camera.xml | 6 + .../main/res/drawable/icon_camera_back.xml | 9 ++ .../main/res/drawable/icon_camera_front.xml | 9 ++ app/src/main/res/drawable/icon_encrypt.xml | 9 +- app/src/main/res/drawable/icon_flash_auto.xml | 5 + app/src/main/res/drawable/icon_flash_off.xml | 5 + app/src/main/res/drawable/icon_flash_on.xml | 5 + .../main/res/drawable/take_photo_button.xml | 17 +++ app/src/main/res/layout/activity_camera.xml | 52 +++++++ .../res/layout/activity_change_password.xml | 10 +- app/src/main/res/layout/activity_create.xml | 8 +- app/src/main/res/layout/activity_explorer.xml | 46 +----- .../res/layout/activity_explorer_drop.xml | 18 +-- app/src/main/res/layout/activity_main.xml | 6 +- app/src/main/res/layout/activity_open.xml | 6 +- .../res/layout/adapter_dialog_icon_text.xml | 3 +- app/src/main/res/layout/explorer_info_bar.xml | 5 +- app/src/main/res/values/dimens.xml | 8 +- app/src/main/res/values/strings.xml | 13 +- app/src/main/res/values/styles.xml | 7 +- 48 files changed, 564 insertions(+), 394 deletions(-) create mode 100644 app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt create mode 100644 app/src/main/java/sushi/hardcore/droidfs/adapters/IconTextDialogAdapter.kt create mode 100644 app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt delete mode 100644 app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredButton.kt delete mode 100644 app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAM.kt delete mode 100644 app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredSeekBar.kt create mode 100644 app/src/main/java/sushi/hardcore/droidfs/widgets/TakePhotoButton.kt create mode 100644 app/src/main/res/drawable/button_background.xml delete mode 100644 app/src/main/res/drawable/fab_label_background.xml create mode 100644 app/src/main/res/drawable/icon_camera.xml create mode 100644 app/src/main/res/drawable/icon_camera_back.xml create mode 100644 app/src/main/res/drawable/icon_camera_front.xml create mode 100644 app/src/main/res/drawable/icon_flash_auto.xml create mode 100644 app/src/main/res/drawable/icon_flash_off.xml create mode 100644 app/src/main/res/drawable/icon_flash_on.xml create mode 100644 app/src/main/res/drawable/take_photo_button.xml create mode 100644 app/src/main/res/layout/activity_camera.xml diff --git a/app/build.gradle b/app/build.gradle index 5f72869..a6ea886 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -15,7 +15,7 @@ android { minSdkVersion 21 targetSdkVersion 29 versionCode 1 - versionName "1.1.2" + versionName "1.1.3" ndk { abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a' @@ -40,15 +40,16 @@ android { dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'androidx.core:core-ktx:1.3.1' - implementation 'androidx.appcompat:appcompat:1.1.0' - testImplementation 'junit:junit:4.12' + implementation "androidx.core:core-ktx:1.3.1" + implementation "androidx.appcompat:appcompat:1.1.0" + implementation "androidx.constraintlayout:constraintlayout:1.1.3" - implementation 'androidx.sqlite:sqlite:2.1.0' - implementation 'androidx.preference:preference:1.1.1' - implementation 'com.github.clans:fab:1.6.4' - implementation 'com.jaredrummler:cyanea:1.0.2' - implementation 'com.github.bumptech.glide:glide:4.11.0' - implementation 'com.google.android.exoplayer:exoplayer-core:2.11.7' - implementation 'com.google.android.exoplayer:exoplayer-ui:2.11.7' + implementation "androidx.sqlite:sqlite:2.1.0" + implementation "androidx.preference:preference:1.1.1" + implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0" + implementation "com.jaredrummler:cyanea:1.0.2" + implementation "com.github.bumptech.glide:glide:4.11.0" + implementation "com.google.android.exoplayer:exoplayer-core:2.11.7" + implementation "com.google.android.exoplayer:exoplayer-ui:2.11.7" + implementation "com.otaliastudios:cameraview:2.6.3" } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b056198..324019b 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,25 +4,27 @@ + android:protectionLevel="signature" /> + + android:theme="@style/AppTheme"> + + android:parentActivityName=".MainActivity" /> @@ -34,7 +36,9 @@ + + @@ -52,19 +56,28 @@ android:screenOrientation="nosensor"> + - - - - + + + + + android:writePermission="${applicationId}.WRITE_TEMPORARY_STORAGE" /> - + \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt new file mode 100644 index 0000000..16fe204 --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt @@ -0,0 +1,89 @@ +package sushi.hardcore.droidfs + +import androidx.appcompat.app.AppCompatActivity +import android.os.Bundle +import android.view.View +import android.widget.Toast +import com.otaliastudios.cameraview.CameraListener +import com.otaliastudios.cameraview.PictureResult +import com.otaliastudios.cameraview.controls.Facing +import com.otaliastudios.cameraview.controls.Flash +import kotlinx.android.synthetic.main.activity_camera.* +import sushi.hardcore.droidfs.util.GocryptfsVolume +import sushi.hardcore.droidfs.util.MiscUtils +import sushi.hardcore.droidfs.util.PathUtils +import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder +import java.io.ByteArrayInputStream +import java.io.FileOutputStream +import java.io.InputStream +import java.text.SimpleDateFormat +import java.util.* + +class CameraActivity : AppCompatActivity() { + companion object { + private val flashModes = listOf(Flash.AUTO, Flash.ON, Flash.OFF) + private const val fileNameRandomMin = 100000 + private const val fileNameRandomMax = 999999 + private val dateFormat = SimpleDateFormat("yyyyMMdd_HHmmss") + private val random = Random() + } + private var currentFlashModeIndex = 0 + private lateinit var gocryptfsVolume: GocryptfsVolume + private lateinit var outputDirectory: String + private lateinit var fileName: String + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_camera) + gocryptfsVolume = GocryptfsVolume(intent.getIntExtra("sessionID", -1)) + outputDirectory = intent.getStringExtra("path")!! + camera.setLifecycleOwner(this) + camera.addCameraListener(object: CameraListener(){ + override fun onPictureTaken(result: PictureResult) { + take_photo_button.onPhotoTaken() + val inputStream = ByteArrayInputStream(result.data) + if (gocryptfsVolume.importFile(inputStream, PathUtils.path_join(outputDirectory, fileName))){ + Toast.makeText(applicationContext, getString(R.string.picture_save_success, fileName), Toast.LENGTH_SHORT).show() + } else { + ColoredAlertDialogBuilder(applicationContext) + .setTitle(R.string.error) + .setMessage(R.string.picture_save_failed) + .setCancelable(false) + .setPositiveButton(R.string.ok) { _, _ -> finish() } + .show() + } + } + }) + take_photo_button.onClick = ::onClickTakePhoto + } + + private fun onClickTakePhoto() { + val baseName = "IMG_"+dateFormat.format(Date())+"_" + do { + fileName = baseName+(random.nextInt(fileNameRandomMax-fileNameRandomMin)+fileNameRandomMin)+".jpg" + } while (gocryptfsVolume.pathExists(fileName)) + camera.takePicture() + } + + fun onClickFlash(view: View) { + currentFlashModeIndex = MiscUtils.incrementIndex(currentFlashModeIndex, flashModes) + camera.flash = flashModes[currentFlashModeIndex] + image_flash.setImageResource(when (camera.flash) { + Flash.AUTO -> R.drawable.icon_flash_auto + Flash.ON -> R.drawable.icon_flash_on + else -> R.drawable.icon_flash_off + }) + } + + fun onClickCameraSwitch(view: View) { + camera.toggleFacing() + if (camera.facing == Facing.FRONT){ + image_camera_switch.setImageResource(R.drawable.icon_camera_back) + } else { + image_camera_switch.setImageResource(R.drawable.icon_camera_front) + Thread { + Thread.sleep(25) + camera.flash = flashModes[currentFlashModeIndex] //refresh flash mode after switching camera + }.start() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt b/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt index 9bfcb6b..cfff818 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/adapters/ExplorerElementAdapter.kt @@ -113,15 +113,4 @@ class ExplorerElementAdapter(private val context: Context) : BaseAdapter() { unSelectAll() this.explorerElements = explorer_elements } - - val currentDirectoryTotalSize: Long - get() { - var totalSize: Long = 0 - for (e in explorerElements) { - if (e.isRegularFile) { - totalSize += e.size - } - } - return totalSize - } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/adapters/IconTextDialogAdapter.kt b/app/src/main/java/sushi/hardcore/droidfs/adapters/IconTextDialogAdapter.kt new file mode 100644 index 0000000..1f60a17 --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/adapters/IconTextDialogAdapter.kt @@ -0,0 +1,32 @@ +package sushi.hardcore.droidfs.adapters + +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import android.widget.TextView +import sushi.hardcore.droidfs.R +import sushi.hardcore.droidfs.widgets.ColoredImageView + +open class IconTextDialogAdapter(private val context: Context): BaseAdapter() { + private val inflater: LayoutInflater = LayoutInflater.from(context) + lateinit var items: List> + + override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { + val view: View = convertView ?: inflater.inflate(R.layout.adapter_dialog_icon_text, parent, false) + val text = view.findViewById(R.id.text) + text.text = context.getString(items[position][1] as Int) + val icon = view.findViewById(R.id.icon) + icon.setImageDrawable(context.getDrawable(items[position][2] as Int)) + return view + } + + override fun getItem(position: Int): Any { + return items[position][0] as String + } + + override fun getItemId(position: Int): Long { return 0 } + + override fun getCount(): Int { return items.size } +} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/adapters/OpenAsDialogAdapter.kt b/app/src/main/java/sushi/hardcore/droidfs/adapters/OpenAsDialogAdapter.kt index 10859ed..a72cb88 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/adapters/OpenAsDialogAdapter.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/adapters/OpenAsDialogAdapter.kt @@ -1,36 +1,24 @@ package sushi.hardcore.droidfs.adapters import android.content.Context -import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.BaseAdapter +import android.widget.LinearLayout import android.widget.TextView +import androidx.appcompat.widget.LinearLayoutCompat +import androidx.core.view.marginEnd +import androidx.core.view.setPadding import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.widgets.ColoredImageView -class OpenAsDialogAdapter(private val context: Context): BaseAdapter() { - private val inflater: LayoutInflater = LayoutInflater.from(context) - private val items = listOf( - listOf("image", context.getString(R.string.image), R.drawable.icon_file_image), - listOf("video", context.getString(R.string.video), R.drawable.icon_file_video), - listOf("audio", context.getString(R.string.audio), R.drawable.icon_file_audio), - listOf("text", context.getString(R.string.text), R.drawable.icon_file_text) +class OpenAsDialogAdapter(context: Context) : IconTextDialogAdapter(context) { + private val openAsItems = listOf( + listOf("image", R.string.image, R.drawable.icon_file_image), + listOf("video", R.string.video, R.drawable.icon_file_video), + listOf("audio", R.string.audio, R.drawable.icon_file_audio), + listOf("text", R.string.text, R.drawable.icon_file_text) ) - override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { - val view: View = convertView ?: inflater.inflate(R.layout.adapter_dialog_icon_text, parent, false) - val text = view.findViewById(R.id.text) - text.text = items[position][1] as String - val icon = view.findViewById(R.id.icon) - icon.setImageDrawable(context.getDrawable(items[position][2] as Int)) - return view + init { + items = openAsItems } - - override fun getItem(position: Int): String { - return items[position][0] as String - } - - override fun getItemId(position: Int): Long { return 0 } - - override fun getCount(): Int { return items.size } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/adapters/SavedVolumesAdapter.kt b/app/src/main/java/sushi/hardcore/droidfs/adapters/SavedVolumesAdapter.kt index 733425f..8e7cde2 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/adapters/SavedVolumesAdapter.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/adapters/SavedVolumesAdapter.kt @@ -13,33 +13,35 @@ import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.util.WidgetUtil import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder +import sushi.hardcore.droidfs.widgets.NonScrollableColoredBorderListView import java.util.* -class SavedVolumesAdapter(val context: Context, val shared_prefs: SharedPreferences) : BaseAdapter() { +class SavedVolumesAdapter(val context: Context, private val sharedPrefs: SharedPreferences) : BaseAdapter() { private val inflater: LayoutInflater = LayoutInflater.from(context) - private val saved_volumes_paths: MutableList = ArrayList() - private val shared_prefs_editor: Editor = shared_prefs.edit() + private lateinit var nonScrollableColoredBorderListView: NonScrollableColoredBorderListView + private val savedVolumesPaths: MutableList = ArrayList() + private val sharedPrefsEditor: Editor = sharedPrefs.edit() init { - val saved_volumes_paths_set = shared_prefs.getStringSet(ConstValues.saved_volumes_key, HashSet()) as Set - for (volume_path in saved_volumes_paths_set) { - saved_volumes_paths.add(volume_path) + val savedVolumesPathsSet = sharedPrefs.getStringSet(ConstValues.saved_volumes_key, HashSet()) as Set + for (volume_path in savedVolumesPathsSet) { + savedVolumesPaths.add(volume_path) } } - private fun update_shared_prefs() { - val saved_volumes_paths_set = saved_volumes_paths.toSet() - shared_prefs_editor.remove(ConstValues.saved_volumes_key) - shared_prefs_editor.putStringSet(ConstValues.saved_volumes_key, saved_volumes_paths_set) - shared_prefs_editor.apply() + private fun updateSharedPrefs() { + val savedVolumesPathsSet = savedVolumesPaths.toSet() + sharedPrefsEditor.remove(ConstValues.saved_volumes_key) + sharedPrefsEditor.putStringSet(ConstValues.saved_volumes_key, savedVolumesPathsSet) + sharedPrefsEditor.apply() } override fun getCount(): Int { - return saved_volumes_paths.size + return savedVolumesPaths.size } override fun getItem(position: Int): String { - return saved_volumes_paths[position] + return savedVolumesPaths[position] } override fun getItemId(position: Int): Long { @@ -47,32 +49,35 @@ class SavedVolumesAdapter(val context: Context, val shared_prefs: SharedPreferen } override fun getView(position: Int, convertView: View?, parent: ViewGroup): View { + if (!::nonScrollableColoredBorderListView.isInitialized){ + nonScrollableColoredBorderListView = parent as NonScrollableColoredBorderListView + } val view: View = convertView ?: inflater.inflate(R.layout.adapter_saved_volume, parent, false) - val volume_name_textview = view.findViewById(R.id.volume_name_textview) + val volumeNameTextview = view.findViewById(R.id.volume_name_textview) val currentVolume = getItem(position) - volume_name_textview.text = currentVolume - val delete_imageview = view.findViewById(R.id.delete_imageview) - delete_imageview.setOnClickListener { - val volume_path = saved_volumes_paths[position] + volumeNameTextview.text = currentVolume + val deleteImageview = view.findViewById(R.id.delete_imageview) + deleteImageview.setOnClickListener { + val volumePath = savedVolumesPaths[position] val dialog = ColoredAlertDialogBuilder(context) dialog.setTitle(R.string.warning) - if (shared_prefs.getString(volume_path, null) != null){ + if (sharedPrefs.getString(volumePath, null) != null){ dialog.setMessage(context.getString(R.string.delete_hash_or_all)) dialog.setPositiveButton(context.getString(R.string.delete_all)) { _, _ -> - saved_volumes_paths.removeAt(position) - shared_prefs_editor.remove(volume_path) - update_shared_prefs() + savedVolumesPaths.removeAt(position) + sharedPrefsEditor.remove(volumePath) + updateSharedPrefs() refresh(parent) } dialog.setNegativeButton(context.getString(R.string.delete_hash)) { _, _ -> - shared_prefs_editor.remove(volume_path) - shared_prefs_editor.apply() + sharedPrefsEditor.remove(volumePath) + sharedPrefsEditor.apply() } } else { dialog.setMessage(context.getString(R.string.ask_delete_volume_path)) dialog.setPositiveButton(R.string.ok) {_, _ -> - saved_volumes_paths.removeAt(position) - update_shared_prefs() + savedVolumesPaths.removeAt(position) + updateSharedPrefs() refresh(parent) } dialog.setNegativeButton(R.string.cancel, null) @@ -86,13 +91,15 @@ class SavedVolumesAdapter(val context: Context, val shared_prefs: SharedPreferen notifyDataSetChanged() if (count == 0){ WidgetUtil.hide(parent) + } else { + nonScrollableColoredBorderListView.layoutParams.height = nonScrollableColoredBorderListView.computeHeight() } } fun addVolumePath(volume_path: String) { - if (!saved_volumes_paths.contains(volume_path)) { - saved_volumes_paths.add(volume_path) - update_shared_prefs() + if (!savedVolumesPaths.contains(volume_path)) { + savedVolumesPaths.add(volume_path) + updateSharedPrefs() } } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt index bcdb636..7c97caf 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/BaseExplorerActivity.kt @@ -23,16 +23,16 @@ import sushi.hardcore.droidfs.ConstValues.Companion.isText import sushi.hardcore.droidfs.ConstValues.Companion.isVideo import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter -import sushi.hardcore.droidfs.adapters.OpenAsDialogAdapter import sushi.hardcore.droidfs.adapters.ExplorerElementAdapter +import sushi.hardcore.droidfs.adapters.OpenAsDialogAdapter import sushi.hardcore.droidfs.file_viewers.AudioPlayer import sushi.hardcore.droidfs.file_viewers.ImageViewer import sushi.hardcore.droidfs.file_viewers.TextEditor import sushi.hardcore.droidfs.file_viewers.VideoPlayer import sushi.hardcore.droidfs.provider.RestrictedFileProvider import sushi.hardcore.droidfs.util.ExternalProvider -import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.util.GocryptfsVolume +import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder open class BaseExplorerActivity : BaseActivity() { @@ -49,6 +49,7 @@ open class BaseExplorerActivity : BaseActivity() { } protected lateinit var explorerElements: MutableList protected lateinit var explorerAdapter: ExplorerElementAdapter + private var isCreating = true private var usf_open = false override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -100,7 +101,7 @@ open class BaseExplorerActivity : BaseActivity() { explorerAdapter.onItemClick(position) if (explorerAdapter.selectedItems.isEmpty()) { if (!wasSelecting) { - val fullPath = explorerElements[position].getFullPath() + val fullPath = explorerElements[position].fullPath when { explorerElements[position].isDirectory -> { setCurrentPath(fullPath) @@ -171,7 +172,15 @@ open class BaseExplorerActivity : BaseActivity() { explorerAdapter.setExplorerElements(explorerElements) currentDirectoryPath = path current_path_text.text = getString(R.string.location, currentDirectoryPath) - total_size_text.text = getString(R.string.total_size, PathUtils.formatSize(explorerAdapter.currentDirectoryTotalSize)) + Thread{ + var totalSize: Long = 0 + for (e in gocryptfsVolume.recursiveMapFiles(currentDirectoryPath)){ + if (e.isRegularFile){ + totalSize += e.size + } + } + total_size_text.text = getString(R.string.total_size, PathUtils.formatSize(totalSize)) + }.start() } private fun askCloseVolume() { @@ -222,8 +231,7 @@ open class BaseExplorerActivity : BaseActivity() { } } - fun onClickAddFolder(view: View?) { - findViewById(R.id.fam_explorer).close(true) + protected fun openDialogCreateFolder() { val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null) val dialogEditText = dialogEditTextView.findViewById(R.id.dialog_edit_text) val dialog = ColoredAlertDialogBuilder(this) @@ -245,7 +253,7 @@ open class BaseExplorerActivity : BaseActivity() { dialog.show() } - fun rename(old_name: String, new_name: String){ + protected fun rename(old_name: String, new_name: String){ if (new_name.isEmpty()) { Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show() } else { @@ -262,7 +270,7 @@ open class BaseExplorerActivity : BaseActivity() { } } - fun handleMenuItems(menu: Menu){ + protected fun handleMenuItems(menu: Menu){ menu.findItem(R.id.rename).isVisible = false if (usf_open){ menu.findItem(R.id.external_open)?.isVisible = false @@ -350,6 +358,10 @@ open class BaseExplorerActivity : BaseActivity() { override fun onResume() { super.onResume() - ExternalProvider.removeFiles(this) + if (isCreating){ + isCreating = false + } else { + ExternalProvider.removeFiles(this) + } } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt index ecc8437..e3b8a58 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivity.kt @@ -10,11 +10,10 @@ import android.view.WindowManager import android.widget.EditText import android.widget.Toast import androidx.appcompat.app.AppCompatActivity -import com.github.clans.fab.FloatingActionButton -import com.github.clans.fab.FloatingActionMenu -import kotlinx.android.synthetic.main.activity_explorer.* +import sushi.hardcore.droidfs.CameraActivity import sushi.hardcore.droidfs.OpenActivity import sushi.hardcore.droidfs.R +import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter import sushi.hardcore.droidfs.util.* import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder import java.io.File @@ -59,43 +58,71 @@ class ExplorerActivity : BaseExplorerActivity() { } } - fun onClickCreateFile(view: View) { - findViewById(R.id.fam_explorer).close(true) - val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null) - val dialogEditText = dialogEditTextView.findViewById(R.id.dialog_edit_text) - val dialog = ColoredAlertDialogBuilder(this) - .setView(dialogEditTextView) - .setTitle(getString(R.string.enter_file_name)) - .setPositiveButton(R.string.ok) { _, _ -> - val fileName = dialogEditText.text.toString() - createNewFile(fileName) - } - .setNegativeButton(R.string.cancel, null) - .create() - dialogEditText.setOnEditorActionListener { _, _, _ -> - val fileName = dialogEditText.text.toString() - dialog.dismiss() - createNewFile(fileName) - true + fun onClickFAB(view: View) { + if (modeSelectLocation){ + openDialogCreateFolder() + } else { + val adapter = IconTextDialogAdapter(this) + adapter.items = listOf( + listOf("importFromOtherVolumes", R.string.import_from_other_volume, R.drawable.icon_transfert), + listOf("importFiles", R.string.import_files, R.drawable.icon_encrypt), + listOf("createFile", R.string.new_file, R.drawable.icon_file_unknown), + listOf("createFolder", R.string.mkdir, R.drawable.icon_folder), + listOf("takePhoto", R.string.take_photo, R.drawable.icon_camera) + ) + ColoredAlertDialogBuilder(this) + .setSingleChoiceItems(adapter, -1){ thisDialog, which -> + when (adapter.getItem(which)){ + "importFromOtherVolumes" -> { + val intent = Intent(this, OpenActivity::class.java) + intent.action = "pick" + startActivityForResult(intent, PICK_OTHER_VOLUME_ITEMS_REQUEST_CODE) + } + "importFiles" -> { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + intent.type = "*/*" + intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) + intent.addCategory(Intent.CATEGORY_OPENABLE) + startActivityForResult(intent, PICK_FILES_REQUEST_CODE) + } + "createFile" -> { + val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null) + val dialogEditText = dialogEditTextView.findViewById(R.id.dialog_edit_text) + val dialog = ColoredAlertDialogBuilder(this) + .setView(dialogEditTextView) + .setTitle(getString(R.string.enter_file_name)) + .setPositiveButton(R.string.ok) { _, _ -> + val fileName = dialogEditText.text.toString() + createNewFile(fileName) + } + .setNegativeButton(R.string.cancel, null) + .create() + dialogEditText.setOnEditorActionListener { _, _, _ -> + val fileName = dialogEditText.text.toString() + dialog.dismiss() + createNewFile(fileName) + true + } + dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) + dialog.show() + } + "createFolder" -> { + openDialogCreateFolder() + } + "takePhoto" -> { + val intent = Intent(this, CameraActivity::class.java) + intent.putExtra("path", currentDirectoryPath) + intent.putExtra("sessionID", gocryptfsVolume.sessionID) + startActivity(intent) + } + } + thisDialog.dismiss() + } + .setTitle(getString(R.string.fab_dialog_title)) + .setNegativeButton(R.string.cancel, null) + .create() + .show() } - dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE) - dialog.show() - } - - fun onClickAddFile(view: View?) { - fam_explorer.close(true) - val i = Intent(Intent.ACTION_OPEN_DOCUMENT) - i.type = "*/*" - i.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true) - i.addCategory(Intent.CATEGORY_OPENABLE) - startActivityForResult(i, PICK_FILES_REQUEST_CODE) - } - - fun onClickAddFileFromOtherVolume(view: View?) { - fam_explorer.close(true) - val intent = Intent(this, OpenActivity::class.java) - intent.action = "pick" - startActivityForResult(intent, PICK_OTHER_VOLUME_ITEMS_REQUEST_CODE) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { @@ -323,9 +350,6 @@ class ExplorerActivity : BaseExplorerActivity() { } modeSelectLocation = true unselectAll() - findViewById(R.id.fab_add_file).visibility = View.GONE - findViewById(R.id.fab_import_file).visibility = View.GONE - findViewById(R.id.fab_import_file_from_other_volume).visibility = View.GONE true } R.id.validate -> { @@ -333,11 +357,10 @@ class ExplorerActivity : BaseExplorerActivity() { override fun doTask(activity: AppCompatActivity) { var failedItem: String? = null for (element in filesToCopy) { - val originalPath = element.getFullPath() failedItem = if (element.isDirectory) { - recursiveCopyDirectory(originalPath, currentDirectoryPath) + recursiveCopyDirectory(element.fullPath, currentDirectoryPath) } else { - if (copyFile(originalPath, PathUtils.path_join(currentDirectoryPath, element.name))) null else originalPath + if (copyFile(element.fullPath, PathUtils.path_join(currentDirectoryPath, element.name))) null else element.fullPath } if (failedItem != null) { stopTask { @@ -385,7 +408,7 @@ class ExplorerActivity : BaseExplorerActivity() { R.id.share -> { val paths: MutableList = ArrayList() for (i in explorerAdapter.selectedItems) { - paths.add(explorerElements[i].getFullPath()) + paths.add(explorerElements[i].fullPath) } ExternalProvider.share(this, gocryptfsVolume, paths) unselectAll() @@ -403,9 +426,6 @@ class ExplorerActivity : BaseExplorerActivity() { private fun cancelCopy() { if (modeSelectLocation){ modeSelectLocation = false - findViewById(R.id.fab_add_file).visibility = View.VISIBLE - findViewById(R.id.fab_import_file).visibility = View.VISIBLE - findViewById(R.id.fab_import_file_from_other_volume).visibility = View.VISIBLE filesToCopy.clear() } } @@ -457,15 +477,14 @@ class ExplorerActivity : BaseExplorerActivity() { } } for (e in mappedElements) { - val srcPath = e.getFullPath() - val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, srcPath)) + val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath)) if (e.isDirectory) { if (!gocryptfsVolume.mkdir(dstPath)){ - return srcPath + return e.fullPath } } else { - if (!copyFile(srcPath, dstPath)) { - return srcPath + if (!copyFile(e.fullPath, dstPath)) { + return e.fullPath } } } @@ -506,15 +525,14 @@ class ExplorerActivity : BaseExplorerActivity() { } } for (e in mappedElements) { - val srcPath = e.getFullPath() - val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, srcPath)) + val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath)) if (e.isDirectory) { if (!gocryptfsVolume.mkdir(dstPath)){ - return srcPath + return e.fullPath } } else { - if (!importFileFromOtherVolume(remote_gocryptfsVolume, srcPath, dstPath)) { - return srcPath + if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, dstPath)) { + return e.fullPath } } } diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityDrop.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityDrop.kt index cc84905..782c1eb 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityDrop.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerActivityDrop.kt @@ -4,6 +4,7 @@ import android.content.Intent import android.net.Uri import android.view.Menu import android.view.MenuItem +import android.view.View import sushi.hardcore.droidfs.R import sushi.hardcore.droidfs.util.PathUtils import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder @@ -13,6 +14,10 @@ class ExplorerActivityDrop : BaseExplorerActivity() { setContentView(R.layout.activity_explorer_drop) } + fun onClickFAB(view: View) { + openDialogCreateFolder() + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.explorer_drop, menu) handleMenuItems(menu) diff --git a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerElement.kt b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerElement.kt index 27e45d8..173f5d4 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerElement.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/explorers/ExplorerElement.kt @@ -5,6 +5,7 @@ import java.util.* class ExplorerElement(val name: String, val elementType: Short, val size: Long, mtime: Long, private val parentPath: String) { val mTime = Date((mtime * 1000).toString().toLong()) + val fullPath: String = PathUtils.path_join(parentPath, name) val isDirectory: Boolean get() = elementType.toInt() == 0 @@ -15,15 +16,11 @@ class ExplorerElement(val name: String, val elementType: Short, val size: Long, val isRegularFile: Boolean get() = elementType.toInt() == 1 - fun getFullPath(): String { - return PathUtils.path_join(parentPath, name) - } - companion object { fun sortBy(sortOrder: String, explorerElements: MutableList) { when (sortOrder) { "name" -> { - explorerElements.sortWith(Comparator { o1, o2 -> o1.name.compareTo(o2.name) }) + explorerElements.sortWith(Comparator { o1, o2 -> o1.fullPath.compareTo(o2.fullPath) }) } "size" -> { explorerElements.sortWith(Comparator { o1, o2 -> (o1.size - o2.size).toInt() }) @@ -32,7 +29,7 @@ class ExplorerElement(val name: String, val elementType: Short, val size: Long, explorerElements.sortWith(Comparator { o1, o2 -> o1.mTime.compareTo(o2.mTime) }) } "name_desc" -> { - explorerElements.sortWith(Comparator { o1, o2 -> o2.name.compareTo(o1.name) }) + explorerElements.sortWith(Comparator { o1, o2 -> o2.fullPath.compareTo(o1.fullPath) }) } "size_desc" -> { explorerElements.sortWith(Comparator { o1, o2 -> (o2.size - o1.size).toInt() }) diff --git a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt index bb39bbd..27279f9 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/file_viewers/ImageViewer.kt @@ -13,11 +13,8 @@ import com.bumptech.glide.load.resource.bitmap.BitmapTransformation import kotlinx.android.synthetic.main.activity_image_viewer.* import sushi.hardcore.droidfs.ConstValues import sushi.hardcore.droidfs.R -<<<<<<< HEAD -======= import sushi.hardcore.droidfs.util.MiscUtils import sushi.hardcore.droidfs.explorers.ExplorerElement ->>>>>>> ccc453a... Sorted image swipe & ExplorerViewModel import sushi.hardcore.droidfs.util.PathUtils import java.security.MessageDigest import kotlin.math.abs @@ -66,26 +63,18 @@ class ImageViewer: FileViewerActivity() { sortOrder = intent.getStringExtra("sortOrder") ?: "name" ExplorerElement.sortBy(sortOrder, mappedImages) for ((i, e) in mappedImages.withIndex()){ - if (filePath == e.getFullPath()){ + if (filePath == e.fullPath){ currentMappedImageIndex = i } } wasMapped = true } - if (deltaX < 0){ - if (currentMappedImageIndex == mappedImages.size-1){ - currentMappedImageIndex = 0 - } else { - currentMappedImageIndex += 1 - } + currentMappedImageIndex = if (deltaX < 0){ + MiscUtils.incrementIndex(currentMappedImageIndex, mappedImages) } else { - if (currentMappedImageIndex == 0){ - currentMappedImageIndex = mappedImages.size-1 - } else { - currentMappedImageIndex -= 1 - } + MiscUtils.decrementIndex(currentMappedImageIndex, mappedImages) } - loadWholeFile(mappedImages[currentMappedImageIndex].getFullPath())?.let { + loadWholeFile(mappedImages[currentMappedImageIndex].fullPath)?.let { glideImage = Glide.with(this).load(it) glideImage.into(image_viewer) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/provider/RestrictedFileProvider.kt b/app/src/main/java/sushi/hardcore/droidfs/provider/RestrictedFileProvider.kt index 0f1bfa9..02dd1e5 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/provider/RestrictedFileProvider.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/provider/RestrictedFileProvider.kt @@ -84,6 +84,7 @@ class RestrictedFileProvider: ContentProvider() { Wiper.wipe(file) } } + dbHelper?.close() context.deleteDatabase(DB_NAME) } @@ -134,28 +135,26 @@ class RestrictedFileProvider: ContentProvider() { } override fun query(uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, sortOrder: String?): Cursor? { + var resultCursor: MatrixCursor? = null val temporaryFile = getFileFromUri(uri) temporaryFile?.let{ - val fileName = - dbHelper?.readableDatabase?.query(TABLE_FILES, arrayOf(TemporaryFileColumns.COLUMN_NAME), TemporaryFileColumns.COLUMN_UUID + "=?", arrayOf(uri.lastPathSegment), null, null, null) + val fileName = dbHelper?.readableDatabase?.query(TABLE_FILES, arrayOf(TemporaryFileColumns.COLUMN_NAME), TemporaryFileColumns.COLUMN_UUID + "=?", arrayOf(uri.lastPathSegment), null, null, null) fileName?.let{ if (fileName.moveToNext()) { - val cursor = MatrixCursor( + resultCursor = MatrixCursor( arrayOf( MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.SIZE ) ) - cursor.newRow() + resultCursor!!.newRow() .add(fileName.getString(0)) .add(temporaryFile.length()) - fileName.close() - return cursor } fileName.close() } } - return null + return resultCursor } override fun delete(uri: Uri, givenSelection: String?, givenSelectionArgs: Array?): Int { diff --git a/app/src/main/java/sushi/hardcore/droidfs/util/GocryptfsVolume.kt b/app/src/main/java/sushi/hardcore/droidfs/util/GocryptfsVolume.kt index c791731..d891848 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/util/GocryptfsVolume.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/util/GocryptfsVolume.kt @@ -166,7 +166,7 @@ class GocryptfsVolume(var sessionID: Int) { result.addAll(explorerElements) for (e in explorerElements){ if (e.isDirectory){ - result.addAll(recursiveMapFiles(e.getFullPath())) + result.addAll(recursiveMapFiles(e.fullPath)) } } return result diff --git a/app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt b/app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt new file mode 100644 index 0000000..3abe8df --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt @@ -0,0 +1,18 @@ +package sushi.hardcore.droidfs.util + +object MiscUtils { + fun incrementIndex(index: Int, list: List): Int { + var i = index+1 + if (i >= list.size){ + i = 0 + } + return i + } + fun decrementIndex(index: Int, list: List): Int { + var i = index-1 + if (i <= 0){ + i = list.size-1 + } + return i + } +} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredBorderListView.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredBorderListView.kt index 2f09a23..a6226c3 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredBorderListView.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredBorderListView.kt @@ -12,12 +12,9 @@ import androidx.core.content.ContextCompat import sushi.hardcore.droidfs.R open class ColoredBorderListView: ListView { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ val background = ContextCompat.getDrawable(context, R.drawable.listview_border) as StateListDrawable val dcs = background.constantState as DrawableContainer.DrawableContainerState diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredButton.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredButton.kt deleted file mode 100644 index 6913e89..0000000 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredButton.kt +++ /dev/null @@ -1,18 +0,0 @@ -package sushi.hardcore.droidfs.widgets - -import android.content.Context -import android.content.res.ColorStateList -import android.util.AttributeSet -import androidx.appcompat.widget.AppCompatButton - -class ColoredButton: AppCompatButton { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } - private fun applyColor(){ - super.setBackgroundTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context))) - } -} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredCheckBox.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredCheckBox.kt index d316d5b..f943b9a 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredCheckBox.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredCheckBox.kt @@ -6,12 +6,9 @@ import android.util.AttributeSet import androidx.appcompat.widget.AppCompatCheckBox class ColoredCheckBox: AppCompatCheckBox { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + //constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ super.setButtonTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context))) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredEditText.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredEditText.kt index b6bcee4..de45fae 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredEditText.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredEditText.kt @@ -14,12 +14,9 @@ import androidx.core.content.ContextCompat import sushi.hardcore.droidfs.R class ColoredEditText: AppCompatEditText { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ super.setBackgroundTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context))) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAB.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAB.kt index e7f2da9..0077a42 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAB.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAB.kt @@ -1,19 +1,18 @@ package sushi.hardcore.droidfs.widgets import android.content.Context +import android.content.res.ColorStateList import android.util.AttributeSet -import com.github.clans.fab.FloatingActionButton +import androidx.core.content.ContextCompat +import com.google.android.material.floatingactionbutton.FloatingActionButton class ColoredFAB: FloatingActionButton { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ val themeColor = ThemeColor.getThemeColor(context) - super.setColorNormal(themeColor) - super.setColorPressed(themeColor) + backgroundTintList = ColorStateList.valueOf(themeColor) + setColorFilter(ContextCompat.getColor(context, android.R.color.white)) } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAM.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAM.kt deleted file mode 100644 index 4421e8a..0000000 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredFAM.kt +++ /dev/null @@ -1,19 +0,0 @@ -package sushi.hardcore.droidfs.widgets - -import android.content.Context -import android.util.AttributeSet -import com.github.clans.fab.FloatingActionMenu - -class ColoredFAM: FloatingActionMenu { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } - private fun applyColor(){ - val themeColor = ThemeColor.getThemeColor(context) - super.setMenuButtonColorNormal(themeColor) - super.setMenuButtonColorPressed(themeColor) - } -} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageButton.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageButton.kt index 300a526..fe98131 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageButton.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageButton.kt @@ -5,12 +5,9 @@ import android.util.AttributeSet import androidx.appcompat.widget.AppCompatImageButton class ColoredImageButton: AppCompatImageButton { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ super.setColorFilter(ThemeColor.getThemeColor(context)) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageView.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageView.kt index df90dc8..752659b 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageView.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredImageView.kt @@ -5,12 +5,9 @@ import android.util.AttributeSet import androidx.appcompat.widget.AppCompatImageView class ColoredImageView : AppCompatImageView { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } + constructor(context: Context) : super(context) { applyColor() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() } private fun applyColor(){ super.setColorFilter(ThemeColor.getThemeColor(context)) } diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredSeekBar.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredSeekBar.kt deleted file mode 100644 index f2d3cf7..0000000 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/ColoredSeekBar.kt +++ /dev/null @@ -1,21 +0,0 @@ -package sushi.hardcore.droidfs.widgets - -import android.content.Context -import android.graphics.PorterDuff -import android.graphics.PorterDuffColorFilter -import android.util.AttributeSet -import androidx.appcompat.widget.AppCompatSeekBar - -class ColoredSeekBar : AppCompatSeekBar { - constructor(context: Context) : super(context) { - applyColor() - } - constructor(context: Context, attrs: AttributeSet): super(context, attrs){ - applyColor() - } - private fun applyColor(){ - val colorFilter = PorterDuffColorFilter(ThemeColor.getThemeColor(context), PorterDuff.Mode.SRC_IN) - super.getProgressDrawable().colorFilter = colorFilter - super.getThumb().colorFilter = colorFilter - } -} \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/NonScrollableColoredBorderListView.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/NonScrollableColoredBorderListView.kt index c488e7c..bf31c1a 100644 --- a/app/src/main/java/sushi/hardcore/droidfs/widgets/NonScrollableColoredBorderListView.kt +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/NonScrollableColoredBorderListView.kt @@ -7,17 +7,20 @@ import android.widget.ListAdapter class NonScrollableColoredBorderListView: ColoredBorderListView { constructor(context: Context) : super(context) constructor(context: Context, attrs: AttributeSet): super(context, attrs) + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) + + fun computeHeight(): Int { + var totalHeight = 0 + for (i in 0 until adapter.count){ + val item = adapter.getView(i, null, this) + item.measure(0, 0) + totalHeight += item.measuredHeight + } + return totalHeight + (dividerHeight * (adapter.count-1)) + } override fun setAdapter(adapter: ListAdapter?) { super.setAdapter(adapter) - adapter?.let { - var totalHeight = 0 - for (i in 0 until adapter.count){ - val item = adapter.getView(i, null, this) - item.measure(0, 0) - totalHeight += item.measuredHeight - } - layoutParams.height = totalHeight + (dividerHeight * (adapter.count-1)) - } + layoutParams.height = computeHeight() } } \ No newline at end of file diff --git a/app/src/main/java/sushi/hardcore/droidfs/widgets/TakePhotoButton.kt b/app/src/main/java/sushi/hardcore/droidfs/widgets/TakePhotoButton.kt new file mode 100644 index 0000000..c1dd211 --- /dev/null +++ b/app/src/main/java/sushi/hardcore/droidfs/widgets/TakePhotoButton.kt @@ -0,0 +1,27 @@ +package sushi.hardcore.droidfs.widgets + +import android.content.Context +import android.util.AttributeSet +import android.view.MotionEvent +import androidx.appcompat.widget.AppCompatImageView + +class TakePhotoButton: AppCompatImageView { + constructor(context: Context) : super(context) { init() } + constructor(context: Context, attrs: AttributeSet): super(context, attrs) { init() } + constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { init() } + lateinit var onClick: ()->Unit + + private fun init(){ + setOnTouchListener{ _, event -> + when (event.action) { + MotionEvent.ACTION_DOWN -> onClick() + MotionEvent.ACTION_UP -> isPressed = true + } + true + } + } + + fun onPhotoTaken(){ + isPressed = false + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/button_background.xml b/app/src/main/res/drawable/button_background.xml new file mode 100644 index 0000000..eea8b35 --- /dev/null +++ b/app/src/main/res/drawable/button_background.xml @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/fab_label_background.xml b/app/src/main/res/drawable/fab_label_background.xml deleted file mode 100644 index 1be5bed..0000000 --- a/app/src/main/res/drawable/fab_label_background.xml +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/icon_camera.xml b/app/src/main/res/drawable/icon_camera.xml new file mode 100644 index 0000000..9141101 --- /dev/null +++ b/app/src/main/res/drawable/icon_camera.xml @@ -0,0 +1,6 @@ + + + + diff --git a/app/src/main/res/drawable/icon_camera_back.xml b/app/src/main/res/drawable/icon_camera_back.xml new file mode 100644 index 0000000..50f2251 --- /dev/null +++ b/app/src/main/res/drawable/icon_camera_back.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_camera_front.xml b/app/src/main/res/drawable/icon_camera_front.xml new file mode 100644 index 0000000..d3b0138 --- /dev/null +++ b/app/src/main/res/drawable/icon_camera_front.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/icon_encrypt.xml b/app/src/main/res/drawable/icon_encrypt.xml index 46412c1..2ca3d21 100644 --- a/app/src/main/res/drawable/icon_encrypt.xml +++ b/app/src/main/res/drawable/icon_encrypt.xml @@ -1,11 +1,10 @@ - - - + diff --git a/app/src/main/res/drawable/icon_flash_auto.xml b/app/src/main/res/drawable/icon_flash_auto.xml new file mode 100644 index 0000000..7014c76 --- /dev/null +++ b/app/src/main/res/drawable/icon_flash_auto.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/icon_flash_off.xml b/app/src/main/res/drawable/icon_flash_off.xml new file mode 100644 index 0000000..a7f19f7 --- /dev/null +++ b/app/src/main/res/drawable/icon_flash_off.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/icon_flash_on.xml b/app/src/main/res/drawable/icon_flash_on.xml new file mode 100644 index 0000000..118d8a2 --- /dev/null +++ b/app/src/main/res/drawable/icon_flash_on.xml @@ -0,0 +1,5 @@ + + + diff --git a/app/src/main/res/drawable/take_photo_button.xml b/app/src/main/res/drawable/take_photo_button.xml new file mode 100644 index 0000000..655beda --- /dev/null +++ b/app/src/main/res/drawable/take_photo_button.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_camera.xml b/app/src/main/res/layout/activity_camera.xml new file mode 100644 index 0000000..d7ebedc --- /dev/null +++ b/app/src/main/res/layout/activity_camera.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_change_password.xml b/app/src/main/res/layout/activity_change_password.xml index 8992fcb..ca7ca28 100644 --- a/app/src/main/res/layout/activity_change_password.xml +++ b/app/src/main/res/layout/activity_change_password.xml @@ -25,7 +25,7 @@ android:layout_height="match_parent" android:gravity="center_vertical" android:text="@string/volume_path" - android:textSize="@dimen/edit_text_label_size" /> + android:textSize="@dimen/edit_text_label_text_size" /> + android:textSize="@dimen/edit_text_label_text_size" /> + android:textSize="@dimen/edit_text_label_text_size" /> + android:textSize="@dimen/edit_text_label_text_size" /> -