Skip to content

Commit

Permalink
Optimized the scanning process
Browse files Browse the repository at this point in the history
  • Loading branch information
D4rK7355608 committed Jun 30, 2024
1 parent c8be9b9 commit 79d31bc
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 64 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ android {
applicationId = "com.d4rk.cleaner"
minSdk = 26
targetSdk = 34
versionCode = 77
versionCode = 78
versionName = "2.0.0"
archivesName = "${applicationId}-v${versionName}"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
Expand Down
Binary file not shown.
Binary file not shown.
Binary file removed app/release/com.d4rk.cleaner-v1.0.0-release.apk
Binary file not shown.
10 changes: 5 additions & 5 deletions app/release/output-metadata.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
"type": "SINGLE",
"filters": [],
"attributes": [],
"versionCode": 68,
"versionName": "1.0.0",
"outputFile": "com.d4rk.cleaner-v1.0.0-release.apk"
"versionCode": 78,
"versionName": "2.0.0",
"outputFile": "com.d4rk.cleaner-v2.0.0-release.apk"
}
],
"elementType": "File",
Expand All @@ -22,14 +22,14 @@
"minApi": 28,
"maxApi": 30,
"baselineProfiles": [
"baselineProfiles/1/com.d4rk.cleaner-v1.0.0-release.dm"
"baselineProfiles/1/com.d4rk.cleaner-v2.0.0-release.dm"
]
},
{
"minApi": 31,
"maxApi": 2147483647,
"baselineProfiles": [
"baselineProfiles/0/com.d4rk.cleaner-v1.0.0-release.dm"
"baselineProfiles/0/com.d4rk.cleaner-v2.0.0-release.dm"
]
}
],
Expand Down
19 changes: 15 additions & 4 deletions app/src/main/kotlin/com/d4rk/cleaner/ui/home/HomeComposable.kt
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand Down Expand Up @@ -78,6 +80,9 @@ fun HomeComposable() {
val showCleaningComposable by viewModel.showCleaningComposable.observeAsState(false)
val isAnalyzing by viewModel.isAnalyzing.observeAsState(false)
val selectedFileCount by viewModel.selectedFileCount.collectAsState()

val launchScanningKey = remember { mutableStateOf(false) }

Column(
modifier = Modifier.fillMaxSize()
) {
Expand Down Expand Up @@ -105,7 +110,7 @@ fun HomeComposable() {
)
}
else {
AnalyzeComposable()
AnalyzeComposable(launchScanningKey)
}
}
Row(
Expand Down Expand Up @@ -205,12 +210,18 @@ fun HomeComposable() {
* @param viewModel The HomeViewModel instance used to interact with the data and business logic.
*/
@Composable
fun AnalyzeComposable() {
fun AnalyzeComposable(launchScanningKey: MutableState<Boolean>) {
val viewModel : HomeViewModel = viewModel()
val files by viewModel.scannedFiles.asFlow().collectAsState(initial = listOf())

val allFilesSelected by viewModel.allFilesSelected
val selectedFileCount by viewModel.selectedFileCount.collectAsState()

LaunchedEffect(key1 = launchScanningKey.value) {
viewModel.fileScanner.startScanning()
launchScanningKey.value = false
}

LaunchedEffect(Unit) {
viewModel.fileScanner.startScanning()
}
Expand All @@ -234,7 +245,7 @@ fun AnalyzeComposable() {
modifier = Modifier.padding(8.dp)
) {
items(files) { file ->
FileCard(file = file , viewModel = viewModel)
FileCard(file = file , viewModel = viewModel) // FIXME: Type mismatch: inferred type is Int but File was expected
}
}
}
Expand Down Expand Up @@ -274,7 +285,7 @@ fun FileCard(file: File, viewModel: HomeViewModel) {
val context = LocalContext.current
val fileExtension = getFileExtension(file.name)
val thumbnail = remember {
getVideoThumbnail(file.absolutePath, thumbnailWidth = 128, thumbnailHeight = 128)
getVideoThumbnail(file.absolutePath, thumbnailWidth = 64, thumbnailHeight = 64)
}
Card(
modifier = Modifier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import androidx.lifecycle.viewModelScope
import com.d4rk.cleaner.data.datastore.DataStore
import com.d4rk.cleaner.utils.FileScanner
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
Expand Down Expand Up @@ -104,7 +105,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
}
isAnalyzing.value = true
showCleaningComposable.value = true
viewModelScope.launch(Dispatchers.IO) {
viewModelScope.launch {
delay(100)
isAnalyzing.value = true
fileScanner.startScanning()
scannedFiles.postValue(fileScanner.getFilteredFiles())
isAnalyzing.postValue(false)
Expand Down
109 changes: 56 additions & 53 deletions app/src/main/kotlin/com/d4rk/cleaner/utils/FileScanner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@ import android.content.res.Resources
import android.os.Environment
import com.d4rk.cleaner.R
import com.d4rk.cleaner.data.datastore.DataStore
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.toList
import kotlinx.coroutines.withContext
import java.io.File

/**
Expand All @@ -28,9 +33,12 @@ class FileScanner(private val dataStore: DataStore, private val resources: Resou
* @throws Exception If an error occurs during the scanning process.
*/
suspend fun startScanning() {
loadPreferences()
val allFiles = getAllFiles()
filteredFiles = filterFiles(allFiles).toList()
withContext(Dispatchers.IO) {
loadPreferences()
val allFiles = getAllFiles()
filteredFiles = filterFiles(allFiles)
.toList() // Collect the flow into a list asynchronously
}
}

/**
Expand Down Expand Up @@ -72,62 +80,57 @@ class FileScanner(private val dataStore: DataStore, private val resources: Resou
return files
}

/**
* Filters files based on user-defined preferences and returns them as a sequence.
*
* This function takes a list of all files as input and returns a sequence of files that match the user-defined preferences. The sequence allows for real-time display of filtered files as they are discovered during the scanning process.
*
* @param allFiles The list of all files to filter.
* @return A sequence of files filtered based on user-defined preferences.
*/
private fun filterFiles(allFiles: List<File>): Sequence<File> {
return sequence {
private fun filterFiles(allFiles: List<File>): Flow<File> {
return flow {
for (file in allFiles) {
if (preferences.any { (key, value) ->
val result = when (key) {
"generic_extensions" -> {
val extensions =
resources.getStringArray(R.array.generic_extensions)
value && extensions.map { it.removePrefix(".") }
.contains(file.extension)
}

"archive_extensions" -> {
val extensions =
resources.getStringArray(R.array.archive_extensions)
value && extensions.contains(file.extension)
}

"apk_extensions" -> {
val extensions = resources.getStringArray(R.array.apk_extensions)
value && extensions.contains(file.extension)
}

"audio_extensions" -> {
val extensions = resources.getStringArray(R.array.audio_extensions)
value && extensions.contains(file.extension)
}

"video_extensions" -> {
val extensions = resources.getStringArray(R.array.video_extensions)
value && extensions.contains(file.extension)
}

"image_extensions" -> {
val extensions = resources.getStringArray(R.array.image_extensions)
value && extensions.contains(file.extension)
}

else -> false
}
result
}) {
yield(file)
if (shouldFilterFile(file)) {
emit(file)
}
}
}
}

private fun shouldFilterFile(file: File): Boolean {
return preferences.any { (key, value) ->
when (key) {
"generic_extensions" -> {
val extensions =
resources.getStringArray(R.array.generic_extensions)
value && extensions.map { it.removePrefix(".") }
.contains(file.extension)
}

"archive_extensions" -> {
val extensions =
resources.getStringArray(R.array.archive_extensions)
value && extensions.contains(file.extension)
}

"apk_extensions" -> {
val extensions = resources.getStringArray(R.array.apk_extensions)
value && extensions.contains(file.extension)
}

"audio_extensions" -> {
val extensions = resources.getStringArray(R.array.audio_extensions)
value && extensions.contains(file.extension)
}

"video_extensions" -> {
val extensions = resources.getStringArray(R.array.video_extensions)
value && extensions.contains(file.extension)
}

"image_extensions" -> {
val extensions = resources.getStringArray(R.array.image_extensions)
value && extensions.contains(file.extension)
}

else -> false
}
}
}

/**
* Returns the list of filtered files.
*
Expand Down

0 comments on commit 79d31bc

Please sign in to comment.