diff --git a/.idea/dictionaries/shared.xml b/.idea/dictionaries/shared.xml index 216a8cbd20..7c04ccd5e7 100644 --- a/.idea/dictionaries/shared.xml +++ b/.idea/dictionaries/shared.xml @@ -2,6 +2,8 @@ backstack + kover + onboarding textfields diff --git a/.maestro/tests/account/login.yaml b/.maestro/tests/account/login.yaml index 3733b2b047..59cc0980e4 100644 --- a/.maestro/tests/account/login.yaml +++ b/.maestro/tests/account/login.yaml @@ -1,6 +1,6 @@ appId: ${APP_ID} --- -- tapOn: "Get started" +- tapOn: "Sign in manually" - runFlow: ../assertions/assertLoginDisplayed.yaml - takeScreenshot: build/maestro/100-SignIn - runFlow: changeServer.yaml diff --git a/.maestro/tests/assertions/assertInitDisplayed.yaml b/.maestro/tests/assertions/assertInitDisplayed.yaml index 0bcef846c6..b68412be84 100644 --- a/.maestro/tests/assertions/assertInitDisplayed.yaml +++ b/.maestro/tests/assertions/assertInitDisplayed.yaml @@ -1,5 +1,5 @@ appId: ${APP_ID} --- - extendedWaitUntil: - visible: "Own your conversations." + visible: "Communicate and collaborate securely" timeout: 10_000 diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 5447327152..78c39f93e6 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -93,10 +93,10 @@ class RootFlowNode @AssistedInject constructor( if (isLoggedIn) { tryToRestoreLatestSession( onSuccess = { switchToLoggedInFlow(it) }, - onFailure = { switchToLogoutFlow() } + onFailure = { switchToNotLoggedInFlow() } ) } else { - switchToLogoutFlow() + switchToNotLoggedInFlow() } } .launchIn(lifecycleScope) @@ -106,7 +106,7 @@ class RootFlowNode @AssistedInject constructor( backstack.safeRoot(NavTarget.LoggedInFlow(sessionId)) } - private fun switchToLogoutFlow() { + private fun switchToNotLoggedInFlow() { matrixClientsHolder.removeAll() backstack.safeRoot(NavTarget.NotLoggedInFlow) } diff --git a/build.gradle.kts b/build.gradle.kts index 8657aa7b4c..3fe16b498d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -203,6 +203,8 @@ koverMerged { includes += "*Presenter" excludes += "*Fake*Presenter" excludes += "io.element.android.appnav.loggedin.LoggedInPresenter$*" + // Too small presenter, cannot reach the threshold. + excludes += "io.element.android.features.onboarding.impl.OnBoardingPresenter" } bound { minValue = 90 diff --git a/features/onboarding/impl/build.gradle.kts b/features/onboarding/impl/build.gradle.kts index 22480bfd1b..86b4d1ede9 100644 --- a/features/onboarding/impl/build.gradle.kts +++ b/features/onboarding/impl/build.gradle.kts @@ -40,8 +40,6 @@ dependencies { implementation(projects.libraries.testtags) implementation(projects.libraries.uiStrings) implementation(projects.libraries.androidutils) - implementation(libs.accompanist.pager) - implementation(libs.accompanist.pagerindicator) api(projects.features.onboarding.api) ksp(libs.showkase.processor) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselData.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingConfig.kt similarity index 67% rename from features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselData.kt rename to features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingConfig.kt index c4674b3ead..de164386b3 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselData.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingConfig.kt @@ -16,16 +16,7 @@ package io.element.android.features.onboarding.impl -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes - -data class SplashCarouselData( - val items: List -) { - data class Item( - @StringRes val title: Int, - @StringRes val body: Int, - @DrawableRes val image: Int, - @DrawableRes val pageBackground: Int - ) +object OnBoardingConfig { + const val canLoginWithQrCode = false + const val canCreateAccount = false } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt index a6cb0a3b49..a081c0b7ab 100644 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingNode.kt @@ -32,6 +32,7 @@ import io.element.android.libraries.di.AppScope class OnBoardingNode @AssistedInject constructor( @Assisted buildContext: BuildContext, @Assisted plugins: List, + private val presenter: OnBoardingPresenter, ) : Node( buildContext = buildContext, plugins = plugins @@ -47,10 +48,11 @@ class OnBoardingNode @AssistedInject constructor( @Composable override fun View(modifier: Modifier) { - OnBoardingScreen( + val state = presenter.present() + OnBoardingView( + state = state, modifier = modifier, - onSignIn = this::onSignIn, - onSignUp = this::onSignUp + onSignIn = ::onSignIn, ) } } diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt new file mode 100644 index 0000000000..48a360e6c9 --- /dev/null +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenter.kt @@ -0,0 +1,36 @@ +/* + * 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.features.onboarding.impl + +import androidx.compose.runtime.Composable +import io.element.android.libraries.architecture.Presenter +import javax.inject.Inject + +/** + * Note: this Presenter is ignored regarding code coverage because it cannot reach the coverage threshold. + * When this presenter get more code in it, please remove the ignore rule in the kover configuration. + */ +class OnBoardingPresenter @Inject constructor( +) : Presenter { + @Composable + override fun present(): OnBoardingState { + return OnBoardingState( + canLoginWithQrCode = OnBoardingConfig.canLoginWithQrCode, + canCreateAccount = OnBoardingConfig.canCreateAccount, + ) + } +} diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt deleted file mode 100644 index 8694865938..0000000000 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingScreen.kt +++ /dev/null @@ -1,182 +0,0 @@ -/* - * 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.features.onboarding.impl - -import androidx.compose.foundation.Image -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.systemBarsPadding -import androidx.compose.material3.MaterialTheme -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshotFlow -import androidx.compose.ui.Alignment.Companion.CenterHorizontally -import androidx.compose.ui.Modifier -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import com.google.accompanist.pager.HorizontalPager -import com.google.accompanist.pager.HorizontalPagerIndicator -import com.google.accompanist.pager.rememberPagerState -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.testtags.TestTags -import io.element.android.libraries.testtags.testTag -import kotlinx.coroutines.delay -import kotlinx.coroutines.launch - -@Composable -fun OnBoardingScreen( - modifier: Modifier = Modifier, - onPageChanged: (Int) -> Unit = {}, - onSignUp: () -> Unit = {}, - onSignIn: () -> Unit = {}, -) { - val carrouselData = remember { SplashCarouselDataFactory().create() } - val nbOfPages = carrouselData.items.size - var key by remember { mutableStateOf(false) } - Box( - modifier = modifier - .fillMaxSize() - .systemBarsPadding() - .padding(vertical = 16.dp) - ) { - Column( - modifier = Modifier.fillMaxSize(), - ) { - val pagerState = rememberPagerState() - LaunchedEffect(key) { - launch { - delay(3_000) - pagerState.animateScrollToPage((pagerState.currentPage + 1) % nbOfPages) - // https://stackoverflow.com/questions/73714228/accompanist-pager-animatescrolltopage-doesnt-scroll-to-next-page-correctly - key = !key - } - } - LaunchedEffect(pagerState) { - // Collect from the pager state a snapshotFlow reading the currentPage - snapshotFlow { pagerState.currentPage }.collect { page -> - onPageChanged(page) - } - } - HorizontalPager( - modifier = Modifier.weight(1f), - count = nbOfPages, - state = pagerState, - ) { page -> - // Our page content - OnBoardingPage(carrouselData.items[page]) - } - HorizontalPagerIndicator( - pagerState = pagerState, - modifier = Modifier - .align(CenterHorizontally) - .padding(16.dp), - ) - Button( - onClick = { - onSignIn() - }, - enabled = true, - modifier = Modifier - .align(CenterHorizontally) - .testTag(TestTags.onBoardingSignIn) - .padding(top = 16.dp) - ) { - Text(text = stringResource(id = R.string.login_splash_submit)) - } - } - } -} - -@Composable -fun OnBoardingPage( - item: SplashCarouselData.Item, - modifier: Modifier = Modifier, -) { - Box( - modifier = modifier, - ) { - /* - Image( - painterResource(id = item.pageBackground), - contentDescription = null, - modifier = Modifier.fillMaxSize() - ) - */ - Column( - modifier = Modifier.padding(vertical = 16.dp, horizontal = 32.dp) - ) { - Image( - painterResource(id = item.image), - contentDescription = null, - modifier = Modifier - .align(CenterHorizontally) - .size(192.dp) - .padding(16.dp) - ) - Text( - text = stringResource(id = item.title), - modifier = Modifier - .fillMaxWidth() - .align(CenterHorizontally) - .padding(8.dp), - textAlign = TextAlign.Center, - fontWeight = FontWeight.Bold, - color = MaterialTheme.colorScheme.primary, - fontSize = 24.sp, - ) - Text( - text = stringResource(id = item.body), - modifier = Modifier - .fillMaxWidth() - .align(CenterHorizontally), - textAlign = TextAlign.Center, - color = MaterialTheme.colorScheme.primary, - ) - } - } -} - -@Preview -@Composable -internal fun OnBoardingScreenLightPreview() = - ElementPreviewLight { ContentToPreview() } - -@Preview -@Composable -internal fun OnBoardingScreenDarkPreview() = - ElementPreviewDark { ContentToPreview() } - -@Composable -private fun ContentToPreview() { - OnBoardingScreen() -} diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt new file mode 100644 index 0000000000..88215c0c1e --- /dev/null +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingState.kt @@ -0,0 +1,22 @@ +/* + * 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.features.onboarding.impl + +data class OnBoardingState( + val canLoginWithQrCode: Boolean, + val canCreateAccount: Boolean, +) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt new file mode 100644 index 0000000000..1c60a56018 --- /dev/null +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingStateProvider.kt @@ -0,0 +1,37 @@ +/* + * 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.features.onboarding.impl + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider + +open class OnBoardingStateProvider : PreviewParameterProvider { + override val values: Sequence + get() = sequenceOf( + anOnBoardingState(), + anOnBoardingState(canLoginWithQrCode = true), + anOnBoardingState(canCreateAccount = true), + anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true), + ) +} + +fun anOnBoardingState( + canLoginWithQrCode: Boolean = false, + canCreateAccount: Boolean = false +) = OnBoardingState( + canLoginWithQrCode = canLoginWithQrCode, + canCreateAccount = canCreateAccount +) diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt new file mode 100644 index 0000000000..fd736dc0e5 --- /dev/null +++ b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/OnBoardingView.kt @@ -0,0 +1,182 @@ +/* + * 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.features.onboarding.impl + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.QrCode +import androidx.compose.material3.MaterialTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment.Companion.CenterHorizontally +import androidx.compose.ui.BiasAlignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.ColorFilter +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.tooling.preview.PreviewParameter +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.atomic.pages.OnBoardingPage +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.Icon +import io.element.android.libraries.designsystem.theme.components.OutlinedButton +import io.element.android.libraries.designsystem.theme.components.Text +import io.element.android.libraries.testtags.TestTags +import io.element.android.libraries.testtags.testTag + +// Ref: https://www.figma.com/file/o9p34zmiuEpZRyvZXJZAYL/FTUE?type=design&node-id=133-5427&t=5SHVppfYzjvkEywR-0 +@Composable +fun OnBoardingView( + state: OnBoardingState, + modifier: Modifier = Modifier, + onSignInWithQrCode: () -> Unit = {}, + onSignIn: () -> Unit = {}, + onCreateAccount: () -> Unit = {}, +) { + OnBoardingPage( + modifier = modifier, + footer = { + OnBoardingButtons( + state = state, + onSignInWithQrCode = onSignInWithQrCode, + onSignIn = onSignIn, + onCreateAccount = onCreateAccount, + ) + } + ) { + OnBoardingContent() + } +} + +@Composable +private fun OnBoardingContent(modifier: Modifier = Modifier) { + Box( + modifier = modifier.fillMaxSize(), + contentAlignment = BiasAlignment( + horizontalBias = 0f, + verticalBias = -0.2f + ) + ) { + Column( + modifier = Modifier + .fillMaxWidth(), + horizontalAlignment = CenterHorizontally, + ) { + Image( + painter = painterResource(id = R.drawable.element_logo), + contentDescription = null, + ) + Image( + modifier = Modifier.padding(top = 14.dp), + painter = painterResource(id = R.drawable.element), + colorFilter = ColorFilter.tint(MaterialTheme.colorScheme.primary), + contentDescription = null, + ) + Text( + modifier = Modifier.padding(top = 24.dp), + text = stringResource(id = R.string.screen_onboarding_subtitle), + color = MaterialTheme.colorScheme.secondary, + fontSize = 20.sp, + textAlign = TextAlign.Center + ) + } + } +} + +@Composable +private fun OnBoardingButtons( + state: OnBoardingState, + onSignInWithQrCode: () -> Unit, + onSignIn: () -> Unit, + onCreateAccount: () -> Unit, + modifier: Modifier = Modifier, +) { + Column( + modifier = modifier + .fillMaxWidth(), + horizontalAlignment = CenterHorizontally, + verticalArrangement = Arrangement.spacedBy(16.dp) + ) { + if (state.canLoginWithQrCode) { + Button( + onClick = { + onSignInWithQrCode() + }, + enabled = true, + modifier = Modifier + .fillMaxWidth() + ) { + Icon( + imageVector = Icons.Default.QrCode, contentDescription = null, + tint = MaterialTheme.colorScheme.onPrimary + ) + Spacer(Modifier.width(14.dp)) + Text(text = stringResource(id = R.string.screen_onboarding_sign_in_with_qr_code)) + } + } + Button( + onClick = { + onSignIn() + }, + enabled = true, + modifier = Modifier + .fillMaxWidth() + .testTag(TestTags.onBoardingSignIn) + ) { + Text(text = stringResource(id = R.string.screen_onboarding_sign_in_manually)) + } + if (state.canCreateAccount) { + OutlinedButton( + onClick = { + onCreateAccount() + }, + enabled = true, + modifier = Modifier + .fillMaxWidth() + ) { + Text(text = stringResource(id = R.string.screen_onboarding_sign_up)) + } + } + } +} + +@Preview +@Composable +internal fun OnBoardingScreenLightPreview(@PreviewParameter(OnBoardingStateProvider::class) state: OnBoardingState) = + ElementPreviewLight { ContentToPreview(state) } + +@Preview +@Composable +internal fun OnBoardingScreenDarkPreview(@PreviewParameter(OnBoardingStateProvider::class) state: OnBoardingState) = + ElementPreviewDark { ContentToPreview(state) } + +@Composable +private fun ContentToPreview(state: OnBoardingState) { + OnBoardingView(state) +} diff --git a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselDataFactory.kt b/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselDataFactory.kt deleted file mode 100644 index 5068bda82b..0000000000 --- a/features/onboarding/impl/src/main/kotlin/io/element/android/features/onboarding/impl/SplashCarouselDataFactory.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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.features.onboarding.impl - -import androidx.annotation.DrawableRes - -class SplashCarouselDataFactory { - fun create(): SplashCarouselData { - val lightTheme = true - - fun background(@DrawableRes lightDrawable: Int) = - if (lightTheme) lightDrawable else R.drawable.bg_color_background - - fun hero(@DrawableRes lightDrawable: Int, @DrawableRes darkDrawable: Int) = - if (lightTheme) lightDrawable else darkDrawable - - return SplashCarouselData( - listOf( - SplashCarouselData.Item( - R.string.ftue_auth_carousel_secure_title, - R.string.ftue_auth_carousel_secure_body, - hero( - R.drawable.ic_splash_conversations, - R.drawable.ic_splash_conversations_dark - ), - background(R.drawable.bg_carousel_page_1) - ), - SplashCarouselData.Item( - R.string.ftue_auth_carousel_control_title, - R.string.ftue_auth_carousel_control_body, - hero(R.drawable.ic_splash_control, R.drawable.ic_splash_control_dark), - background(R.drawable.bg_carousel_page_2) - ), - SplashCarouselData.Item( - R.string.ftue_auth_carousel_encrypted_title, - R.string.ftue_auth_carousel_encrypted_body, - hero(R.drawable.ic_splash_secure, R.drawable.ic_splash_secure_dark), - background(R.drawable.bg_carousel_page_3) - ), - SplashCarouselData.Item( - collaborationTitle(), - R.string.ftue_auth_carousel_workplace_body, - hero( - R.drawable.ic_splash_collaboration, - R.drawable.ic_splash_collaboration_dark - ), - background(R.drawable.bg_carousel_page_4) - ) - ) - ) - } - - private fun collaborationTitle(): Int { - return when { - true -> R.string.cut_the_slack_from_teams - else -> R.string.ftue_auth_carousel_workplace_title - } - } -} diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration.webp deleted file mode 100644 index 7042e030d0..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration_dark.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration_dark.webp deleted file mode 100644 index 6e4297183a..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_collaboration_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control.webp deleted file mode 100644 index 82c04e402b..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control_dark.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control_dark.webp deleted file mode 100644 index 0d0c6ad78b..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_control_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations.webp deleted file mode 100644 index ee9604c1f1..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations_dark.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations_dark.webp deleted file mode 100644 index c5cdf4e6fe..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_conversations_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure.webp deleted file mode 100644 index a880031ada..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure_dark.webp b/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure_dark.webp deleted file mode 100644 index 65ef9f35ff..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-hdpi/ic_splash_secure_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration.webp deleted file mode 100644 index d32d9f6026..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration_dark.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration_dark.webp deleted file mode 100644 index 04af9e2db4..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_collaboration_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control.webp deleted file mode 100644 index 972d91d5d0..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control_dark.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control_dark.webp deleted file mode 100644 index cbbea1ae87..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_control_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations.webp deleted file mode 100644 index 4057edfc66..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations_dark.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations_dark.webp deleted file mode 100644 index e3b7f22c1a..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_conversations_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure.webp deleted file mode 100644 index b8c772bde2..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure_dark.webp b/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure_dark.webp deleted file mode 100644 index d4c1f97652..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xhdpi/ic_splash_secure_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration.webp deleted file mode 100644 index 8feed1f9f9..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration_dark.webp deleted file mode 100644 index 02e44fbf44..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_collaboration_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control.webp deleted file mode 100644 index 99d4c4049d..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control_dark.webp deleted file mode 100644 index 9afa384f27..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_control_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations.webp deleted file mode 100644 index 99a4c0c6f5..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations_dark.webp deleted file mode 100644 index 361981eec7..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_conversations_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure.webp deleted file mode 100644 index 114421453e..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure_dark.webp deleted file mode 100644 index 737bcbdf17..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxhdpi/ic_splash_secure_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration.webp deleted file mode 100644 index 1dc31f6447..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration_dark.webp deleted file mode 100644 index 943f2b9ba8..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_collaboration_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control.webp deleted file mode 100644 index 9375475513..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control_dark.webp deleted file mode 100644 index 905851dc26..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_control_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations.webp deleted file mode 100644 index 0d669312f5..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations_dark.webp deleted file mode 100644 index c5c4b2ccdd..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_conversations_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure.webp deleted file mode 100644 index 6a2a3fda56..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure_dark.webp b/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure_dark.webp deleted file mode 100644 index b792cb16ea..0000000000 Binary files a/features/onboarding/impl/src/main/res/drawable-xxxhdpi/ic_splash_secure_dark.webp and /dev/null differ diff --git a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_1.xml b/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_1.xml deleted file mode 100644 index 03414760f5..0000000000 --- a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_1.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_2.xml b/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_2.xml deleted file mode 100644 index 216f37c056..0000000000 --- a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_2.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_3.xml b/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_3.xml deleted file mode 100644 index b206670820..0000000000 --- a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_3.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_4.xml b/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_4.xml deleted file mode 100644 index 8eca5f922f..0000000000 --- a/features/onboarding/impl/src/main/res/drawable/bg_carousel_page_4.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/features/onboarding/impl/src/main/res/drawable/bg_color_background.xml b/features/onboarding/impl/src/main/res/drawable/bg_color_background.xml deleted file mode 100644 index df950fd479..0000000000 --- a/features/onboarding/impl/src/main/res/drawable/bg_color_background.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/features/onboarding/impl/src/main/res/drawable/element.xml b/features/onboarding/impl/src/main/res/drawable/element.xml new file mode 100644 index 0000000000..96a86d0db5 --- /dev/null +++ b/features/onboarding/impl/src/main/res/drawable/element.xml @@ -0,0 +1,27 @@ + + + + + + + + + diff --git a/features/onboarding/impl/src/main/res/drawable/element_logo.xml b/features/onboarding/impl/src/main/res/drawable/element_logo.xml new file mode 100644 index 0000000000..9601fe3d06 --- /dev/null +++ b/features/onboarding/impl/src/main/res/drawable/element_logo.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/features/onboarding/impl/src/main/res/values/strings.xml b/features/onboarding/impl/src/main/res/values/strings.xml deleted file mode 100644 index d325d6ad1c..0000000000 --- a/features/onboarding/impl/src/main/res/values/strings.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - - - - - Cut the slack from teams. - - Get started - - Own your conversations. - You\'re in control. - Secure messaging. - Messaging for your team. - - Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home. - Choose where your conversations are kept, giving you control and independence. Connected via Matrix. - End-to-end encrypted and no phone number required. No ads or datamining. - - Element is also great for the workplace. It’s trusted by the world’s most secure organisations. - - - diff --git a/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt new file mode 100644 index 0000000000..f415cd795f --- /dev/null +++ b/features/onboarding/impl/src/test/kotlin/io/element/android/features/onboarding/impl/OnBoardingPresenterTest.kt @@ -0,0 +1,38 @@ +/* + * 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.features.onboarding.impl + +import app.cash.molecule.RecompositionClock +import app.cash.molecule.moleculeFlow +import app.cash.turbine.test +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.runTest +import org.junit.Test + +class OnBoardingPresenterTest { + @Test + fun `present - initial state`() = runTest { + val presenter = OnBoardingPresenter() + moleculeFlow(RecompositionClock.Immediate) { + presenter.present() + }.test { + val initialState = awaitItem() + assertThat(initialState.canLoginWithQrCode).isFalse() + assertThat(initialState.canCreateAccount).isFalse() + } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2f84422fce..cce55faaca 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -96,8 +96,6 @@ accompanist_permission = { module = "com.google.accompanist:accompanist-permissi accompanist_material = { module = "com.google.accompanist:accompanist-navigation-material", version.ref = "accompanist" } accompanist_systemui = { module = "com.google.accompanist:accompanist-systemuicontroller", version.ref = "accompanist" } accompanist_placeholder = { module = "com.google.accompanist:accompanist-placeholder-material", version.ref = "accompanist" } -accompanist_pager = { module = "com.google.accompanist:accompanist-pager", version.ref = "accompanist" } -accompanist_pagerindicator = { module = "com.google.accompanist:accompanist-pager-indicators", version.ref = "accompanist" } accompanist_flowlayout = { module = "com.google.accompanist:accompanist-flowlayout", version.ref = "accompanist" } # Libraries diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeFactories.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeFactories.kt index 82ec21667b..6073b45351 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeFactories.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/NodeFactories.kt @@ -34,6 +34,8 @@ inline fun Context.createNode(context: BuildContext, plugi inline fun NodeFactoriesBindings.createNode(context: BuildContext, plugins: List = emptyList()): NODE { val nodeClass = NODE::class.java val nodeFactoryMap = nodeFactories() + // Note to developers: If you got the error below, make sure to build again after + // clearing the cache (sometimes several times) to let Dagger generate the NodeFactory. val nodeFactory = nodeFactoryMap[nodeClass] ?: error("Cannot find NodeFactory for ${nodeClass.name}.") @Suppress("UNCHECKED_CAST") diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/OnBoardingPage.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/OnBoardingPage.kt new file mode 100644 index 0000000000..0e0292957b --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/OnBoardingPage.kt @@ -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.pages + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.systemBarsPadding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.ContentScale +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import io.element.android.libraries.designsystem.R +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.theme.components.Text + +/** + * Page for onboarding screens, with content and optional footer. + * + * Ref: https://www.figma.com/file/o9p34zmiuEpZRyvZXJZAYL/FTUE?type=design&node-id=133-5427&t=5SHVppfYzjvkEywR-0 + * @param modifier Classical modifier. + * @param footer optional footer. + * @param content main content. + */ +@Composable +fun OnBoardingPage( + modifier: Modifier = Modifier, + footer: @Composable () -> Unit = {}, + content: @Composable () -> Unit = {}, +) { + Box( + modifier = modifier + .fillMaxSize() + ) { + // BG + Image( + modifier = Modifier + .fillMaxSize(), + painter = painterResource(id = R.drawable.onboarding_bg), + contentScale = ContentScale.Crop, + contentDescription = null, + ) + Column( + modifier = Modifier + .fillMaxSize() + .systemBarsPadding() + .padding(vertical = 16.dp), + ) { + // Content + Column( + modifier = Modifier + .weight(1f) + .padding(horizontal = 24.dp) + .fillMaxWidth(), + ) { + content() + } + // Footer + Box(modifier = Modifier.padding(horizontal = 16.dp)) { + footer() + } + } + } +} + +@Preview +@Composable +internal fun OnBoardingPageLightPreview() = + ElementPreviewLight { ContentToPreview() } + +@Preview +@Composable +internal fun OnBoardingPageDarkPreview() = + ElementPreviewDark { ContentToPreview() } + +@Composable +private fun ContentToPreview() { + OnBoardingPage( + content = { + Box( + Modifier + .fillMaxSize(), + contentAlignment = Alignment.Center + ) { + Text( + text = "Content", + fontSize = 40.sp + ) + } + }, + footer = { + Box( + Modifier + .fillMaxWidth(), + contentAlignment = Alignment.Center + ) { + Text( + text = "Footer", + fontSize = 40.sp + ) + } + } + ) +} diff --git a/libraries/designsystem/src/main/res/drawable/onboarding_bg.png b/libraries/designsystem/src/main/res/drawable/onboarding_bg.png new file mode 100644 index 0000000000..61e2264ced Binary files /dev/null and b/libraries/designsystem/src/main/res/drawable/onboarding_bg.png differ diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index 94817469d3..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49e2768b2a111af737a30038913481113f759a20d3cf5df0166964c75926ec1f -size 6545 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index 40f9c06277..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewDarkPreview_0_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:eac9030993d92ef7f57ae5e622d566cd88555a60c462c0299f2a16a0c3e5daa8 -size 6853 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_0,NEXUS_5,1.0,en].png deleted file mode 100644 index 94817469d3..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_0,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:49e2768b2a111af737a30038913481113f759a20d3cf5df0166964c75926ec1f -size 6545 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_1,NEXUS_5,1.0,en].png deleted file mode 100644 index 7ae58a8744..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.login.impl.oidc_null_DefaultGroup_OidcViewLightPreview_0_null_1,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:74a1a3ac6ae62c3573ce5834f5ae17952049ee77a8be76bfcb99e78b8fc6cb97 -size 6675 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index b1f708d57c..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b53d55b5085673ac3a0a7663f7ff68e7d510fe352f3931b49c7e75e4c3767b93 -size 60007 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..d8bebb7201 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0e7ee7df10cd863d2ec989fa4dc6621d38464de9ce640947a392c2397f53eb8c +size 254906 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..d930025396 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5e22509b6b519792ec8927c543373abe3976335aab96c72d99d40c8f924b410d +size 244289 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..4a4853308a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3661424e8a5268b0606e5d70ea4cf6e42133c03d8ad88190669b887e9a3197d4 +size 254282 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..12155debdf --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenDarkPreview_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9efc0ec64518c059d10edbfa4b1136237330a5bd9a1000a444a18df9044e788 +size 241109 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png deleted file mode 100644 index d020b1e521..0000000000 --- a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null,NEXUS_5,1.0,en].png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a761318f3dfbc2ce6e777cfabc19eeb2f89100ae7631660f4b4d7550cd947c84 -size 57580 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..16881ad056 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_0,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:75045402335b2f02962c64cb0884b7e6132b8314bcfc225b6c71ebf303e13675 +size 241702 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..62c0cafdec --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_1,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f9fb6b0905faf223fd0505197060ff2838329435a2588a44c200277a5ed34083 +size 231701 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..1fcf7d32aa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_2,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:96d3d1147d02b49eb206cd0f051882cdb7ce7f66088e1d01b62f30cf9469d5a1 +size 241589 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..29d66a93e6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.features.onboarding.impl_null_DefaultGroup_OnBoardingScreenLightPreview_0_null_3,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ec6523d971baf66b6946334927069491c7203345aeda820cac35e168d95779bf +size 227789 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageDarkPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageDarkPreview_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..8ac535e6c0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageDarkPreview_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:237bf6506435a954985cccc4f40333a02f8d74a11b57671414442f09706aa6c1 +size 253095 diff --git a/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageLightPreview_0_null,NEXUS_5,1.0,en].png b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageLightPreview_0_null,NEXUS_5,1.0,en].png new file mode 100644 index 0000000000..269a829676 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/io.element.android.tests.uitests_ScreenshotTest_preview_tests[io.element.android.libraries.designsystem.atomic.pages_null_DefaultGroup_OnBoardingPageLightPreview_0_null,NEXUS_5,1.0,en].png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7b9e801ae788e63a0737d4ae043cfdbeebbda9de07f925d15ceebb0ba1467795 +size 241513