Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import com.looker.droidify.compose.components.BackButton
import com.looker.droidify.compose.settings.SettingsViewModel.Companion.cleanUpIntervals
import com.looker.droidify.compose.settings.SettingsViewModel.Companion.localeCodesList
import com.looker.droidify.compose.settings.components.ActionSettingItem
import com.looker.droidify.compose.settings.components.BlacklistSettingItem
import com.looker.droidify.compose.settings.components.CustomButtonsSettingItem
import com.looker.droidify.compose.settings.components.SelectionSettingItem
import com.looker.droidify.compose.settings.components.SettingHeader
Expand All @@ -44,13 +45,14 @@ import com.looker.droidify.utility.common.SdkCheck
import com.looker.droidify.utility.common.extension.openLink
import com.looker.droidify.utility.common.isIgnoreBatteryEnabled
import com.looker.droidify.utility.common.requestBatteryFreedom
import java.util.*
import java.util.Locale
import kotlin.time.Duration

private const val BACKUP_MIME_TYPE = "application/json"
private const val SETTINGS_BACKUP_NAME = "droidify_settings"
private const val REPO_BACKUP_NAME = "droidify_repos"
private const val CUSTOM_BUTTONS_BACKUP_NAME = "custom_buttons"
private const val APP_BLACKLIST_BACKUP_NAME = "app_blacklist"

private const val FOXY_DROID_TITLE = "FoxyDroid"
private const val FOXY_DROID_URL = "https://github.com/kitsunyan/foxy-droid"
Expand All @@ -66,6 +68,7 @@ fun SettingsScreen(
val context = LocalContext.current
val settings by viewModel.settings.collectAsStateWithLifecycle()
val customButtons by viewModel.customButtons.collectAsStateWithLifecycle()
val appBlacklist by viewModel.appBlacklist.collectAsStateWithLifecycle()
val isBackgroundAllowed by viewModel.isBackgroundAllowed.collectAsStateWithLifecycle()

LaunchedEffect(Unit) {
Expand Down Expand Up @@ -114,6 +117,20 @@ fun SettingsScreen(
}
}

val exportBlacklistLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.CreateDocument(BACKUP_MIME_TYPE),
) { uri -> uri?.let { viewModel.exportBlacklist(it) } }

val importBlacklistLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.OpenDocument(),
) { uri ->
if (uri != null) {
viewModel.importBlacklist(uri)
} else {
viewModel.showSnackbar(R.string.file_format_error_DESC)
}
}

Scaffold(
topBar = {
TopAppBar(
Expand Down Expand Up @@ -371,6 +388,19 @@ fun SettingsScreen(
)
}

item { SettingHeader(title = stringResource(R.string.app_blacklist_section)) }

item {
BlacklistSettingItem(
entries = appBlacklist,
onAddEntry = viewModel::addBlacklistEntry,
onUpdateEntry = viewModel::updateBlacklistEntry,
onRemoveEntry = viewModel::removeBlacklistEntry,
onExport = { exportBlacklistLauncher.launch(APP_BLACKLIST_BACKUP_NAME) },
onImport = { importBlacklistLauncher.launch(arrayOf(BACKUP_MIME_TYPE)) },
)
}

item { SettingHeader(title = stringResource(R.string.credits)) }

item {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import com.looker.droidify.data.PrivacyRepository
import com.looker.droidify.data.StringHandler
import com.looker.droidify.database.Database
import com.looker.droidify.database.RepositoryExporter
import com.looker.droidify.datastore.AppBlacklistRepository
import com.looker.droidify.datastore.CustomButtonRepository
import com.looker.droidify.datastore.Settings
import com.looker.droidify.datastore.SettingsRepository
import com.looker.droidify.datastore.model.AutoSync
import com.looker.droidify.datastore.model.BlacklistEntry
import com.looker.droidify.datastore.model.CustomButton
import com.looker.droidify.datastore.model.InstallerType
import com.looker.droidify.datastore.model.LegacyInstallerComponent
Expand All @@ -33,31 +35,34 @@ import com.looker.droidify.utility.common.extension.asStateFlow
import com.looker.droidify.utility.common.extension.updateAsMutable
import com.looker.droidify.work.CleanUpWorker
import dagger.hilt.android.lifecycle.HiltViewModel
import java.util.*
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import java.util.Locale
import javax.inject.Inject
import kotlin.time.Duration
import kotlin.time.Duration.Companion.days
import kotlin.time.Duration.Companion.hours

@HiltViewModel
class SettingsViewModel @Inject constructor(
private val settingsRepository: SettingsRepository,
private val privacyRepository: PrivacyRepository,
private val repositoryExporter: RepositoryExporter,
private val customButtonRepository: CustomButtonRepository,
private val appBlacklistRepository: AppBlacklistRepository,
private val handler: StringHandler,
) : ViewModel() {

val snackbarHostState = SnackbarHostState()

val settings = settingsRepository.data.asStateFlow(Settings())

val customButtons: StateFlow<List<CustomButton>> = customButtonRepository.buttons
.asStateFlow(emptyList())
val customButtons: StateFlow<List<CustomButton>> =
customButtonRepository.buttons.asStateFlow(emptyList())
val appBlacklist: StateFlow<List<BlacklistEntry>> =
appBlacklistRepository.entries.asStateFlow(emptyList())

private val _isBackgroundAllowed = MutableStateFlow(true)
val isBackgroundAllowed = _isBackgroundAllowed.asStateFlow()
Expand Down Expand Up @@ -155,6 +160,7 @@ class SettingsViewModel @Inject constructor(
settingsRepository.setDeleteApkOnInstall(false)
settingsRepository.setInstallerType(installerType)
}

else -> settingsRepository.setInstallerType(installerType)
}
}
Expand Down Expand Up @@ -300,7 +306,48 @@ class SettingsViewModel @Inject constructor(
},
onFailure = {
showSnackbar(R.string.file_format_error_DESC)
}
},
)
}
}

fun addBlacklistEntry(entry: BlacklistEntry) {
viewModelScope.launch {
appBlacklistRepository.addEntry(entry)
}
}

fun updateBlacklistEntry(entry: BlacklistEntry) {
viewModelScope.launch {
appBlacklistRepository.updateEntry(entry)
}
}

fun removeBlacklistEntry(entryId: String) {
viewModelScope.launch {
appBlacklistRepository.removeEntry(entryId)
}
}

fun exportBlacklist(uri: Uri) {
viewModelScope.launch {
appBlacklistRepository.exportToUri(uri).onFailure {
showSnackbar(R.string.file_format_error_DESC)
}
}
}

fun importBlacklist(uri: Uri) {
viewModelScope.launch {
appBlacklistRepository.importFromUri(uri).fold(
onSuccess = { count ->
if (count > 0) {
showSnackbar(R.string.app_blacklist_imported)
}
},
onFailure = {
showSnackbar(R.string.file_format_error_DESC)
},
)
}
}
Expand All @@ -315,9 +362,8 @@ class SettingsViewModel @Inject constructor(
Duration.INFINITE,
)

val localeCodesList: List<String> = BuildConfig.DETECTED_LOCALES
.toList()
.updateAsMutable { add(0, "system") }
val localeCodesList: List<String> =
BuildConfig.DETECTED_LOCALES.toList().updateAsMutable { add(0, "system") }
}
}

Expand Down
Loading