1
0
Fork 0
mirror of https://github.com/anyproto/anytype-kotlin.git synced 2025-06-08 05:47:05 +09:00

DROID-2274 Payments | Design | Layout for screens with membership details (#992)

This commit is contained in:
Konstantin Ivanov 2024-03-08 10:39:18 +01:00 committed by GitHub
parent fe71de374f
commit 8c6dce6f8f
Signed by: github
GPG key ID: B5690EEEBB952194
16 changed files with 624 additions and 97 deletions

View file

@ -0,0 +1,11 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="16dp"
android:height="17dp"
android:viewportWidth="16"
android:viewportHeight="17">
<path
android:pathData="M3,8.688L7,12.688L13,3.688"
android:strokeWidth="1.25"
android:fillColor="#00000000"
android:strokeColor="@color/text_primary"/>
</vector>

View file

@ -0,0 +1,59 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="96dp"
android:height="97dp"
android:viewportWidth="96"
android:viewportHeight="97">
<path
android:pathData="M26.4,27.353m0,26.4a26.4,26.4 0,1 1,0 -52.8a26.4,26.4 0,1 1,0 52.8">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="26.4"
android:centerY="27.353"
android:gradientRadius="26.4"
android:type="radial">
<item android:offset="0.41" android:color="#00A5AEFF"/>
<item android:offset="1" android:color="#FFA5AEFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M26.4,70.553m0,26.4a26.4,26.4 0,1 1,0 -52.8a26.4,26.4 0,1 1,0 52.8">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="26.4"
android:centerY="70.553"
android:gradientRadius="26.4"
android:type="radial">
<item android:offset="0.41" android:color="#00A5AEFF"/>
<item android:offset="1" android:color="#FFA5AEFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M69.6,27.353m0,26.4a26.4,26.4 0,1 1,0 -52.8a26.4,26.4 0,1 1,0 52.8">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="69.6"
android:centerY="27.353"
android:gradientRadius="26.4"
android:type="radial">
<item android:offset="0.41" android:color="#00A5AEFF"/>
<item android:offset="1" android:color="#FFA5AEFF"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M69.6,70.553m0,26.4a26.4,26.4 0,1 1,0 -52.8a26.4,26.4 0,1 1,0 52.8">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="69.6"
android:centerY="70.553"
android:gradientRadius="26.4"
android:type="radial">
<item android:offset="0.41" android:color="#00A5AEFF"/>
<item android:offset="1" android:color="#FFA5AEFF"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -0,0 +1,131 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="96dp"
android:height="97dp"
android:viewportWidth="96"
android:viewportHeight="97">
<group>
<clip-path
android:pathData="M0,0.126h96v96h-96z"/>
<path
android:pathData="M48.001,20.123m0,20a20,20 0,1 1,0 -40a20,20 0,1 1,0 40"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="48.001"
android:centerY="20.123"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M48.001,76.126m0,20a20,20 0,1 1,0 -40a20,20 0,1 1,0 40"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="48.001"
android:centerY="76.126"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M20,48.12m20,-0a20,20 0,1 1,-40 -0a20,20 0,1 1,40 -0"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="20"
android:centerY="48.12"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M76,48.12m20,-0a20,20 0,1 1,-40 -0a20,20 0,1 1,40 -0"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="76"
android:centerY="48.12"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M14.059,14.18C21.869,6.37 34.533,6.37 42.343,14.18C50.154,21.99 50.154,34.654 42.343,42.464C34.533,50.275 21.869,50.275 14.059,42.464C6.249,34.654 6.249,21.99 14.059,14.18Z"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="28.201"
android:centerY="28.322"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M53.658,53.781C61.468,45.97 74.132,45.97 81.942,53.781C89.753,61.591 89.753,74.254 81.942,82.065C74.132,89.875 61.468,89.875 53.658,82.065C45.847,74.254 45.847,61.591 53.658,53.781Z"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="67.8"
android:centerY="67.923"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M14.057,82.062C6.247,74.252 6.247,61.588 14.057,53.778C21.868,45.967 34.531,45.967 42.342,53.778C50.152,61.588 50.152,74.252 42.342,82.062C34.531,89.872 21.868,89.872 14.057,82.062Z"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="28.2"
android:centerY="67.92"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M53.655,42.464C45.845,34.654 45.845,21.991 53.655,14.18C61.466,6.37 74.129,6.37 81.939,14.18C89.75,21.991 89.75,34.654 81.939,42.464C74.129,50.275 61.466,50.275 53.655,42.464Z"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="67.797"
android:centerY="28.322"
android:gradientRadius="20"
android:type="radial">
<item android:offset="0.41" android:color="#00F05F5F"/>
<item android:offset="1" android:color="#FFF05F5F"/>
</gradient>
</aapt:attr>
</path>
</group>
</vector>

View file

@ -0,0 +1,52 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="96dp"
android:height="96dp"
android:viewportWidth="96"
android:viewportHeight="96">
<path
android:pathData="M48,48m-48,0a48,48 0,1 1,96 0a48,48 0,1 1,-96 0"
android:strokeAlpha="0.4"
android:fillAlpha="0.4">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="48"
android:centerY="48"
android:gradientRadius="48"
android:type="radial">
<item android:offset="0.41" android:color="#0024BFD4"/>
<item android:offset="1" android:color="#FF24BFD4"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M48,48.262m-26.4,0a26.4,26.4 0,1 1,52.8 0a26.4,26.4 0,1 1,-52.8 0"
android:strokeAlpha="0.6"
android:fillAlpha="0.6">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="48"
android:centerY="48.262"
android:gradientRadius="26.4"
android:type="radial">
<item android:offset="0.41" android:color="#0024BFD4"/>
<item android:offset="1" android:color="#FF24BFD4"/>
</gradient>
</aapt:attr>
</path>
<path
android:pathData="M48,48.263m-6,0a6,6 0,1 1,12 0a6,6 0,1 1,-12 0"
android:strokeAlpha="0.8"
android:fillAlpha="0.8">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="48"
android:centerY="48.263"
android:gradientRadius="6"
android:type="radial">
<item android:offset="0.285" android:color="#002AAFC1"/>
<item android:offset="1" android:color="#FF2AAFC1"/>
</gradient>
</aapt:attr>
</path>
</vector>

View file

@ -1368,4 +1368,40 @@
<string name="payments_let_us_link_start">Would you like to use Anytype for business, education, etc.?</string>
<string name="payments_let_us_link_end">Please let us know here.</string>
<!-- Membership Level Details -->
<string name="payments_details_name_title">Pick your unique name</string>
<string name="payments_details_name_subtitle">This name acts like a personal domain, making it easier for others to find you</string>
<string name="payments_details_name_hint">Myself</string>
<string name="payments_details_name_domain">.any</string>
<string name="payments_details_name_error">This name is already taken!</string>
<string name="payments_details_name_success">This name is up for grabs!</string>
<string name="payments_details_info_explorer">Dive into the network and enjoy the thrill of one-on-one collaboration</string>
<string-array name="payments_benefits_explorer">
<item>1 GB of network space</item>
<item>10 one-to-one spaces</item>
<item>Up to 10 shared spaces in read-only mode</item>
</string-array>
<string name="payments_details_info_builder">Unlock the magic of multi-party collaboration and enjoy top-notch support</string>
<string-array name="payments_benefits_builder">
<item>Unique name (from 7 characters)</item>
<item>128 GB of network space</item>
<item>10 Guest collaborator seats</item>
<item>Priority support</item>
</string-array>
<string name="payments_details_info_cocreator">Support our adventure and unlock exclusive access and perks</string>
<string-array name="payments_benefits_cocreator">
<item>Unique name (from 5 characters)</item>
<item>256 GB of network space</item>
<item>25 Guest collaborator seats</item>
<item>Chat with the team</item>
<item>Unique collectible</item>
</string-array>
<string name="payments_detials_button_pay">Pay by Card</string>
<string name="payments_detials_button_submit">Submit</string>
<string name="payments_details_whats_included">Whats included</string>
</resources>

View file

@ -0,0 +1,30 @@
package com.anytypeio.anytype.models
sealed class Tier {
abstract val id: String
abstract val isCurrent: Boolean
data class Explorer(
override val id: String,
override val isCurrent: Boolean,
val price: String = ""
) : Tier()
data class Builder(
override val id: String,
override val isCurrent: Boolean,
val price: String = ""
) : Tier()
data class CoCreator(
override val id: String,
override val isCurrent: Boolean,
val price: String = ""
) : Tier()
data class Custom(
override val id: String,
override val isCurrent: Boolean,
val price: String = ""
) : Tier()
}

View file

@ -16,7 +16,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@ -33,8 +32,6 @@ fun InfoCard(
title: String,
subtitle: String,
) {
val configuration = LocalConfiguration.current
Column(
modifier = Modifier
.height(284.dp)

View file

@ -53,8 +53,8 @@ import com.anytypeio.anytype.core_ui.views.BodyRegular
import com.anytypeio.anytype.core_ui.views.Caption1Regular
import com.anytypeio.anytype.core_ui.views.Relations2
import com.anytypeio.anytype.core_ui.views.fontRiccioneRegular
import com.anytypeio.anytype.models.Tier
import com.anytypeio.anytype.viewmodel.PaymentsState
import com.anytypeio.anytype.viewmodel.TierState
@Composable
fun MainPaymentsScreen(state: PaymentsState) {
@ -78,7 +78,7 @@ fun MainPaymentsScreen(state: PaymentsState) {
Header(state = state)
Spacer(modifier = Modifier.height(32.dp))
InfoCards()
Tiers(state = state)
TiersList(state = state)
Spacer(modifier = Modifier.height(32.dp))
LinkButton(text = stringResource(id = R.string.payments_member_link), action = {})
Divider()
@ -90,6 +90,7 @@ fun MainPaymentsScreen(state: PaymentsState) {
}
}
}
MembershipLevels(tier = Tier.Explorer(id = "888", isCurrent = true))
}
@Composable
@ -140,7 +141,7 @@ private fun Header(state: PaymentsState.Success) {
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun Tiers(state: PaymentsState.Success) {
fun TiersList(state: PaymentsState.Success) {
val itemsScroll = rememberLazyListState(initialFirstVisibleItemIndex = 1)
LazyRow(
state = itemsScroll,
@ -151,8 +152,17 @@ fun Tiers(state: PaymentsState.Success) {
contentPadding = PaddingValues(start = 20.dp, end = 20.dp),
flingBehavior = rememberSnapFlingBehavior(lazyListState = itemsScroll)
) {
itemsIndexed(state.tiers) { index, tier ->
TierByType(tier = tier)
itemsIndexed(state.tiers) { _, tier ->
val resources = mapTierToResources(tier)
TierView(
title = resources.title,
subTitle = resources.subtitle,
colorGradient = resources.colorGradient,
radialGradient = resources.radialGradient,
icon = resources.smallIcon,
buttonText = stringResource(id = R.string.payments_button_learn),
onClick = { /*TODO*/ }
)
}
}
}
@ -257,10 +267,10 @@ fun BottomText() {
@Composable
fun MainPaymentsScreenPreview() {
val tiers = listOf(
TierState.Explorer("999", isCurrent = true),
TierState.Builder("999", isCurrent = false),
TierState.CoCreator("999", isCurrent = false),
TierState.Custom("999", isCurrent = false)
Tier.Explorer("999", isCurrent = true),
Tier.Builder("999", isCurrent = false),
Tier.CoCreator("999", isCurrent = false),
Tier.Custom("999", isCurrent = false)
)
MainPaymentsScreen(PaymentsState.Success(tiers))
}

View file

@ -0,0 +1,226 @@
package com.anytypeio.anytype.screens
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.Orientation
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.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.layout.wrapContentSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.FractionalThreshold
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material.rememberSwipeableState
import androidx.compose.material.swipeable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.colorResource
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.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.anytypeio.anytype.core_ui.foundation.noRippleThrottledClickable
import com.anytypeio.anytype.core_ui.views.BodyBold
import com.anytypeio.anytype.core_ui.views.BodyCallout
import com.anytypeio.anytype.core_ui.views.BodyRegular
import com.anytypeio.anytype.core_ui.views.Caption1Regular
import com.anytypeio.anytype.core_ui.views.HeadlineTitle
import com.anytypeio.anytype.core_ui.widgets.DragStates
import com.anytypeio.anytype.models.Tier
import com.anytypeio.anytype.peyments.R
import kotlin.math.roundToInt
@OptIn(ExperimentalMaterialApi::class)
@Composable
fun MembershipLevels(tier: Tier) {
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
Box(
modifier = Modifier
.fillMaxSize()
.background(color = colorResource(id = R.color.shape_tertiary)),
contentAlignment = Alignment.BottomStart,
) {
val swipeableState = rememberSwipeableState(DragStates.VISIBLE)
val keyboardController = LocalSoftwareKeyboardController.current
if (swipeableState.isAnimationRunning && swipeableState.targetValue == DragStates.DISMISSED) {
DisposableEffect(Unit) {
onDispose {
keyboardController?.hide()
focusManager.clearFocus()
}
}
}
val sizePx =
with(LocalDensity.current) { LocalConfiguration.current.screenHeightDp.dp.toPx() }
val tierResources = mapTierToResources(tier)
AnimatedVisibility(
visible = true,
enter = slideInVertically { it },
exit = slideOutVertically { it },
modifier = Modifier
.swipeable(state = swipeableState,
orientation = Orientation.Vertical,
anchors = mapOf(
0f to DragStates.VISIBLE, sizePx to DragStates.DISMISSED
),
thresholds = { _, _ -> FractionalThreshold(0.3f) })
.offset { IntOffset(0, swipeableState.offset.value.roundToInt()) }
) {
val brush = Brush.verticalGradient(
listOf(
tierResources.colorGradient,
Color.Transparent
)
)
Column {
Box(
modifier = Modifier
.fillMaxWidth()
.height(132.dp)
.background(brush = brush, shape = RoundedCornerShape(16.dp)),
contentAlignment = androidx.compose.ui.Alignment.BottomStart
) {
Icon(
modifier = Modifier
.padding(start = 16.dp),
painter = painterResource(id = tierResources.mediumIcon!!),
contentDescription = "logo",
tint = tierResources.radialGradient
)
}
Spacer(modifier = Modifier.height(14.dp))
Text(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp),
text = tierResources.title,
color = colorResource(id = R.color.text_primary),
style = HeadlineTitle,
textAlign = TextAlign.Start
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 6.dp),
text = tierResources.subtitle,
color = colorResource(id = R.color.text_primary),
style = BodyCallout,
textAlign = TextAlign.Start
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 22.dp),
text = stringResource(id = R.string.payments_details_whats_included),
color = colorResource(id = R.color.text_secondary),
style = BodyCallout,
textAlign = TextAlign.Start
)
Spacer(modifier = Modifier.height(6.dp))
tierResources.benefits.forEach { benefit ->
Benefit(benefit = benefit)
Spacer(modifier = Modifier.height(6.dp))
}
Spacer(modifier = Modifier.height(30.dp))
NamePicker()
}
}
}
}
@Composable
fun NamePicker() {
Column(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.background(
shape = RoundedCornerShape(8.dp),
color = colorResource(id = R.color.background_primary)
)
) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 26.dp),
text = stringResource(id = R.string.payments_details_name_title),
color = colorResource(id = R.color.text_primary),
style = BodyBold,
textAlign = TextAlign.Start
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 6.dp),
text = stringResource(id = R.string.payments_details_name_subtitle),
color = colorResource(id = R.color.text_primary),
style = BodyCallout,
textAlign = TextAlign.Start
)
}
}
@Composable
fun Benefit(benefit: String) {
Box(
modifier = Modifier
.wrapContentHeight()
.fillMaxWidth()
.padding(horizontal = 20.dp)
) {
Image(
modifier = Modifier
.wrapContentSize()
.align(Alignment.CenterStart),
painter = painterResource(id = R.drawable.ic_check_16),
contentDescription = "text check icon"
)
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 22.dp)
.align(Alignment.CenterStart),
text = benefit,
style = BodyCallout,
color = colorResource(id = R.color.text_primary)
)
}
}
@Preview()
@Composable
fun MyLevel() {
MembershipLevels(tier = Tier.Explorer("121", true))
}

