Merge pull request #4880 from vector-im/feature/adm/carousel-images-update
Updated splash carousel images and copy
1
changelog.d/4880.wip
Normal file
@ -0,0 +1 @@
|
||||
Updates the onboarding carousel images, copy and improves the handling of different device sizes
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<gradient
|
||||
android:angle="270"
|
||||
android:endColor="?vctr_system"
|
||||
android:startColor="#000000" />
|
||||
</shape>
|
5
library/ui-styles/src/main/res/values-h720dp/dimens.xml
Normal file
@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<item name="ftue_auth_carousel_item_spacing" format="float" type="dimen">0.05</item>
|
||||
<item name="ftue_auth_carousel_item_image_height" format="float" type="dimen">0.40</item>
|
||||
</resources>
|
@ -51,4 +51,7 @@
|
||||
<!-- Onboarding -->
|
||||
<item name="ftue_auth_gutter_start_percent" format="float" type="dimen">0.05</item>
|
||||
<item name="ftue_auth_gutter_end_percent" format="float" type="dimen">0.95</item>
|
||||
|
||||
<item name="ftue_auth_carousel_item_spacing" format="float" type="dimen">0.01</item>
|
||||
<item name="ftue_auth_carousel_item_image_height" format="float" type="dimen">0.35</item>
|
||||
</resources>
|
@ -27,3 +27,5 @@ class LocaleProvider @Inject constructor(private val resources: Resources) {
|
||||
return ConfigurationCompat.getLocales(resources.configuration)[0]
|
||||
}
|
||||
}
|
||||
|
||||
fun LocaleProvider.isEnglishSpeaking() = current().language.startsWith("en")
|
||||
|
@ -49,7 +49,8 @@ private const val CAROUSEL_TRANSITION_TIME_MS = 500L
|
||||
class FtueAuthSplashCarouselFragment @Inject constructor(
|
||||
private val vectorPreferences: VectorPreferences,
|
||||
private val vectorFeatures: VectorFeatures,
|
||||
private val carouselController: SplashCarouselController
|
||||
private val carouselController: SplashCarouselController,
|
||||
private val carouselStateFactory: SplashCarouselStateFactory
|
||||
) : AbstractFtueAuthFragment<FragmentFtueSplashCarouselBinding>() {
|
||||
|
||||
override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSplashCarouselBinding {
|
||||
@ -65,7 +66,7 @@ class FtueAuthSplashCarouselFragment @Inject constructor(
|
||||
val carouselAdapter = carouselController.adapter
|
||||
views.splashCarousel.adapter = carouselAdapter
|
||||
TabLayoutMediator(views.carouselIndicator, views.splashCarousel) { _, _ -> }.attach()
|
||||
carouselController.setData(SplashCarouselState())
|
||||
carouselController.setData(carouselStateFactory.create())
|
||||
|
||||
views.loginSplashSubmit.debouncedClicks { getStarted() }
|
||||
views.loginSplashAlreadyHaveAccount.apply {
|
||||
|
@ -35,7 +35,7 @@ abstract class SplashCarouselItem : VectorEpoxyModel<SplashCarouselItem.Holder>(
|
||||
|
||||
holder.view.setBackgroundResource(item.pageBackground)
|
||||
holder.image.setImageResource(item.image)
|
||||
holder.title.setText(item.title)
|
||||
holder.title.text = item.title.charSequence
|
||||
holder.body.setText(item.body)
|
||||
}
|
||||
|
||||
|
@ -18,38 +18,13 @@ package im.vector.app.features.onboarding.ftueauth
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.annotation.StringRes
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
|
||||
data class SplashCarouselState(
|
||||
val items: List<Item> = listOf(
|
||||
Item(
|
||||
R.string.ftue_auth_carousel_1_title,
|
||||
R.string.ftue_auth_carousel_1_body,
|
||||
R.drawable.onboarding_carousel_conversations,
|
||||
R.drawable.bg_carousel_page_1
|
||||
),
|
||||
Item(
|
||||
R.string.ftue_auth_carousel_2_title,
|
||||
R.string.ftue_auth_carousel_2_body,
|
||||
R.drawable.onboarding_carousel_ems,
|
||||
R.drawable.bg_carousel_page_2
|
||||
),
|
||||
Item(
|
||||
R.string.ftue_auth_carousel_3_title,
|
||||
R.string.ftue_auth_carousel_3_body,
|
||||
R.drawable.onboarding_carousel_connect,
|
||||
R.drawable.bg_carousel_page_3
|
||||
),
|
||||
Item(
|
||||
R.string.ftue_auth_carousel_4_title,
|
||||
R.string.ftue_auth_carousel_4_body,
|
||||
R.drawable.onboarding_carousel_universal,
|
||||
R.drawable.bg_carousel_page_4
|
||||
)
|
||||
)
|
||||
val items: List<Item>
|
||||
) {
|
||||
data class Item(
|
||||
@StringRes val title: Int,
|
||||
val title: EpoxyCharSequence,
|
||||
@StringRes val body: Int,
|
||||
@DrawableRes val image: Int,
|
||||
@DrawableRes val pageBackground: Int
|
||||
|
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2022 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 im.vector.app.features.onboarding.ftueauth
|
||||
|
||||
import android.content.Context
|
||||
import androidx.annotation.AttrRes
|
||||
import androidx.annotation.DrawableRes
|
||||
import im.vector.app.R
|
||||
import im.vector.app.core.epoxy.charsequence.EpoxyCharSequence
|
||||
import im.vector.app.core.epoxy.charsequence.toEpoxyCharSequence
|
||||
import im.vector.app.core.resources.LocaleProvider
|
||||
import im.vector.app.core.resources.StringProvider
|
||||
import im.vector.app.core.resources.isEnglishSpeaking
|
||||
import im.vector.app.features.themes.ThemeProvider
|
||||
import im.vector.app.features.themes.ThemeUtils
|
||||
import me.gujun.android.span.span
|
||||
import javax.inject.Inject
|
||||
|
||||
class SplashCarouselStateFactory @Inject constructor(
|
||||
private val context: Context,
|
||||
private val stringProvider: StringProvider,
|
||||
private val localeProvider: LocaleProvider,
|
||||
private val themeProvider: ThemeProvider,
|
||||
) {
|
||||
|
||||
fun create(): SplashCarouselState {
|
||||
val lightTheme = themeProvider.isLightTheme()
|
||||
fun background(@DrawableRes lightDrawable: Int) = if (lightTheme) lightDrawable else R.drawable.bg_carousel_page_dark
|
||||
fun hero(@DrawableRes lightDrawable: Int, @DrawableRes darkDrawable: Int) = if (lightTheme) lightDrawable else darkDrawable
|
||||
return SplashCarouselState(listOf(
|
||||
SplashCarouselState.Item(
|
||||
R.string.ftue_auth_carousel_1_title.colorTerminatingFullStop(R.attr.colorAccent),
|
||||
R.string.ftue_auth_carousel_body_secure,
|
||||
hero(R.drawable.ic_splash_conversations, R.drawable.ic_splash_conversations_dark),
|
||||
background(R.drawable.bg_carousel_page_1)
|
||||
),
|
||||
SplashCarouselState.Item(
|
||||
R.string.ftue_auth_carousel_2_title.colorTerminatingFullStop(R.attr.colorAccent),
|
||||
R.string.ftue_auth_carousel_body_control,
|
||||
hero(R.drawable.ic_splash_control, R.drawable.ic_splash_control_dark),
|
||||
background(R.drawable.bg_carousel_page_2)
|
||||
),
|
||||
SplashCarouselState.Item(
|
||||
R.string.ftue_auth_carousel_3_title.colorTerminatingFullStop(R.attr.colorAccent),
|
||||
R.string.ftue_auth_carousel_body_encrypted,
|
||||
hero(R.drawable.ic_splash_secure, R.drawable.ic_splash_secure_dark),
|
||||
background(R.drawable.bg_carousel_page_3)
|
||||
),
|
||||
SplashCarouselState.Item(
|
||||
collaborationTitle().colorTerminatingFullStop(R.attr.colorAccent),
|
||||
R.string.ftue_auth_carousel_body_workplace,
|
||||
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 {
|
||||
localeProvider.isEnglishSpeaking() -> R.string.cut_the_slack_from_teams
|
||||
else -> R.string.ftue_auth_carousel_title_messaging
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.colorTerminatingFullStop(@AttrRes color: Int): EpoxyCharSequence {
|
||||
val string = stringProvider.getString(this)
|
||||
val fullStop = "."
|
||||
val charSequence = if (string.endsWith(fullStop)) {
|
||||
span {
|
||||
+string.removeSuffix(fullStop)
|
||||
span(fullStop) {
|
||||
textColor = ThemeUtils.getColor(context, color)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
string
|
||||
}
|
||||
return charSequence.toEpoxyCharSequence()
|
||||
}
|
||||
}
|
BIN
vector/src/main/res/drawable-hdpi/ic_splash_collaboration.webp
Normal file
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 28 KiB |
BIN
vector/src/main/res/drawable-hdpi/ic_splash_control.webp
Normal file
After Width: | Height: | Size: 25 KiB |
BIN
vector/src/main/res/drawable-hdpi/ic_splash_control_dark.webp
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
vector/src/main/res/drawable-hdpi/ic_splash_conversations.webp
Normal file
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 84 KiB |
BIN
vector/src/main/res/drawable-hdpi/ic_splash_secure.webp
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
vector/src/main/res/drawable-hdpi/ic_splash_secure_dark.webp
Normal file
After Width: | Height: | Size: 3.4 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_collaboration.webp
Normal file
After Width: | Height: | Size: 20 KiB |
After Width: | Height: | Size: 43 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_control.webp
Normal file
After Width: | Height: | Size: 34 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_control_dark.webp
Normal file
After Width: | Height: | Size: 33 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_conversations.webp
Normal file
After Width: | Height: | Size: 38 KiB |
After Width: | Height: | Size: 140 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_secure.webp
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
vector/src/main/res/drawable-xhdpi/ic_splash_secure_dark.webp
Normal file
After Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 184 KiB |
Before Width: | Height: | Size: 141 KiB |
Before Width: | Height: | Size: 27 KiB |
Before Width: | Height: | Size: 190 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_collaboration.webp
Normal file
After Width: | Height: | Size: 32 KiB |
After Width: | Height: | Size: 79 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_control.webp
Normal file
After Width: | Height: | Size: 58 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_control_dark.webp
Normal file
After Width: | Height: | Size: 55 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_conversations.webp
Normal file
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 277 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_secure.webp
Normal file
After Width: | Height: | Size: 7.5 KiB |
BIN
vector/src/main/res/drawable-xxhdpi/ic_splash_secure_dark.webp
Normal file
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 44 KiB |
After Width: | Height: | Size: 119 KiB |
BIN
vector/src/main/res/drawable-xxxhdpi/ic_splash_control.webp
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
vector/src/main/res/drawable-xxxhdpi/ic_splash_control_dark.webp
Normal file
After Width: | Height: | Size: 83 KiB |
After Width: | Height: | Size: 102 KiB |
After Width: | Height: | Size: 468 KiB |
BIN
vector/src/main/res/drawable-xxxhdpi/ic_splash_secure.webp
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
vector/src/main/res/drawable-xxxhdpi/ic_splash_secure_dark.webp
Normal file
After Width: | Height: | Size: 11 KiB |
@ -24,7 +24,9 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toTopOf="@id/carousel_item_image_container"
|
||||
app:layout_constraintHeight_percent="0.1"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:layout_constraintVertical_bias="0.0"
|
||||
app:layout_constraintHeight_percent="@dimen/ftue_auth_carousel_item_spacing"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
@ -32,6 +34,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="center"
|
||||
app:layout_constraintHeight_percent="@dimen/ftue_auth_carousel_item_image_height"
|
||||
app:layout_constraintBottom_toTopOf="@id/carousel_item_image_bottom_space"
|
||||
app:layout_constraintEnd_toEndOf="@id/splashCarouselGutterEnd"
|
||||
app:layout_constraintStart_toStartOf="@id/splashCarouselGutterStart"
|
||||
@ -39,10 +42,9 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/carousel_item_image"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null" />
|
||||
|
||||
</FrameLayout>
|
||||
@ -51,9 +53,8 @@
|
||||
android:id="@+id/carousel_item_image_bottom_space"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="0.05"
|
||||
app:layout_constraintBottom_toTopOf="@id/carousel_item_title"
|
||||
app:layout_constraintHeight_percent="0.05"
|
||||
app:layout_constraintHeight_percent="@dimen/ftue_auth_carousel_item_spacing"
|
||||
app:layout_constraintTop_toBottomOf="@id/carousel_item_image_container" />
|
||||
|
||||
<TextView
|
||||
|
@ -14,7 +14,17 @@
|
||||
<!-- Temporary string -->
|
||||
<string name="template_not_implemented" translatable="false">Not implemented yet in ${app_name}</string>
|
||||
|
||||
<!-- onboarding english only word play -->
|
||||
<string name="cut_the_slack_from_teams" translatable="false">Cut the slack from teams.</string>
|
||||
|
||||
<!-- WIP strings, will move to strings.xml when signed off -->
|
||||
<string name="ftue_auth_carousel_body_secure" translatable="false">Secure and independent communication that gives you the same level of privacy as a face-to-face conversation in your own home.</string>
|
||||
<string name="ftue_auth_carousel_body_control" translatable="false">Choose where your conversations are kept, giving you control and independence. Connected via Matrix.</string>
|
||||
<string name="ftue_auth_carousel_body_encrypted" translatable="false">End-to-end encrypted and no phone number required. No ads or datamining.</string>
|
||||
<string name="ftue_auth_carousel_title_messaging" translatable="false">Messaging for your team.</string>
|
||||
<!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name -->
|
||||
<string name="template_ftue_auth_carousel_body_workplace" translatable="false">${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations.</string>
|
||||
|
||||
<string name="ftue_auth_use_case_title" translatable="false">Who will you chat to the most?</string>
|
||||
<string name="ftue_auth_use_case_subtitle" translatable="false">We\'ll help you get connected.</string>
|
||||
<string name="ftue_auth_use_case_option_one" translatable="false">Friends and family</string>
|
||||
@ -24,5 +34,4 @@
|
||||
<string name="ftue_auth_use_case_skip_partial" translatable="false">You can skip this question</string>
|
||||
<string name="ftue_auth_use_case_join_existing_server" translatable="false">Looking to join an existing server?</string>
|
||||
<string name="ftue_auth_use_case_connect_to_server" translatable="false">Connect to server</string>
|
||||
|
||||
</resources>
|
||||
|
@ -2521,12 +2521,16 @@
|
||||
|
||||
<!-- Onboarding -->
|
||||
<string name="ftue_auth_carousel_1_title">Own your conversations.</string>
|
||||
<!-- TODO TO BE REMOVED -->
|
||||
<string name="ftue_auth_carousel_1_body">End-to-end encrypted messaging for secure and independent communication, connected via Matrix.</string>
|
||||
<string name="ftue_auth_carousel_2_title">You\'re in control.</string>
|
||||
<string name="ftue_auth_carousel_2_body">Element lets you choose where you messages are stored, keeping you in control of your data.</string>
|
||||
<string name="ftue_auth_carousel_3_title">Connect with anyone.</string>
|
||||
<string name="ftue_auth_carousel_3_body">Element works with all Matrix-based apps and can even bridge into proprietary messengers.</string>
|
||||
<!-- TODO TO BE REMOVED -->
|
||||
<string name="ftue_auth_carousel_2_body">Element lets you choose where your messages are stored, keeping you in control of your data.</string>
|
||||
<string name="ftue_auth_carousel_3_title">Secure Messaging.</string>
|
||||
<!-- TODO TO BE REMOVED -->
|
||||
<string name="ftue_auth_carousel_3_body">No phone number required, so you don\'t have to share those details with the outside world. No ads, no datamining.</string>
|
||||
<string name="ftue_auth_carousel_4_title">Cut the slack from teams.</string>
|
||||
<!-- TODO TO BE REMOVED -->
|
||||
<string name="ftue_auth_carousel_4_body">As universal as email, Element is a completely new type of collaboration.</string>
|
||||
|
||||
<string name="login_splash_title">It\'s your conversation. Own it.</string>
|
||||
|
@ -9,5 +9,4 @@
|
||||
<string name="resources_country_code">US</string>
|
||||
<!-- Value MUST have 4 letters and MUST be in this list: https://www.unicode.org/iso15924/iso15924-codes.html. Example: "Arab", "Cyrl", "Latn", etc. -->
|
||||
<string name="resources_script">Latn</string>
|
||||
|
||||
</resources>
|