Add new account dialog in AccountTab

This commit is contained in:
Shinokuni 2024-02-19 21:53:33 +01:00
parent 13557c00e6
commit 7b537123c8
6 changed files with 262 additions and 87 deletions

View File

@ -33,6 +33,8 @@ import cafe.adriel.voyager.navigator.currentOrThrow
import cafe.adriel.voyager.navigator.tab.Tab
import cafe.adriel.voyager.navigator.tab.TabOptions
import com.readrops.app.compose.R
import com.readrops.app.compose.account.credentials.AccountCredentialsScreen
import com.readrops.app.compose.account.selection.AccountSelectionDialog
import com.readrops.app.compose.account.selection.AccountSelectionScreen
import com.readrops.app.compose.util.components.SelectableIconText
import com.readrops.app.compose.util.components.TwoChoicesDialog
@ -80,7 +82,13 @@ object AccountTab : Tab {
}
DialogState.NewAccount -> {
AccountSelectionDialog(
onDismiss = { viewModel.closeDialog() },
onValidate = { accountType ->
viewModel.closeDialog()
navigator.push(AccountCredentialsScreen(accountType, state.account))
}
)
}
else -> {}
@ -104,7 +112,7 @@ object AccountTab : Tab {
},
floatingActionButton = {
FloatingActionButton(
onClick = {}
onClick = { viewModel.openDialog(DialogState.NewAccount) }
) {
Icon(
painter = painterResource(id = R.drawable.ic_add_account),
@ -142,6 +150,7 @@ object AccountTab : Tab {
icon = painterResource(id = R.drawable.ic_add_account),
text = stringResource(R.string.credentials),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.mediumSpacing,
onClick = { }
)
@ -150,6 +159,7 @@ object AccountTab : Tab {
icon = painterResource(id = R.drawable.ic_notifications),
text = stringResource(R.string.notifications),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.mediumSpacing,
onClick = { }
)
@ -158,6 +168,7 @@ object AccountTab : Tab {
icon = rememberVectorPainter(image = Icons.Default.AccountCircle),
text = stringResource(R.string.delete_account),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.mediumSpacing,
color = MaterialTheme.colorScheme.error,
tint = MaterialTheme.colorScheme.error,

View File

@ -0,0 +1,80 @@
package com.readrops.app.compose.account.selection
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
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.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import com.readrops.app.compose.R
import com.readrops.app.compose.util.components.SelectableImageText
import com.readrops.app.compose.util.theme.MediumSpacer
import com.readrops.app.compose.util.theme.spacing
import com.readrops.db.entities.account.AccountType
@Composable
fun AccountSelectionDialog(
onDismiss: () -> Unit,
onValidate: (AccountType) -> Unit,
) {
Dialog(
onDismissRequest = onDismiss
) {
Card(
shape = RoundedCornerShape(24.dp)
) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.background)
.padding(MaterialTheme.spacing.largeSpacing)
) {
Icon(
painter = painterResource(id = R.drawable.ic_add_account),
contentDescription = null,
modifier = Modifier.size(MaterialTheme.spacing.largeSpacing)
)
MediumSpacer()
Text(
text = stringResource(R.string.new_account),
style = MaterialTheme.typography.headlineSmall
)
MediumSpacer()
AccountType.values().forEach { type ->
SelectableImageText(
image = painterResource(
id = if (type != AccountType.LOCAL)
type.iconRes
else
R.drawable.ic_rss_feed_grey
),
text = stringResource(id = type.typeName),
style = MaterialTheme.typography.titleMedium,
spacing = MaterialTheme.spacing.mediumSpacing,
padding = MaterialTheme.spacing.shortSpacing,
imageSize = 36.dp,
onClick = { onValidate(type) }
)
}
}
}
}
}

View File

@ -4,7 +4,7 @@ import androidx.activity.compose.BackHandler
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AccountBox
import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.MoreVert
import androidx.compose.material3.BottomAppBar
import androidx.compose.material3.Icon
@ -15,6 +15,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import cafe.adriel.voyager.androidx.AndroidScreen
import cafe.adriel.voyager.navigator.LocalNavigator
import cafe.adriel.voyager.navigator.currentOrThrow
@ -33,75 +34,74 @@ class HomeScreen : AndroidScreen() {
val navigator = LocalNavigator.currentOrThrow
TabNavigator(
tab = TimelineTab
tab = TimelineTab
) { tabNavigator ->
CompositionLocalProvider(LocalNavigator provides navigator) {
Scaffold(
bottomBar = {
BottomAppBar {
NavigationBarItem(
selected = tabNavigator.current.key == TimelineTab.key,
onClick = { tabNavigator.current = TimelineTab },
icon = {
Icon(
painter = painterResource(R.drawable.ic_timeline),
contentDescription = null
)
},
label = { Text("Timeline") }
)
bottomBar = {
BottomAppBar {
NavigationBarItem(
selected = tabNavigator.current.key == TimelineTab.key,
onClick = { tabNavigator.current = TimelineTab },
icon = {
Icon(
painter = painterResource(R.drawable.ic_timeline),
contentDescription = null
)
},
label = { Text("Timeline") }
)
NavigationBarItem(
selected = tabNavigator.current.key == FeedTab.key,
onClick = { tabNavigator.current = FeedTab },
icon = {
Icon(
painter = painterResource(R.drawable.ic_rss_feed_grey),
contentDescription = null
)
},
label = { Text("Feeds") }
)
NavigationBarItem(
selected = tabNavigator.current.key == FeedTab.key,
onClick = { tabNavigator.current = FeedTab },
icon = {
Icon(
painter = painterResource(R.drawable.ic_rss_feed_grey),
contentDescription = null
)
},
label = { Text(text = stringResource(R.string.feeds)) }
)
NavigationBarItem(
selected = tabNavigator.current.key == AccountTab.key,
onClick = { tabNavigator.current = AccountTab },
icon = {
Icon(
imageVector = Icons.Default.AccountBox,
contentDescription = null,
)
},
label = { Text("Account") }
)
NavigationBarItem(
selected = tabNavigator.current.key == AccountTab.key,
onClick = { tabNavigator.current = AccountTab },
icon = {
Icon(
imageVector = Icons.Default.AccountCircle,
contentDescription = null,
)
},
label = { Text(text = stringResource(R.string.account)) }
)
NavigationBarItem(
selected = tabNavigator.current.key == MoreTab.key,
onClick = { tabNavigator.current = MoreTab },
icon = {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = null,
)
},
label = { Text("More") }
)
}
},
NavigationBarItem(
selected = tabNavigator.current.key == MoreTab.key,
onClick = { tabNavigator.current = MoreTab },
icon = {
Icon(
imageVector = Icons.Default.MoreVert,
contentDescription = null,
)
},
label = { Text("More") }
)
}
},
) { paddingValues ->
Box(
modifier = Modifier.padding(paddingValues)
modifier = Modifier.padding(paddingValues)
) {
CurrentTab()
}
BackHandler(
enabled = tabNavigator.current != TimelineTab,
onBack = { tabNavigator.current = TimelineTab }
enabled = tabNavigator.current != TimelineTab,
onBack = { tabNavigator.current = TimelineTab }
)
}
}
}
}
}

