Merge pull request #549 from vector-im/feature/bma/onboardingServer

Onboarding iteration
This commit is contained in:
Benoit Marty 2023-06-13 09:21:50 +02:00 committed by GitHub
commit ef7ddb8d0f
168 changed files with 3294 additions and 1406 deletions

View file

@ -0,0 +1,126 @@
/*
* Copyright (c) 2023 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.element.android.libraries.designsystem.atomic.atoms
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Home
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Icon
/**
* RoundedIconAtom is an atom which displays an icon inside a rounded container.
*
* @param modifier the modifier to apply to this layout
* @param size the size of the icon
* @param resourceId the resource id of the icon to display, exclusive with [imageVector]
* @param imageVector the image vector of the icon to display, exclusive with [resourceId]
* @param tint the tint to apply to the icon
*/
@Composable
fun RoundedIconAtom(
modifier: Modifier = Modifier,
size: RoundedIconAtomSize = RoundedIconAtomSize.Large,
resourceId: Int? = null,
imageVector: ImageVector? = null,
tint: Color = MaterialTheme.colorScheme.secondary
) {
Box(
modifier = modifier
.size(size.toContainerSize())
.background(
color = LocalColors.current.quinary,
shape = RoundedCornerShape(size.toCornerSize())
)
) {
Icon(
modifier = Modifier
.align(Alignment.Center)
.size(size.toIconSize()),
tint = tint,
resourceId = resourceId,
imageVector = imageVector,
contentDescription = "",
)
}
}
private fun RoundedIconAtomSize.toContainerSize(): Dp {
return when (this) {
RoundedIconAtomSize.Medium -> 30.dp
RoundedIconAtomSize.Large -> 70.dp
}
}
private fun RoundedIconAtomSize.toCornerSize(): Dp {
return when (this) {
RoundedIconAtomSize.Medium -> 8.dp
RoundedIconAtomSize.Large -> 14.dp
}
}
private fun RoundedIconAtomSize.toIconSize(): Dp {
return when (this) {
RoundedIconAtomSize.Medium -> 16.dp
RoundedIconAtomSize.Large -> 48.dp
}
}
@Preview
@Composable
internal fun RoundedIconAtomLightPreview() =
ElementPreviewLight { ContentToPreview() }
@Preview
@Composable
internal fun RoundedIconAtomDarkPreview() =
ElementPreviewDark { ContentToPreview() }
@Composable
private fun ContentToPreview() {
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
RoundedIconAtom(
size = RoundedIconAtomSize.Medium,
imageVector = Icons.Filled.Home,
)
RoundedIconAtom(
size = RoundedIconAtomSize.Large,
imageVector = Icons.Filled.Home,
)
}
}
enum class RoundedIconAtomSize {
Medium,
Large
}

View file