View file

@ -18,6 +18,7 @@ import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringArrayResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontWeight
@ -32,13 +33,12 @@ import com.anytypeio.anytype.core_ui.views.ButtonPrimary
import com.anytypeio.anytype.core_ui.views.ButtonSize
import com.anytypeio.anytype.core_ui.views.Caption1Regular
import com.anytypeio.anytype.core_ui.views.fontInterSemibold
import com.anytypeio.anytype.viewmodel.TierState
import com.anytypeio.anytype.models.Tier
@Composable
private fun Tier(
fun TierView(
title: String,
subTitle: String,
price: String,
colorGradient: Color,
radialGradient: Color,
icon: Int,
@ -120,72 +120,58 @@ fun PriceOrOption() {
}
@Composable
fun TierByType(tier: TierState) {
when (tier) {
is TierState.Builder -> {
Tier(
title = stringResource(id = R.string.payments_tier_builder),
subTitle = stringResource(id = R.string.payments_tier_builder_description),
price = tier.price,
colorGradient = Color(0xFFE4E7FF),
radialGradient = Color(0xFFA5AEFF),
icon = R.drawable.logo_builder,
buttonText = stringResource(id = R.string.payments_button_learn),
onClick = { /*TODO*/ }
)
}
fun mapTierToResources(tier: Tier): TierResources {
return when (tier) {
is Tier.Builder -> TierResources(
title = stringResource(id = R.string.payments_tier_builder),
subtitle = stringResource(id = R.string.payments_tier_builder_description),
mediumIcon = R.drawable.logo_builder_96,
smallIcon = R.drawable.logo_builder_64,
colorGradient = Color(0xFFE4E7FF),
radialGradient = Color(0xFFA5AEFF),
benefits = stringArrayResource(id = R.array.payments_benefits_builder).toList()
)
is TierState.CoCreator -> {
Tier(
title = stringResource(id = R.string.payments_tier_cocreator),
subTitle = stringResource(id = R.string.payments_tier_cocreator_description),
price = tier.price,
colorGradient = Color(0xFFFBEAEA),
radialGradient = Color(0xFFF05F5F),
icon = R.drawable.logo_co_creator,
buttonText = stringResource(id = R.string.payments_button_learn),
onClick = { /*TODO*/ }
)
}
is Tier.CoCreator -> TierResources(
title = stringResource(id = R.string.payments_tier_cocreator),
subtitle = stringResource(id = R.string.payments_tier_cocreator_description),
mediumIcon = R.drawable.logo_co_creator_96,
smallIcon = R.drawable.logo_co_creator_64,
colorGradient = Color(0xFFFBEAEA),
radialGradient = Color(0xFFF05F5F),
benefits = stringArrayResource(id = R.array.payments_benefits_cocreator).toList()
)
is TierState.Custom -> {
Tier(
title = stringResource(id = R.string.payments_tier_custom),
subTitle = stringResource(id = R.string.payments_tier_custom_description),
price = tier.price,
colorGradient = Color(0xFFFBEAFF),
radialGradient = Color(0xFFFE86DE3),
icon = R.drawable.logo_custom,
buttonText = stringResource(id = R.string.payments_button_learn),
onClick = { /*TODO*/ }
)
}
is Tier.Custom -> TierResources(
title = stringResource(id = R.string.payments_tier_custom),
subtitle = stringResource(id = R.string.payments_tier_custom_description),
smallIcon = R.drawable.logo_custom_64,
colorGradient = Color(0xFFFBEAFF),
radialGradient = Color(0xFFFE86DE3),
benefits = emptyList()
)
is TierState.Explorer -> {
Tier(
title = stringResource(id = R.string.payments_tier_explorer),
subTitle = stringResource(id = R.string.payments_tier_explorer_description),
price = tier.price,
colorGradient = Color(0xFFCFFAFF),
radialGradient = Color(0xFF24BFD4),
icon = R.drawable.logo_explorer,
buttonText = stringResource(id = R.string.payments_button_learn),
onClick = { /*TODO*/ }
)
}
is Tier.Explorer -> TierResources(
title = stringResource(id = R.string.payments_tier_explorer),
subtitle = stringResource(id = R.string.payments_tier_explorer_description),
mediumIcon = R.drawable.logo_explorer_96,
smallIcon = R.drawable.logo_explorer_64,
colorGradient = Color(0xFFCFFAFF),
radialGradient = Color(0xFF24BFD4),
benefits = stringArrayResource(id = R.array.payments_benefits_explorer).toList()
)
}
}
@Preview
@Composable
fun TierPreview() {
Tier(
TierView(
title = "Explorer",
subTitle = "Dive into the network and enjoy the thrill of one-on-one collaboration",
price = "9.99",
buttonText = "Subscribe",
onClick = {},
icon = R.drawable.logo_co_creator,
icon = R.drawable.logo_co_creator_64,
colorGradient = Color(0xFFCFF6CF),
radialGradient = Color(0xFF24BFD4)
)
@ -197,4 +183,14 @@ val titleTextStyle = TextStyle(
fontSize = 17.sp,
lineHeight = 24.sp,
letterSpacing = (-0.024).em
)
data class TierResources(
val title: String,
val subtitle: String,
val mediumIcon: Int? = null,
val smallIcon: Int,
val colorGradient: Color,
val radialGradient: Color,
val benefits: List<String>
)

View file

@ -1,30 +1,8 @@
package com.anytypeio.anytype.viewmodel
import com.anytypeio.anytype.models.Tier
sealed class PaymentsState {
object Loading : PaymentsState()
data class Success(val tiers: List<TierState>) : PaymentsState()
}
sealed class TierState {
abstract val isCurrent: Boolean
data class Explorer(
val price: String,
override val isCurrent: Boolean
) : TierState()
data class Builder(
val price: String,
override val isCurrent: Boolean
) : TierState()
data class CoCreator(
val price: String,
override val isCurrent: Boolean
) : TierState()
data class Custom(
val price: String,
override val isCurrent: Boolean
) : TierState()
data class Success(val tiers: List<Tier>) : PaymentsState()
}

View file

@ -2,6 +2,7 @@ package com.anytypeio.anytype.viewmodel
import androidx.lifecycle.ViewModel
import com.anytypeio.anytype.analytics.base.Analytics
import com.anytypeio.anytype.models.Tier
import kotlinx.coroutines.flow.MutableStateFlow
import timber.log.Timber
@ -15,10 +16,10 @@ class PaymentsViewModel(
Timber.d("PaymentsViewModel created")
viewState.value = PaymentsState.Success(
listOf(
TierState.Explorer("Free", true),
TierState.Builder("$9.99/mo", false),
TierState.CoCreator("$19.99/mo", false),
TierState.Custom("$29.99/mo", false)
Tier.Explorer("Free", true),
Tier.Builder("$9.99/mo", false),
Tier.CoCreator("$19.99/mo", false),
Tier.Custom("$29.99/mo", false)
)
)
}