Базовая навигация

This commit is contained in:
Roman Pytkov
2024-11-08 23:55:08 +03:00
parent 09210ff6f4
commit 7a9aee46a6
12 changed files with 149 additions and 99 deletions

View File

@@ -53,9 +53,6 @@ android {
} }
dependencies { dependencies {
implementation(libs.navigation)
implementation(libs.navigation.hilt.compose)
// Yandex // Yandex
implementation(libs.yandex.oauth) implementation(libs.yandex.oauth)
@@ -66,20 +63,17 @@ dependencies {
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom)) //implementation(platform(libs.androidx.compose.bom))
debugImplementation(libs.androidx.ui.tooling) //debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest) //debugImplementation(libs.androidx.ui.test.manifest)
implementation(libs.androidx.ui) //implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit) testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit) androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core) androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom)) //androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4) //androidTestImplementation(libs.androidx.ui.test.junit4)
implementation(project(":domain")) implementation(project(":domain"))
implementation(project(":presentation")) implementation(project(":presentation"))

View File

@@ -20,7 +20,6 @@
android:theme="@style/Theme.Wallenc"> android:theme="@style/Theme.Wallenc">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>

View File

@@ -1,30 +1,10 @@
package com.github.nullptroma.wallenc.app package com.github.nullptroma.wallenc.app
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement import com.github.nullptroma.wallenc.presentation.WallencUi
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import com.github.nullptroma.wallenc.presentation.screens.main.MainScreen
import com.github.nullptroma.wallenc.presentation.theme.WallencTheme
import com.yandex.authsdk.YandexAuthLoginOptions
import com.yandex.authsdk.YandexAuthOptions
import com.yandex.authsdk.YandexAuthResult
import com.yandex.authsdk.YandexAuthSdk
import com.yandex.authsdk.internal.strategy.LoginType
import dagger.hilt.android.AndroidEntryPoint import dagger.hilt.android.AndroidEntryPoint
@@ -34,57 +14,21 @@ class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
enableEdgeToEdge() enableEdgeToEdge()
val sdk = YandexAuthSdk.create(YandexAuthOptions(applicationContext, true)) // val sdk = YandexAuthSdk.create(YandexAuthOptions(applicationContext, true))
val launcher = // val launcher =
registerForActivityResult(sdk.contract) { result -> handleResult(result) } // registerForActivityResult(sdk.contract) { result -> handleResult(result) }
val loginOptions = YandexAuthLoginOptions(LoginType.CHROME_TAB) // val loginOptions = YandexAuthLoginOptions(LoginType.CHROME_TAB)
setContent { setContent {
WallencTheme { WallencUi()
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
// Greeting(Modifier.padding(innerPadding)) {
// launcher.launch(loginOptions)
// }
MainScreen(
Modifier.padding(
innerPadding
)
)
}
}
} }
} }
private fun handleResult(result: YandexAuthResult) { // private fun handleResult(result: YandexAuthResult) {
when (result) { // when (result) {
is YandexAuthResult.Success -> Toast.makeText(applicationContext, "Success: ${result.token}", Toast.LENGTH_SHORT).show() // is YandexAuthResult.Success -> Toast.makeText(applicationContext, "Success: ${result.token}", Toast.LENGTH_SHORT).show()
is YandexAuthResult.Failure -> Toast.makeText(applicationContext, "Success: ${result.exception}", Toast.LENGTH_SHORT).show() // is YandexAuthResult.Failure -> Toast.makeText(applicationContext, "Success: ${result.exception}", Toast.LENGTH_SHORT).show()
YandexAuthResult.Cancelled -> Toast.makeText(applicationContext, "Cancel", Toast.LENGTH_SHORT).show() // YandexAuthResult.Cancelled -> Toast.makeText(applicationContext, "Cancel", Toast.LENGTH_SHORT).show()
} // }
} // }
} }
@Composable
fun Greeting(modifier: Modifier = Modifier, onClick: () -> Unit) {
Column(
modifier = modifier
.fillMaxWidth()
.fillMaxHeight(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
Button(onClick = onClick) {
Text(text = "Login")
}
}
}
@Preview(showBackground = true)
@Composable
fun GreetingPreview() {
com.github.nullptroma.wallenc.presentation.theme.WallencTheme {
Greeting(Modifier) {
}
}
}

View File

@@ -1,11 +1,12 @@
[versions] [versions]
agp = "8.7.1" agp = "8.7.1"
kotlin = "2.0.20" kotlin = "2.0.21"
coreKtx = "1.15.0" coreKtx = "1.15.0"
junit = "4.13.2" junit = "4.13.2"
junitVersion = "1.2.1" junitVersion = "1.2.1"
espressoCore = "3.6.1" espressoCore = "3.6.1"
kotlinxCoroutinesCore = "1.9.0" kotlinxCoroutinesCore = "1.9.0"
kotlinxSerializationJson = "1.7.3"
lifecycleRuntimeKtx = "2.8.7" lifecycleRuntimeKtx = "2.8.7"
activityCompose = "1.9.3" activityCompose = "1.9.3"
composeBom = "2024.10.01" composeBom = "2024.10.01"
@@ -19,11 +20,11 @@ retrofit = "2.11.0"
gson = "2.11.0" gson = "2.11.0"
appcompat = "1.7.0" appcompat = "1.7.0"
material = "1.12.0" material = "1.12.0"
jetbrainsKotlinJvm = "2.0.20"
runtimeAndroid = "1.7.5" runtimeAndroid = "1.7.5"
[libraries] [libraries]
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesCore" } kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinxCoroutinesCore" }
kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinxSerializationJson" }
navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" } navigation = { group = "androidx.navigation", name = "navigation-compose", version.ref = "navigation" }
navigation-hilt-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigation" } navigation-hilt-compose = { group = "androidx.hilt", name = "hilt-navigation-compose", version.ref = "hiltNavigation" }
@@ -69,8 +70,8 @@ androidx-runtime-android = { group = "androidx.compose.runtime", name = "runtime
android-application = { id = "com.android.application", version.ref = "agp" } android-application = { id = "com.android.application", version.ref = "agp" }
kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
jetbrains-kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" }
dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "daggerHilt" } dagger-hilt = { id = "com.google.dagger.hilt.android", version.ref = "daggerHilt" }
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
android-library = { id = "com.android.library", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" }
jetbrains-kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "jetbrainsKotlinJvm" }

