Skip to content

Commit 4c45346

Browse files
committed
Add a way to customize the on boarding logo.
1 parent 8245ad8 commit 4c45346

File tree

8 files changed

+111
-8
lines changed

8 files changed

+111
-8
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.features.login.impl.screens.onboarding
9+
10+
import android.annotation.SuppressLint
11+
import android.content.Context
12+
import com.squareup.anvil.annotations.ContributesBinding
13+
import io.element.android.libraries.di.AppScope
14+
import io.element.android.libraries.di.ApplicationContext
15+
import javax.inject.Inject
16+
17+
fun interface CustomLogoResIdProvider {
18+
fun get(): Int?
19+
}
20+
21+
@ContributesBinding(AppScope::class)
22+
class DefaultCustomLogoResIdProvider @Inject constructor(
23+
@ApplicationContext private val context: Context,
24+
) : CustomLogoResIdProvider {
25+
@SuppressLint("DiscouragedApi")
26+
override fun get(): Int? {
27+
val resId = context.resources
28+
.getIdentifier("custom_logo", "drawable", context.packageName)
29+
.takeIf { it != 0 }
30+
return resId
31+
}
32+
}

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenter.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ class OnBoardingPresenter @AssistedInject constructor(
3636
private val defaultAccountProviderAccessControl: DefaultAccountProviderAccessControl,
3737
private val rageshakeFeatureAvailability: RageshakeFeatureAvailability,
3838
private val loginHelper: LoginHelper,
39+
private val customLogoResIdProvider: CustomLogoResIdProvider,
3940
) : Presenter<OnBoardingState> {
4041
@AssistedFactory
4142
interface Factory {
@@ -81,6 +82,9 @@ class OnBoardingPresenter @AssistedInject constructor(
8182
}
8283
val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false)
8384
var showReportBug by rememberSaveable { mutableStateOf(false) }
85+
val customLogoResId = remember {
86+
customLogoResIdProvider.get()
87+
}
8488

8589
val loginMode by loginHelper.collectLoginMode()
8690

@@ -112,6 +116,7 @@ class OnBoardingPresenter @AssistedInject constructor(
112116
canReportBug = canReportBug && showReportBug,
113117
loginMode = loginMode,
114118
version = buildMeta.versionName,
119+
customLogoResId = customLogoResId,
115120
eventSink = ::handleEvent,
116121
)
117122
}

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingState.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package io.element.android.features.login.impl.screens.onboarding
99

10+
import androidx.annotation.DrawableRes
1011
import io.element.android.features.login.impl.login.LoginMode
1112
import io.element.android.libraries.architecture.AsyncData
1213

@@ -18,6 +19,8 @@ data class OnBoardingState(
1819
val canCreateAccount: Boolean,
1920
val canReportBug: Boolean,
2021
val version: String,
22+
@DrawableRes
23+
val customLogoResId: Int?,
2124
val loginMode: AsyncData<LoginMode>,
2225
val eventSink: (OnBoardingEvents) -> Unit,
2326
) {

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingStateProvider.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
package io.element.android.features.login.impl.screens.onboarding
99

10+
import androidx.annotation.DrawableRes
1011
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
1112
import io.element.android.features.login.impl.login.LoginMode
1213
import io.element.android.libraries.architecture.AsyncData
14+
import io.element.android.libraries.designsystem.R
1315

1416
open class OnBoardingStateProvider : PreviewParameterProvider<OnBoardingState> {
1517
override val values: Sequence<OnBoardingState>
@@ -20,6 +22,7 @@ open class OnBoardingStateProvider : PreviewParameterProvider<OnBoardingState> {
2022
anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true),
2123
anOnBoardingState(canLoginWithQrCode = true, canCreateAccount = true, canReportBug = true),
2224
anOnBoardingState(defaultAccountProvider = "element.io", canCreateAccount = false, canReportBug = true),
25+
anOnBoardingState(customLogoResId = R.drawable.sample_background),
2326
)
2427
}
2528

