diff --git a/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt b/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt index 42b5d1e..9402e4e 100644 --- a/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt +++ b/manager/src/main/java/org/lsposed/lspatch/ui/page/SettingsScreen.kt @@ -1,7 +1,10 @@ package org.lsposed.lspatch.ui.page +import android.app.Activity import android.content.ComponentName +import android.content.Intent import android.content.pm.PackageManager +import android.util.Log import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.clickable @@ -15,6 +18,7 @@ import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Ballot import androidx.compose.material.icons.outlined.BugReport +import androidx.compose.material.icons.outlined.Folder import androidx.compose.material3.* import androidx.compose.runtime.* import androidx.compose.runtime.saveable.rememberSaveable @@ -34,12 +38,15 @@ import org.lsposed.lspatch.lspApp import org.lsposed.lspatch.ui.component.AnywhereDropdown import org.lsposed.lspatch.ui.component.CenterTopBar import org.lsposed.lspatch.ui.component.settings.SettingsItem +import org.lsposed.lspatch.ui.component.settings.SettingsSlot import org.lsposed.lspatch.ui.component.settings.SettingsSwitch +import org.lsposed.lspatch.ui.util.LocalSnackbarHost import java.io.IOException import java.security.GeneralSecurityException import java.security.KeyStore -@OptIn(ExperimentalMaterial3Api::class) +private const val TAG = "SettingsScreen" + @Destination @Composable fun SettingsScreen() { @@ -53,6 +60,7 @@ fun SettingsScreen() { ) { KeyStore() DetailPatchLogs() + StorageDirectory() SwitchInstallPackage() } } @@ -243,6 +251,41 @@ private fun DetailPatchLogs() { icon = Icons.Outlined.BugReport, title = stringResource(R.string.settings_detail_patch_logs) ) + ) +} + +@Composable +private fun StorageDirectory() { + val context = LocalContext.current + val snackbarHost = LocalSnackbarHost.current + val scope = rememberCoroutineScope() + val errorText = stringResource(R.string.patch_select_dir_error) + val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { + try { + if (it.resultCode == Activity.RESULT_CANCELED) return@rememberLauncherForActivityResult + val uri = it.data?.data ?: throw IOException("No data") + val takeFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION + context.contentResolver.takePersistableUriPermission(uri, takeFlags) + Configs.storageDirectory = uri.toString() + Log.i(TAG, "Storage directory: ${uri.path}") + } catch (e: Exception) { + Log.e(TAG, "Error when requesting saving directory", e) + scope.launch { snackbarHost.showSnackbar(errorText) } + } + } + AnywhereDropdown( + expanded = false, + onDismissRequest = { }, + onClick = { + launcher.launch(Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)) + }, + surface = { + SettingsItem( + title = stringResource(R.string.settings_storage_directory), + desc = Configs.storageDirectory ?: "undefined", + icon = Icons.Outlined.Folder + ) + }) {} } @Composable