Skip to content

Commit

Permalink
Merge SettingsActivity into MainActivity
Browse files Browse the repository at this point in the history
Now making use of Jetpack Navigation

New dependency:
navigationCompose: 2.7.7
  • Loading branch information
MateusRodCosta committed Feb 12, 2024
1 parent a321927 commit 7540750
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 98 deletions.
4 changes: 0 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,6 @@

</activity>

<activity
android:name=".SettingsActivity"
android:exported="false" />

<activity
android:name=".DetailsActivity"
android:exported="true">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,36 @@
package com.mateusrodcosta.apps.share2storage

import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import com.mateusrodcosta.apps.share2storage.screens.MainScreen
import androidx.activity.result.contract.ActivityResultContracts
import com.mateusrodcosta.apps.share2storage.screens.AppNavigation

class MainActivity : ComponentActivity() {

private val settingsViewModel: SettingsViewModel = SettingsViewModel()

private val getSaveLocationDirIntent =
registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
if (uri == null) return@registerForActivityResult

Log.d("settings] getSaveLocationDir] uri", uri.toString())
Log.d("settings] getSaveLocationDir] uri.path", uri.path.toString())

settingsViewModel.updateDefaultSaveLocation(uri)
}

override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
setContent { MainScreen() }

settingsViewModel.receiveContext(applicationContext)
settingsViewModel.assignSaveLocationDirIntent(getSaveLocationDirIntent)
settingsViewModel.initPreferences()