View File

@ -66,7 +66,7 @@ object MoreTab : Tab {
icon = painterResource(id = R.drawable.ic_settings),
text = stringResource(R.string.settings),
style = MaterialTheme.typography.titleMedium,
padding = MaterialTheme.spacing.mediumSpacing,
spacing = MaterialTheme.spacing.mediumSpacing,
onClick = { }
)
@ -74,7 +74,7 @@ object MoreTab : Tab {
icon = painterResource(id = R.drawable.ic_settings),
text = "Backup",
style = MaterialTheme.typography.titleMedium,
padding = MaterialTheme.spacing.mediumSpacing,
spacing = MaterialTheme.spacing.mediumSpacing,
onClick = { }
)
@ -82,7 +82,7 @@ object MoreTab : Tab {
icon = painterResource(id = R.drawable.ic_settings),
text = "Open-source libraries",
style = MaterialTheme.typography.titleMedium,
padding = MaterialTheme.spacing.mediumSpacing,
spacing = MaterialTheme.spacing.mediumSpacing,
onClick = { }
)
}

View File

@ -1,5 +1,6 @@
package com.readrops.app.compose.util.components
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
@ -23,28 +24,22 @@ import com.readrops.app.compose.util.theme.spacing
import com.readrops.app.compose.util.toDp
@Composable
fun IconText(
icon: Painter,
fun BaseText(
text: String,
style: TextStyle,
modifier: Modifier = Modifier,
color: Color = LocalContentColor.current,
tint: Color = LocalContentColor.current,
padding: Dp = MaterialTheme.spacing.veryShortSpacing,
spacing: Dp = MaterialTheme.spacing.veryShortSpacing,
onClick: (() -> Unit)? = null,
leftContent: @Composable () -> Unit
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = if (onClick != null) modifier.clickable { onClick() } else modifier,
) {
Icon(
painter = icon,
tint = tint,
contentDescription = null,
modifier = Modifier.size(style.toDp()),
)
leftContent()
Spacer(Modifier.width(padding))
Spacer(Modifier.width(spacing))
Text(
text = text,
@ -54,6 +49,63 @@ fun IconText(
}
}
@Composable
fun IconText(
icon: Painter,
text: String,
style: TextStyle,
modifier: Modifier = Modifier,
color: Color = LocalContentColor.current,
tint: Color = LocalContentColor.current,
spacing: Dp = MaterialTheme.spacing.veryShortSpacing,
onClick: (() -> Unit)? = null,
) {
BaseText(
text = text,
style = style,
color = color,
spacing = spacing,
modifier = modifier,
onClick = onClick
) {
Icon(
painter = icon,
tint = tint,
contentDescription = null,
modifier = Modifier.size(style.toDp()),
)
}
}
@Composable
fun ImageText(
image: Painter,
text: String,
style: TextStyle,
modifier: Modifier = Modifier,
color: Color = LocalContentColor.current,
spacing: Dp = MaterialTheme.spacing.veryShortSpacing,
imageSize: Dp = style.toDp(),
onClick: (() -> Unit)? = null
) {
BaseText(
text = text,
style = style,
color = color,
spacing = spacing,
modifier = modifier,
onClick = onClick
) {
Image(
painter = image,
contentDescription = null,
modifier = Modifier.size(imageSize),
)
}
}
@Composable
fun SelectableIconText(
icon: Painter,
@ -63,27 +115,59 @@ fun SelectableIconText(
modifier: Modifier = Modifier,
color: Color = LocalContentColor.current,
tint: Color = LocalContentColor.current,
padding: Dp = MaterialTheme.spacing.veryShortSpacing,
spacing: Dp = MaterialTheme.spacing.veryShortSpacing,
padding: Dp = MaterialTheme.spacing.shortSpacing
) {
Box(
modifier = modifier.clickable { onClick() }
modifier = modifier
.fillMaxWidth()
.clickable { onClick() }
.padding(padding)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
.padding(
horizontal = MaterialTheme.spacing.mediumSpacing,
vertical = MaterialTheme.spacing.mediumSpacing
)
BaseText(
text = text,
style = style,
color = color,
spacing = spacing
) {
IconText(
icon = icon,
text = text,
style = style,
padding = padding,
Icon(
painter = icon,
tint = tint,
color = color
contentDescription = null,
modifier = Modifier.size(style.toDp()),
)
}
}
}
@Composable
fun SelectableImageText(
image: Painter,
text: String,
style: TextStyle,
onClick: () -> Unit,
modifier: Modifier = Modifier,
color: Color = LocalContentColor.current,
spacing: Dp = MaterialTheme.spacing.veryShortSpacing,
padding: Dp = MaterialTheme.spacing.shortSpacing,
imageSize: Dp = style.toDp()
) {
Box(
modifier = modifier
.fillMaxWidth()
.clickable { onClick() }
.padding(padding)
) {
BaseText(
text = text,
style = style,
color = color,
spacing = spacing
) {
Image(
painter = image,
contentDescription = null,
modifier = Modifier.size(imageSize),
)
}
}

View File

@ -12,6 +12,6 @@ enum class AccountType(@DrawableRes val iconRes: Int,
val accountConfig: AccountConfig?) : Parcelable {
LOCAL(R.mipmap.ic_launcher, R.string.local_account, AccountConfig.LOCAL),
NEXTCLOUD_NEWS(R.drawable.ic_nextcloud_news, R.string.nextcloud_news, AccountConfig.NEXTCLOUD_NEWS),
FEEDLY(R.drawable.ic_feedly, R.string.feedly, null),
/* FEEDLY(R.drawable.ic_feedly, R.string.feedly, null),*/
FRESHRSS(R.drawable.ic_freshrss, R.string.freshrss, AccountConfig.FRESHRSS);
}