@ -16,55 +16,55 @@
package io.element.android.libraries.designsystem.atomic.molecules
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import io.element.android.libraries.designsystem.ElementTextStyles
import io.element.android.libraries.designsystem.R
import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtom
import io.element.android.libraries.designsystem.atomic.atoms.RoundedIconAtomSize
import io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.LocalColors
import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.Text
/**
* IconTitleSubtitleMolecule is a molecule which displays an icon, a title and a subtitle.
*
* @param title the title to display
* @param subTitle the subtitle to display
* @param modifier the modifier to apply to this layout
* @param iconResourceId the resource id of the icon to display, exclusive with [iconImageVector]
* @param iconImageVector the image vector of the icon to display, exclusive with [iconResourceId]
* @param iconTint the tint to apply to the icon
*/
@Composable
fun IconTitleSubtitleMolecule(
iconResourceId: Int,
title: String,
subTitle: String,
modifier: Modifier = Modifier,
iconResourceId: Int? = null,
iconImageVector: ImageVector? = null,
iconTint: Color = MaterialTheme.colorScheme.primary,
) {
Column(modifier) {
Box(
RoundedIconAtom(
modifier = Modifier
.size(width = 70.dp, height = 70.dp)
.align(Alignment.CenterHorizontally)
.background(
color = LocalColors.current.quinary,
shape = RoundedCornerShape(14.dp)
)
) {
Icon(
modifier = Modifier
.align(Alignment.Center)
.size(width = 48.dp, height = 48.dp),
tint = MaterialTheme.colorScheme.secondary,
resourceId = iconResourceId,
contentDescription = "",
)
}
.align(Alignment.CenterHorizontally),
size = RoundedIconAtomSize.Large,
resourceId = iconResourceId,
imageVector = iconImageVector,
tint = iconTint,
)
Spacer(modifier = Modifier.height(16.dp))
Text(
text = title,

View file

@ -37,8 +37,8 @@ fun LabelledTextField(
value: String,
modifier: Modifier = Modifier,
placeholder: String? = null,
maxLines: Int = Int.MAX_VALUE,
singleLine: Boolean = false,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
onValueChange: (String) -> Unit = {},
) {
Column(

View file

@ -24,12 +24,14 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
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 io.element.android.libraries.designsystem.preview.ElementPreviewDark
import io.element.android.libraries.designsystem.preview.ElementPreviewLight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.ui.strings.R as StringR
@Composable
fun AsyncFailure(
@ -43,11 +45,11 @@ fun AsyncFailure(
.padding(vertical = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(text = throwable.message ?: "An error occurred")
Text(text = throwable.message ?: stringResource(id = StringR.string.error_unknown))
if (onRetry != null) {
Spacer(modifier = Modifier.height(24.dp))
Button(onClick = onRetry) {
Text(text = "Retry")
Text(text = stringResource(id = StringR.string.action_retry))
}
}
}

View file

@ -22,5 +22,5 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
@Composable
public fun textFieldState(stateValue: String): MutableState<String> =
fun textFieldState(stateValue: String): MutableState<String> =
remember(stateValue) { mutableStateOf(stateValue) }

View file

@ -69,14 +69,11 @@ fun PreferenceView(
)
},
content = {
val scrollState = rememberScrollState()
Column(
modifier = Modifier
.padding(it)
.consumeWindowInsets(it)
.verticalScroll(
state = scrollState,
)
.verticalScroll(state = rememberScrollState())
) {
content()
}

View file

@ -30,6 +30,54 @@ import androidx.compose.ui.tooling.preview.Preview
import io.element.android.libraries.designsystem.preview.ElementThemedPreview
import io.element.android.libraries.designsystem.preview.PreviewGroup
/**
* Icon is a wrapper around [androidx.compose.material3.Icon] which allows to use
* [ImageVector], [ImageBitmap] or [DrawableRes] as icon source.
*
* @param contentDescription the content description to be used for accessibility
* @param modifier the modifier to apply to this layout
* @param tint the tint to apply to the icon
* @param imageVector the image vector of the icon to display, exclusive with [bitmap] and [resourceId]
* @param bitmap the bitmap of the icon to display, exclusive with [imageVector] and [resourceId]
* @param resourceId the resource id of the icon to display, exclusive with [imageVector] and [bitmap]
*/
@Composable
fun Icon(
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current,
imageVector: ImageVector? = null,
bitmap: ImageBitmap? = null,
@DrawableRes resourceId: Int? = null,
) {
when {
imageVector != null -> {
Icon(
imageVector = imageVector,
contentDescription = contentDescription,
modifier = modifier,
tint = tint
)
}
bitmap != null -> {
Icon(
bitmap = bitmap,
contentDescription = contentDescription,
modifier = modifier,
tint = tint
)
}
resourceId != null -> {
Icon(
resourceId = resourceId,
contentDescription = contentDescription,
modifier = modifier,
tint = tint
)
}
}
}
@Composable
fun Icon(
imageVector: ImageVector,

View file

@ -67,7 +67,7 @@ fun OutlinedTextField(
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = OutlinedTextFieldDefaults.shape,
colors: TextFieldColors = OutlinedTextFieldDefaults.colors()

View file

@ -68,7 +68,7 @@ fun TextField(
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
maxLines: Int = if (singleLine) 1 else Int.MAX_VALUE,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
shape: Shape = TextFieldDefaults.shape,
colors: TextFieldColors = TextFieldDefaults.colors()