Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V1.0.0 beta8 #55

Merged
merged 3 commits into from
May 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
## v1.0.0-beta-8 (25.05.2024)
* Sorting feature added for file and media items
* The synchronization issue with the show hidden files setting button has been fixed

## v1.0.0-beta7 (26.04.2024)

* ActivityNotFoundException and ClassNotFoundException fixed.
* ActivityNotFoundException and ClassNotFoundException fixed

## v1.0.0-beta6 (24.04.2024)

* The "Rename" feature added.
* Dialogs UI improvement
* The issue of license URLs redirecting to the wrong address fixed
* The 'Access Denied' error in the function calculating file count and size fixed.
* The 'Access Denied' error in the function calculating file count and size fixed

## v1.0.0-beta5 (08.04.2024)

Expand Down
4 changes: 2 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ android {
applicationId "com.sn.snfilemanager"
minSdk 26
targetSdk 34
versionCode 7
versionName "1.0.0-beta7"
versionCode 8
versionName "1.0.0-beta8"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/java/com/sn/snfilemanager/MainViewModel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ package com.sn.snfilemanager
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.sn.snfilemanager.core.util.Config
import com.sn.snfilemanager.core.util.Event
import com.sn.snfilemanager.core.util.SortCriterion
import com.sn.snfilemanager.core.util.SortOrder
import com.sn.snfilemanager.providers.preferences.MySharedPreferences
import com.sn.snfilemanager.providers.preferences.PrefsTag
import dagger.hilt.android.lifecycle.HiltViewModel
Expand All @@ -20,10 +23,24 @@ class MainViewModel

init {
checkFirsRun()
getSortData()
}

private fun checkFirsRun() {
val firstRun: Boolean = mySharedPreferences.getBoolean(PrefsTag.FIRST_RUN)
_firstRunLiveData.postValue(Event(firstRun))
}

private fun getSortData() {
val criterionString = mySharedPreferences.getString(PrefsTag.SORT_CRITERION)
val sortOrderString = mySharedPreferences.getString(PrefsTag.SORT_ORDER)
val mediaCriterionString = mySharedPreferences.getString(PrefsTag.MEDIA_SORT_CRITERION)
val mediaSortOrderString = mySharedPreferences.getString(PrefsTag.MEDIA_SORT_ORDER)

Config.sortCriterion = SortCriterion.valueOf(criterionString ?: SortCriterion.NAME.name)
Config.sortOrder = SortOrder.valueOf(sortOrderString ?: SortOrder.ASCENDING.name)

Config.mediaSortCriterion = SortCriterion.valueOf(mediaCriterionString ?: SortCriterion.NAME.name)
Config.mediaSortOrder = SortOrder.valueOf(mediaSortOrderString ?: SortOrder.ASCENDING.name)
}
}
11 changes: 11 additions & 0 deletions app/src/main/java/com/sn/snfilemanager/core/extensions/String.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.sn.snfilemanager.core.extensions

import android.webkit.MimeTypeMap
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale

