Disable search fab and add a skeleton of search screen.
This commit is contained in:
parent
54e09e5f1d
commit
70aa2a7972
15 changed files with 296 additions and 49 deletions
20
app/release/output-metadata.json
Normal file
20
app/release/output-metadata.json
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"version": 3,
|
||||
"artifactType": {
|
||||
"type": "APK",
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.pixelized.rplexicon",
|
||||
"variantName": "release",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"attributes": [],
|
||||
"versionCode": 1,
|
||||
"versionName": "0.1.0",
|
||||
"outputFile": "app-release.apk"
|
||||
}
|
||||
],
|
||||
"elementType": "File"
|
||||
}
|
||||
|
|
@ -23,12 +23,7 @@ class AuthenticationRepository @Inject constructor(
|
|||
val credential: GoogleAccountCredential
|
||||
get() {
|
||||
val credential = GoogleAccountCredential
|
||||
.usingOAuth2(
|
||||
context, listOf(
|
||||
SheetsScopes.SPREADSHEETS,
|
||||
SheetsScopes.SPREADSHEETS_READONLY,
|
||||
)
|
||||
)
|
||||
.usingOAuth2(context, capabilities)
|
||||
.setBackOff(ExponentialBackOff())
|
||||
|
||||
credential.selectedAccount = signInCredential.value?.let {
|
||||
|
|
@ -43,4 +38,11 @@ class AuthenticationRepository @Inject constructor(
|
|||
) {
|
||||
signInCredential.value = credential
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val capabilities = listOf(
|
||||
// SheetsScopes.SPREADSHEETS,
|
||||
SheetsScopes.SPREADSHEETS_READONLY,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -95,16 +95,16 @@ class LexiconRepository @Inject constructor(
|
|||
Lexicon(
|
||||
id = index,
|
||||
name = name,
|
||||
diminutive = diminutive,
|
||||
diminutive = diminutive?.takeIf { it.isNotBlank() },
|
||||
gender = when (gender) {
|
||||
"Male" -> Lexicon.Gender.MALE
|
||||
"Femelle" -> Lexicon.Gender.FEMALE
|
||||
else -> Lexicon.Gender.UNDETERMINED
|
||||
},
|
||||
race = race,
|
||||
race = race?.takeIf { it.isNotBlank() },
|
||||
portrait = portrait?.split("\n")?.mapNotNull { it.toUriOrNull() } ?: emptyList(),
|
||||
description = description,
|
||||
history = history,
|
||||
description = description?.takeIf { it.isNotBlank() },
|
||||
history = history?.takeIf { it.isNotBlank() },
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
|
@ -119,7 +119,7 @@ class LexiconRepository @Inject constructor(
|
|||
}
|
||||
|
||||
private fun String?.toUriOrNull(): Uri? = try {
|
||||
this?.toUri()
|
||||
this?.takeIf { it.isNotBlank() }?.toUri()
|
||||
} catch (_: Exception) {
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,6 +9,11 @@ import androidx.navigation.NavHostController
|
|||
import androidx.navigation.NavOptionsBuilder
|
||||
import com.google.accompanist.navigation.animation.AnimatedNavHost
|
||||
import com.google.accompanist.navigation.animation.rememberAnimatedNavController
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.AUTHENTICATION_ROUTE
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableAuthentication
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableCharacterDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableLexicon
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.composableSearch
|
||||
|
||||
val LocalScreenNavHost = staticCompositionLocalOf<NavHostController> {
|
||||
error("LocalScreenNavHost not ready")
|
||||
|
|
@ -32,12 +37,11 @@ fun ScreenNavHost(
|
|||
composableAuthentication()
|
||||
composableLexicon(lazyListState = lexiconListState)
|
||||
composableCharacterDetail()
|
||||
composableSearch()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun defaultOption(): NavOptionsBuilder.() -> Unit = { }
|
||||
|
||||
fun rootOption(): NavOptionsBuilder.() -> Unit = {
|
||||
launchSingleTop = true
|
||||
restoreState = true
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package com.pixelized.rplexicon.ui.navigation
|
||||
package com.pixelized.rplexicon.ui.navigation.screens
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptionsBuilder
|
||||
import com.pixelized.rplexicon.ui.navigation.NavigationAnimation
|
||||
import com.pixelized.rplexicon.ui.navigation.animatedComposable
|
||||
import com.pixelized.rplexicon.ui.screens.authentication.AuthenticationScreen
|
||||
|
||||
private const val ROUTE = "authentication"
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package com.pixelized.rplexicon.ui.navigation
|
||||
package com.pixelized.rplexicon.ui.navigation.screens
|
||||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.Stable
|
||||
|
|
@ -8,6 +8,8 @@ import androidx.navigation.NavHostController
|
|||
import androidx.navigation.NavOptionsBuilder
|
||||
import androidx.navigation.NavType
|
||||
import androidx.navigation.navArgument
|
||||
import com.pixelized.rplexicon.ui.navigation.NavigationAnimation
|
||||
import com.pixelized.rplexicon.ui.navigation.animatedComposable
|
||||
import com.pixelized.rplexicon.ui.screens.detail.CharacterDetailScreen
|
||||
import com.pixelized.rplexicon.utilitary.extentions.ARG
|
||||
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
package com.pixelized.rplexicon.ui.navigation
|
||||
package com.pixelized.rplexicon.ui.navigation.screens
|
||||
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptionsBuilder
|
||||
import com.pixelized.rplexicon.ui.navigation.NavigationAnimation
|
||||
import com.pixelized.rplexicon.ui.navigation.animatedComposable
|
||||
import com.pixelized.rplexicon.ui.screens.lexicon.LexiconScreen
|
||||
|
||||
private const val ROUTE = "lexicon"
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
package com.pixelized.rplexicon.ui.navigation.screens
|
||||
|
||||
import androidx.navigation.NavGraphBuilder
|
||||
import androidx.navigation.NavHostController
|
||||
import androidx.navigation.NavOptionsBuilder
|
||||
import com.pixelized.rplexicon.ui.navigation.NavigationAnimation
|
||||
import com.pixelized.rplexicon.ui.navigation.animatedComposable
|
||||
import com.pixelized.rplexicon.ui.screens.search.SearchScreen
|
||||
|
||||
private const val ROUTE = "search"
|
||||
|
||||
const val SEARCH_ROUTE = ROUTE
|
||||
|
||||
fun NavGraphBuilder.composableSearch() {
|
||||
animatedComposable(
|
||||
route = SEARCH_ROUTE,
|
||||
animation = NavigationAnimation.Push,
|
||||
) {
|
||||
SearchScreen()
|
||||
}
|
||||
}
|
||||
|
||||
fun NavHostController.navigateToSearch(
|
||||
option: NavOptionsBuilder.() -> Unit = {},
|
||||
) {
|
||||
navigate(route = ROUTE, builder = option)
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ import androidx.hilt.navigation.compose.hiltViewModel
|
|||
import com.pixelized.rplexicon.LocalActivity
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.navigation.navigateToLexicon
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToLexicon
|
||||
import com.pixelized.rplexicon.ui.navigation.rootOption
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
import com.pixelized.rplexicon.ui.theme.colors.GoogleColorPalette
|
||||
|
|
|
|||
|
|
@ -175,13 +175,13 @@ private fun CharacterDetailScreenContent(
|
|||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
horizontalArrangement = Arrangement.spacedBy(4.dp)
|
||||
) {
|
||||
item.value.race?.let {
|
||||
item.value.gender?.let {
|
||||
Text(
|
||||
style = remember { typography.labelMedium.copy(fontStyle = FontStyle.Italic) },
|
||||
text = it,
|
||||
)
|
||||
}
|
||||
item.value.gender?.let {
|
||||
item.value.race?.let {
|
||||
Text(
|
||||
style = remember { typography.labelMedium.copy(fontStyle = FontStyle.Italic) },
|
||||
text = it,
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import androidx.lifecycle.SavedStateHandle
|
|||
import androidx.lifecycle.ViewModel
|
||||
import com.pixelized.rplexicon.model.Lexicon
|
||||
import com.pixelized.rplexicon.repository.LexiconRepository
|
||||
import com.pixelized.rplexicon.ui.navigation.characterDetailArgument
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.characterDetailArgument
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import javax.inject.Inject
|
||||
|
||||
|
|
@ -21,11 +21,11 @@ class CharacterDetailViewModel @Inject constructor(
|
|||
val source = repository.data.value[savedStateHandle.characterDetailArgument.id]
|
||||
return CharacterDetailUio(
|
||||
name = source.name,
|
||||
diminutive = source.diminutive?.takeIf { it.isNotBlank() }?.let { "./ $it" },
|
||||
diminutive = source.diminutive?.let { "./ $it" },
|
||||
gender = when (source.gender) {
|
||||
Lexicon.Gender.MALE -> "homme"
|
||||
Lexicon.Gender.FEMALE -> "femme"
|
||||
Lexicon.Gender.UNDETERMINED -> "inconnu"
|
||||
Lexicon.Gender.MALE -> "Male"
|
||||
Lexicon.Gender.FEMALE -> "Femelle"
|
||||
Lexicon.Gender.UNDETERMINED -> "Inconnu"
|
||||
},
|
||||
race = source.race,
|
||||
portrait = source.portrait,
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ import com.pixelized.rplexicon.LocalSnack
|
|||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.composable.FloatingActionButton
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.navigation.navigateToCharacterDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToCharacterDetail
|
||||
import com.pixelized.rplexicon.ui.navigation.screens.navigateToSearch
|
||||
import com.pixelized.rplexicon.ui.screens.lexicon.LexiconErrorUio.Default
|
||||
import com.pixelized.rplexicon.ui.screens.lexicon.LexiconErrorUio.Permission
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
|
|
@ -96,7 +97,7 @@ fun LexiconScreen(
|
|||
refreshing = viewModel.isLoading,
|
||||
isFabExpended = isFabExpended,
|
||||
onSearch = {
|
||||
|
||||
screen.navigateToSearch()
|
||||
},
|
||||
onItem = {
|
||||
screen.navigateToCharacterDetail(id = it.id)
|
||||
|
|
@ -134,26 +135,26 @@ private fun LexiconScreenContent(
|
|||
)
|
||||
},
|
||||
floatingActionButton = {
|
||||
FloatingActionButton(
|
||||
modifier = Modifier.padding(start = 32.dp),
|
||||
expended = isFabExpended.value,
|
||||
onClick = onSearch,
|
||||
icon = {
|
||||
Icon(
|
||||
tint = MaterialTheme.colorScheme.onPrimary,
|
||||
painter = painterResource(id = R.drawable.ic_baseline_search_24),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
text = {
|
||||
val typography = MaterialTheme.typography
|
||||
Text(
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
style = remember { typography.bodyLarge.copy(fontWeight = FontWeight.Bold) },
|
||||
text = "Rechercher",
|
||||
)
|
||||
},
|
||||
)
|
||||
// FloatingActionButton(
|
||||
// modifier = Modifier.padding(start = 32.dp),
|
||||
// expended = isFabExpended.value,
|
||||
// onClick = onSearch,
|
||||
// icon = {
|
||||
// Icon(
|
||||
// tint = MaterialTheme.colorScheme.onPrimary,
|
||||
// painter = painterResource(id = R.drawable.ic_baseline_search_24),
|
||||
// contentDescription = null,
|
||||
// )
|
||||
// },
|
||||
// text = {
|
||||
// val typography = MaterialTheme.typography
|
||||
// Text(
|
||||
// color = MaterialTheme.colorScheme.onPrimary,
|
||||
// style = remember { typography.bodyLarge.copy(fontWeight = FontWeight.Bold) },
|
||||
// text = "Rechercher",
|
||||
// )
|
||||
// },
|
||||
// )
|
||||
}
|
||||
) {
|
||||
Box(
|
||||
|
|
@ -167,7 +168,7 @@ private fun LexiconScreenContent(
|
|||
state = lazyColumnState,
|
||||
contentPadding = PaddingValues(
|
||||
top = 8.dp,
|
||||
bottom = 8.dp + 16.dp + 56.dp + 16.dp
|
||||
bottom = 8.dp + 16.dp // + 56.dp + 16.dp,
|
||||
),
|
||||
) {
|
||||
items(items = items.value) { item ->
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ class LexiconViewModel @Inject constructor(
|
|||
name = item.name,
|
||||
diminutive = item.diminutive?.takeIf { it.isNotBlank() }?.let { "./ $it" },
|
||||
gender = when (item.gender) {
|
||||
Lexicon.Gender.MALE -> "h."
|
||||
Lexicon.Gender.MALE -> "m."
|
||||
Lexicon.Gender.FEMALE -> "f."
|
||||
Lexicon.Gender.UNDETERMINED -> "u."
|
||||
},
|
||||
|
|
|
|||
|
|
@ -0,0 +1,183 @@
|
|||
package com.pixelized.rplexicon.ui.screens.search
|
||||
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_NO
|
||||
import android.content.res.Configuration.UI_MODE_NIGHT_YES
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material.DropdownMenuItem
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.ExposedDropdownMenuBox
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.State
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.pixelized.rplexicon.R
|
||||
import com.pixelized.rplexicon.ui.navigation.LocalScreenNavHost
|
||||
import com.pixelized.rplexicon.ui.theme.LexiconTheme
|
||||
|
||||
@Composable
|
||||
fun SearchScreen() {
|
||||
val screen = LocalScreenNavHost.current
|
||||
|
||||
Surface {
|
||||
SearchScreenContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
onBack = {
|
||||
screen.popBackStack()
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
private fun SearchScreenContent(
|
||||
modifier: Modifier = Modifier,
|
||||
onBack: () -> Unit,
|
||||
) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
containerColor = Color.Transparent,
|
||||
topBar = {
|
||||
TopAppBar(
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBack) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_arrow_back_ios_new_24),
|
||||
contentDescription = null
|
||||
)
|
||||
}
|
||||
},
|
||||
title = {
|
||||
Text(text = "Rechercher")
|
||||
},
|
||||
)
|
||||
},
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(paddingValues = it)
|
||||
.padding(all = 16.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
TextField(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
value = "",
|
||||
label = {
|
||||
Text("Nom")
|
||||
},
|
||||
onValueChange = { _ -> },
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surface,
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
|
||||
),
|
||||
)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(8.dp),
|
||||
) {
|
||||
DropDownField(
|
||||
modifier = Modifier.weight(1f),
|
||||
subject = remember { mutableStateOf("1") },
|
||||
subjects = listOf("1", "2"),
|
||||
onChange = { },
|
||||
expanded = remember { mutableStateOf(false) },
|
||||
onExpandedChange = { }
|
||||
)
|
||||
DropDownField(
|
||||
modifier = Modifier.weight(1f),
|
||||
subject = remember { mutableStateOf("1") },
|
||||
subjects = listOf("1", "2"),
|
||||
onChange = { },
|
||||
expanded = remember { mutableStateOf(false) },
|
||||
onExpandedChange = { }
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterialApi::class)
|
||||
@Composable
|
||||
fun DropDownField(
|
||||
modifier: Modifier = Modifier,
|
||||
subjects: List<String>,
|
||||
subject: State<String>,
|
||||
onChange: (String) -> Unit,
|
||||
expanded: State<Boolean>,
|
||||
onExpandedChange: (Boolean) -> Unit
|
||||
) {
|
||||
ExposedDropdownMenuBox(
|
||||
modifier = modifier,
|
||||
expanded = expanded.value,
|
||||
onExpandedChange = onExpandedChange,
|
||||
) {
|
||||
TextField(
|
||||
modifier = Modifier.clickable { onExpandedChange(true) },
|
||||
readOnly = true,
|
||||
singleLine = true,
|
||||
placeholder = {
|
||||
Text(
|
||||
text = "pouet"
|
||||
)
|
||||
},
|
||||
trailingIcon = {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_baseline_arrow_drop_down_24),
|
||||
contentDescription = null,
|
||||
)
|
||||
},
|
||||
colors = TextFieldDefaults.colors(
|
||||
focusedContainerColor = MaterialTheme.colorScheme.surface,
|
||||
unfocusedContainerColor = MaterialTheme.colorScheme.surface,
|
||||
),
|
||||
value = subject.value,
|
||||
onValueChange = {},
|
||||
)
|
||||
|
||||
ExposedDropdownMenu(
|
||||
expanded = expanded.value,
|
||||
onDismissRequest = { onExpandedChange(false) },
|
||||
) {
|
||||
subjects.forEach {
|
||||
DropdownMenuItem(
|
||||
onClick = { onChange(it) },
|
||||
content = { Text(text = it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview(uiMode = UI_MODE_NIGHT_NO)
|
||||
@Preview(uiMode = UI_MODE_NIGHT_YES)
|
||||
private fun SearchScreenContentPreview() {
|
||||
LexiconTheme {
|
||||
Surface {
|
||||
SearchScreenContent(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
onBack = { },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M7,10l5,5 5,-5z"/>
|
||||
</vector>
|
||||
Loading…
Add table
Add a link
Reference in a new issue