mirror of
https://github.com/IllusionMan1212/lyrics-grabbr.git
synced 2026-10-24 18:12:27 +00:00
Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
37b5ca8917
|
||
|
|
6b64ead713
|
@@ -118,7 +118,7 @@ dependencies {
|
||||
implementation("androidx.compose.ui:ui")
|
||||
implementation("androidx.compose.ui:ui-graphics")
|
||||
implementation("androidx.compose.ui:ui-tooling-preview")
|
||||
implementation("androidx.compose.material3:material3:1.3.0-beta04")
|
||||
implementation("androidx.compose.material3:material3:1.2.1")
|
||||
implementation("com.google.android.material:material:1.12.0")
|
||||
implementation("androidx.compose.material:material-icons-extended:1.6.8")
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE" />
|
||||
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"
|
||||
tools:ignore="QueryAllPackagesPermission" />
|
||||
|
||||
<application
|
||||
android:name=".LGApp"
|
||||
|
||||
@@ -35,7 +35,6 @@ import com.illusionman1212.lyricsgrabbr.ui.screens.HomePage
|
||||
import com.illusionman1212.lyricsgrabbr.ui.screens.LyricsPage
|
||||
import com.illusionman1212.lyricsgrabbr.ui.theme.LyricsGrabbrTheme
|
||||
import com.illusionman1212.lyricsgrabbr.ui.screens.SettingsPage
|
||||
import com.illusionman1212.lyricsgrabbr.ui.screens.WhitelistPage
|
||||
import com.illusionman1212.lyricsgrabbr.viewmodels.LyricsViewModel
|
||||
import com.illusionman1212.lyricsgrabbr.viewmodels.SettingsViewModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -131,17 +130,6 @@ class MainActivity : AppCompatActivity() {
|
||||
}
|
||||
composable(Routes.Settings.route) {
|
||||
SettingsPage(
|
||||
goBack = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
navigateToWhitelist = {
|
||||
navController.navigate(Routes.Whitelist.route)
|
||||
},
|
||||
viewModel = settingsViewModel,
|
||||
)
|
||||
}
|
||||
composable(Routes.Whitelist.route) {
|
||||
WhitelistPage(
|
||||
goBack = {
|
||||
navController.popBackStack()
|
||||
},
|
||||
|
||||
@@ -20,29 +20,15 @@ import androidx.core.app.NotificationManagerCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.os.BundleCompat
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager
|
||||
import com.illusionman1212.lyricsgrabbr.data.SettingsPreferencesRepository
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class NotificationListener: NotificationListenerService() {
|
||||
private var notificationManager : NotificationManagerCompat? = null
|
||||
private lateinit var settingsPrefsRepo: SettingsPreferencesRepository
|
||||
private val serviceScope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
initNotificationChannels(this)
|
||||
notificationManager = NotificationManagerCompat.from(applicationContext)
|
||||
settingsPrefsRepo = (application as LGApp).settingsPreferencesRepository
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
serviceScope.cancel()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
@@ -67,11 +53,7 @@ class NotificationListener: NotificationListenerService() {
|
||||
}
|
||||
|
||||
override fun onNotificationPosted(sbn: StatusBarNotification) {
|
||||
serviceScope.launch {
|
||||
val whitelist = settingsPrefsRepo.preferences.first().whitelist
|
||||
if (sbn.packageName !in whitelist) return@launch
|
||||
sendNotificationBroadcast(sbn, applicationContext)
|
||||
}
|
||||
sendNotificationBroadcast(sbn, applicationContext)
|
||||
}
|
||||
|
||||
private fun getStopServiceNotificationAction(): PendingIntent {
|
||||
@@ -109,13 +91,8 @@ class NotificationListener: NotificationListenerService() {
|
||||
|
||||
private fun getCurrentNotifications(context: Context) {
|
||||
val sbns = activeNotifications
|
||||
serviceScope.launch {
|
||||
val whitelist = settingsPrefsRepo.preferences.first().whitelist
|
||||
|
||||
for (sbn in sbns) {
|
||||
if (sbn.packageName !in whitelist) continue
|
||||
sendNotificationBroadcast(sbn, context)
|
||||
}
|
||||
for (sbn in sbns) {
|
||||
sendNotificationBroadcast(sbn, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
package com.illusionman1212.lyricsgrabbr
|
||||
|
||||
sealed class Routes(val route: String) {
|
||||
data object Home : Routes("home")
|
||||
data object Lyrics : Routes("lyrics")
|
||||
data object Settings : Routes("settings")
|
||||
data object Whitelist : Routes("settings/whitelist")
|
||||
object Home : Routes("home")
|
||||
object Lyrics : Routes("lyrics")
|
||||
object Settings : Routes("settings")
|
||||
}
|
||||
|
||||
|
||||
-16
@@ -4,7 +4,6 @@ import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringSetPreferencesKey
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
enum class Theme {
|
||||
@@ -15,7 +14,6 @@ enum class Theme {
|
||||
|
||||
data class SettingsPreferences(
|
||||
val appTheme: Int = Theme.SYSTEM.ordinal,
|
||||
val whitelist: Set<String> = emptySet(),
|
||||
)
|
||||
|
||||
class SettingsPreferencesRepository(
|
||||
@@ -23,7 +21,6 @@ class SettingsPreferencesRepository(
|
||||
) {
|
||||
companion object {
|
||||
private val APP_THEME = intPreferencesKey("app_theme")
|
||||
private val WHITELIST = stringSetPreferencesKey("apps_whitelist")
|
||||
}
|
||||
|
||||
val preferences = dataStore.data.map { mapSettingsPreferences(it) }
|
||||
@@ -34,22 +31,9 @@ class SettingsPreferencesRepository(
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun addToWhitelist(packageName: String) {
|
||||
dataStore.edit { prefs ->
|
||||
prefs[WHITELIST] = (prefs[WHITELIST]?.toMutableSet() ?: emptySet()) + packageName
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun removeFromWhitelist(packageName: String) {
|
||||
dataStore.edit { prefs ->
|
||||
prefs[WHITELIST] = (prefs[WHITELIST]?.toMutableSet() ?: emptySet()) - packageName
|
||||
}
|
||||
}
|
||||
|
||||
private fun mapSettingsPreferences(prefs: Preferences): SettingsPreferences {
|
||||
return SettingsPreferences(
|
||||
prefs[APP_THEME] ?: Theme.SYSTEM.ordinal,
|
||||
prefs[WHITELIST] ?: emptySet(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -433,6 +433,7 @@ fun LongClickBottomSheet(
|
||||
dragHandle = {},
|
||||
onDismissRequest = onDismiss,
|
||||
sheetState = sheetState,
|
||||
windowInsets = WindowInsets(top = 0.dp),
|
||||
) {
|
||||
Column {
|
||||
if (artistUri != Uri.EMPTY) {
|
||||
|
||||
@@ -16,7 +16,6 @@ import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Apps
|
||||
import androidx.compose.material.icons.filled.Check
|
||||
import androidx.compose.material.icons.outlined.Palette
|
||||
import androidx.compose.material.icons.outlined.Translate
|
||||
@@ -62,7 +61,6 @@ private val Themes = hashMapOf(
|
||||
@Composable
|
||||
fun SettingsPage(
|
||||
goBack: () -> Unit,
|
||||
navigateToWhitelist: () -> Unit,
|
||||
viewModel: SettingsViewModel,
|
||||
) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
@@ -96,7 +94,6 @@ fun SettingsPage(
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Appearance(viewModel, uiState)
|
||||
Listening(navigateToWhitelist)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -141,35 +138,6 @@ fun Appearance(viewModel: SettingsViewModel, uiState: SettingsState) {
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Listening(navigateToWhitelist: () -> Unit) {
|
||||
SettingGroup(title = stringResource(id = R.string.listening)) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { navigateToWhitelist() }
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(vertical = 8.dp)
|
||||
) {
|
||||
Icon(imageVector = Icons.Default.Apps, contentDescription = null, modifier = Modifier.width(56.dp))
|
||||
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
|
||||
Text(text = stringResource(id = R.string.whitelist_apps), color = MaterialTheme.colorScheme.onBackground)
|
||||
Text(
|
||||
text = stringResource(id = R.string.whitelist_desc),
|
||||
color = ColorSecondaryLight,
|
||||
fontSize = 14.sp,
|
||||
maxLines = 2,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
modifier = Modifier.padding(end = 24.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ThemeDialog(
|
||||
uiState: SettingsState,
|
||||
|
||||
@@ -1,162 +0,0 @@
|
||||
package com.illusionman1212.lyricsgrabbr.ui.screens
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Clear
|
||||
import androidx.compose.material3.Checkbox
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.pulltorefresh.PullToRefreshBox
|
||||
import androidx.compose.material3.pulltorefresh.rememberPullToRefreshState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.semantics.Role
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import coil.compose.AsyncImage
|
||||
import com.illusionman1212.lyricsgrabbr.R
|
||||
import com.illusionman1212.lyricsgrabbr.ui.components.LGIconButton
|
||||
import com.illusionman1212.lyricsgrabbr.ui.theme.Typography
|
||||
import com.illusionman1212.lyricsgrabbr.viewmodels.AppInfo
|
||||
import com.illusionman1212.lyricsgrabbr.viewmodels.SettingsViewModel
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun WhitelistPage(goBack: () -> Unit, viewModel: SettingsViewModel) {
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
Scaffold(topBar = {
|
||||
TopAppBar(
|
||||
title = {
|
||||
TextField(
|
||||
value = uiState.whitelistSearchQuery,
|
||||
onValueChange = {
|
||||
viewModel.filterPackages(it)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
placeholder = {
|
||||
Text(text = stringResource(id = R.string.search), style = Typography.titleLarge)
|
||||
},
|
||||
trailingIcon = {
|
||||
LGIconButton(tooltip = stringResource(id = R.string.clear), onClick = { viewModel.clearWhitelistSearch() }) {
|
||||
Icon(Icons.Default.Clear, contentDescription = stringResource(id = R.string.clear))
|
||||
}
|
||||
},
|
||||
singleLine = true,
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = Color.Transparent,
|
||||
unfocusedContainerColor = Color.Transparent,
|
||||
disabledContainerColor = Color.Transparent,
|
||||
cursorColor = MaterialTheme.colorScheme.primary,
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
),
|
||||
)
|
||||
},
|
||||
navigationIcon = {
|
||||
LGIconButton(tooltip = stringResource(id = R.string.go_back), onClick = goBack) {
|
||||
Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack, contentDescription = stringResource(
|
||||
id = R.string.go_back
|
||||
))
|
||||
}
|
||||
}
|
||||
)
|
||||
}) { padding ->
|
||||
val context = LocalContext.current
|
||||
|
||||
val refreshState = rememberPullToRefreshState()
|
||||
var isRefreshing by remember { mutableStateOf(false) }
|
||||
|
||||
if (uiState.applications.isNotEmpty()) {
|
||||
isRefreshing = false
|
||||
}
|
||||
|
||||
PullToRefreshBox(
|
||||
state = refreshState,
|
||||
isRefreshing = isRefreshing,
|
||||
onRefresh = {
|
||||
isRefreshing = true
|
||||
viewModel.refreshPackages(context)
|
||||
},
|
||||
modifier = Modifier.padding(padding)
|
||||
) {
|
||||
LazyColumn(Modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally) {
|
||||
if (uiState.applications.any { it.value.isWhitelisted }) {
|
||||
for ((packageName, appInfo) in uiState.applications.filter { it.value.isWhitelisted }) {
|
||||
item {
|
||||
Application(packageName, appInfo, viewModel)
|
||||
}
|
||||
}
|
||||
item {
|
||||
HorizontalDivider(
|
||||
Modifier
|
||||
.width(84.dp)
|
||||
.padding(vertical = 12.dp))
|
||||
}
|
||||
}
|
||||
for ((packageName, appInfo) in uiState.applications.filter { !it.value.isWhitelisted }) {
|
||||
item {
|
||||
Application(packageName, appInfo, viewModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Application(packageName: String, app: AppInfo, viewModel: SettingsViewModel) {
|
||||
Box(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable(
|
||||
role = Role.Checkbox,
|
||||
onClick = {
|
||||
if (app.isWhitelisted) {
|
||||
viewModel.removeFromWhitelist(packageName)
|
||||
} else {
|
||||
viewModel.addToWhitelist(packageName)
|
||||
}
|
||||
}
|
||||
)) {
|
||||
Row(
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 5.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
AsyncImage(modifier = Modifier.size(32.dp), model = app.icon, contentDescription = null)
|
||||
Text(app.displayName, Modifier.weight(1f))
|
||||
Checkbox(
|
||||
checked = app.isWhitelisted,
|
||||
onCheckedChange = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-112
@@ -1,8 +1,5 @@
|
||||
package com.illusionman1212.lyricsgrabbr.viewmodels
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.ViewModelProvider.AndroidViewModelFactory.Companion.APPLICATION_KEY
|
||||
@@ -17,23 +14,13 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
data class AppInfo(
|
||||
val displayName: String,
|
||||
val icon: Drawable,
|
||||
var isWhitelisted: Boolean,
|
||||
)
|
||||
|
||||
data class SettingsState(
|
||||
val appTheme: Int = Theme.SYSTEM.ordinal,
|
||||
val applications: Map<String, AppInfo> = emptyMap(),
|
||||
val whitelistSearchQuery: String = "",
|
||||
)
|
||||
|
||||
class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesRepository, context: Context): ViewModel() {
|
||||
private var immutablePackages: Map<String, AppInfo> = emptyMap()
|
||||
class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesRepository): ViewModel() {
|
||||
private val _uiState = MutableStateFlow(SettingsState())
|
||||
val uiState = _uiState.asStateFlow()
|
||||
|
||||
@@ -47,104 +34,7 @@ class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesReposi
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun getWhitelistedApps(): Set<String> {
|
||||
return settingsPrefsRepo.preferences.first().whitelist
|
||||
}
|
||||
|
||||
private fun getPackages(context: Context) {
|
||||
if (immutablePackages.isNotEmpty()) return
|
||||
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
val pm = context.packageManager
|
||||
val packages = pm.getInstalledApplications(PackageManager.GET_META_DATA)
|
||||
.filter { it.packageName != context.packageName && pm.getLaunchIntentForPackage(it.packageName) != null }
|
||||
.sortedWith(compareBy(String.CASE_INSENSITIVE_ORDER) { it.loadLabel(pm).toString() })
|
||||
|
||||
val apps: MutableMap<String, AppInfo> = mutableMapOf()
|
||||
val whitelistedApps = getWhitelistedApps()
|
||||
|
||||
packages.forEach { pkg ->
|
||||
val label = pkg.loadLabel(pm)
|
||||
val icon = pkg.loadIcon(pm)
|
||||
apps[pkg.packageName] = AppInfo(
|
||||
displayName = label.toString(),
|
||||
icon = icon,
|
||||
isWhitelisted = pkg.packageName in whitelistedApps
|
||||
)
|
||||
}
|
||||
immutablePackages = apps
|
||||
_uiState.update {
|
||||
SettingsState(
|
||||
appTheme = uiState.value.appTheme,
|
||||
applications = apps,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshPackages(context: Context) {
|
||||
_uiState.update {
|
||||
val apps = uiState.value.applications.toMutableMap()
|
||||
apps.clear()
|
||||
it.copy(whitelistSearchQuery = "", applications = apps)
|
||||
}
|
||||
val apps = immutablePackages.toMutableMap()
|
||||
apps.clear()
|
||||
immutablePackages = apps
|
||||
getPackages(context)
|
||||
}
|
||||
|
||||
fun filterPackages(query: String) {
|
||||
_uiState.update { state ->
|
||||
state.copy(
|
||||
applications = immutablePackages.filter {
|
||||
it.value.displayName.lowercase().contains(query.lowercase())
|
||||
}.toMutableMap(),
|
||||
whitelistSearchQuery = query,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearWhitelistSearch() {
|
||||
_uiState.update {
|
||||
it.copy(applications = immutablePackages, whitelistSearchQuery = "")
|
||||
}
|
||||
}
|
||||
|
||||
fun addToWhitelist(packageName: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
_uiState.update { state ->
|
||||
val apps = immutablePackages.toMutableMap()
|
||||
apps[packageName] = apps[packageName]!!.copy(isWhitelisted = true)
|
||||
immutablePackages = apps
|
||||
state.copy(
|
||||
applications = immutablePackages.filter {
|
||||
it.value.displayName.lowercase().contains(uiState.value.whitelistSearchQuery.lowercase())
|
||||
}.toMutableMap(),
|
||||
)
|
||||
}
|
||||
settingsPrefsRepo.addToWhitelist(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
fun removeFromWhitelist(packageName: String) {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
_uiState.update { state ->
|
||||
val apps = immutablePackages.toMutableMap()
|
||||
apps[packageName] = apps[packageName]!!.copy(isWhitelisted = false)
|
||||
immutablePackages = apps
|
||||
state.copy(
|
||||
applications = immutablePackages.filter {
|
||||
it.value.displayName.lowercase().contains(uiState.value.whitelistSearchQuery.lowercase())
|
||||
}.toMutableMap(),
|
||||
)
|
||||
}
|
||||
settingsPrefsRepo.removeFromWhitelist(packageName)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
getPackages(context)
|
||||
viewModelScope.launch {
|
||||
settingsPrefsRepo.preferences.collectLatest {
|
||||
_uiState.value = _uiState.value.copy(
|
||||
@@ -158,7 +48,7 @@ class SettingsViewModel(private val settingsPrefsRepo: SettingsPreferencesReposi
|
||||
val Factory: ViewModelProvider.Factory = viewModelFactory {
|
||||
initializer {
|
||||
val application = (this[APPLICATION_KEY] as LGApp)
|
||||
SettingsViewModel(application.settingsPreferencesRepository, application.applicationContext)
|
||||
SettingsViewModel(application.settingsPreferencesRepository)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,12 +34,6 @@
|
||||
<string name="theme_system">استخدم مظهر النظام</string>
|
||||
<string name="language">اللغة</string>
|
||||
<string name="_default">الإفتراضي</string>
|
||||
<string name="listening">الإستماع</string>
|
||||
<string name="whitelist">القائمة البيضاء</string>
|
||||
<string name="whitelist_apps">تطبيقات القائمة البيضاء</string>
|
||||
<string name="whitelist_desc">اختر التطبيقات التي سيستمع التطبيق إلى إشعاراتها</string>
|
||||
<string name="search">بحث</string>
|
||||
<string name="clear">مسح</string>
|
||||
|
||||
<!-- Lyrics -->
|
||||
<string name="lyrics">كلمات الأغنية</string>
|
||||
|
||||
@@ -33,12 +33,6 @@
|
||||
<string name="theme_system">Use System Theme</string>
|
||||
<string name="language">Language</string>
|
||||
<string name="_default">Default</string>
|
||||
<string name="listening">Listening</string>
|
||||
<string name="whitelist">Whitelist</string>
|
||||
<string name="whitelist_apps">Whitelist Apps</string>
|
||||
<string name="whitelist_desc">Choose which apps Lyrics Grabbr will listen to</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="clear">Clear</string>
|
||||
|
||||
<!-- Lyrics -->
|
||||
<string name="lyrics">Lyrics</string>
|
||||
|
||||
Reference in New Issue
Block a user