fun String.getDirectoryNameFromPath(): String {
val lastSeparatorIndex = this.lastIndexOf("/")
Expand All @@ -24,3 +27,11 @@ fun String.getMimeType(): String? {
val ext = if (extension.isNullOrEmpty()) this.getFileExtension() else extension
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(ext)
}

fun String.toDate(format: String = "dd/MM/yyyy"): Date? {
return try {
SimpleDateFormat(format, Locale.getDefault()).parse(this)
} catch (e: Exception) {
null
}
}
4 changes: 4 additions & 0 deletions app/src/main/java/com/sn/snfilemanager/core/util/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ package com.sn.snfilemanager.core.util

object Config {
var hiddenFile: Boolean = false
var sortCriterion: SortCriterion = SortCriterion.NAME
var sortOrder: SortOrder = SortOrder.ASCENDING
var mediaSortCriterion: SortCriterion = SortCriterion.NAME
var mediaSortOrder: SortOrder = SortOrder.ASCENDING
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sn.snfilemanager.core.util

enum class SortCriterion {
NAME,
LAST_MODIFIED,
}
6 changes: 6 additions & 0 deletions app/src/main/java/com/sn/snfilemanager/core/util/SortOrder.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package com.sn.snfilemanager.core.util

enum class SortOrder {
ASCENDING,
DESCENDING,
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import com.sn.snfilemanager.core.extensions.openFileWithOtherApp
import com.sn.snfilemanager.core.extensions.shareFiles
import com.sn.snfilemanager.core.extensions.visible
import com.sn.snfilemanager.core.extensions.warningToast
import com.sn.snfilemanager.core.util.Config.sortCriterion
import com.sn.snfilemanager.core.util.Config.sortOrder
import com.sn.snfilemanager.core.util.RootPath
import com.sn.snfilemanager.databinding.FragmentFilesListBinding
import com.sn.snfilemanager.feature.files.adapter.FileItemAdapter
Expand All @@ -37,6 +39,7 @@ import com.sn.snfilemanager.view.dialog.ConflictDialog
import com.sn.snfilemanager.view.dialog.CreateDirectoryDialog
import com.sn.snfilemanager.view.dialog.RenameFileDialog
import com.sn.snfilemanager.view.dialog.detail.DetailDialog
import com.sn.snfilemanager.view.dialog.sort.SortDialog
import dagger.hilt.android.AndroidEntryPoint
import java.io.File
import java.nio.file.Files
Expand Down Expand Up @@ -68,6 +71,11 @@ class FilesListFragment :
true
}

R.id.sort -> {
showSortDialog()
true
}

R.id.create_folder -> {
viewModel.currentPath?.let { path ->
showCreateDirectoryDialog(path)
Expand Down Expand Up @@ -188,15 +196,21 @@ class FilesListFragment :
JobType.CREATE -> {
activity?.runOnUiThread {
data?.filterIsInstance<Path>()?.firstOrNull()?.toFileModel()?.let { file ->
adapter?.addItem(file)
// adapter?.addItem(file)
viewModel.currentPath?.let { path ->
viewModel.getFilesList(path)
}
}
}
}

JobType.RENAME -> {
activity?.runOnUiThread {
data?.filterIsInstance<FileModel>()?.firstOrNull()?.let { file ->
adapter?.updateItem(file)
// adapter?.updateItem(file)
viewModel.currentPath?.let { path ->
viewModel.getFilesList(path)
}
}
}
}
Expand Down Expand Up @@ -379,6 +393,14 @@ class FilesListFragment :
}).showDialog(childFragmentManager)
}

private fun showSortDialog() {
SortDialog(isMedia = false, onConfirm = { sortData ->
sortCriterion = sortData.first
sortOrder = sortData.second
with(viewModel) { currentPath?.let { getFilesList(it) } }
}).showDialog(childFragmentManager)
}

private fun showRenameDialog() {
RenameFileDialog(file = viewModel.getSelectedItem().first(), onRename = { newName ->
viewModel.renameFile(newName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@ import androidx.lifecycle.viewModelScope
import com.sn.mediastorepv.data.ConflictStrategy
import com.sn.mediastorepv.data.MediaType
import com.sn.snfilemanager.core.base.BaseResult
import com.sn.snfilemanager.core.extensions.toDate
import com.sn.snfilemanager.core.util.Config
import com.sn.snfilemanager.core.util.Config.sortCriterion
import com.sn.snfilemanager.core.util.Config.sortOrder
import com.sn.snfilemanager.core.util.Event
import com.sn.snfilemanager.core.util.RootPath
import com.sn.snfilemanager.core.util.SortCriterion
import com.sn.snfilemanager.core.util.SortOrder
import com.sn.snfilemanager.feature.files.data.FileModel
import com.sn.snfilemanager.feature.files.data.toFileModel
import com.sn.snfilemanager.providers.filepath.FilePathProvider
Expand All @@ -28,6 +33,7 @@ import java.lang.Long.min
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.util.Locale
import javax.inject.Inject

@HiltViewModel
Expand Down Expand Up @@ -73,7 +79,8 @@ class FilesListViewModel
private val _startCreateFolderJob: MutableLiveData<Event<Path>> = MutableLiveData()
val startCreateFolderJob: LiveData<Event<Path>> = _startCreateFolderJob

private val _startRenameFileJob: MutableLiveData<Event<Pair<FileModel, String>>> = MutableLiveData()
private val _startRenameFileJob: MutableLiveData<Event<Pair<FileModel, String>>> =
MutableLiveData()
val startRenameFileJob: LiveData<Event<Pair<FileModel, String>>> = _startRenameFileJob

var conflictDialogDeferred = CompletableDeferred<Pair<ConflictStrategy, Boolean>>()
Expand Down Expand Up @@ -153,15 +160,13 @@ class FilesListViewModel
.limit(currentBatchSize)
.forEach { file ->
if (Files.isReadable(file) && (
Config.hiddenFile ||
!Files.isHidden(
file,
)
Config.hiddenFile || !Files.isHidden(file)
)
) {
fileList.add(file.toFileModel())
}
}
sortFileList(fileList)
}
withContext(Dispatchers.Main) {
_updateListLiveData.postValue(Event(fileList))
Expand All @@ -171,10 +176,6 @@ class FilesListViewModel
}
}

fun setUpdateList(files: MutableList<FileModel>) {
_updateListLiveData.postValue(Event(files))
}

fun cancelFileListJob() {
if (fileListJob != null && fileListJob?.isActive == true) {
fileListJob?.cancel()
Expand Down Expand Up @@ -222,7 +223,9 @@ class FilesListViewModel
}
}
job.await()
_startMoveJobLiveData.postValue(Event(Pair(operationItemList, destinationPath)))
if (operationItemList.isNotEmpty()) {
_startMoveJobLiveData.postValue(Event(Pair(operationItemList, destinationPath)))
}
}
}

Expand All @@ -247,6 +250,26 @@ class FilesListViewModel
_startDeleteJobLiveData.postValue(Event(operationItemList))
}

