Merge pull request #4880 from vector-im/feature/adm/carousel-images-update

Updated splash carousel images and copy
This commit is contained in:
Adam Brown 2022-01-17 15:11:08 +00:00 committed by GitHub
commit 256929b78f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
49 changed files with 144 additions and 43 deletions

1
changelog.d/4880.wip Normal file
View file

@ -0,0 +1 @@
Updates the onboarding carousel images, copy and improves the handling of different device sizes

View file

@ -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>

View 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>

View file

@ -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>

View file

@ -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")

View file

@ -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 {

View file

@ -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)
}

View file

@ -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

View file

@ -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()
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 468 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View file

@ -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

View file

@ -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. Its trusted by the worlds 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>

View file

@ -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>
@ -3657,8 +3661,8 @@
<!-- %s will be replaced by the value of link_this_email_settings_link and styled as a link -->
<string name="link_this_email_with_your_account">%s in Settings to receive invites directly in Element.</string>
<string name="labs_enable_latex_maths">Enable LaTeX mathematics</string>
<string name="restart_the_application_to_apply_changes">Restart the application for the change to take effect.</string>
<string name="labs_enable_latex_maths">Enable LaTeX mathematics</string>
<string name="restart_the_application_to_apply_changes">Restart the application for the change to take effect.</string>
<!-- Poll -->
<string name="create_poll_title">Create Poll</string>

View file

@ -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>