Skip to content

Commit

Permalink
[feature] Folder creation capability: ARK-Builders/ark-filepicker#5
Browse files Browse the repository at this point in the history
  • Loading branch information
tuancoltech authored and kirillt committed Jan 31, 2024
1 parent 6a1a437 commit 3a53ef1
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package dev.arkbuilders.components.filepicker

import android.app.AlertDialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
Expand Down Expand Up @@ -38,6 +39,7 @@ import dev.arkbuilders.arklib.utils.DeviceStorageUtils
import dev.arkbuilders.arklib.utils.INTERNAL_STORAGE
import org.orbitmvi.orbit.viewmodel.observe
import dev.arkbuilders.components.R
import dev.arkbuilders.components.databinding.ArkFilePickerDialogNewFolderBinding
import dev.arkbuilders.components.databinding.ArkFilePickerHostFragmentBinding
import dev.arkbuilders.components.databinding.ArkFilePickerItemFileBinding
import dev.arkbuilders.components.databinding.ArkFilePickerItemFilesRootsPageBinding
Expand All @@ -47,6 +49,7 @@ import dev.arkbuilders.components.utils.dpToPx
import dev.arkbuilders.components.utils.formatSize
import dev.arkbuilders.components.utils.iconForExtension
import dev.arkbuilders.components.utils.setDragSensitivity
import java.io.File
import java.lang.Exception
import java.nio.file.Path
import kotlin.io.path.Path
Expand All @@ -60,20 +63,20 @@ import kotlin.io.path.name
open class ArkFilePickerFragment :
DialogFragment(R.layout.ark_file_picker_host_fragment) {

var titleStringId by args<Int>()
var pickButtonStringId by args<Int>()
var cancelButtonStringId by args<Int>()
var internalStorageStringId by args<Int>()
var itemsPluralId by args<Int>()
var themeId by args<Int>()
var accessDeniedStringId by args<Int>()
var mode by args<Int>()
var initialPath by args<String?>()
var showRoots by args<Boolean>()
var pathPickedRequestKey by args<String>()
var rootsFirstPage by args<Boolean>()

var currentFolder: Path? = null
private var titleStringId by args<Int>()
private var pickButtonStringId by args<Int>()
private var cancelButtonStringId by args<Int>()
private var internalStorageStringId by args<Int>()
private var itemsPluralId by args<Int>()
private var themeId by args<Int>()
private var accessDeniedStringId by args<Int>()
private var mode by args<Int>()
private var initialPath by args<String?>()
private var showRoots by args<Boolean>()
private var pathPickedRequestKey by args<String>()
private var rootsFirstPage by args<Boolean>()

private var currentFolder: Path? = null
val binding by viewBinding(ArkFilePickerHostFragmentBinding::bind)
private val viewModel by viewModels<ArkFilePickerViewModel> {
ArkFilePickerViewModelFactory(
Expand Down Expand Up @@ -148,6 +151,41 @@ open class ArkFilePickerFragment :
} else {
tabs.isVisible = false
}

if (mode == ArkFilePickerMode.FOLDER.ordinal) {
binding.ivNewFolder.visibility = View.VISIBLE
binding.ivNewFolder.setOnClickListener {
showCreateFolderDialog()
}
} else {
binding.ivNewFolder.visibility = View.GONE
}
}

private fun showCreateFolderDialog() {
val builder = AlertDialog.Builder(activity, android.R.style.ThemeOverlay_Material_Dialog_Alert)
builder.setTitle(R.string.ark_file_picker_new_folder)
val binding = ArkFilePickerDialogNewFolderBinding.inflate(layoutInflater)
builder.setView(binding.root)
builder.setPositiveButton(android.R.string.ok, null)

builder.setNegativeButton(android.R.string.cancel) { _, _ -> }
val dialog = builder.create()
dialog.show()
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener {
val newFolder = File(currentFolder.toString(), binding.editTextFolderName.text.toString().trim())
if (newFolder.exists()) {
binding.inputLayoutFolderName.error = getString(R.string.ark_file_picker_folder_existing)
return@setOnClickListener
}

if (newFolder.mkdirs()) {
//Reload current files tree
currentFolder?.let { viewModel.onItemClick(it) }
dialog.dismiss()
}
}

}

private fun render(state: FilePickerState) = binding.apply {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<vector android:height="24dp" android:tint="#000000"
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="M20,6h-8l-2,-2L4,4c-1.11,0 -1.99,0.89 -1.99,2L2,18c0,1.11 0.89,2 2,2h16c1.11,0 2,-0.89 2,-2L22,8c0,-1.11 -0.89,-2 -2,-2zM19,14h-3v3h-2v-3h-3v-2h3L14,9h2v3h3v2z"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.textfield.TextInputLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="20dp"
android:layout_marginHorizontal="20dp"
android:id="@+id/input_layout_folder_name"
android:hint="@string/ark_file_picker_new_folder_hint">

<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/edit_text_folder_name"
android:background="@android:color/transparent"
tools:ignore="VisualLintTextFieldSize" />


</com.google.android.material.textfield.TextInputLayout>
20 changes: 13 additions & 7 deletions components/src/main/res/layout/ark_file_picker_host_fragment.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@

<TextView
android:id="@+id/tv_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Pick"
android:textAlignment="center"
android:padding="8dp"
android:textColor="@color/black"
android:textSize="18sp" />
android:text="@string/ark_file_picker_pick_title"
style="@style/ArkFileDialogTitle"
android:padding="@dimen/padding_text_dialog_title"/>

<HorizontalScrollView
android:id="@+id/scroll_path"
Expand All @@ -40,6 +36,16 @@
</LinearLayout>
</HorizontalScrollView>

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ark_file_picker_ic_new_folder"
android:layout_gravity="end"
android:layout_marginEnd="16dp"
android:id="@+id/iv_new_folder"
app:tint="@color/ark_file_picker_gray"
android:background="?attr/selectableItemBackgroundBorderless"/>

<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
Expand Down
5 changes: 5 additions & 0 deletions components/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="text_size_dialog_title">18sp</dimen>
<dimen name="padding_text_dialog_title">8dp</dimen>
</resources>
3 changes: 3 additions & 0 deletions components/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
<string name="ark_file_picker_add_favorite">Add favorite</string>
<string name="ark_file_picker_forget_root">Forget root</string>
<string name="ark_file_picker_forget_favorite">Forget favorite</string>
<string name="ark_file_picker_new_folder">New folder</string>
<string name="ark_file_picker_folder_existing">Folder already exists!</string>
<string name="ark_file_picker_new_folder_hint">Name your folder</string>
<plurals name="ark_file_picker_items">
<item quantity="one">%d item</item>
<item quantity="other">%d items</item>
Expand Down
9 changes: 9 additions & 0 deletions components/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,13 @@
<item name="android:windowEnterAnimation">@anim/ark_file_picker_fade_in</item>
<item name="android:windowExitAnimation">@anim/ark_file_pickerfade_out</item>
</style>

<style name="ArkFileDialogTitle">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textSize">@dimen/text_size_dialog_title</item>
<item name="android:textColor">@color/black</item>
<item name="android:gravity">center</item>
</style>

</resources>
11 changes: 9 additions & 2 deletions sample/src/main/java/dev/arkbuilders/sample/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,17 @@ class MainActivity : AppCompatActivity() {
.newInstance()
.show(supportFragmentManager, null)
}

findViewById<MaterialButton>(R.id.btn_open_file_mode).setOnClickListener {
resolvePermissions()
ArkFilePickerFragment
.newInstance(getFilePickerConfig(mode = ArkFilePickerMode.FILE))
.show(supportFragmentManager, null)
}
}

private fun getFilePickerConfig() = ArkFilePickerConfig(
mode = ArkFilePickerMode.FOLDER,
private fun getFilePickerConfig(mode: ArkFilePickerMode? = null) = ArkFilePickerConfig(
mode = mode ?: ArkFilePickerMode.FOLDER,
titleStringId = R.string.file_picker_title,
showRoots = true,
rootsFirstPage = false
Expand Down
12 changes: 10 additions & 2 deletions sample/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Open file picker"
android:text="@string/file_picker_open_folder"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
Expand All @@ -24,4 +23,13 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/btn_open" />

<com.google.android.material.button.MaterialButton
android:id="@+id/btn_open_file_mode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/file_picker_open_file"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_root_picker"/>

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions sample/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<resources>
<string name="app_name">Ark Components</string>
<string name="file_picker_title">Pick favorite folder</string>
<string name="file_picker_open_folder">Open folder picker</string>
<string name="file_picker_open_file">Open file picker</string>
</resources>

0 comments on commit 3a53ef1

Please sign in to comment.