private fun sortFileList(fileList: MutableList<FileModel>) {
when (sortCriterion) {
SortCriterion.NAME -> {
if (sortOrder == SortOrder.ASCENDING) {
fileList.sortBy { it.name.lowercase(Locale.getDefault()) }
} else {
fileList.sortByDescending { it.name.lowercase(Locale.getDefault()) }
}
}

SortCriterion.LAST_MODIFIED -> {
if (sortOrder == SortOrder.ASCENDING) {
fileList.sortBy { it.lastModified.toDate() }
} else {
fileList.sortByDescending { it.lastModified.toDate() }
}
}
}
}

private fun removeSearchCallback() {
searchRunnable?.let { handler.removeCallbacks(it) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import com.sn.snfilemanager.core.extensions.openFile
import com.sn.snfilemanager.core.extensions.openFileWithOtherApp
import com.sn.snfilemanager.core.extensions.shareFiles
import com.sn.snfilemanager.core.extensions.warningToast
import com.sn.snfilemanager.core.util.Config.mediaSortCriterion
import com.sn.snfilemanager.core.util.Config.mediaSortOrder
import com.sn.snfilemanager.core.util.DocumentType
import com.sn.snfilemanager.databinding.FragmentMediaBinding
import com.sn.snfilemanager.feature.media.adapter.MediaItemAdapter
Expand All @@ -29,6 +31,7 @@ import com.sn.snfilemanager.view.dialog.ConflictDialog
import com.sn.snfilemanager.view.dialog.FilterBottomSheetDialog
import com.sn.snfilemanager.view.dialog.RenameFileDialog
import com.sn.snfilemanager.view.dialog.detail.DetailDialog
import com.sn.snfilemanager.view.dialog.sort.SortDialog
import dagger.hilt.android.AndroidEntryPoint
import java.nio.file.Path
import java.nio.file.Paths
Expand Down Expand Up @@ -65,6 +68,10 @@ class MediaFragment :
true
}

R.id.sort -> {
showSortDialog()
true
}
else -> super.onMenuItemSelected(menuItemId)
}