setContent { AppNavigation(settingsViewModel) }
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import android.content.Intent
import android.content.SharedPreferences
import android.net.Uri
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
import androidx.core.content.edit
import androidx.lifecycle.ViewModel
import androidx.preference.PreferenceManager
Expand All @@ -34,13 +35,22 @@ class SettingsViewModel : ViewModel() {

private lateinit var sharedPreferences: SharedPreferences
private lateinit var contentResolver: ContentResolver
private lateinit var getSaveLocationDirIntent: ActivityResultLauncher<Uri?>

private val _defaultSaveLocation = MutableStateFlow<Uri?>(null)
val defaultSaveLocation: StateFlow<Uri?> = _defaultSaveLocation

private val _skipFileDetails = MutableStateFlow(false)
val skipFileDetails: StateFlow<Boolean> = _skipFileDetails

fun assignSaveLocationDirIntent(intent: ActivityResultLauncher<Uri?>) {
getSaveLocationDirIntent = intent
}

fun getSaveLocationDirIntent(): ActivityResultLauncher<Uri?> {
return getSaveLocationDirIntent
}

fun receiveContext(context: Context) {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
contentResolver = context.contentResolver
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (C) 2022 - 2024 Mateus Rodrigues Costa
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

package com.mateusrodcosta.apps.share2storage.screens

import androidx.compose.runtime.Composable
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import com.mateusrodcosta.apps.share2storage.SettingsViewModel

@Composable
fun AppNavigation(settingsViewModel: SettingsViewModel) {
val navController = rememberNavController()

NavHost(navController = navController, startDestination = "main") {
composable("main") { MainScreen(navController) }
composable("settings") { SettingsScreen(navController, settingsViewModel) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@

package com.mateusrodcosta.apps.share2storage.screens

import android.content.Intent
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
Expand Down Expand Up @@ -46,38 +45,38 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.mateusrodcosta.apps.share2storage.R
import com.mateusrodcosta.apps.share2storage.SettingsActivity
import com.mateusrodcosta.apps.share2storage.ui.theme.AppTheme
import com.mateusrodcosta.apps.share2storage.utils.AppBasicDivider
import com.mateusrodcosta.apps.share2storage.utils.appTopAppBarColors

@Preview(apiLevel = 33, showBackground = true)
@Composable
fun MainScreenPreview() {
MainScreen()
MainScreenContent(navController = null)
}

@Composable
fun MainScreen(navController: NavController) {
MainScreenContent(navController = navController)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen() {
val context = LocalContext.current
fun MainScreenContent(navController: NavController?) {
AppTheme {
Scaffold(topBar = {
TopAppBar(
title = { Text(stringResource(R.string.app_name)) },
actions = {
IconButton(onClick = {
val intent = Intent(context, SettingsActivity::class.java)
context.startActivity(intent)
}) {
IconButton(onClick = { navController?.navigate("settings") }) {
Icon(Icons.Rounded.Settings, stringResource(id = R.string.settings))
}
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import com.mateusrodcosta.apps.share2storage.R
import com.mateusrodcosta.apps.share2storage.SettingsViewModel
import com.mateusrodcosta.apps.share2storage.ui.theme.AppTheme
import com.mateusrodcosta.apps.share2storage.utils.AppBasicDivider
import com.mateusrodcosta.apps.share2storage.utils.appTopAppBarColors
Expand All @@ -62,37 +64,48 @@ fun SettingsScreenPreview() {
val mockDefaultSaveLocation = MutableStateFlow(null)
val mockSkipFileDetails = MutableStateFlow(false)

SettingsScreen(
SettingsScreenContent(
navController = null,
spDefaultSaveLocation = mockDefaultSaveLocation,
spSkipFileDetails = mockSkipFileDetails,
launchFilePicker = {},
clearSaveDirectory = {},
updateSkipFileDetails = { _ -> },
closeActivity = {},
updateSkipFileDetails = {},
)
}

@Composable
fun SettingsScreen(navController: NavController, settingsViewModel: SettingsViewModel) {
SettingsScreenContent(
navController = navController,
spDefaultSaveLocation = settingsViewModel.defaultSaveLocation,
spSkipFileDetails = settingsViewModel.skipFileDetails,
launchFilePicker = { settingsViewModel.getSaveLocationDirIntent().launch(null) },
clearSaveDirectory = { settingsViewModel.clearSaveDirectory() },
updateSkipFileDetails = { value: Boolean ->
settingsViewModel.updateSkipFileDetails(value)
},
)
}

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun SettingsScreen(
fun SettingsScreenContent(
navController: NavController?,
spDefaultSaveLocation: StateFlow<Uri?>,
spSkipFileDetails: StateFlow<Boolean>,
launchFilePicker: (() -> Unit),
clearSaveDirectory: (() -> Unit),
updateSkipFileDetails: ((Boolean) -> Unit),
closeActivity: () -> Unit,
launchFilePicker: () -> Unit,
clearSaveDirectory: () -> Unit,
updateSkipFileDetails: (Boolean) -> Unit,
) {
val defaultSaveLocation by spDefaultSaveLocation.collectAsState()
val skipFileDetails by spSkipFileDetails.collectAsState()

val settingsPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)

AppTheme {
Scaffold(topBar = {
TopAppBar(title = { Text(stringResource(R.string.settings)) },
colors = appTopAppBarColors(),
navigationIcon = {
IconButton(onClick = { closeActivity() }) {
IconButton(onClick = { navController?.navigateUp() }) {
Icon(
Icons.AutoMirrored.Filled.ArrowBack,
stringResource(id = R.string.back_arrow)
Expand All @@ -110,14 +123,14 @@ fun SettingsScreen(
Column {
SkipFileDetailsSetting(
updateSkipFileDetails = updateSkipFileDetails,
skipFileDetails = skipFileDetails,
spSkipFileDetails = spSkipFileDetails,
paddingValues = settingsPadding,
)
AppBasicDivider()
DefaultSaveLocationSetting(
launchFilePicker = launchFilePicker,
clearSaveDirectory = clearSaveDirectory,
defaultSaveLocation = defaultSaveLocation,
spDefaultSaveLocation = spDefaultSaveLocation,
paddingValues = settingsPadding,
)
AppBasicDivider()
Expand All @@ -130,10 +143,12 @@ fun SettingsScreen(

@Composable
fun SkipFileDetailsSetting(
updateSkipFileDetails: ((Boolean) -> Unit),
skipFileDetails: Boolean,
updateSkipFileDetails: (Boolean) -> Unit,
spSkipFileDetails: StateFlow<Boolean>,
paddingValues: PaddingValues,
) {
val skipFileDetails by spSkipFileDetails.collectAsState()

Row(modifier = Modifier
.clickable { updateSkipFileDetails(!skipFileDetails) }
.padding(paddingValues)
Expand All @@ -158,11 +173,13 @@ fun SkipFileDetailsSetting(

@Composable
fun DefaultSaveLocationSetting(
launchFilePicker: (() -> Unit),
clearSaveDirectory: (() -> Unit),
defaultSaveLocation: Uri?,
launchFilePicker: () -> Unit,
clearSaveDirectory: () -> Unit,
spDefaultSaveLocation: StateFlow<Uri?>,
paddingValues: PaddingValues,
) {
val defaultSaveLocation by spDefaultSaveLocation.collectAsState()

Row(modifier = Modifier
.clickable { launchFilePicker() }
.padding(paddingValues)
Expand Down
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ preference-ktx = "1.2.1"
composeBom = "2024.01.00"
composeMaterial3WindowSizeClass = "1.1.2"
activityCompose = "1.8.2"
navigationCompose = "2.7.7"
junit = "4.13.2"
androidxTestRunner = "1.5.2"
androidxTestRules = "1.5.0"
Expand All @@ -23,6 +24,7 @@ compose-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling
compose-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
compose-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" }
androidx-navigation-compose = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigationCompose" }
junit-junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-test-runner = { group = "androidx.test", name="runner", version.ref = "androidxTestRunner" }
androidx-test-rules = { group = "androidx.test", name="rules", version.ref = "androidxTestRules" }
Expand All @@ -31,7 +33,7 @@ androidx-test-rules = { group = "androidx.test", name="rules", version.ref = "an
androidx-ktx = ["androidx.core.ktx", "androidx.preference.ktx"]
compose = ["compose.material3", "compose.material3.window.size.classes", "compose.ui.tooling.preview", "compose.ui.material.icons.extended"]
compose-debug = ["compose.ui.tooling", "compose.ui.test.manifest"]
androidx-compose-integration = ["androidx.activity.compose"]
androidx-compose-integration = ["androidx.activity.compose", "androidx.navigation.compose"]
testing = ["junit.junit"]
ui-testing = ["androidx.test.runner", "androidx.test.rules", "compose.ui.test.junit4"]

Expand Down

0 comments on commit 7540750

Please sign in to comment.