Skip to content

Commit

Permalink
Add "Skip file picker" setting
Browse files Browse the repository at this point in the history
  • Loading branch information
MateusRodCosta committed Nov 12, 2024
1 parent 916860b commit bf7448e
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.activity.result.ActivityResultLauncher
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.calculateWindowSizeClass
import androidx.compose.runtime.LaunchedEffect
import androidx.documentfile.provider.DocumentFile
import androidx.lifecycle.lifecycleScope
import androidx.preference.PreferenceManager
import com.mateusrodcosta.apps.share2storage.model.UriData
Expand All @@ -42,19 +43,19 @@ import com.mateusrodcosta.apps.share2storage.utils.SharedPreferenceKeys
import com.mateusrodcosta.apps.share2storage.utils.getUriData
import com.mateusrodcosta.apps.share2storage.utils.saveFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.time.DurationUnit
import kotlin.time.toDuration

class DetailsActivity : ComponentActivity() {
private lateinit var createFile: ActivityResultLauncher<String>
private var uriData: UriData? = null
private lateinit var fileUri: Uri
private lateinit var uriData: UriData

private var skipFileDetails: Boolean = false
private var defaultSaveLocation: Uri? = null
private var showFilePreview: Boolean = true
private var shouldSkipFilePicker: Boolean = false


@OptIn(ExperimentalMaterial3WindowSizeClassApi::class)
override fun onCreate(savedInstanceState: Bundle?) {
Expand All @@ -64,7 +65,17 @@ class DetailsActivity : ComponentActivity() {
getPreferences()
handleIntent(intent)
val launchFilePicker = {
createFile.launch(uriData?.displayName ?: "")
if (shouldSkipFilePicker) {
lifecycleScope.launch {
val dir = DocumentFile.fromTreeUri(applicationContext, defaultSaveLocation!!)
val file = dir!!.createFile(uriData.type, uriData.displayName)

if (file?.uri != null) handleFileSave(file.uri, fileUri)
}
} else {
createFile.launch(uriData.displayName)
}
Unit
}

setContent {
Expand All @@ -88,20 +99,30 @@ class DetailsActivity : ComponentActivity() {
private fun getPreferences() {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)

skipFileDetails =
val skipFileDetails =
sharedPreferences.getBoolean(SharedPreferenceKeys.SKIP_FILE_DETAILS_KEY, false)
Log.d("details] skipFileDetails", skipFileDetails.toString())
this.skipFileDetails = skipFileDetails

val defaultSaveLocationRaw =
sharedPreferences.getString(SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY, null)
Log.d("details] defaultSaveLocationRaw", defaultSaveLocationRaw.toString())
defaultSaveLocation = if (defaultSaveLocationRaw != null) Uri.parse(defaultSaveLocationRaw)
else null
val defaultSaveLocation =
if (defaultSaveLocationRaw != null) Uri.parse(defaultSaveLocationRaw)
else null
Log.d("details] defaultSaveLocation", defaultSaveLocation.toString())
this.defaultSaveLocation = defaultSaveLocation

showFilePreview =
val showFilePreview =
sharedPreferences.getBoolean(SharedPreferenceKeys.SHOW_FILE_PREVIEW_KEY, true)
Log.d("details] showFilePreview", showFilePreview.toString())
this.showFilePreview = showFilePreview

val skipFilePicker =
sharedPreferences.getBoolean(SharedPreferenceKeys.SKIP_FILE_PICKER, false)
Log.d("details] skipFilePicker", skipFilePicker.toString())
// Only skip file picker if both a default folder is set and "Skip File Picker is selected"
this.shouldSkipFilePicker = defaultSaveLocation != null && skipFilePicker
}

private fun handleIntent(intent: Intent?) {
Expand All @@ -115,10 +136,13 @@ class DetailsActivity : ComponentActivity() {
Log.d("fileUri", "Action: ${intent?.action}, uri: $fileUri")

if (fileUri == null) return
uriData = getUriData(contentResolver, fileUri, getPreview = showFilePreview)
if(uriData == null) return
this.fileUri = fileUri
val uriData = getUriData(contentResolver, fileUri, getPreview = showFilePreview)
if (uriData == null) return
this.uriData = uriData

createFile = registerForActivityResult(
CreateDocumentWithInitialUri(uriData?.type ?: "*/*", defaultSaveLocation)
CreateDocumentWithInitialUri(uriData.type, defaultSaveLocation)
) { uri ->
if (uri == null) {
if (skipFileDetails) finish()
Expand All @@ -144,7 +168,7 @@ class DetailsActivity : ComponentActivity() {
).show()
}

if (skipFileDetails) {
if (skipFileDetails || shouldSkipFilePicker) {
finish()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,26 +41,30 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.navigation.NavController
import com.mateusrodcosta.apps.share2storage.R
import com.mateusrodcosta.apps.share2storage.screens.shared.AppBasicDivider
import com.mateusrodcosta.apps.share2storage.screens.shared.AppListHeader
import com.mateusrodcosta.apps.share2storage.ui.theme.AppTheme
import com.mateusrodcosta.apps.share2storage.utils.Utils
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow

@Preview(apiLevel = 34, showSystemUi = true, showBackground = true)
@Composable
fun SettingsScreenPreview() {
val mockDefaultSaveLocation = MutableStateFlow(null)
val mockSkipFilePicker = MutableStateFlow(false)
val mockSkipFileDetails = MutableStateFlow(false)
val mockInterceptActionViewIntents = MutableStateFlow(false)
val mockShowFilePreview = MutableStateFlow(true)

SettingsScreenContent(
spDefaultSaveLocation = mockDefaultSaveLocation,
spSkipFilePicker = mockSkipFilePicker,
spSkipFileDetails = mockSkipFileDetails,
spInterceptActionViewIntents = mockInterceptActionViewIntents,
spShowFilePreview = mockShowFilePreview,
Expand All @@ -72,12 +76,14 @@ fun SettingsScreenPreview() {
@Composable
fun SettingsScreenPreviewPtBr() {
val mockDefaultSaveLocation = MutableStateFlow(null)
val mockSkipFilePicker = MutableStateFlow(false)
val mockSkipFileDetails = MutableStateFlow(false)
val mockInterceptActionViewIntents = MutableStateFlow(false)
val mockShowFilePreview = MutableStateFlow(true)

SettingsScreenContent(
spDefaultSaveLocation = mockDefaultSaveLocation,
spSkipFilePicker = mockSkipFilePicker,
spSkipFileDetails = mockSkipFileDetails,
spInterceptActionViewIntents = mockInterceptActionViewIntents,
spShowFilePreview = mockShowFilePreview,
Expand All @@ -89,11 +95,15 @@ fun SettingsScreen(navController: NavController, settingsViewModel: SettingsView
SettingsScreenContent(
navController = navController,
spDefaultSaveLocation = settingsViewModel.defaultSaveLocation,
spSkipFilePicker = settingsViewModel.skipFilePicker,
spSkipFileDetails = settingsViewModel.skipFileDetails,
spInterceptActionViewIntents = settingsViewModel.interceptActionViewIntents,
spShowFilePreview = settingsViewModel.showFilePreview,
launchFilePicker = { settingsViewModel.getSaveLocationDirIntent().launch(null) },
clearSaveDirectory = { settingsViewModel.clearSaveDirectory() },
updateSkipFilePicker = { value: Boolean ->
settingsViewModel.updateSkipFilePicker(value)
},
updateSkipFileDetails = { value: Boolean ->
settingsViewModel.updateSkipFileDetails(value)
},
Expand All @@ -111,11 +121,13 @@ fun SettingsScreen(navController: NavController, settingsViewModel: SettingsView
fun SettingsScreenContent(
navController: NavController? = null,
spDefaultSaveLocation: StateFlow<Uri?>,
spSkipFilePicker: StateFlow<Boolean>,
spSkipFileDetails: StateFlow<Boolean>,
spInterceptActionViewIntents: StateFlow<Boolean>,
spShowFilePreview: StateFlow<Boolean>,
launchFilePicker: () -> Unit = {},
clearSaveDirectory: () -> Unit = {},
updateSkipFilePicker: (Boolean) -> Unit = {},
updateSkipFileDetails: (Boolean) -> Unit = {},
updateInterceptActionViewIntents: (Boolean) -> Unit = {},
updateShowFilePreview: (Boolean) -> Unit = {},
Expand Down Expand Up @@ -145,6 +157,11 @@ fun SettingsScreenContent(
clearSaveDirectory = clearSaveDirectory,
spDefaultSaveLocation = spDefaultSaveLocation,
)
SkipFilePickerSetting(
spDefaultSaveLocation = spDefaultSaveLocation,
updateSkipFilePicker = updateSkipFilePicker,
spSkipFilePicker = spSkipFilePicker,
)
AppBasicDivider()
AppListHeader(stringResource(R.string.settings_category_file_details))
SkipFileDetailsSetting(
Expand Down Expand Up @@ -190,6 +207,34 @@ fun DefaultSaveLocationSetting(
})
}

@Composable
fun SkipFilePickerSetting(
spDefaultSaveLocation: StateFlow<Uri?>,
updateSkipFilePicker: (Boolean) -> Unit,
spSkipFilePicker: StateFlow<Boolean>,
) {
val skipFilePicker by spSkipFilePicker.collectAsState()
val defaultSaveLocation by spDefaultSaveLocation.collectAsState()

ListItem(modifier = if (defaultSaveLocation != null) Modifier.clickable {
updateSkipFilePicker(
!skipFilePicker
)
} else Modifier.alpha(Utils.CONTENT_ALPHA_DISABLED), headlineContent = {
Text(stringResource(R.string.settings_skip_file_picker))
}, supportingContent = {
Text(stringResource(R.string.settings_skip_file_picker_info))
}, trailingContent = {
Switch(
enabled = defaultSaveLocation != null,
checked = skipFilePicker,
onCheckedChange = { value ->
updateSkipFilePicker(value)
},
)
})
}

@Composable
fun SkipFileDetailsSetting(
updateSkipFileDetails: (Boolean) -> Unit,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class SettingsViewModel : ViewModel() {
private val _interceptActionViewIntents = MutableStateFlow(false)
val interceptActionViewIntents: StateFlow<Boolean> = _interceptActionViewIntents

private val _skipFilePicker = MutableStateFlow(false)
val skipFilePicker: StateFlow<Boolean> = _skipFilePicker

fun assignSaveLocationDirIntent(intent: ActivityResultLauncher<Uri?>) {
getSaveLocationDirIntent = intent
}
Expand Down Expand Up @@ -105,10 +108,15 @@ class SettingsViewModel : ViewModel() {
"settings] initSharedPreferences] showFilePreview", spShowFilePreview.toString()
)

val spSkipFilePicker =
sharedPreferences.getBoolean(SharedPreferenceKeys.SKIP_FILE_PICKER, false)
Log.d("settings] initSharedPreferences] skipFilePicker", spSkipFilePicker.toString())

_defaultSaveLocation.value = spDefaultSaveLocation
_skipFileDetails.value = spSkipFileDetails
_interceptActionViewIntents.value = spInterceptActionViewIntents
_showFilePreview.value = spShowFilePreview
_skipFilePicker.value = spSkipFilePicker
}

fun updateDefaultSaveLocation(value: Uri?) {
Expand Down Expand Up @@ -194,4 +202,12 @@ class SettingsViewModel : ViewModel() {
_showFilePreview.value = value
}
}

fun updateSkipFilePicker(value: Boolean) {
sharedPreferences.edit(commit = true) {
putBoolean(SharedPreferenceKeys.SKIP_FILE_PICKER, value)
Log.e("settings] updateSkipFilePicker", value.toString())
_skipFilePicker.value = value
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ object SharedPreferenceKeys {
const val DEFAULT_SAVE_LOCATION_KEY: String = "default_save_location"
const val INTERCEPT_ACTION_VIEW_INTENTS_KEY: String = "intercept_action_view_intents"
const val SHOW_FILE_PREVIEW_KEY: String = "show_file_preview"
const val SKIP_FILE_PICKER: String = "skip_file_picker"
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import java.io.*

object Utils {
const val BUFFER_SIZE: Int = 1024
const val CONTENT_ALPHA_DISABLED = 0.38f
}

fun getUriData(contentResolver: ContentResolver, uri: Uri, getPreview: Boolean): UriData? {
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values-pt-rBR/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<string name="settings_category_file_picker">Seletor de Arquivos</string>
<string name="settings_default_save_location">Local de salvamento padrão</string>
<string name="settings_default_save_location_last_used">Última pasta usada</string>
<string name="settings_skip_file_picker">Pular seletor de arquivos</string>
<string name="settings_skip_file_picker_info">Pular seletor de arquivos e salvar imediatamente (apenas disponível quando uma pasta padrão for configurada)</string>

<string name="settings_category_file_details">Detalhes do arquivo</string>
<string name="settings_skip_file_details_page">Pular página de Detalhes do arquivo</string>
Expand All @@ -34,7 +36,7 @@
<string name="settings_intercept_action_view_intents_info">Permite registrar como uma opção quando aplicativos tentam automaticamente abrir um visualizador de arquivos</string>

<string name="no_file_found">Nenhum arquivo</string>
<string name="saving_file">Salvando arquivo...</string>
<string name="saving_file">Salvando arquivo</string>

<string name="file_details">Detalhes do arquivo</string>
<string name="file_name">Nome do arquivo</string>
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
<string name="settings_category_file_picker">File Picker</string>
<string name="settings_default_save_location">Default save location</string>
<string name="settings_default_save_location_last_used">Last used folder</string>
<string name="settings_skip_file_picker">Skip File Picker</string>
<string name="settings_skip_file_picker_info">Skip File Picker and immediately save files (only available when a default folder is set)</string>

<string name="settings_category_file_details">File Details</string>
<string name="settings_skip_file_details_page">Skip File Details page</string>
Expand All @@ -34,7 +36,7 @@
<string name="settings_intercept_action_view_intents_info">Allow registering as an option when apps try to automatically open a file viewer</string>

<string name="no_file_found">No file found</string>
<string name="saving_file">Saving file...</string>
<string name="saving_file">Saving file</string>

<string name="file_details">File Details</string>
<string name="file_name">File name</string>
Expand Down

0 comments on commit bf7448e

Please sign in to comment.