Expand Down Expand Up @@ -192,6 +199,7 @@ class MediaFragment :
observe(getMediaLiveData) { event ->
event.getContentIfNotHandled()?.let { data ->
adapter?.setItems(data.toMutableList())
binding.recyclerView.scrollToPosition(0)
}
}
observe(conflictQuestionLiveData) { event ->
Expand Down Expand Up @@ -238,6 +246,16 @@ class MediaFragment :
context?.shareFiles(uris)
}

private fun showSortDialog() {
SortDialog(isMedia = true, onConfirm = { sortData ->
with(viewModel) {
mediaSortCriterion = sortData.first
mediaSortOrder = sortData.second
getMedia()
}
}).showDialog(childFragmentManager)
}

private fun actionDelete() {
ConfirmationDialog(
getString(R.string.are_you_sure),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,15 @@ import androidx.lifecycle.viewModelScope
import com.sn.mediastorepv.data.ConflictStrategy
import com.sn.mediastorepv.data.Media
import com.sn.mediastorepv.data.MediaType
import com.sn.mediastorepv.data.OrderStrategy
import com.sn.snfilemanager.core.base.BaseResult
import com.sn.snfilemanager.core.util.Config.mediaSortCriterion
import com.sn.snfilemanager.core.util.Config.mediaSortOrder
import com.sn.snfilemanager.core.util.DocumentType
import com.sn.snfilemanager.core.util.Event
import com.sn.snfilemanager.core.util.MimeTypes
import com.sn.snfilemanager.core.util.SortCriterion
import com.sn.snfilemanager.core.util.SortOrder
import com.sn.snfilemanager.providers.mediastore.MediaStoreProvider
import com.sn.snfilemanager.providers.preferences.MySharedPreferences
import com.sn.snfilemanager.providers.preferences.PrefsTag
Expand Down Expand Up @@ -83,11 +88,31 @@ class MediaViewModel
}
}

private fun getOrderStrategy(): String {
return when (mediaSortCriterion) {
SortCriterion.NAME -> {
if (mediaSortOrder == SortOrder.ASCENDING) {
OrderStrategy.name(OrderStrategy.ASC)
} else {
OrderStrategy.name(OrderStrategy.DESC)
}
}

SortCriterion.LAST_MODIFIED -> {
if (mediaSortOrder == SortOrder.ASCENDING) {
OrderStrategy.dateModified(OrderStrategy.ASC)
} else {
OrderStrategy.dateModified(OrderStrategy.DESC)
}
}
}
}

fun getMedia() =
viewModelScope.launch {
val filteredMediaTypes: MutableSet<String>? = getFilteredMediaTypes()
mediaType?.let {
when (val result = mediaStoreProvider.getMedia(it, getDocumentMime())) {
when (val result = mediaStoreProvider.getMedia(it, getDocumentMime(), order = getOrderStrategy())) {
is BaseResult.Success -> {
fullMediaList = result.data
fullMediaList?.let { mediaList ->
Expand Down Expand Up @@ -147,7 +172,9 @@ class MediaViewModel
}
}
job.await()
_startMoveJobLiveData.postValue(Event(Pair(operationItemList, destinationPath)))
if (operationItemList.isNotEmpty()) {
_startMoveJobLiveData.postValue(Event(Pair(operationItemList, destinationPath)))
}
}
}

Expand Down
Loading