@@ -49,11 +49,16 @@ class AppListFragment : Fragment() {
4949 private var showSystemApps = false
5050 private var executionMode: ExecutionMode = ExecutionMode .None
5151 private var currentSearchQuery: String = " "
52+ private var currentStatusFilter: StatusFilter = StatusFilter .ALL
5253
5354 // App cache - persists until package change detected
5455 private var cachedUserApps: List <AppInfo >? = null
5556 private var cachedSystemApps: List <AppInfo >? = null
5657
58+ enum class StatusFilter {
59+ ALL , RUNNING , STOPPED , FROZEN , RESTRICTED
60+ }
61+
5762 // Package change receiver
5863 private val packageReceiver = object : BroadcastReceiver () {
5964 override fun onReceive (context : Context ? , intent : Intent ? ) {
@@ -89,6 +94,7 @@ class AppListFragment : Fragment() {
8994 setupSwipeRefresh()
9095 setupSearch()
9196 setupChips()
97+ setupStatusFilter()
9298 setupSelectionBar()
9399 setupSelectAll()
94100 registerPackageReceiver()
@@ -119,11 +125,21 @@ class AppListFragment : Fragment() {
119125 val cachedApps = if (showSystemApps) cachedSystemApps else cachedUserApps
120126 if (cachedApps == null ) return
121127
122- val filtered = if (currentSearchQuery.isBlank()) {
123- cachedApps
124- } else {
128+ var filtered = cachedApps
129+
130+ // Apply status filter
131+ filtered = when (currentStatusFilter) {
132+ StatusFilter .ALL -> filtered
133+ StatusFilter .RUNNING -> filtered.filter { it.isRunning }
134+ StatusFilter .STOPPED -> filtered.filter { it.isStopped }
135+ StatusFilter .FROZEN -> filtered.filter { ! it.isEnabled }
136+ StatusFilter .RESTRICTED -> filtered.filter { it.isBackgroundRestricted }
137+ }
138+
139+ // Apply search filter
140+ if (currentSearchQuery.isNotBlank()) {
125141 val query = currentSearchQuery.lowercase()
126- cachedApps .filter { app ->
142+ filtered = filtered .filter { app ->
127143 app.appName.lowercase().contains(query) ||
128144 app.packageName.lowercase().contains(query)
129145 }
@@ -195,19 +211,50 @@ class AppListFragment : Fragment() {
195211 b.chipUserApps.isChecked = true
196212
197213 b.chipUserApps.setOnClickListener {
198- showSystemApps = false
199- b.chipUserApps.isChecked = true
200- b.chipSystemApps.isChecked = false
201- adapter.deselectAll()
202- loadApps()
214+ if (showSystemApps) {
215+ showSystemApps = false
216+ b.chipUserApps.isChecked = true
217+ b.chipSystemApps.isChecked = false
218+ adapter.deselectAll()
219+ loadApps()
220+ }
203221 }
204222
205223 b.chipSystemApps.setOnClickListener {
206- showSystemApps = true
207- b.chipSystemApps.isChecked = true
208- b.chipUserApps.isChecked = false
209- adapter.deselectAll()
210- loadApps()
224+ if (! showSystemApps) {
225+ showSystemApps = true
226+ b.chipSystemApps.isChecked = true
227+ b.chipUserApps.isChecked = false
228+ adapter.deselectAll()
229+ loadApps()
230+ }
231+ }
232+ }
233+
234+ private fun setupStatusFilter () {
235+ val b = binding ? : return
236+
237+ b.chipStatusFilter.setOnClickListener {
238+ val filterNames = arrayOf(
239+ getString(R .string.filter_all),
240+ getString(R .string.filter_running),
241+ getString(R .string.filter_stopped),
242+ getString(R .string.filter_frozen),
243+ getString(R .string.filter_restricted)
244+ )
245+ val filters = StatusFilter .values()
246+ val currentIndex = filters.indexOf(currentStatusFilter)
247+
248+ MaterialAlertDialogBuilder (requireContext())
249+ .setTitle(R .string.filter_status_title)
250+ .setSingleChoiceItems(filterNames, currentIndex) { dialog, which ->
251+ currentStatusFilter = filters[which]
252+ b.chipStatusFilter.text = filterNames[which]
253+ filterApps()
254+ dialog.dismiss()
255+ }
256+ .setNegativeButton(android.R .string.cancel, null )
257+ .show()
211258 }
212259 }
213260
0 commit comments