@@ -31,6 +34,8 @@ fun anOnBoardingState(
3134
canCreateAccount: Boolean = false,
3235
canReportBug: Boolean = false,
3336
version: String = "1.0.0",
37+
@DrawableRes
38+
customLogoResId: Int? = null,
3439
loginMode: AsyncData<LoginMode> = AsyncData.Uninitialized,
3540
eventSink: (OnBoardingEvents) -> Unit = {},
3641
) = OnBoardingState(
@@ -42,5 +47,6 @@ fun anOnBoardingState(
4247
canReportBug = canReportBug,
4348
version = version,
4449
loginMode = loginMode,
50+
customLogoResId = customLogoResId,
4551
eventSink = eventSink,
4652
)

features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingView.kt

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
package io.element.android.features.login.impl.screens.onboarding
99

10+
import androidx.compose.foundation.Image
1011
import androidx.compose.foundation.clickable
1112
import androidx.compose.foundation.layout.Box
1213
import androidx.compose.foundation.layout.Column
@@ -19,9 +20,11 @@ import androidx.compose.runtime.Composable
1920
import androidx.compose.runtime.derivedStateOf
2021
import androidx.compose.runtime.getValue
2122
import androidx.compose.runtime.remember
23+
import androidx.compose.ui.Alignment
2224
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
2325
import androidx.compose.ui.BiasAlignment
2426
import androidx.compose.ui.Modifier
27+
import androidx.compose.ui.res.painterResource
2528
import androidx.compose.ui.res.stringResource
2629
import androidx.compose.ui.text.style.TextAlign
2730
import androidx.compose.ui.tooling.preview.PreviewParameter
@@ -67,8 +70,15 @@ fun OnBoardingView(
6770
) {
6871
OnBoardingPage(
6972
modifier = modifier,
73+
renderBackground = state.customLogoResId == null,
7074
content = {
71-
OnBoardingContent(state = state)
75+
if (state.customLogoResId != null) {
76+
OnBoardingSimpleLogo(
77+
customLogoResId = state.customLogoResId,
78+
)
79+
} else {
80+
OnBoardingContent(state = state)
81+
}
7282
LoginModeView(
7383
loginMode = state.loginMode,
7484
onClearError = {
@@ -139,6 +149,24 @@ private fun OnBoardingContent(state: OnBoardingState) {
139149
}
140150
}
141151

152+
@Composable
153+
private fun OnBoardingSimpleLogo(
154+
customLogoResId: Int,
155+
modifier: Modifier = Modifier,
156+
) {
157+
Box(
158+
modifier = modifier
159+
.fillMaxSize()
160+
.padding(16.dp),
161+
contentAlignment = Alignment.Center,
162+
) {
163+
Image(
164+
painter = painterResource(id = customLogoResId),
165+
contentDescription = null
166+
)
167+
}
168+
}
169+
142170
@Composable
143171
private fun OnBoardingButtons(
144172
state: OnBoardingState,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="utf-8"?><!--
2+
~ Copyright 2025 New Vector Ltd.
3+
~
4+
~ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
~ Please see LICENSE files in the repository root for full details.
6+
-->
7+
<!--
8+
Note: one or several custom_logo drawable can be added at build time. Ensure that these
9+
resource are not stripped out by the resource shrinker.
10+
-->
11+
<resources xmlns:tools="http://schemas.android.com/tools"
12+
tools:keep="@drawable/custom_logo" />

features/login/impl/src/test/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingPresenterTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,18 @@ class OnBoardingPresenterTest {
8484
}
8585
}
8686

87+
@Test
88+
fun `present - custom logo`() = runTest {
89+
val presenter = createPresenter(
90+
customLogoResIdProvider = CustomLogoResIdProvider { 42 },
91+
)
92+
presenter.test {
93+
skipItems(1)
94+
val initialState = awaitItem()
95+
assertThat(initialState.customLogoResId).isEqualTo(42)
96+
}
97+
}
98+
8799
@Test
88100
fun `present - clicking on version 7 times has no effect if rageshake not available`() = runTest {
89101
val presenter = createPresenter(
@@ -224,6 +236,7 @@ private fun createPresenter(
224236
wellknownRetriever: WellknownRetriever = FakeWellknownRetriever(),
225237
rageshakeFeatureAvailability: () -> Flow<Boolean> = { flowOf(true) },
226238
loginHelper: LoginHelper = createLoginHelper(),
239+
customLogoResIdProvider: CustomLogoResIdProvider = CustomLogoResIdProvider { null },
227240
) = OnBoardingPresenter(
228241
params = params,
229242
buildMeta = buildMeta,
@@ -234,6 +247,7 @@ private fun createPresenter(
234247
),
235248
rageshakeFeatureAvailability = rageshakeFeatureAvailability,
236249
loginHelper = loginHelper,
250+
customLogoResIdProvider = customLogoResIdProvider,
237251
)
238252

239253
fun createLoginHelper(

libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/atomic/pages/OnBoardingPage.kt

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
3838
@Composable
3939
fun OnBoardingPage(
4040
modifier: Modifier = Modifier,
41+
renderBackground: Boolean = true,
4142
contentAlignment: Alignment.Horizontal = Alignment.CenterHorizontally,
4243
footer: @Composable () -> Unit = {},
4344
content: @Composable () -> Unit = {},
@@ -47,13 +48,15 @@ fun OnBoardingPage(
4748
.fillMaxSize()
4849
) {
4950
// BG
50-
Image(
51-
modifier = Modifier
52-
.fillMaxSize(),
53-
painter = painterResource(id = R.drawable.onboarding_bg),
54-
contentScale = ContentScale.Crop,
55-
contentDescription = null,
56-
)
51+
if (renderBackground) {
52+
Image(
53+
modifier = Modifier
54+
.fillMaxSize(),
55+
painter = painterResource(id = R.drawable.onboarding_bg),
56+
contentScale = ContentScale.Crop,
57+
contentDescription = null,
58+
)
59+
}
5760
Column(
5861
modifier = Modifier
5962
.fillMaxSize()

0 commit comments

Comments
 (0)