@@ -24,6 +24,7 @@ import com.github.droidworksstudio.common.searchCustomSearchEngine
24
24
import com.github.droidworksstudio.common.searchOnPlayStore
25
25
import com.github.droidworksstudio.common.showKeyboard
26
26
import com.github.droidworksstudio.common.showLongToast
27
+ import com.github.droidworksstudio.fuzzywuzzy.FuzzyFinder
27
28
import com.github.droidworksstudio.launcher.R
28
29
import com.github.droidworksstudio.launcher.adapter.drawer.DrawAdapter
29
30
import com.github.droidworksstudio.launcher.data.entities.AppInfo
@@ -35,6 +36,7 @@ import com.github.droidworksstudio.launcher.listener.OnItemClickedListener
35
36
import com.github.droidworksstudio.launcher.listener.OnSwipeTouchListener
36
37
import com.github.droidworksstudio.launcher.listener.ScrollEventListener
37
38
import com.github.droidworksstudio.launcher.ui.bottomsheetdialog.AppInfoBottomSheetFragment
39
+ import com.github.droidworksstudio.launcher.utils.Constants
38
40
import com.github.droidworksstudio.launcher.viewmodel.AppViewModel
39
41
import dagger.hilt.android.AndroidEntryPoint
40
42
import kotlinx.coroutines.launch
@@ -194,7 +196,7 @@ class DrawFragment : Fragment(),
194
196
// Use repeatOnLifecycle to manage the lifecycle state
195
197
repeatOnLifecycle(Lifecycle .State .CREATED ) {
196
198
val trimmedQuery = searchQuery.trim()
197
- viewModel.searchAppInfo(trimmedQuery ).collect { searchResults ->
199
+ viewModel.searchAppInfo().collect { searchResults ->
198
200
val numberOfItemsLeft = searchResults.size
199
201
val appResults = searchResults.firstOrNull()
200
202
if (numberOfItemsLeft == 0 && ! requireContext().searchOnPlayStore(trimmedQuery)) {
@@ -211,34 +213,70 @@ class DrawFragment : Fragment(),
211
213
}
212
214
213
215
private fun searchApp (query : String ) {
214
- val searchQuery = " %$query %"
215
-
216
216
// Launch a coroutine tied to the lifecycle of the view
217
217
viewLifecycleOwner.lifecycleScope.launch {
218
218
// Repeat the block when the lifecycle is at least CREATED
219
219
repeatOnLifecycle(Lifecycle .State .CREATED ) {
220
+ val trimmedQuery = query.trim()
221
+
220
222
// Collect search results from the ViewModel
221
- viewModel.searchAppInfo(searchQuery).collect { searchResults ->
222
- val numberOfItemsLeft = searchResults.size
223
- val appResults = searchResults.firstOrNull()
223
+ viewModel.searchAppInfo().collect { searchResults ->
224
+ // Filter and score results using FuzzyFinder
225
+ val filteredResults = searchResults
226
+ .map { appInfo ->
227
+ val score = FuzzyFinder .scoreApp(appInfo, trimmedQuery, Constants .FILTER_STRENGTH_MAX )
228
+ appInfo to score // Pairing app info with its score
229
+ }
230
+ .filter { it.second > 25 } // Only keep results with a positive score
231
+ .sortedByDescending { it.second } // Sort results by score, descending
232
+
233
+ // Applying additional filtering based on preferences
234
+ val scoredApps = filteredResults.toMap()
235
+
236
+ val finalResults = if (preferenceHelper.filterStrength >= 1 ) {
237
+ // Filtering based on score strength
238
+ if (preferenceHelper.searchFromStart) {
239
+ // Filter apps that start with the search query and score higher than the filter strength
240
+ scoredApps.filter { (app, _) ->
241
+ app.appName.startsWith(trimmedQuery, ignoreCase = true )
242
+ }
243
+ .filter { (_, score) -> score > preferenceHelper.filterStrength }
244
+ .map { it.key }
245
+ .toMutableList()
246
+ } else {
247
+ // Filter based on score strength alone
248
+ scoredApps.filterValues { it > preferenceHelper.filterStrength }
249
+ .keys
250
+ .toMutableList()
251
+ }
252
+ } else {
253
+ // If filter strength is less than 1, normalize app names for both cases
254
+ searchResults.filter { app ->
255
+ FuzzyFinder .normalizeString(app.appName, trimmedQuery)
256
+ }.toMutableList()
257
+ }
258
+
259
+
260
+ val numberOfItemsLeft = finalResults.size
261
+ val appResults = finalResults.firstOrNull()
262
+
224
263
when (numberOfItemsLeft) {
225
264
1 -> {
226
265
appResults?.let { appInfo ->
227
266
if (preferenceHelper.automaticOpenApp) observeBioAuthCheck(appInfo)
228
267
}
229
- drawAdapter.submitList(searchResults )
268
+ drawAdapter.submitList(finalResults )
230
269
}
231
270
232
271
else -> {
233
- drawAdapter.submitList(searchResults )
272
+ drawAdapter.submitList(finalResults )
234
273
}
235
274
}
236
275
}
237
276
}
238
277
}
239
278
}
240
279
241
-
242
280
private fun showSelectedApp (appInfo : AppInfo ) {
243
281
binding.searchViewText.setQuery(" " , false )
244
282
0 commit comments