From 225480ee9c134033b8342136985cdda134bed3b2 Mon Sep 17 00:00:00 2001
From: emreesen27 <45034416+emreesen27@users.noreply.github.com>
Date: Sat, 17 Feb 2024 16:56:18 +0300
Subject: [PATCH 01/12] [DEV][Update README.md]
---
README.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/README.md b/README.md
index 739f04c..b6a83c1 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,7 @@ Simple File Manager for Android
Overview
---
+
@@ -16,6 +17,12 @@ Overview
+Downloads
+---
+
+[](https://play.google.com/store/apps/details?id=com.sn.snfilemanager)
+
+
Preview
---
| Home | Media | Folders |
From b6b97c64308b3f6a96e9e0b0eaf86cdc2c911908 Mon Sep 17 00:00:00 2001
From: emreesen27 <45034416+emreesen27@users.noreply.github.com>
Date: Sat, 17 Feb 2024 16:59:51 +0300
Subject: [PATCH 02/12] [FIX][README.md icon size fix]
---
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index b6a83c1..ccc632c 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Simple File Manager for Android
Overview
---
-
+
@@ -20,7 +20,7 @@ Overview
Downloads
---
-[
](https://play.google.com/store/apps/details?id=com.sn.snfilemanager)
+[
](https://play.google.com/store/apps/details?id=com.sn.snfilemanager)
Preview
From f52579d5257af8582e00ba843a788134842520b8 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Wed, 21 Feb 2024 13:21:59 +0300
Subject: [PATCH 03/12] [DEV][version update]
---
app/build.gradle | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/app/build.gradle b/app/build.gradle
index 981dc5f..c6acb5a 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -39,8 +39,8 @@ android {
applicationId "com.sn.snfilemanager"
minSdk 26
targetSdk 34
- versionCode 3
- versionName "1.0.0-beta3"
+ versionCode 4
+ versionName "1.0.0-beta4"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
From 45b8e732406f056931ad3f1079666aa8ba29bd11 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Wed, 21 Feb 2024 20:48:07 +0300
Subject: [PATCH 04/12] [DEV][home menu edited]
---
.../sn/snfilemanager/core/extensions/Context.kt | 7 +++++++
.../com/sn/snfilemanager/core/util/Constant.kt | 1 +
.../snfilemanager/feature/about/AboutFragment.kt | 13 +++----------
.../sn/snfilemanager/feature/home/HomeFragment.kt | 15 +++++++--------
.../snfilemanager/feature/start/StartFragment.kt | 13 +++----------
.../view/dialog/license/LicenseAdapter.kt | 13 +++----------
app/src/main/res/menu/menu_home.xml | 9 ++-------
app/src/main/res/values-tr/strings.xml | 1 +
app/src/main/res/values/strings.xml | 1 +
9 files changed, 28 insertions(+), 45 deletions(-)
diff --git a/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt b/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt
index 2ba9ea2..e9e0642 100644
--- a/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt
+++ b/app/src/main/java/com/sn/snfilemanager/core/extensions/Context.kt
@@ -115,3 +115,10 @@ fun Context.startActivitySafely(intent: Intent) {
// Todo
}
}
+
+fun Context.openUrl(url: String) {
+ val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
+ startActivitySafely(intent)
+}
+
+fun Context.getPackage(): String = "package:${this.packageName}"
diff --git a/app/src/main/java/com/sn/snfilemanager/core/util/Constant.kt b/app/src/main/java/com/sn/snfilemanager/core/util/Constant.kt
index 755beaf..88f3070 100644
--- a/app/src/main/java/com/sn/snfilemanager/core/util/Constant.kt
+++ b/app/src/main/java/com/sn/snfilemanager/core/util/Constant.kt
@@ -7,4 +7,5 @@ object Constant {
"https://github.com/emreesen27/Android-Sn-File-Manager/blob/develop/PRIVACY.md"
const val OPEN_SOURCE_LICENSE =
"https://github.com/emreesen27/Android-Sn-File-Manager/blob/develop/LICENSE"
+ const val STORE_URL = "https://play.google.com/store/apps/details?id=com.sn.snfilemanager"
}
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt
index d628b04..52ba261 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/about/AboutFragment.kt
@@ -1,11 +1,9 @@
package com.sn.snfilemanager.feature.about
-import android.content.Intent
-import android.net.Uri
import androidx.navigation.fragment.findNavController
import com.sn.snfilemanager.core.base.BaseFragment
import com.sn.snfilemanager.core.extensions.click
-import com.sn.snfilemanager.core.extensions.startActivitySafely
+import com.sn.snfilemanager.core.extensions.openUrl
import com.sn.snfilemanager.core.util.Constant.GITHUB_URL
import com.sn.snfilemanager.core.util.Constant.PRIVACY_URL
import com.sn.snfilemanager.databinding.FragmentAboutBinding
@@ -24,17 +22,12 @@ class AboutFragment : BaseFragment() {
private fun initClicks() {
binding.toolbar.setNavigationOnClickListener { findNavController().popBackStack() }
- binding.btnGithub.click { openUrl(GITHUB_URL) }
+ binding.btnGithub.click { context?.openUrl(GITHUB_URL) }
binding.btnLicense.click { showLicensesDialog() }
- binding.btnPrivacy.click { openUrl(PRIVACY_URL) }
+ binding.btnPrivacy.click { context?.openUrl(PRIVACY_URL) }
}
private fun showLicensesDialog() {
LicenseDialog().show(childFragmentManager, LicenseDialog.TAG)
}
-
- private fun openUrl(url: String) {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- context?.startActivitySafely(intent)
- }
}
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt
index 45a498d..92d2427 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/home/HomeFragment.kt
@@ -18,8 +18,11 @@ import com.sn.mediastorepv.data.MediaType
import com.sn.snfilemanager.R
import com.sn.snfilemanager.core.base.BaseFragment
import com.sn.snfilemanager.core.extensions.click
+import com.sn.snfilemanager.core.extensions.getPackage
import com.sn.snfilemanager.core.extensions.infoToast
import com.sn.snfilemanager.core.extensions.observe
+import com.sn.snfilemanager.core.extensions.openUrl
+import com.sn.snfilemanager.core.util.Constant
import com.sn.snfilemanager.core.util.DocumentType
import com.sn.snfilemanager.core.util.RootPath
import com.sn.snfilemanager.databinding.FragmentHomeBinding
@@ -53,12 +56,8 @@ class HomeFragment : BaseFragment() {
override fun onMenuItemSelected(menuItemId: Int) =
when (menuItemId) {
- R.id.settings -> {
- navigate(HomeFragmentDirections.actionSettings())
- true
- }
-
- R.id.about -> {
+ R.id.store -> {
+ context?.openUrl(Constant.STORE_URL)
true
}
@@ -135,7 +134,7 @@ class HomeFragment : BaseFragment() {
val intent =
Intent(
Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION,
- Uri.parse("package:${requireActivity().packageName}"),
+ Uri.parse(context?.getPackage()),
)
startActivity(intent)
}
@@ -144,7 +143,7 @@ class HomeFragment : BaseFragment() {
val intent =
Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
- Uri.parse("package:${requireActivity().packageName}"),
+ Uri.parse(context?.getPackage()),
)
startActivity(intent)
}
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/start/StartFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/start/StartFragment.kt
index ce7cc6c..3fe9b7b 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/start/StartFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/start/StartFragment.kt
@@ -1,11 +1,9 @@
package com.sn.snfilemanager.feature.start
-import android.content.Intent
-import android.net.Uri
import com.sn.snfilemanager.BuildConfig
import com.sn.snfilemanager.core.base.BaseFragment
import com.sn.snfilemanager.core.extensions.click
-import com.sn.snfilemanager.core.extensions.startActivitySafely
+import com.sn.snfilemanager.core.extensions.openUrl
import com.sn.snfilemanager.core.util.Constant.OPEN_SOURCE_LICENSE
import com.sn.snfilemanager.core.util.Constant.PRIVACY_URL
import com.sn.snfilemanager.databinding.FragmentStartBinding
@@ -35,12 +33,7 @@ class StartFragment : BaseFragment() {
}
private fun clicksPolicy() {
- binding.mtvPrivacyPolicy.click { openUrl(PRIVACY_URL) }
- binding.mtvOpenSourcePolicy.click { openUrl(OPEN_SOURCE_LICENSE) }
- }
-
- private fun openUrl(url: String) {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- context?.startActivitySafely(intent)
+ binding.mtvPrivacyPolicy.click { context?.openUrl(PRIVACY_URL) }
+ binding.mtvOpenSourcePolicy.click { context?.openUrl(OPEN_SOURCE_LICENSE) }
}
}
diff --git a/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt
index 464d29e..319536b 100644
--- a/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt
+++ b/app/src/main/java/com/sn/snfilemanager/view/dialog/license/LicenseAdapter.kt
@@ -1,13 +1,11 @@
package com.sn.snfilemanager.view.dialog.license
import android.content.Context
-import android.content.Intent
-import android.net.Uri
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.sn.snfilemanager.core.extensions.click
-import com.sn.snfilemanager.core.extensions.startActivitySafely
+import com.sn.snfilemanager.core.extensions.openUrl
import com.sn.snfilemanager.databinding.ItemLicenseBinding
class LicenseAdapter(private val context: Context) :
@@ -72,13 +70,13 @@ class LicenseAdapter(private val context: Context) :
binding.mtvGithub.click {
if (adapterPosition != RecyclerView.NO_POSITION) {
val clickedLicense = licenses[adapterPosition]
- openUrl(clickedLicense.url)
+ context.openUrl(clickedLicense.url)
}
}
binding.mtvLicense.click {
if (adapterPosition != RecyclerView.NO_POSITION) {
val clickedLicense = licenses[adapterPosition]
- openUrl(clickedLicense.license)
+ context.openUrl(clickedLicense.url)
}
}
}
@@ -87,9 +85,4 @@ class LicenseAdapter(private val context: Context) :
binding.mtvName.text = model.name
}
}
-
- private fun openUrl(url: String) {
- val intent = Intent(Intent.ACTION_VIEW, Uri.parse(url))
- context.startActivitySafely(intent)
- }
}
diff --git a/app/src/main/res/menu/menu_home.xml b/app/src/main/res/menu/menu_home.xml
index 71f931a..066275e 100644
--- a/app/src/main/res/menu/menu_home.xml
+++ b/app/src/main/res/menu/menu_home.xml
@@ -3,13 +3,8 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
-
-
\ No newline at end of file
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 9d02f7c..775439b 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -98,4 +98,5 @@
Sistem
Koyu
Açık
+ Mağazada göster
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3b4fa1f..3e025cf 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -102,4 +102,5 @@
System
Dark
Light
+ Show in store
\ No newline at end of file
From 30382328f82b545a7a08e87745ee6528e75b1e71 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Wed, 21 Feb 2024 20:50:49 +0300
Subject: [PATCH 05/12] [DEV][changelog updated]
---
CHANGELOG.md | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index baea749..e6fc4e1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+## v1.0.0-beta4 (--.--.----)
+
+* Home screen menu arrangement
+
## v1.0.0-beta3 (16.02.2024)
* UI improvement
From bd27ee67d577ec1a91683be59912207667d9b9a0 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Sat, 24 Feb 2024 14:15:52 +0300
Subject: [PATCH 06/12] [DEV][create folder feature is completed]
---
.../feature/files/adapter/FileItemAdapter.kt | 11 ++-
.../files/presentation/FilesListFragment.kt | 40 ++++++++-
.../files/presentation/FilesListViewModel.kt | 32 +++++--
.../media/presentation/MediaFragment.kt | 1 +
.../com/sn/snfilemanager/job/JobService.kt | 9 ++
.../java/com/sn/snfilemanager/job/JobType.kt | 1 +
.../snfilemanager/job/file/CreateDirectory.kt | 23 +++++
.../view/dialog/CreateDirectoryDialog.kt | 72 ++++++++++++++++
.../color/text_input_layout_stroke_color.xml | 6 ++
.../res/layout/dialog_create_directory.xml | 85 +++++++++++++++++++
app/src/main/res/menu/menu_files.xml | 19 +++++
app/src/main/res/values-tr/strings.xml | 4 +
app/src/main/res/values/strings.xml | 4 +
app/src/main/res/values/styles.xml | 5 ++
14 files changed, 303 insertions(+), 9 deletions(-)
create mode 100644 app/src/main/java/com/sn/snfilemanager/job/file/CreateDirectory.kt
create mode 100644 app/src/main/java/com/sn/snfilemanager/view/dialog/CreateDirectoryDialog.kt
create mode 100644 app/src/main/res/color/text_input_layout_stroke_color.xml
create mode 100644 app/src/main/res/layout/dialog_create_directory.xml
create mode 100644 app/src/main/res/menu/menu_files.xml
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/files/adapter/FileItemAdapter.kt b/app/src/main/java/com/sn/snfilemanager/feature/files/adapter/FileItemAdapter.kt
index 8e93ee5..2fe8c2b 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/files/adapter/FileItemAdapter.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/files/adapter/FileItemAdapter.kt
@@ -24,14 +24,19 @@ class FileItemAdapter(
) : RecyclerView.Adapter() {
private val selectedItems: MutableList = mutableListOf()
private var isSelectionModeActive = false
- private var fileItems: List = emptyList()
+ private var fileItems: MutableList = mutableListOf()
- fun setItems(newItems: List) {
+ fun setItems(newItems: MutableList) {
val diffResult = DiffUtil.calculateDiff(FileDiffCallback(fileItems, newItems))
fileItems = newItems
diffResult.dispatchUpdatesTo(this)
}
+ fun addItem(newItems: FileModel) {
+ fileItems.add(newItems)
+ notifyItemInserted(fileItems.size)
+ }
+
fun removeItems(filesToRemove: List) {
for (fileToRemove in filesToRemove) {
val position = fileItems.indexOf(fileToRemove)
@@ -55,6 +60,8 @@ class FileItemAdapter(
selectionCallback?.onEndSelection()
}
+ fun getItems(): MutableList = fileItems
+
fun getSelectedItems(): MutableList = selectedItems
fun selectionIsActive(): Boolean = isSelectionModeActive
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListFragment.kt
index 0914b9d..b9600b6 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListFragment.kt
@@ -25,6 +25,7 @@ import com.sn.snfilemanager.core.util.RootPath
import com.sn.snfilemanager.databinding.FragmentFilesListBinding
import com.sn.snfilemanager.feature.files.adapter.FileItemAdapter
import com.sn.snfilemanager.feature.files.data.FileModel
+import com.sn.snfilemanager.feature.files.data.toFileModel
import com.sn.snfilemanager.feature.pathpicker.presentation.PathPickerFragment
import com.sn.snfilemanager.job.JobCompletedCallback
import com.sn.snfilemanager.job.JobService
@@ -33,6 +34,7 @@ import com.sn.snfilemanager.view.component.breadcrumb.BreadCrumbItemClickListene
import com.sn.snfilemanager.view.component.breadcrumb.BreadItem
import com.sn.snfilemanager.view.dialog.ConfirmationDialog
import com.sn.snfilemanager.view.dialog.ConflictDialog
+import com.sn.snfilemanager.view.dialog.CreateDirectoryDialog
import com.sn.snfilemanager.view.dialog.detail.DetailDialog
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
@@ -54,7 +56,7 @@ class FilesListFragment :
override fun getViewBinding() = FragmentFilesListBinding.inflate(layoutInflater)
- override fun getMenuResId(): Int = R.menu.menu_base
+ override fun getMenuResId(): Int = R.menu.menu_files
override fun getToolbar(): Toolbar = binding.toolbar
@@ -65,6 +67,13 @@ class FilesListFragment :
true
}
+ R.id.create_folder -> {
+ viewModel.currentPath?.let { path ->
+ showCreateDirectoryDialog(path)
+ }
+ true
+ }
+
else -> super.onMenuItemSelected(menuItemId)
}
@@ -164,6 +173,16 @@ class FilesListFragment :
JobType.DELETE -> {
activity?.runOnUiThread {
data?.filterIsInstance()?.let { adapter?.removeItems(it) }
+ adapter?.getItems()?.let { viewModel.setUpdateList(it) }
+ }
+ }
+
+ JobType.CREATE -> {
+ activity?.runOnUiThread {
+ data?.filterIsInstance()?.firstOrNull()?.toFileModel()?.let { file ->
+ adapter?.addItem(file)
+ adapter?.getItems()?.let { viewModel.setUpdateList(it) }
+ }
}
}
}
@@ -195,6 +214,11 @@ class FilesListFragment :
startDeleteService(data)
}
}
+ observe(viewModel.startCreateFolderJob) { event ->
+ event.getContentIfNotHandled()?.let { path ->
+ startCreateDirectory(path)
+ }
+ }
observe(viewModel.updateListLiveData) { event ->
event.getContentIfNotHandled()?.let { list ->
adapter?.setItems(list)
@@ -330,6 +354,12 @@ class FilesListFragment :
)
}
+ private fun showCreateDirectoryDialog(path: String) {
+ CreateDirectoryDialog(path = path, onCreate = { folderName ->
+ viewModel.createFolder(folderName)
+ }).show(childFragmentManager, CreateDirectoryDialog.TAG)
+ }
+
private fun actionDetail() {
DetailDialog(requireContext(), viewModel.getSelectedItem()).show(
childFragmentManager,
@@ -389,6 +419,14 @@ class FilesListFragment :
)
}
+ private fun startCreateDirectory(destinationPath: Path) {
+ JobService.createDirectory(
+ destinationPath,
+ this@FilesListFragment,
+ requireContext(),
+ )
+ }
+
private fun initSearch() {
binding.toolbar.menu?.findItem(R.id.action_search)?.let { item ->
val searchView = item.actionView as? SearchView
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListViewModel.kt b/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListViewModel.kt
index 3a76f35..15d35c3 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListViewModel.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/files/presentation/FilesListViewModel.kt
@@ -62,13 +62,17 @@ class FilesListViewModel
MutableLiveData()
val startDeleteJobLiveData: LiveData>> = _startDeleteJobLiveData
- private val _updateListLiveData: MutableLiveData>> = MutableLiveData()
- val updateListLiveData: LiveData>> = _updateListLiveData
+ private val _updateListLiveData: MutableLiveData>> =
+ MutableLiveData()
+ val updateListLiveData: LiveData>> = _updateListLiveData
private val _searchStateLiveData: MutableLiveData>> =
MutableLiveData()
val searchStateLiveData: LiveData>> = _searchStateLiveData
+ private val _startCreateFolderJob: MutableLiveData> = MutableLiveData()
+ val startCreateFolderJob: LiveData> = _startCreateFolderJob
+
var conflictDialogDeferred = CompletableDeferred>()
companion object {
@@ -133,7 +137,7 @@ class FilesListViewModel
val fileList: MutableList = mutableListOf()
if (totalFiles == 0L) {
- _updateListLiveData.postValue(Event(emptyList()))
+ _updateListLiveData.postValue(Event(mutableListOf()))
return@launch
}
@@ -145,25 +149,36 @@ class FilesListViewModel
.skip(processedFiles)
.limit(currentBatchSize)
.forEach { file ->
- if (Files.isReadable(file) && (Config.hiddenFile || !Files.isHidden(file))) {
+ if (Files.isReadable(file) && (
+ Config.hiddenFile ||
+ !Files.isHidden(
+ file,
+ )
+ )
+ ) {
fileList.add(file.toFileModel())
}
}
}
withContext(Dispatchers.Main) {
- _updateListLiveData.postValue(Event(fileList.toList()))
+ _updateListLiveData.postValue(Event(fileList))
}
processedFiles += currentBatchSize
}
}
}
+ fun setUpdateList(files: MutableList) {
+ _updateListLiveData.postValue(Event(files))
+ }
+
fun cancelFileListJob() {
if (fileListJob != null && fileListJob?.isActive == true) {
fileListJob?.cancel()
}
}
+ // Todo check free space
fun moveFilesAndDirectories(destinationPath: Path) {
val operationItemList: MutableList = mutableListOf()
viewModelScope.launch {
@@ -208,6 +223,11 @@ class FilesListViewModel
}
}
+ // Todo check free space
+ fun createFolder(targetPath: Path) {
+ _startCreateFolderJob.value = Event(targetPath)
+ }
+
fun deleteFiles() {
val operationItemList: List = selectedItemList.toList()
_startDeleteJobLiveData.postValue(Event(operationItemList))
@@ -252,7 +272,7 @@ class FilesListViewModel
is BaseResult.Success -> {
val list = result.data.map { Paths.get(it).toFileModel() }
_searchStateLiveData.postValue(Event(Pair(false, false)))
- _updateListLiveData.postValue(Event(list))
+ _updateListLiveData.postValue(Event(list.toMutableList()))
}
is BaseResult.Failure -> {
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
index ffb6737..684f062 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
@@ -170,6 +170,7 @@ class MediaFragment :
data?.filterIsInstance()?.let { adapter?.removeItems(it) }
}
}
+ JobType.CREATE -> {}
}
activity?.runOnUiThread { context?.infoToast(getString(R.string.completed)) }
}
diff --git a/app/src/main/java/com/sn/snfilemanager/job/JobService.kt b/app/src/main/java/com/sn/snfilemanager/job/JobService.kt
index ce7dae9..c1d7311 100644
--- a/app/src/main/java/com/sn/snfilemanager/job/JobService.kt
+++ b/app/src/main/java/com/sn/snfilemanager/job/JobService.kt
@@ -12,6 +12,7 @@ import com.sn.snfilemanager.core.util.FrNotificationManager
import com.sn.snfilemanager.core.util.WakeWifiLock
import com.sn.snfilemanager.feature.files.data.FileModel
import com.sn.snfilemanager.job.file.CopyFileJob
+import com.sn.snfilemanager.job.file.CreateDirectory
import com.sn.snfilemanager.job.file.DeleteFileJob
import com.sn.snfilemanager.job.media.DeleteMediaJob
import com.sn.snfilemanager.job.media.MoveMediaJob
@@ -151,6 +152,14 @@ class JobService : Service() {
startJob(MoveMediaJob(sources, targetPath, isCopy, completed), context)
}
+ fun createDirectory(
+ targetPath: Path,
+ completed: JobCompletedCallback,
+ context: Context,
+ ) {
+ startJob(CreateDirectory(targetPath, completed), context)
+ }
+
@MainThread
fun cancelJob(id: Int) {
pendingJobs.removeFirst { it.id == id }
diff --git a/app/src/main/java/com/sn/snfilemanager/job/JobType.kt b/app/src/main/java/com/sn/snfilemanager/job/JobType.kt
index 0165b70..0b256f7 100644
--- a/app/src/main/java/com/sn/snfilemanager/job/JobType.kt
+++ b/app/src/main/java/com/sn/snfilemanager/job/JobType.kt
@@ -3,4 +3,5 @@ package com.sn.snfilemanager.job
enum class JobType {
COPY,
DELETE,
+ CREATE,
}
diff --git a/app/src/main/java/com/sn/snfilemanager/job/file/CreateDirectory.kt b/app/src/main/java/com/sn/snfilemanager/job/file/CreateDirectory.kt
new file mode 100644
index 0000000..7319942
--- /dev/null
+++ b/app/src/main/java/com/sn/snfilemanager/job/file/CreateDirectory.kt
@@ -0,0 +1,23 @@
+package com.sn.snfilemanager.job.file
+
+import com.sn.snfilemanager.core.base.BaseJob
+import com.sn.snfilemanager.job.JobCompletedCallback
+import com.sn.snfilemanager.job.JobType
+import java.nio.file.Files
+import java.nio.file.Path
+
+class CreateDirectory(
+ private val targetPath: Path,
+ private val completed: JobCompletedCallback,
+) : BaseJob() {
+ private val directory: MutableList = mutableListOf()
+
+ override fun run() {
+ val dir = Files.createDirectories(targetPath)
+ directory.add(dir)
+ }
+
+ override fun onCompleted() {
+ completed.jobOnCompleted(JobType.CREATE, directory)
+ }
+}
diff --git a/app/src/main/java/com/sn/snfilemanager/view/dialog/CreateDirectoryDialog.kt b/app/src/main/java/com/sn/snfilemanager/view/dialog/CreateDirectoryDialog.kt
new file mode 100644
index 0000000..1b4bb90
--- /dev/null
+++ b/app/src/main/java/com/sn/snfilemanager/view/dialog/CreateDirectoryDialog.kt
@@ -0,0 +1,72 @@
+package com.sn.snfilemanager.view.dialog
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.constraintlayout.widget.ConstraintLayout
+import androidx.core.widget.addTextChangedListener
+import androidx.fragment.app.DialogFragment
+import com.sn.snfilemanager.R
+import com.sn.snfilemanager.core.extensions.click
+import com.sn.snfilemanager.databinding.DialogCreateDirectoryBinding
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.Paths
+
+class CreateDirectoryDialog(
+ private val path: String,
+ private val onCreate: ((Path) -> Unit)? = null,
+) :
+ DialogFragment() {
+ private val binding: DialogCreateDirectoryBinding by lazy {
+ DialogCreateDirectoryBinding.inflate(layoutInflater)
+ }
+
+ companion object {
+ const val TAG = "CREATE_DIRECTORY_DIALOG"
+ }
+
+ override fun onStart() {
+ super.onStart()
+ dialog?.window?.setLayout(
+ ConstraintLayout.LayoutParams.MATCH_PARENT,
+ ConstraintLayout.LayoutParams.WRAP_CONTENT,
+ )
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
+ ): View {
+ return binding.root
+ }
+
+ override fun onViewCreated(
+ view: View,
+ savedInstanceState: Bundle?,
+ ) {
+ super.onViewCreated(view, savedInstanceState)
+ binding.etFolderName.requestFocus()
+ binding.btnCancel.click { dismiss() }
+ binding.btnCreate.click {
+ val name = binding.etFolderName.text.toString()
+ if (checkNameExists(name)) {
+ binding.inputLayout.error = getString(R.string.folder_exists_warning)
+ } else {
+ onCreate?.invoke(Paths.get(path).resolve(name))
+ dismiss()
+ }
+ }
+ binding.etFolderName.addTextChangedListener { text ->
+ binding.btnCreate.isEnabled = !text.isNullOrEmpty()
+ binding.inputLayout.error = null
+ }
+ }
+
+ private fun checkNameExists(name: String): Boolean {
+ val targetPath = Paths.get(path).resolve(name)
+ return Files.exists(targetPath)
+ }
+}
diff --git a/app/src/main/res/color/text_input_layout_stroke_color.xml b/app/src/main/res/color/text_input_layout_stroke_color.xml
new file mode 100644
index 0000000..61e815d
--- /dev/null
+++ b/app/src/main/res/color/text_input_layout_stroke_color.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_create_directory.xml b/app/src/main/res/layout/dialog_create_directory.xml
new file mode 100644
index 0000000..471335d
--- /dev/null
+++ b/app/src/main/res/layout/dialog_create_directory.xml
@@ -0,0 +1,85 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/menu_files.xml b/app/src/main/res/menu/menu_files.xml
new file mode 100644
index 0000000..d744562
--- /dev/null
+++ b/app/src/main/res/menu/menu_files.xml
@@ -0,0 +1,19 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index 775439b..ce14d1a 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -99,4 +99,8 @@
Koyu
Açık
Mağazada göster
+ Klasör oluştur
+ Oluştur
+ Klasör adı
+ Bu ada sahip klasör zaten mevcut
\ No newline at end of file
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 3e025cf..d8ffd53 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -103,4 +103,8 @@
Dark
Light
Show in store
+ Create folder
+ Create
+ Folder name
+ The folder with this name already exists
\ No newline at end of file
diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml
index fff775f..659c3c5 100644
--- a/app/src/main/res/values/styles.xml
+++ b/app/src/main/res/values/styles.xml
@@ -47,4 +47,9 @@
- @android:color/transparent
+
+
\ No newline at end of file
From fede5081ed06f995686753e8ad41ffb690bef883 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Sat, 24 Feb 2024 14:18:05 +0300
Subject: [PATCH 07/12] [DEV][changelog edited]
---
CHANGELOG.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index e6fc4e1..8d0d136 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,8 @@
## v1.0.0-beta4 (--.--.----)
* Home screen menu arrangement
+* Create folder feature added
+* Minor UI fix
## v1.0.0-beta3 (16.02.2024)
From ca60916020dfe1051499c3eb4fafaee67e89f1aa Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Thu, 29 Feb 2024 19:39:41 +0300
Subject: [PATCH 08/12] [FIX][media open with selection bug fixed]
---
.../snfilemanager/feature/media/presentation/MediaFragment.kt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt b/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
index 684f062..38ceaaf 100644
--- a/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
+++ b/app/src/main/java/com/sn/snfilemanager/feature/media/presentation/MediaFragment.kt
@@ -93,6 +93,7 @@ class MediaFragment :
mode: ActionMode?,
item: MenuItem?,
): Boolean {
+ checkActionMenuStatus()
when (item?.itemId) {
R.id.action_copy -> {
viewModel.isCopy = true
@@ -373,8 +374,8 @@ class MediaFragment :
MediaItemAdapter(
onClick = { model -> openFile(model) },
onSelected = { model, selected ->
- checkActionMenuStatus()
viewModel.addSelectedItem(model, selected)
+ checkActionMenuStatus()
},
selectionCallback = this@MediaFragment,
)
From 4d65c9c73e239e8978da96ff96c98763ba8ba077 Mon Sep 17 00:00:00 2001
From: Emre Esen
Date: Thu, 29 Feb 2024 19:56:25 +0300
Subject: [PATCH 09/12] [DEV][v1.0.0-beta4 is completed]
---
CHANGELOG.md | 2 +-
app/src/main/res/layout/layout_chip.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8d0d136..ac4dac4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-## v1.0.0-beta4 (--.--.----)
+## v1.0.0-beta4 (29.02.2024)
* Home screen menu arrangement
* Create folder feature added
diff --git a/app/src/main/res/layout/layout_chip.xml b/app/src/main/res/layout/layout_chip.xml
index 4a5c5ec..b2bd3f9 100644
--- a/app/src/main/res/layout/layout_chip.xml
+++ b/app/src/main/res/layout/layout_chip.xml
@@ -2,7 +2,7 @@
Date: Thu, 29 Feb 2024 21:40:19 +0300
Subject: [PATCH 10/12] [DEV][Update README.md]
---
README.md | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index ccc632c..819003f 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Simple File Manager for Android
Overview
---
-
+
@@ -13,8 +13,11 @@ Overview
- Open Source, light and smooth
- No ads or In-app purchases
- Supports dark theme
+- Access media items efficiently with MediaStore
+- Quick navigation with Breadcrumb
+- It supports basic operations such as file moving, deleting, and copying
+- A fast and user-friendly interface
- Lots more...
-
Downloads
@@ -27,8 +30,8 @@ Preview
---
| Home | Media | Folders |
|--------------|---------------|--------------|
-| | | |
-| | | |
+| | | |
+| | | |
From 1c5b03f7099d0bfb2434bba701a9d4a695bfccb6 Mon Sep 17 00:00:00 2001
From: emreesen27 <45034416+emreesen27@users.noreply.github.com>
Date: Thu, 29 Feb 2024 22:21:10 +0300
Subject: [PATCH 11/12] [DEV][Create CONTRIBUTING.md]
---
CONTRIBUTING.md | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
create mode 100644 CONTRIBUTING.md
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
new file mode 100644
index 0000000..28114c0
--- /dev/null
+++ b/CONTRIBUTING.md
@@ -0,0 +1,28 @@
+RUN & CONTRIBUTING
+---
+
+#### Run the Project
+
+The application performs operations related to media files through a [submodule](https://github.com/emreesen27/media-store).
+
+Clone the project:
+```
+git clone
+```
+
+Run to fetch and update the submodule:
+```
+git submodule update --init
+```
+
+#### Contribute
+
+At the commit stage, I run commit-msg and lint checks. Committing automatically triggers the lint task. If you encounter any issues, manually trigger it.
+
+```
+./gradlew ktlintFormat
+```
+Ensure your commit message follows this format:
+```
+[DEV]||[FIX] [commit message]
+```
From 4a038af17ee00e29a68352201553b5abc7d083f9 Mon Sep 17 00:00:00 2001
From: emreesen27 <45034416+emreesen27@users.noreply.github.com>
Date: Thu, 29 Feb 2024 22:33:12 +0300
Subject: [PATCH 12/12] [DEV][Update README.md]
---
README.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 819003f..0c716bd 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# Sn File Manager
+# Sn File Manager
Simple File Manager for Android
@@ -33,6 +33,6 @@ Preview
| | | |
| | | |
-
-
-
+Run & Contributing
+---
+ Read [this](https://github.com/emreesen27/Android-Sn-File-Manager/blob/develop/CONTRIBUTING.md) before running the project or contributing