View File

@@ -3,6 +3,7 @@ plugins {
alias(libs.plugins.kotlin.android) alias(libs.plugins.kotlin.android)
alias(libs.plugins.compose.compiler) alias(libs.plugins.compose.compiler)
alias(libs.plugins.dagger.hilt) alias(libs.plugins.dagger.hilt)
alias(libs.plugins.jetbrains.kotlin.serialization)
alias(libs.plugins.ksp) alias(libs.plugins.ksp)
} }
@@ -52,6 +53,8 @@ dependencies {
implementation(libs.dagger.hilt) implementation(libs.dagger.hilt)
ksp(libs.dagger.hilt.compiler) ksp(libs.dagger.hilt.compiler)
implementation(libs.kotlinx.serialization.json)
implementation(libs.androidx.core.ktx) implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx) implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose) implementation(libs.androidx.activity.compose)

View File

@@ -0,0 +1,44 @@
package com.github.nullptroma.wallenc.presentation
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.toRoute
import com.github.nullptroma.wallenc.presentation.screens.main.MainRoute
import com.github.nullptroma.wallenc.presentation.screens.main.MainScreen
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsScreen
import com.github.nullptroma.wallenc.presentation.theme.WallencTheme
@Composable
fun WallencUi() {
WallencTheme {
Surface {
WallencNavRoot()
}
}
}
@Composable
fun WallencNavRoot() {
val navController = rememberNavController()
Scaffold { innerPaddings ->
NavHost(navController, startDestination = MainRoute()) {
composable<MainRoute> {
MainScreen(Modifier.padding(innerPaddings), onSettingsRoute = { settingsRoute ->
navController.navigate(settingsRoute)
})
}
composable<SettingsRoute> {
val route: SettingsRoute = it.toRoute()
SettingsScreen(Modifier.padding(innerPaddings), route.text)
}
}
}
}

View File

@@ -0,0 +1,25 @@
package com.github.nullptroma.wallenc.presentation.extensions
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.layout
import androidx.compose.ui.unit.Dp
fun Modifier.ignoreHorizontalParentPadding(horizontal: Dp): Modifier {
return this.layout { measurable, constraints ->
val overrideWidth = constraints.maxWidth + 2 * horizontal.roundToPx()
val placeable = measurable.measure(constraints.copy(maxWidth = overrideWidth))
layout(placeable.width, placeable.height) {
placeable.place(0, 0)
}
}
}
fun Modifier.ignoreVerticalParentPadding(vertical: Dp): Modifier {
return this.layout { measurable, constraints ->
val overrideHeight = constraints.maxHeight + 2 * vertical.roundToPx()
val placeable = measurable.measure(constraints.copy(maxHeight = overrideHeight))
layout(placeable.width, placeable.height) {
placeable.place(0, 0)
}
}
}

View File

@@ -0,0 +1,5 @@
package com.github.nullptroma.wallenc.presentation.screens.main
import kotlinx.serialization.Serializable
@Serializable class MainRoute

View File

@@ -1,29 +1,36 @@
package com.github.nullptroma.wallenc.presentation.screens.main package com.github.nullptroma.wallenc.presentation.screens.main
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.imePadding
import androidx.compose.material3.Button
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TextField import androidx.compose.material3.TextField
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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import com.github.nullptroma.wallenc.presentation.screens.settings.SettingsRoute
@androidx.compose.runtime.Composable @androidx.compose.runtime.Composable
fun MainScreen(modifier: Modifier = Modifier.Companion, viewModel: MainViewModel = hiltViewModel()) { fun MainScreen(modifier: Modifier = Modifier,
viewModel: MainViewModel = hiltViewModel(),
onSettingsRoute: (SettingsRoute) -> Unit) {
val state = viewModel.stateFlow val state = viewModel.stateFlow
Column(modifier = modifier.imePadding()) { var text by remember { mutableStateOf("") }
Column(modifier = modifier.imePadding().fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
Text(text = state.value) TextField(text, onValueChange = { s ->
Box( text = s
modifier = Modifier.Companion.fillMaxSize(), })
contentAlignment = Alignment.Companion.BottomCenter Button( onClick = {
) { onSettingsRoute(SettingsRoute(text))
TextField("", onValueChange = { }) {
Text("Press Me!")
})
} }
} }
} }

View File

@@ -0,0 +1,5 @@
package com.github.nullptroma.wallenc.presentation.screens.settings
import kotlinx.serialization.Serializable
@Serializable class SettingsRoute(val text: String)

View File

@@ -0,0 +1,19 @@
package com.github.nullptroma.wallenc.presentation.screens.settings
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import com.github.nullptroma.wallenc.presentation.R
@Composable
fun SettingsScreen(modifier: Modifier, text: String) {
Column (modifier = modifier.fillMaxSize(), horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center) {
Text(text = stringResource(id = R.string.settings_title))
Text(text = text)
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="settings_title">Settings Screen Title!</string>
</resources>