forked from hardcoresushi/DroidFS
Take Photo feature
This commit is contained in:
parent
03d5b468f2
commit
0bfb952365
@ -15,7 +15,7 @@ android {
|
|||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 29
|
targetSdkVersion 29
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.1.2"
|
versionName "1.1.3"
|
||||||
|
|
||||||
ndk {
|
ndk {
|
||||||
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
abiFilters 'x86_64', 'armeabi-v7a', 'arm64-v8a'
|
||||||
@ -40,15 +40,16 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||||
implementation 'androidx.core:core-ktx:1.3.1'
|
implementation "androidx.core:core-ktx:1.3.1"
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation "androidx.appcompat:appcompat:1.1.0"
|
||||||
testImplementation 'junit:junit:4.12'
|
implementation "androidx.constraintlayout:constraintlayout:1.1.3"
|
||||||
|
|
||||||
implementation 'androidx.sqlite:sqlite:2.1.0'
|
implementation "androidx.sqlite:sqlite:2.1.0"
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation "androidx.preference:preference:1.1.1"
|
||||||
implementation 'com.github.clans:fab:1.6.4'
|
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
|
||||||
implementation 'com.jaredrummler:cyanea:1.0.2'
|
implementation "com.jaredrummler:cyanea:1.0.2"
|
||||||
implementation 'com.github.bumptech.glide:glide:4.11.0'
|
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-core:2.11.7"
|
||||||
implementation 'com.google.android.exoplayer:exoplayer-ui:2.11.7'
|
implementation "com.google.android.exoplayer:exoplayer-ui:2.11.7"
|
||||||
|
implementation "com.otaliastudios:cameraview:2.6.3"
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,27 @@
|
|||||||
|
|
||||||
<permission
|
<permission
|
||||||
android:name="${applicationId}.WRITE_TEMPORARY_STORAGE"
|
android:name="${applicationId}.WRITE_TEMPORARY_STORAGE"
|
||||||
android:protectionLevel="signature"/>
|
android:protectionLevel="signature" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".ColoredApplication"
|
android:name=".ColoredApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
android:icon="@mipmap/icon_launcher"
|
android:icon="@mipmap/icon_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:requestLegacyExternalStorage="true"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme"
|
android:theme="@style/AppTheme">
|
||||||
android:requestLegacyExternalStorage="true">
|
<activity android:name=".CameraActivity"/>
|
||||||
<activity
|
<activity
|
||||||
android:name=".SettingsActivity"
|
android:name=".SettingsActivity"
|
||||||
android:label="@string/title_activity_settings"
|
android:label="@string/title_activity_settings"
|
||||||
android:parentActivityName=".MainActivity"/>
|
android:parentActivityName=".MainActivity" />
|
||||||
<activity android:name=".explorers.ExplorerActivity" />
|
<activity android:name=".explorers.ExplorerActivity" />
|
||||||
<activity android:name=".explorers.ExplorerActivityPick" />
|
<activity android:name=".explorers.ExplorerActivityPick" />
|
||||||
<activity android:name=".explorers.ExplorerActivityDrop" />
|
<activity android:name=".explorers.ExplorerActivityDrop" />
|
||||||
@ -34,7 +36,9 @@
|
|||||||
<intent-filter android:label="@string/share_menu_label">
|
<intent-filter android:label="@string/share_menu_label">
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
|
|
||||||
<data android:mimeType="*/*" />
|
<data android:mimeType="*/*" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
@ -52,19 +56,28 @@
|
|||||||
android:screenOrientation="nosensor">
|
android:screenOrientation="nosensor">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
<activity android:name=".file_viewers.ImageViewer" android:configChanges="screenSize|orientation" /> <!-- don't reload content on configuration change -->
|
<activity
|
||||||
<activity android:name=".file_viewers.VideoPlayer" android:configChanges="screenSize|orientation" />
|
android:name=".file_viewers.ImageViewer"
|
||||||
<activity android:name=".file_viewers.AudioPlayer" android:configChanges="screenSize|orientation" />
|
android:configChanges="screenSize|orientation" /> <!-- don't reload content on configuration change -->
|
||||||
<activity android:name=".file_viewers.TextEditor" android:configChanges="screenSize|orientation" />
|
<activity
|
||||||
|
android:name=".file_viewers.VideoPlayer"
|
||||||
|
android:configChanges="screenSize|orientation" />
|
||||||
|
<activity
|
||||||
|
android:name=".file_viewers.AudioPlayer"
|
||||||
|
android:configChanges="screenSize|orientation" />
|
||||||
|
<activity
|
||||||
|
android:name=".file_viewers.TextEditor"
|
||||||
|
android:configChanges="screenSize|orientation" />
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name=".provider.RestrictedFileProvider"
|
android:name=".provider.RestrictedFileProvider"
|
||||||
android:authorities="${applicationId}.temporary_provider"
|
android:authorities="${applicationId}.temporary_provider"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
android:writePermission="${applicationId}.WRITE_TEMPORARY_STORAGE"/>
|
android:writePermission="${applicationId}.WRITE_TEMPORARY_STORAGE" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</manifest>
|
89
app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt
Normal file
89
app/src/main/java/sushi/hardcore/droidfs/CameraActivity.kt
Normal file
@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,15 +113,4 @@ class ExplorerElementAdapter(private val context: Context) : BaseAdapter() {
|
|||||||
unSelectAll()
|
unSelectAll()
|
||||||
this.explorerElements = explorer_elements
|
this.explorerElements = explorer_elements
|
||||||
}
|
}
|
||||||
|
|
||||||
val currentDirectoryTotalSize: Long
|
|
||||||
get() {
|
|
||||||
var totalSize: Long = 0
|
|
||||||
for (e in explorerElements) {
|
|
||||||
if (e.isRegularFile) {
|
|
||||||
totalSize += e.size
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return totalSize
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -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<List<Any>>
|
||||||
|
|
||||||
|
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<TextView>(R.id.text)
|
||||||
|
text.text = context.getString(items[position][1] as Int)
|
||||||
|
val icon = view.findViewById<ColoredImageView>(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 }
|
||||||
|
}
|
@ -1,36 +1,24 @@
|
|||||||
package sushi.hardcore.droidfs.adapters
|
package sushi.hardcore.droidfs.adapters
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.BaseAdapter
|
import android.widget.LinearLayout
|
||||||
import android.widget.TextView
|
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.R
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredImageView
|
import sushi.hardcore.droidfs.widgets.ColoredImageView
|
||||||
|
|
||||||
class OpenAsDialogAdapter(private val context: Context): BaseAdapter() {
|
class OpenAsDialogAdapter(context: Context) : IconTextDialogAdapter(context) {
|
||||||
private val inflater: LayoutInflater = LayoutInflater.from(context)
|
private val openAsItems = listOf(
|
||||||
private val items = listOf(
|
listOf("image", R.string.image, R.drawable.icon_file_image),
|
||||||
listOf("image", context.getString(R.string.image), R.drawable.icon_file_image),
|
listOf("video", R.string.video, R.drawable.icon_file_video),
|
||||||
listOf("video", context.getString(R.string.video), R.drawable.icon_file_video),
|
listOf("audio", R.string.audio, R.drawable.icon_file_audio),
|
||||||
listOf("audio", context.getString(R.string.audio), R.drawable.icon_file_audio),
|
listOf("text", R.string.text, R.drawable.icon_file_text)
|
||||||
listOf("text", context.getString(R.string.text), R.drawable.icon_file_text)
|
|
||||||
)
|
)
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View {
|
init {
|
||||||
val view: View = convertView ?: inflater.inflate(R.layout.adapter_dialog_icon_text, parent, false)
|
items = openAsItems
|
||||||
val text = view.findViewById<TextView>(R.id.text)
|
|
||||||
text.text = items[position][1] as String
|
|
||||||
val icon = view.findViewById<ColoredImageView>(R.id.icon)
|
|
||||||
icon.setImageDrawable(context.getDrawable(items[position][2] as Int))
|
|
||||||
return view
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 }
|
|
||||||
}
|
}
|
@ -13,33 +13,35 @@ import sushi.hardcore.droidfs.ConstValues
|
|||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
import sushi.hardcore.droidfs.util.WidgetUtil
|
import sushi.hardcore.droidfs.util.WidgetUtil
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
import sushi.hardcore.droidfs.widgets.NonScrollableColoredBorderListView
|
||||||
import java.util.*
|
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 inflater: LayoutInflater = LayoutInflater.from(context)
|
||||||
private val saved_volumes_paths: MutableList<String> = ArrayList()
|
private lateinit var nonScrollableColoredBorderListView: NonScrollableColoredBorderListView
|
||||||
private val shared_prefs_editor: Editor = shared_prefs.edit()
|
private val savedVolumesPaths: MutableList<String> = ArrayList()
|
||||||
|
private val sharedPrefsEditor: Editor = sharedPrefs.edit()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val saved_volumes_paths_set = shared_prefs.getStringSet(ConstValues.saved_volumes_key, HashSet()) as Set<String>
|
val savedVolumesPathsSet = sharedPrefs.getStringSet(ConstValues.saved_volumes_key, HashSet()) as Set<String>
|
||||||
for (volume_path in saved_volumes_paths_set) {
|
for (volume_path in savedVolumesPathsSet) {
|
||||||
saved_volumes_paths.add(volume_path)
|
savedVolumesPaths.add(volume_path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun update_shared_prefs() {
|
private fun updateSharedPrefs() {
|
||||||
val saved_volumes_paths_set = saved_volumes_paths.toSet()
|
val savedVolumesPathsSet = savedVolumesPaths.toSet()
|
||||||
shared_prefs_editor.remove(ConstValues.saved_volumes_key)
|
sharedPrefsEditor.remove(ConstValues.saved_volumes_key)
|
||||||
shared_prefs_editor.putStringSet(ConstValues.saved_volumes_key, saved_volumes_paths_set)
|
sharedPrefsEditor.putStringSet(ConstValues.saved_volumes_key, savedVolumesPathsSet)
|
||||||
shared_prefs_editor.apply()
|
sharedPrefsEditor.apply()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getCount(): Int {
|
override fun getCount(): Int {
|
||||||
return saved_volumes_paths.size
|
return savedVolumesPaths.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItem(position: Int): String {
|
override fun getItem(position: Int): String {
|
||||||
return saved_volumes_paths[position]
|
return savedVolumesPaths[position]
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemId(position: Int): Long {
|
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 {
|
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 view: View = convertView ?: inflater.inflate(R.layout.adapter_saved_volume, parent, false)
|
||||||
val volume_name_textview = view.findViewById<TextView>(R.id.volume_name_textview)
|
val volumeNameTextview = view.findViewById<TextView>(R.id.volume_name_textview)
|
||||||
val currentVolume = getItem(position)
|
val currentVolume = getItem(position)
|
||||||
volume_name_textview.text = currentVolume
|
volumeNameTextview.text = currentVolume
|
||||||
val delete_imageview = view.findViewById<ImageView>(R.id.delete_imageview)
|
val deleteImageview = view.findViewById<ImageView>(R.id.delete_imageview)
|
||||||
delete_imageview.setOnClickListener {
|
deleteImageview.setOnClickListener {
|
||||||
val volume_path = saved_volumes_paths[position]
|
val volumePath = savedVolumesPaths[position]
|
||||||
val dialog = ColoredAlertDialogBuilder(context)
|
val dialog = ColoredAlertDialogBuilder(context)
|
||||||
dialog.setTitle(R.string.warning)
|
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.setMessage(context.getString(R.string.delete_hash_or_all))
|
||||||
dialog.setPositiveButton(context.getString(R.string.delete_all)) { _, _ ->
|
dialog.setPositiveButton(context.getString(R.string.delete_all)) { _, _ ->
|
||||||
saved_volumes_paths.removeAt(position)
|
savedVolumesPaths.removeAt(position)
|
||||||
shared_prefs_editor.remove(volume_path)
|
sharedPrefsEditor.remove(volumePath)
|
||||||
update_shared_prefs()
|
updateSharedPrefs()
|
||||||
refresh(parent)
|
refresh(parent)
|
||||||
}
|
}
|
||||||
dialog.setNegativeButton(context.getString(R.string.delete_hash)) { _, _ ->
|
dialog.setNegativeButton(context.getString(R.string.delete_hash)) { _, _ ->
|
||||||
shared_prefs_editor.remove(volume_path)
|
sharedPrefsEditor.remove(volumePath)
|
||||||
shared_prefs_editor.apply()
|
sharedPrefsEditor.apply()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
dialog.setMessage(context.getString(R.string.ask_delete_volume_path))
|
dialog.setMessage(context.getString(R.string.ask_delete_volume_path))
|
||||||
dialog.setPositiveButton(R.string.ok) {_, _ ->
|
dialog.setPositiveButton(R.string.ok) {_, _ ->
|
||||||
saved_volumes_paths.removeAt(position)
|
savedVolumesPaths.removeAt(position)
|
||||||
update_shared_prefs()
|
updateSharedPrefs()
|
||||||
refresh(parent)
|
refresh(parent)
|
||||||
}
|
}
|
||||||
dialog.setNegativeButton(R.string.cancel, null)
|
dialog.setNegativeButton(R.string.cancel, null)
|
||||||
@ -86,13 +91,15 @@ class SavedVolumesAdapter(val context: Context, val shared_prefs: SharedPreferen
|
|||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
if (count == 0){
|
if (count == 0){
|
||||||
WidgetUtil.hide(parent)
|
WidgetUtil.hide(parent)
|
||||||
|
} else {
|
||||||
|
nonScrollableColoredBorderListView.layoutParams.height = nonScrollableColoredBorderListView.computeHeight()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addVolumePath(volume_path: String) {
|
fun addVolumePath(volume_path: String) {
|
||||||
if (!saved_volumes_paths.contains(volume_path)) {
|
if (!savedVolumesPaths.contains(volume_path)) {
|
||||||
saved_volumes_paths.add(volume_path)
|
savedVolumesPaths.add(volume_path)
|
||||||
update_shared_prefs()
|
updateSharedPrefs()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -23,16 +23,16 @@ import sushi.hardcore.droidfs.ConstValues.Companion.isText
|
|||||||
import sushi.hardcore.droidfs.ConstValues.Companion.isVideo
|
import sushi.hardcore.droidfs.ConstValues.Companion.isVideo
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter
|
import sushi.hardcore.droidfs.adapters.DialogSingleChoiceAdapter
|
||||||
import sushi.hardcore.droidfs.adapters.OpenAsDialogAdapter
|
|
||||||
import sushi.hardcore.droidfs.adapters.ExplorerElementAdapter
|
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.AudioPlayer
|
||||||
import sushi.hardcore.droidfs.file_viewers.ImageViewer
|
import sushi.hardcore.droidfs.file_viewers.ImageViewer
|
||||||
import sushi.hardcore.droidfs.file_viewers.TextEditor
|
import sushi.hardcore.droidfs.file_viewers.TextEditor
|
||||||
import sushi.hardcore.droidfs.file_viewers.VideoPlayer
|
import sushi.hardcore.droidfs.file_viewers.VideoPlayer
|
||||||
import sushi.hardcore.droidfs.provider.RestrictedFileProvider
|
import sushi.hardcore.droidfs.provider.RestrictedFileProvider
|
||||||
import sushi.hardcore.droidfs.util.ExternalProvider
|
import sushi.hardcore.droidfs.util.ExternalProvider
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
|
||||||
import sushi.hardcore.droidfs.util.GocryptfsVolume
|
import sushi.hardcore.droidfs.util.GocryptfsVolume
|
||||||
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
|
|
||||||
open class BaseExplorerActivity : BaseActivity() {
|
open class BaseExplorerActivity : BaseActivity() {
|
||||||
@ -49,6 +49,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
protected lateinit var explorerElements: MutableList<ExplorerElement>
|
protected lateinit var explorerElements: MutableList<ExplorerElement>
|
||||||
protected lateinit var explorerAdapter: ExplorerElementAdapter
|
protected lateinit var explorerAdapter: ExplorerElementAdapter
|
||||||
|
private var isCreating = true
|
||||||
private var usf_open = false
|
private var usf_open = false
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -100,7 +101,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
explorerAdapter.onItemClick(position)
|
explorerAdapter.onItemClick(position)
|
||||||
if (explorerAdapter.selectedItems.isEmpty()) {
|
if (explorerAdapter.selectedItems.isEmpty()) {
|
||||||
if (!wasSelecting) {
|
if (!wasSelecting) {
|
||||||
val fullPath = explorerElements[position].getFullPath()
|
val fullPath = explorerElements[position].fullPath
|
||||||
when {
|
when {
|
||||||
explorerElements[position].isDirectory -> {
|
explorerElements[position].isDirectory -> {
|
||||||
setCurrentPath(fullPath)
|
setCurrentPath(fullPath)
|
||||||
@ -171,7 +172,15 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
explorerAdapter.setExplorerElements(explorerElements)
|
explorerAdapter.setExplorerElements(explorerElements)
|
||||||
currentDirectoryPath = path
|
currentDirectoryPath = path
|
||||||
current_path_text.text = getString(R.string.location, currentDirectoryPath)
|
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() {
|
private fun askCloseVolume() {
|
||||||
@ -222,8 +231,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClickAddFolder(view: View?) {
|
protected fun openDialogCreateFolder() {
|
||||||
findViewById<FloatingActionMenu>(R.id.fam_explorer).close(true)
|
|
||||||
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
||||||
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
||||||
val dialog = ColoredAlertDialogBuilder(this)
|
val dialog = ColoredAlertDialogBuilder(this)
|
||||||
@ -245,7 +253,7 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun rename(old_name: String, new_name: String){
|
protected fun rename(old_name: String, new_name: String){
|
||||||
if (new_name.isEmpty()) {
|
if (new_name.isEmpty()) {
|
||||||
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, R.string.error_filename_empty, Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} 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
|
menu.findItem(R.id.rename).isVisible = false
|
||||||
if (usf_open){
|
if (usf_open){
|
||||||
menu.findItem(R.id.external_open)?.isVisible = false
|
menu.findItem(R.id.external_open)?.isVisible = false
|
||||||
@ -350,6 +358,10 @@ open class BaseExplorerActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
ExternalProvider.removeFiles(this)
|
if (isCreating){
|
||||||
|
isCreating = false
|
||||||
|
} else {
|
||||||
|
ExternalProvider.removeFiles(this)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -10,11 +10,10 @@ import android.view.WindowManager
|
|||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.github.clans.fab.FloatingActionButton
|
import sushi.hardcore.droidfs.CameraActivity
|
||||||
import com.github.clans.fab.FloatingActionMenu
|
|
||||||
import kotlinx.android.synthetic.main.activity_explorer.*
|
|
||||||
import sushi.hardcore.droidfs.OpenActivity
|
import sushi.hardcore.droidfs.OpenActivity
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
import sushi.hardcore.droidfs.adapters.IconTextDialogAdapter
|
||||||
import sushi.hardcore.droidfs.util.*
|
import sushi.hardcore.droidfs.util.*
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@ -59,43 +58,71 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun onClickCreateFile(view: View) {
|
fun onClickFAB(view: View) {
|
||||||
findViewById<FloatingActionMenu>(R.id.fam_explorer).close(true)
|
if (modeSelectLocation){
|
||||||
val dialogEditTextView = layoutInflater.inflate(R.layout.dialog_edit_text, null)
|
openDialogCreateFolder()
|
||||||
val dialogEditText = dialogEditTextView.findViewById<EditText>(R.id.dialog_edit_text)
|
} else {
|
||||||
val dialog = ColoredAlertDialogBuilder(this)
|
val adapter = IconTextDialogAdapter(this)
|
||||||
.setView(dialogEditTextView)
|
adapter.items = listOf(
|
||||||
.setTitle(getString(R.string.enter_file_name))
|
listOf("importFromOtherVolumes", R.string.import_from_other_volume, R.drawable.icon_transfert),
|
||||||
.setPositiveButton(R.string.ok) { _, _ ->
|
listOf("importFiles", R.string.import_files, R.drawable.icon_encrypt),
|
||||||
val fileName = dialogEditText.text.toString()
|
listOf("createFile", R.string.new_file, R.drawable.icon_file_unknown),
|
||||||
createNewFile(fileName)
|
listOf("createFolder", R.string.mkdir, R.drawable.icon_folder),
|
||||||
}
|
listOf("takePhoto", R.string.take_photo, R.drawable.icon_camera)
|
||||||
.setNegativeButton(R.string.cancel, null)
|
)
|
||||||
.create()
|
ColoredAlertDialogBuilder(this)
|
||||||
dialogEditText.setOnEditorActionListener { _, _, _ ->
|
.setSingleChoiceItems(adapter, -1){ thisDialog, which ->
|
||||||
val fileName = dialogEditText.text.toString()
|
when (adapter.getItem(which)){
|
||||||
dialog.dismiss()
|
"importFromOtherVolumes" -> {
|
||||||
createNewFile(fileName)
|
val intent = Intent(this, OpenActivity::class.java)
|
||||||
true
|
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<EditText>(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?) {
|
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
|
||||||
@ -323,9 +350,6 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
modeSelectLocation = true
|
modeSelectLocation = true
|
||||||
unselectAll()
|
unselectAll()
|
||||||
findViewById<FloatingActionButton>(R.id.fab_add_file).visibility = View.GONE
|
|
||||||
findViewById<FloatingActionButton>(R.id.fab_import_file).visibility = View.GONE
|
|
||||||
findViewById<FloatingActionButton>(R.id.fab_import_file_from_other_volume).visibility = View.GONE
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
R.id.validate -> {
|
R.id.validate -> {
|
||||||
@ -333,11 +357,10 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
override fun doTask(activity: AppCompatActivity) {
|
override fun doTask(activity: AppCompatActivity) {
|
||||||
var failedItem: String? = null
|
var failedItem: String? = null
|
||||||
for (element in filesToCopy) {
|
for (element in filesToCopy) {
|
||||||
val originalPath = element.getFullPath()
|
|
||||||
failedItem = if (element.isDirectory) {
|
failedItem = if (element.isDirectory) {
|
||||||
recursiveCopyDirectory(originalPath, currentDirectoryPath)
|
recursiveCopyDirectory(element.fullPath, currentDirectoryPath)
|
||||||
} else {
|
} 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) {
|
if (failedItem != null) {
|
||||||
stopTask {
|
stopTask {
|
||||||
@ -385,7 +408,7 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
R.id.share -> {
|
R.id.share -> {
|
||||||
val paths: MutableList<String> = ArrayList()
|
val paths: MutableList<String> = ArrayList()
|
||||||
for (i in explorerAdapter.selectedItems) {
|
for (i in explorerAdapter.selectedItems) {
|
||||||
paths.add(explorerElements[i].getFullPath())
|
paths.add(explorerElements[i].fullPath)
|
||||||
}
|
}
|
||||||
ExternalProvider.share(this, gocryptfsVolume, paths)
|
ExternalProvider.share(this, gocryptfsVolume, paths)
|
||||||
unselectAll()
|
unselectAll()
|
||||||
@ -403,9 +426,6 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
private fun cancelCopy() {
|
private fun cancelCopy() {
|
||||||
if (modeSelectLocation){
|
if (modeSelectLocation){
|
||||||
modeSelectLocation = false
|
modeSelectLocation = false
|
||||||
findViewById<FloatingActionButton>(R.id.fab_add_file).visibility = View.VISIBLE
|
|
||||||
findViewById<FloatingActionButton>(R.id.fab_import_file).visibility = View.VISIBLE
|
|
||||||
findViewById<FloatingActionButton>(R.id.fab_import_file_from_other_volume).visibility = View.VISIBLE
|
|
||||||
filesToCopy.clear()
|
filesToCopy.clear()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -457,15 +477,14 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (e in mappedElements) {
|
for (e in mappedElements) {
|
||||||
val srcPath = e.getFullPath()
|
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, e.fullPath))
|
||||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(srcDirectoryPath, srcPath))
|
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||||
return srcPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!copyFile(srcPath, dstPath)) {
|
if (!copyFile(e.fullPath, dstPath)) {
|
||||||
return srcPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -506,15 +525,14 @@ class ExplorerActivity : BaseExplorerActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (e in mappedElements) {
|
for (e in mappedElements) {
|
||||||
val srcPath = e.getFullPath()
|
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, e.fullPath))
|
||||||
val dstPath = PathUtils.path_join(dstDirectoryPath, PathUtils.getRelativePath(remote_directory_path, srcPath))
|
|
||||||
if (e.isDirectory) {
|
if (e.isDirectory) {
|
||||||
if (!gocryptfsVolume.mkdir(dstPath)){
|
if (!gocryptfsVolume.mkdir(dstPath)){
|
||||||
return srcPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!importFileFromOtherVolume(remote_gocryptfsVolume, srcPath, dstPath)) {
|
if (!importFileFromOtherVolume(remote_gocryptfsVolume, e.fullPath, dstPath)) {
|
||||||
return srcPath
|
return e.fullPath
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import android.content.Intent
|
|||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
|
import android.view.View
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
import sushi.hardcore.droidfs.widgets.ColoredAlertDialogBuilder
|
||||||
@ -13,6 +14,10 @@ class ExplorerActivityDrop : BaseExplorerActivity() {
|
|||||||
setContentView(R.layout.activity_explorer_drop)
|
setContentView(R.layout.activity_explorer_drop)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun onClickFAB(view: View) {
|
||||||
|
openDialogCreateFolder()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
override fun onCreateOptionsMenu(menu: Menu): Boolean {
|
||||||
menuInflater.inflate(R.menu.explorer_drop, menu)
|
menuInflater.inflate(R.menu.explorer_drop, menu)
|
||||||
handleMenuItems(menu)
|
handleMenuItems(menu)
|
||||||
|
@ -5,6 +5,7 @@ import java.util.*
|
|||||||
|
|
||||||
class ExplorerElement(val name: String, val elementType: Short, val size: Long, mtime: Long, private val parentPath: String) {
|
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 mTime = Date((mtime * 1000).toString().toLong())
|
||||||
|
val fullPath: String = PathUtils.path_join(parentPath, name)
|
||||||
|
|
||||||
val isDirectory: Boolean
|
val isDirectory: Boolean
|
||||||
get() = elementType.toInt() == 0
|
get() = elementType.toInt() == 0
|
||||||
@ -15,15 +16,11 @@ class ExplorerElement(val name: String, val elementType: Short, val size: Long,
|
|||||||
val isRegularFile: Boolean
|
val isRegularFile: Boolean
|
||||||
get() = elementType.toInt() == 1
|
get() = elementType.toInt() == 1
|
||||||
|
|
||||||
fun getFullPath(): String {
|
|
||||||
return PathUtils.path_join(parentPath, name)
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun sortBy(sortOrder: String, explorerElements: MutableList<ExplorerElement>) {
|
fun sortBy(sortOrder: String, explorerElements: MutableList<ExplorerElement>) {
|
||||||
when (sortOrder) {
|
when (sortOrder) {
|
||||||
"name" -> {
|
"name" -> {
|
||||||
explorerElements.sortWith(Comparator { o1, o2 -> o1.name.compareTo(o2.name) })
|
explorerElements.sortWith(Comparator { o1, o2 -> o1.fullPath.compareTo(o2.fullPath) })
|
||||||
}
|
}
|
||||||
"size" -> {
|
"size" -> {
|
||||||
explorerElements.sortWith(Comparator { o1, o2 -> (o1.size - o2.size).toInt() })
|
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) })
|
explorerElements.sortWith(Comparator { o1, o2 -> o1.mTime.compareTo(o2.mTime) })
|
||||||
}
|
}
|
||||||
"name_desc" -> {
|
"name_desc" -> {
|
||||||
explorerElements.sortWith(Comparator { o1, o2 -> o2.name.compareTo(o1.name) })
|
explorerElements.sortWith(Comparator { o1, o2 -> o2.fullPath.compareTo(o1.fullPath) })
|
||||||
}
|
}
|
||||||
"size_desc" -> {
|
"size_desc" -> {
|
||||||
explorerElements.sortWith(Comparator { o1, o2 -> (o2.size - o1.size).toInt() })
|
explorerElements.sortWith(Comparator { o1, o2 -> (o2.size - o1.size).toInt() })
|
||||||
|
@ -13,11 +13,8 @@ import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
|||||||
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
import kotlinx.android.synthetic.main.activity_image_viewer.*
|
||||||
import sushi.hardcore.droidfs.ConstValues
|
import sushi.hardcore.droidfs.ConstValues
|
||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
import sushi.hardcore.droidfs.util.MiscUtils
|
import sushi.hardcore.droidfs.util.MiscUtils
|
||||||
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
import sushi.hardcore.droidfs.explorers.ExplorerElement
|
||||||
>>>>>>> ccc453a... Sorted image swipe & ExplorerViewModel
|
|
||||||
import sushi.hardcore.droidfs.util.PathUtils
|
import sushi.hardcore.droidfs.util.PathUtils
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
@ -66,26 +63,18 @@ class ImageViewer: FileViewerActivity() {
|
|||||||
sortOrder = intent.getStringExtra("sortOrder") ?: "name"
|
sortOrder = intent.getStringExtra("sortOrder") ?: "name"
|
||||||
ExplorerElement.sortBy(sortOrder, mappedImages)
|
ExplorerElement.sortBy(sortOrder, mappedImages)
|
||||||
for ((i, e) in mappedImages.withIndex()){
|
for ((i, e) in mappedImages.withIndex()){
|
||||||
if (filePath == e.getFullPath()){
|
if (filePath == e.fullPath){
|
||||||
currentMappedImageIndex = i
|
currentMappedImageIndex = i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
wasMapped = true
|
wasMapped = true
|
||||||
}
|
}
|
||||||
if (deltaX < 0){
|
currentMappedImageIndex = if (deltaX < 0){
|
||||||
if (currentMappedImageIndex == mappedImages.size-1){
|
MiscUtils.incrementIndex(currentMappedImageIndex, mappedImages)
|
||||||
currentMappedImageIndex = 0
|
|
||||||
} else {
|
|
||||||
currentMappedImageIndex += 1
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (currentMappedImageIndex == 0){
|
MiscUtils.decrementIndex(currentMappedImageIndex, mappedImages)
|
||||||
currentMappedImageIndex = mappedImages.size-1
|
|
||||||
} else {
|
|
||||||
currentMappedImageIndex -= 1
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
loadWholeFile(mappedImages[currentMappedImageIndex].getFullPath())?.let {
|
loadWholeFile(mappedImages[currentMappedImageIndex].fullPath)?.let {
|
||||||
glideImage = Glide.with(this).load(it)
|
glideImage = Glide.with(this).load(it)
|
||||||
glideImage.into(image_viewer)
|
glideImage.into(image_viewer)
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,7 @@ class RestrictedFileProvider: ContentProvider() {
|
|||||||
Wiper.wipe(file)
|
Wiper.wipe(file)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dbHelper?.close()
|
||||||
context.deleteDatabase(DB_NAME)
|
context.deleteDatabase(DB_NAME)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,28 +135,26 @@ class RestrictedFileProvider: ContentProvider() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
|
override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
|
||||||
|
var resultCursor: MatrixCursor? = null
|
||||||
val temporaryFile = getFileFromUri(uri)
|
val temporaryFile = getFileFromUri(uri)
|
||||||
temporaryFile?.let{
|
temporaryFile?.let{
|
||||||
val fileName =
|
val fileName = dbHelper?.readableDatabase?.query(TABLE_FILES, arrayOf(TemporaryFileColumns.COLUMN_NAME), TemporaryFileColumns.COLUMN_UUID + "=?", arrayOf(uri.lastPathSegment), null, null, null)
|
||||||
dbHelper?.readableDatabase?.query(TABLE_FILES, arrayOf(TemporaryFileColumns.COLUMN_NAME), TemporaryFileColumns.COLUMN_UUID + "=?", arrayOf(uri.lastPathSegment), null, null, null)
|
|
||||||
fileName?.let{
|
fileName?.let{
|
||||||
if (fileName.moveToNext()) {
|
if (fileName.moveToNext()) {
|
||||||
val cursor = MatrixCursor(
|
resultCursor = MatrixCursor(
|
||||||
arrayOf(
|
arrayOf(
|
||||||
MediaStore.MediaColumns.DISPLAY_NAME,
|
MediaStore.MediaColumns.DISPLAY_NAME,
|
||||||
MediaStore.MediaColumns.SIZE
|
MediaStore.MediaColumns.SIZE
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
cursor.newRow()
|
resultCursor!!.newRow()
|
||||||
.add(fileName.getString(0))
|
.add(fileName.getString(0))
|
||||||
.add(temporaryFile.length())
|
.add(temporaryFile.length())
|
||||||
fileName.close()
|
|
||||||
return cursor
|
|
||||||
}
|
}
|
||||||
fileName.close()
|
fileName.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
return resultCursor
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun delete(uri: Uri, givenSelection: String?, givenSelectionArgs: Array<String>?): Int {
|
override fun delete(uri: Uri, givenSelection: String?, givenSelectionArgs: Array<String>?): Int {
|
||||||
|
@ -166,7 +166,7 @@ class GocryptfsVolume(var sessionID: Int) {
|
|||||||
result.addAll(explorerElements)
|
result.addAll(explorerElements)
|
||||||
for (e in explorerElements){
|
for (e in explorerElements){
|
||||||
if (e.isDirectory){
|
if (e.isDirectory){
|
||||||
result.addAll(recursiveMapFiles(e.getFullPath()))
|
result.addAll(recursiveMapFiles(e.fullPath))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
18
app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt
Normal file
18
app/src/main/java/sushi/hardcore/droidfs/util/MiscUtils.kt
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
package sushi.hardcore.droidfs.util
|
||||||
|
|
||||||
|
object MiscUtils {
|
||||||
|
fun incrementIndex(index: Int, list: List<Any>): Int {
|
||||||
|
var i = index+1
|
||||||
|
if (i >= list.size){
|
||||||
|
i = 0
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
fun decrementIndex(index: Int, list: List<Any>): Int {
|
||||||
|
var i = index-1
|
||||||
|
if (i <= 0){
|
||||||
|
i = list.size-1
|
||||||
|
}
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
}
|
@ -12,12 +12,9 @@ import androidx.core.content.ContextCompat
|
|||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
|
||||||
open class ColoredBorderListView: ListView {
|
open class ColoredBorderListView: ListView {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
val background = ContextCompat.getDrawable(context, R.drawable.listview_border) as StateListDrawable
|
val background = ContextCompat.getDrawable(context, R.drawable.listview_border) as StateListDrawable
|
||||||
val dcs = background.constantState as DrawableContainer.DrawableContainerState
|
val dcs = background.constantState as DrawableContainer.DrawableContainerState
|
||||||
|
@ -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)))
|
|
||||||
}
|
|
||||||
}
|
|
@ -6,12 +6,9 @@ import android.util.AttributeSet
|
|||||||
import androidx.appcompat.widget.AppCompatCheckBox
|
import androidx.appcompat.widget.AppCompatCheckBox
|
||||||
|
|
||||||
class ColoredCheckBox: AppCompatCheckBox {
|
class ColoredCheckBox: AppCompatCheckBox {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
//constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
super.setButtonTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context)))
|
super.setButtonTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context)))
|
||||||
}
|
}
|
||||||
|
@ -14,12 +14,9 @@ import androidx.core.content.ContextCompat
|
|||||||
import sushi.hardcore.droidfs.R
|
import sushi.hardcore.droidfs.R
|
||||||
|
|
||||||
class ColoredEditText: AppCompatEditText {
|
class ColoredEditText: AppCompatEditText {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
super.setBackgroundTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context)))
|
super.setBackgroundTintList(ColorStateList.valueOf(ThemeColor.getThemeColor(context)))
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,18 @@
|
|||||||
package sushi.hardcore.droidfs.widgets
|
package sushi.hardcore.droidfs.widgets
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.res.ColorStateList
|
||||||
import android.util.AttributeSet
|
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 {
|
class ColoredFAB: FloatingActionButton {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
val themeColor = ThemeColor.getThemeColor(context)
|
val themeColor = ThemeColor.getThemeColor(context)
|
||||||
super.setColorNormal(themeColor)
|
backgroundTintList = ColorStateList.valueOf(themeColor)
|
||||||
super.setColorPressed(themeColor)
|
setColorFilter(ContextCompat.getColor(context, android.R.color.white))
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
|
@ -5,12 +5,9 @@ import android.util.AttributeSet
|
|||||||
import androidx.appcompat.widget.AppCompatImageButton
|
import androidx.appcompat.widget.AppCompatImageButton
|
||||||
|
|
||||||
class ColoredImageButton: AppCompatImageButton {
|
class ColoredImageButton: AppCompatImageButton {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
super.setColorFilter(ThemeColor.getThemeColor(context))
|
super.setColorFilter(ThemeColor.getThemeColor(context))
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,9 @@ import android.util.AttributeSet
|
|||||||
import androidx.appcompat.widget.AppCompatImageView
|
import androidx.appcompat.widget.AppCompatImageView
|
||||||
|
|
||||||
class ColoredImageView : AppCompatImageView {
|
class ColoredImageView : AppCompatImageView {
|
||||||
constructor(context: Context) : super(context) {
|
constructor(context: Context) : super(context) { applyColor() }
|
||||||
applyColor()
|
constructor(context: Context, attrs: AttributeSet): super(context, attrs) { applyColor() }
|
||||||
}
|
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int): super(context, attrs, defStyleAttr) { applyColor() }
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs){
|
|
||||||
applyColor()
|
|
||||||
}
|
|
||||||
private fun applyColor(){
|
private fun applyColor(){
|
||||||
super.setColorFilter(ThemeColor.getThemeColor(context))
|
super.setColorFilter(ThemeColor.getThemeColor(context))
|
||||||
}
|
}
|
||||||
|
@ -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
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,17 +7,20 @@ import android.widget.ListAdapter
|
|||||||
class NonScrollableColoredBorderListView: ColoredBorderListView {
|
class NonScrollableColoredBorderListView: ColoredBorderListView {
|
||||||
constructor(context: Context) : super(context)
|
constructor(context: Context) : super(context)
|
||||||
constructor(context: Context, attrs: AttributeSet): super(context, attrs)
|
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?) {
|
override fun setAdapter(adapter: ListAdapter?) {
|
||||||
super.setAdapter(adapter)
|
super.setAdapter(adapter)
|
||||||
adapter?.let {
|
layoutParams.height = computeHeight()
|
||||||
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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
9
app/src/main/res/drawable/button_background.xml
Normal file
9
app/src/main/res/drawable/button_background.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item>
|
||||||
|
<shape android:shape="rectangle">
|
||||||
|
<solid android:color="@color/buttonBackgroundColor"/>
|
||||||
|
<corners android:radius="4dp"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
@ -1,11 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
|
||||||
<solid android:color="#666666"/>
|
|
||||||
<padding
|
|
||||||
android:left="16dp"
|
|
||||||
android:right="16dp"
|
|
||||||
android:top="6dp"
|
|
||||||
android:bottom="6dp"/>
|
|
||||||
<corners
|
|
||||||
android:radius="5dp"/>
|
|
||||||
</shape>
|
|
6
app/src/main/res/drawable/icon_camera.xml
Normal file
6
app/src/main/res/drawable/icon_camera.xml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/icon_camera_back.xml
Normal file
9
app/src/main/res/drawable/icon_camera_back.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="48dp"
|
||||||
|
android:height="48dp"
|
||||||
|
android:viewportWidth="48"
|
||||||
|
android:viewportHeight="48">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M20,40h-10v4h10v4l6,-6 -6,-6v4zM28,40v4h10v-4h-10zM34,0h-20c-2.21,0 -4,1.79 -4,4v28c0,2.21 1.79,4 4,4h20c2.21,0 4,-1.79 4,-4v-28c0,-2.21 -1.79,-4 -4,-4zM23.99,12c-2.21,0 -3.99,-1.79 -3.99,-4s1.78,-4 3.99,-4 4,1.79 4,4 -1.79,4 -4,4z"/>
|
||||||
|
</vector>
|
9
app/src/main/res/drawable/icon_camera_front.xml
Normal file
9
app/src/main/res/drawable/icon_camera_front.xml
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="48dp"
|
||||||
|
android:height="48dp"
|
||||||
|
android:viewportWidth="48"
|
||||||
|
android:viewportHeight="48">
|
||||||
|
<path
|
||||||
|
android:fillColor="#FFFFFF"
|
||||||
|
android:pathData="M20,40h-10v4h10v4l6,-6 -6,-6v4zM28,40v4h10v-4h-10zM24,16c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -3.99,1.79 -3.99,4c0.01,2.21 1.78,4 3.99,4zM34,0h-20c-2.21,0 -4,1.79 -4,4v28c0,2.21 1.79,4 4,4h20c2.21,0 4,-1.79 4,-4v-28c0,-2.21 -1.79,-4 -4,-4zM14,4h20v21c0,-3.33 -6.67,-5 -10,-5s-10,1.67 -10,5v-21z"/>
|
||||||
|
</vector>
|
@ -1,11 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="24dp"
|
android:width="24dp"
|
||||||
android:height="24dp"
|
android:height="24dp"
|
||||||
android:viewportWidth="500"
|
android:viewportWidth="500"
|
||||||
android:viewportHeight="500">
|
android:viewportHeight="500">
|
||||||
|
<path
|
||||||
<path
|
android:pathData="m131.889,118.111l0,63.597l-27.256,0c-20.079,0 -36.343,16.263 -36.343,36.342l0,181.711c0,20.078 16.264,36.34 36.343,36.34l290.734,0c20.078,0 36.345,-16.262 36.345,-36.34l0,-181.711c0,-20.079 -16.267,-36.342 -36.345,-36.342l-27.254,0l0,-63.597c0,-65.232 -52.882,-118.111 -118.112,-118.111s-118.112,52.878 -118.112,118.111zM177.317,181.708l0,-63.597c0,-40.157 32.525,-72.685 72.683,-72.685c40.158,0 72.685,32.528 72.685,72.685l0,63.597l-145.368,0zM213.658,281.649c0,-20.078 16.263,-36.341 36.342,-36.341s36.341,16.263 36.341,36.341c0,12.812 -6.634,24.079 -16.625,30.529c0,0 3.55,21.446 7.542,46.699c0,7.538 -6.087,13.625 -13.629,13.625l-27.258,0c-7.541,0 -13.627,-6.087 -13.627,-13.625l7.542,-46.699c-9.992,-6.45 -16.628,-17.718 -16.628,-30.529z"
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="#FFFFFF"
|
||||||
android:pathData="M131.889,150.061v63.597h-27.256 c-20.079,0-36.343,16.263-36.343,36.342v181.711c0,20.078,16.264,36.34,36.343,36.34h290.734c20.078,0,36.345-16.262,36.345-36.34 V250c0-20.079-16.267-36.342-36.345-36.342h-27.254v-63.597c0-65.232-52.882-118.111-118.112-118.111 S131.889,84.828,131.889,150.061z M177.317,213.658v-63.597c0-40.157,32.525-72.685,72.683-72.685 c40.158,0,72.685,32.528,72.685,72.685v63.597H177.317z M213.658,313.599c0-20.078,16.263-36.341,36.342-36.341 s36.341,16.263,36.341,36.341c0,12.812-6.634,24.079-16.625,30.529c0,0,3.55,21.446,7.542,46.699 c0,7.538-6.087,13.625-13.629,13.625h-27.258c-7.541,0-13.627-6.087-13.627-13.625l7.542-46.699 C220.294,337.678,213.658,326.41,213.658,313.599z" />
|
android:fillType="evenOdd"/>
|
||||||
</vector>
|
</vector>
|
||||||
|
5
app/src/main/res/drawable/icon_flash_auto.xml
Normal file
5
app/src/main/res/drawable/icon_flash_auto.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M3,2v12h3v9l7,-12L9,11l4,-9L3,2zM19,2h-2l-3.2,9h1.9l0.7,-2h3.2l0.7,2h1.9L19,2zM16.85,7.65L18,4l1.15,3.65h-2.3z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/icon_flash_off.xml
Normal file
5
app/src/main/res/drawable/icon_flash_off.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M3.27,3L2,4.27l5,5V13h3v9l3.58,-6.14L17.73,20 19,18.73 3.27,3zM17,10h-4l4,-8H7v2.18l8.46,8.46L17,10z"/>
|
||||||
|
</vector>
|
5
app/src/main/res/drawable/icon_flash_on.xml
Normal file
5
app/src/main/res/drawable/icon_flash_on.xml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24" android:viewportWidth="24"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="@android:color/white" android:pathData="M7,2v11h3v9l7,-12h-4l4,-8z"/>
|
||||||
|
</vector>
|
17
app/src/main/res/drawable/take_photo_button.xml
Normal file
17
app/src/main/res/drawable/take_photo_button.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<solid android:color="#CCCCCC" />
|
||||||
|
<size android:width="75dp" android:height="75dp" />
|
||||||
|
<stroke android:width="15dp" android:color="#444444"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape android:shape="oval">
|
||||||
|
<solid android:color="#FFFFFF"/>
|
||||||
|
<size android:width="75dp" android:height="75dp" />
|
||||||
|
<stroke android:width="8dp" android:color="#444444"/>
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
52
app/src/main/res/layout/activity_camera.xml
Normal file
52
app/src/main/res/layout/activity_camera.xml
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
tools:context=".CameraActivity">
|
||||||
|
|
||||||
|
<com.otaliastudios.cameraview.CameraView
|
||||||
|
android:id="@+id/camera"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
app:cameraGesturePinch="zoom"
|
||||||
|
app:cameraPictureFormat="jpeg"
|
||||||
|
app:cameraAudio="off"/>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginBottom="30dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_flash"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:src="@drawable/icon_flash_auto"
|
||||||
|
android:layout_alignEnd="@id/take_photo_button"
|
||||||
|
android:layout_marginEnd="120dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:onClick="onClickFlash"/>
|
||||||
|
|
||||||
|
<sushi.hardcore.droidfs.widgets.TakePhotoButton
|
||||||
|
android:id="@+id/take_photo_button"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/take_photo_button"
|
||||||
|
android:layout_centerInParent="true"/>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/image_camera_switch"
|
||||||
|
android:layout_width="30dp"
|
||||||
|
android:layout_height="30dp"
|
||||||
|
android:src="@drawable/icon_camera_front"
|
||||||
|
android:layout_alignStart="@id/take_photo_button"
|
||||||
|
android:layout_marginStart="120dp"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:onClick="onClickCameraSwitch"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -25,7 +25,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/volume_path"
|
android:text="@string/volume_path"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_volume_path"
|
android:id="@+id/edit_volume_path"
|
||||||
@ -54,7 +54,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/old_password"
|
android:text="@string/old_password"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_old_password"
|
android:id="@+id/edit_old_password"
|
||||||
@ -74,7 +74,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/new_password"
|
android:text="@string/new_password"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_new_password"
|
android:id="@+id/edit_new_password"
|
||||||
@ -94,7 +94,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/new_password_confirmation"
|
android:text="@string/new_password_confirmation"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_new_password_confirm"
|
android:id="@+id/edit_new_password_confirm"
|
||||||
@ -137,7 +137,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/create_password_warning"/>
|
android:text="@string/create_password_warning"/>
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/action_activity_button_height"
|
android:layout_height="@dimen/action_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/volume_path"
|
android:text="@string/volume_path"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_volume_path"
|
android:id="@+id/edit_volume_path"
|
||||||
@ -54,7 +54,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/password"
|
android:text="@string/password"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_password"
|
android:id="@+id/edit_password"
|
||||||
@ -74,7 +74,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/password_confirm"
|
android:text="@string/password_confirm"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_password_confirm"
|
android:id="@+id/edit_password_confirm"
|
||||||
@ -109,7 +109,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/create_password_warning"/>
|
android:text="@string/create_password_warning"/>
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/action_activity_button_height"
|
android:layout_height="@dimen/action_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
@ -37,53 +36,14 @@
|
|||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAM
|
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
||||||
android:id="@+id/fam_explorer"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_margin="15dp"
|
android:layout_margin="15dp"
|
||||||
app:menu_labels_style="@style/fab_label">
|
android:src="@drawable/icon_add"
|
||||||
|
android:onClick="onClickFAB"/>
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
|
||||||
android:id="@+id/fab_import_file_from_other_volume"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fab_size="mini"
|
|
||||||
app:fab_label="@string/import_from_other_volume"
|
|
||||||
android:src="@drawable/icon_transfert"
|
|
||||||
android:onClick="onClickAddFileFromOtherVolume"/>
|
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
|
||||||
android:id="@+id/fab_import_file"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fab_size="mini"
|
|
||||||
app:fab_label="@string/import_files"
|
|
||||||
android:src="@drawable/icon_encrypt"
|
|
||||||
android:onClick="onClickAddFile"/>
|
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
|
||||||
android:id="@+id/fab_add_file"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fab_size="mini"
|
|
||||||
app:fab_label="@string/new_file"
|
|
||||||
android:src="@drawable/icon_file_unknown"
|
|
||||||
android:onClick="onClickCreateFile"/>
|
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
|
||||||
android:id="@+id/fab_add_folder"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fab_size="mini"
|
|
||||||
app:fab_label="@string/mkdir"
|
|
||||||
android:src="@drawable/icon_folder"
|
|
||||||
android:onClick="onClickAddFolder"
|
|
||||||
tools:ignore="OnClick" />
|
|
||||||
|
|
||||||
</sushi.hardcore.droidfs.widgets.ColoredFAM>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
@ -35,25 +34,14 @@
|
|||||||
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAM
|
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
||||||
android:id="@+id/fam_explorer"
|
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
android:layout_margin="15dp"
|
android:layout_margin="15dp"
|
||||||
app:menu_labels_style="@style/fab_label">
|
android:src="@drawable/icon_add"
|
||||||
|
android:onClick="onClickFAB"/>
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredFAB
|
|
||||||
android:id="@+id/fab_add_folder"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
app:fab_size="mini"
|
|
||||||
app:fab_label="@string/mkdir"
|
|
||||||
android:src="@drawable/icon_folder"
|
|
||||||
android:onClick="onClickAddFolder"/>
|
|
||||||
|
|
||||||
</sushi.hardcore.droidfs.widgets.ColoredFAM>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical">
|
android:orientation="vertical">
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/main_activity_button_height"
|
android:layout_height="@dimen/main_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
||||||
@ -37,7 +37,7 @@
|
|||||||
android:text="@string/open_volume"
|
android:text="@string/open_volume"
|
||||||
style="@style/button"/>
|
style="@style/button"/>
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/main_activity_button_height"
|
android:layout_height="@dimen/main_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
||||||
@ -46,7 +46,7 @@
|
|||||||
android:text="@string/create_volume"
|
android:text="@string/create_volume"
|
||||||
style="@style/button"/>
|
style="@style/button"/>
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/main_activity_button_height"
|
android:layout_height="@dimen/main_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
android:layout_marginHorizontal="@dimen/main_activity_button_hor_margin"
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/volume_path"
|
android:text="@string/volume_path"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_volume_path"
|
android:id="@+id/edit_volume_path"
|
||||||
@ -54,7 +54,7 @@
|
|||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:text="@string/password"
|
android:text="@string/password"
|
||||||
android:textSize="@dimen/edit_text_label_size" />
|
android:textSize="@dimen/edit_text_label_text_size" />
|
||||||
|
|
||||||
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
<sushi.hardcore.droidfs.widgets.ColoredEditText
|
||||||
android:id="@+id/edit_password"
|
android:id="@+id/edit_password"
|
||||||
@ -96,7 +96,7 @@
|
|||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:text="@string/open_activity_warning"/>
|
android:text="@string/open_activity_warning"/>
|
||||||
|
|
||||||
<Button
|
<androidx.appcompat.widget.AppCompatButton
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/action_activity_button_height"
|
android:layout_height="@dimen/action_activity_button_height"
|
||||||
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
android:layout_marginHorizontal="@dimen/action_activity_button_horizontal_margin"
|
||||||
|
@ -8,7 +8,8 @@
|
|||||||
android:id="@+id/icon"
|
android:id="@+id/icon"
|
||||||
android:layout_width="50dp"
|
android:layout_width="50dp"
|
||||||
android:layout_height="50dp"
|
android:layout_height="50dp"
|
||||||
android:layout_marginStart="20dp"/>
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_marginEnd="5dp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/text"
|
android:id="@+id/text"
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
android:singleLine="true"
|
android:singleLine="true"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:layout_marginStart="50dp"
|
android:layout_marginStart="50dp"
|
||||||
android:textSize="15dp"/>
|
android:textSize="15sp"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/total_size_text"
|
android:id="@+id/total_size_text"
|
||||||
@ -23,6 +23,7 @@
|
|||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:textAlignment="viewEnd"
|
android:textAlignment="viewEnd"
|
||||||
android:layout_marginEnd="50dp"
|
android:layout_marginEnd="50dp"
|
||||||
android:textSize="15dp"/>
|
android:textSize="15sp"
|
||||||
|
android:text="@string/default_total_size"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
@ -1,14 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<dimen name="main_activity_button_height">70dp</dimen>
|
<dimen name="main_activity_button_height">60dp</dimen>
|
||||||
<dimen name="main_activity_button_hor_margin">50dp</dimen>
|
<dimen name="main_activity_button_hor_margin">50dp</dimen>
|
||||||
<dimen name="main_activity_button_ver_margin">15dp</dimen>
|
<dimen name="main_activity_button_ver_margin">20dp</dimen>
|
||||||
<dimen name="create_activity_label_width">100dp</dimen>
|
<dimen name="create_activity_label_width">100dp</dimen>
|
||||||
<dimen name="edit_text_label_size">15sp</dimen>
|
<dimen name="edit_text_label_text_size">15sp</dimen>
|
||||||
<dimen name="open_activity_label_width">90dp</dimen>
|
<dimen name="open_activity_label_width">90dp</dimen>
|
||||||
<dimen name="change_password_activity_label_width">100dp</dimen>
|
<dimen name="change_password_activity_label_width">100dp</dimen>
|
||||||
<dimen name="action_activity_button_horizontal_margin">60dp</dimen>
|
<dimen name="action_activity_button_horizontal_margin">60dp</dimen>
|
||||||
<dimen name="action_activity_button_height">60dp</dimen>
|
<dimen name="action_activity_button_height">50dp</dimen>
|
||||||
<dimen name="action_activity_listview_margin_horizontal">50dp</dimen>
|
<dimen name="action_activity_listview_margin_horizontal">50dp</dimen>
|
||||||
<dimen name="action_activity_listview_margin_top">20dp</dimen>
|
<dimen name="action_activity_listview_margin_top">20dp</dimen>
|
||||||
<dimen name="warning_msg_padding">20dp</dimen>
|
<dimen name="warning_msg_padding">20dp</dimen>
|
||||||
|
@ -6,8 +6,8 @@
|
|||||||
<string name="password">Password:</string>
|
<string name="password">Password:</string>
|
||||||
<string name="password_confirm">Password (confirmation):</string>
|
<string name="password_confirm">Password (confirmation):</string>
|
||||||
<string name="volume_path">Volume Path:</string>
|
<string name="volume_path">Volume Path:</string>
|
||||||
<string name="import_files">Import/Encrypt Files</string>
|
<string name="import_files">Import/Encrypt files</string>
|
||||||
<string name="mkdir">Create Folder</string>
|
<string name="mkdir">Create folder</string>
|
||||||
<string name="dir_empty">Directory Empty</string>
|
<string name="dir_empty">Directory Empty</string>
|
||||||
<string name="warning">Warning !</string>
|
<string name="warning">Warning !</string>
|
||||||
<string name="ask_close_volume">Are you sure you want to close this volume ?</string>
|
<string name="ask_close_volume">Are you sure you want to close this volume ?</string>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<string name="error">Error</string>
|
<string name="error">Error</string>
|
||||||
<string name="error_filename_empty">Please enter a name</string>
|
<string name="error_filename_empty">Please enter a name</string>
|
||||||
<string name="error_mkdir">Folder creation failed.</string>
|
<string name="error_mkdir">Folder creation failed.</string>
|
||||||
<string name="success_import">Import Successful !</string>
|
<string name="success_import">Import successful !</string>
|
||||||
<string name="success_import_msg">The selected files have been successfully imported.</string>
|
<string name="success_import_msg">The selected files have been successfully imported.</string>
|
||||||
<string name="import_failed">Import of %1$s failed.</string>
|
<string name="import_failed">Import of %1$s failed.</string>
|
||||||
<string name="export_failed">Export of %1$s failed.</string>
|
<string name="export_failed">Export of %1$s failed.</string>
|
||||||
@ -119,7 +119,7 @@
|
|||||||
<string name="discard">Discard</string>
|
<string name="discard">Discard</string>
|
||||||
<string name="word_wrap">Word Wrap</string>
|
<string name="word_wrap">Word Wrap</string>
|
||||||
<string name="outofmemoryerror_msg">OutOfMemoryError: This file is too large to be loaded in memory.</string>
|
<string name="outofmemoryerror_msg">OutOfMemoryError: This file is too large to be loaded in memory.</string>
|
||||||
<string name="new_file">Create New File</string>
|
<string name="new_file">Create new file</string>
|
||||||
<string name="enter_file_name">File name:</string>
|
<string name="enter_file_name">File name:</string>
|
||||||
<string name="file_creation_failed">Failed to create the file.</string>
|
<string name="file_creation_failed">Failed to create the file.</string>
|
||||||
<string name="loading">Loading…</string>
|
<string name="loading">Loading…</string>
|
||||||
@ -139,4 +139,9 @@
|
|||||||
<string name="copy_failed">Copy of %1$s failed.</string>
|
<string name="copy_failed">Copy of %1$s failed.</string>
|
||||||
<string name="copy_success_msg">The selected items have been successfully copied.</string>
|
<string name="copy_success_msg">The selected items have been successfully copied.</string>
|
||||||
<string name="copy_success">Copy successful !</string>
|
<string name="copy_success">Copy successful !</string>
|
||||||
|
<string name="fab_dialog_title">Add</string>
|
||||||
|
<string name="take_photo">Take photo</string>
|
||||||
|
<string name="picture_save_success">Picture saved to %1$s</string>
|
||||||
|
<string name="picture_save_failed">Failed to save this picture.</string>
|
||||||
|
<string name="default_total_size">N//A</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
@ -4,14 +4,11 @@
|
|||||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||||
<item name="android:colorBackground">@color/backgroundColor</item>
|
<item name="android:colorBackground">@color/backgroundColor</item>
|
||||||
<item name="android:textColor">@color/textColor</item>
|
<item name="android:textColor">@color/textColor</item>
|
||||||
<item name="checkboxStyle">@style/checkbox</item>
|
<!--<item name="checkboxStyle">@style/checkbox</item>-->
|
||||||
<!--<item name="actionOverflowMenuStyle">@style/menu_overflow</item>-->
|
<!--<item name="actionOverflowMenuStyle">@style/menu_overflow</item>-->
|
||||||
</style>
|
</style>
|
||||||
<style name="fab_label">
|
|
||||||
<item name="android:background">@drawable/fab_label_background</item>
|
|
||||||
</style>
|
|
||||||
<style name="button" parent="Widget.AppCompat.Button">
|
<style name="button" parent="Widget.AppCompat.Button">
|
||||||
<item name="android:backgroundTint">@color/buttonBackgroundColor</item>
|
<item name="android:background">@drawable/button_background</item>
|
||||||
</style>
|
</style>
|
||||||
<style name="listViewNoDivider">
|
<style name="listViewNoDivider">
|
||||||
<item name="android:divider">#000000</item>
|
<item name="android:divider">#000000</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user