Skip to content

Commit 680e5e9

Browse files
authored
feat buy & sell kin screen (#3)
* feat buy and sell kin screen * add buy&sell kin to account sheet * fix aspect ratio of image * fix bottom padding click area * add ripple indication back
1 parent 89fdff6 commit 680e5e9

17 files changed

Lines changed: 305 additions & 44 deletions

File tree

api/src/main/java/com/getcode/manager/AnalyticsManager.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ class AnalyticsManager @Inject constructor(private val mixpanelAPI: MixpanelAPI)
223223
Balance("Balance Screen"),
224224
Faq("FAQ Screen"),
225225
Settings("Settings Screen"),
226+
BuyAndSellKin("Buy and Sell Kin Screen"),
226227
Deposit("Deposit Screen"),
227228
Backup("Backup Screen"),
228229
Withdraw("Withdraw Screen"),

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ dependencies {
103103

104104
//standard libraries
105105
implementation(Libs.kotlin_stdlib)
106+
implementation(Libs.kotlinx_collections_immutable)
106107
implementation(Libs.androidx_core)
107108
implementation(Libs.androidx_constraint_layout)
108109
implementation(Libs.androidx_lifecycle_runtime)
11.7 KB
Loading
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package com.getcode.util
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.Modifier
5+
6+
@Composable
7+
inline fun Modifier.conditionally(
8+
condition: Boolean,
9+
whenTrue: Modifier.() -> Modifier,
10+
): Modifier {
11+
return if (condition) {
12+
whenTrue(this)
13+
} else {
14+
this
15+
}
16+
}
17+

app/src/main/java/com/getcode/view/SheetNav.kt

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,8 @@ package com.getcode.view
22

33
import androidx.annotation.StringRes
44
import androidx.compose.animation.*
5-
import androidx.compose.animation.core.tween
65
import androidx.navigation.*
76
import com.getcode.R
8-
import com.getcode.util.AnimationUtils
97
import com.getcode.view.login.PhoneConfirm
108
import com.getcode.view.login.PhoneVerify
119
import com.getcode.view.main.account.*
@@ -14,6 +12,7 @@ import com.getcode.view.main.account.AccountFaq
1412
import com.getcode.view.main.account.withdraw.AccountWithdrawAddress
1513
import com.getcode.view.main.account.withdraw.AccountWithdrawAmount
1614
import com.getcode.view.main.account.withdraw.AccountWithdrawSummary
15+
import com.getcode.view.main.getKin.BuyAndSellKin
1716
import com.getcode.view.main.getKin.GetKin
1817
import com.getcode.view.main.getKin.ReferFriend
1918
import com.getcode.view.main.home.HomeViewModel
@@ -29,6 +28,7 @@ fun NavGraphBuilder.addSheetGraph(
2928
) {
3029
val onAccountHomeNav = { page: AccountPage ->
3130
when (page) {
31+
BUY_AND_SELL_KIN -> navController.navigate(SheetSections.BUY_AND_SELL_KIN.route)
3232
DEPOSIT -> navController.navigate(SheetSections.DEPOSIT.route)
3333
WITHDRAW -> navController.navigate(SheetSections.WITHDRAW_AMOUNT.route)
3434
ACCESS_KEY -> navController.navigate(SheetSections.ACCESS_KEY.route)
@@ -146,6 +146,14 @@ fun NavGraphBuilder.addSheetGraph(
146146
onTitleChange(R.string.empty)
147147
ReferFriend(onClose, navController)
148148
}
149+
150+
composableItem(
151+
route = SheetSections.BUY_AND_SELL_KIN.route
152+
) {
153+
onBackButtonVisibilityChange(true)
154+
onTitleChange(R.string.empty)
155+
BuyAndSellKin()
156+
}
149157
}
150158

151159
enum class SheetSections(
@@ -298,4 +306,8 @@ enum class SheetSections(
298306
title = R.string.title_getFriendStartedOnCode,
299307
route = "sheet/refer-friend"
300308
),
309+
BUY_AND_SELL_KIN(
310+
title = R.string.title_buyAndSellKin,
311+
route = "sheet/buy-and-sell-kin"
312+
),
301313
}

app/src/main/java/com/getcode/view/main/account/AccountHome.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ fun AccountHome(
4444
.verticalScroll(rememberScrollState())
4545
) {
4646
val actions: MutableList<AccountMainItem> = mutableListOf(
47+
AccountMainItem(
48+
name = R.string.title_buyAndSellKin,
49+
icon = R.drawable.ic_currency_dollar_active
50+
) { onPage(AccountPage.BUY_AND_SELL_KIN) },
4751
AccountMainItem(
4852
name = R.string.title_depositKin,
4953
icon = R.drawable.ic_menu_deposit

app/src/main/java/com/getcode/view/main/account/AccountSheetViewModel.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ data class AccountMainItem(
2020
)
2121

2222
enum class AccountPage {
23+
BUY_AND_SELL_KIN,
2324
DEPOSIT,
2425
WITHDRAW,
2526
PHONE,
@@ -61,6 +62,7 @@ class AccountSheetViewModel @Inject constructor(
6162

6263
fun onNavigation(page: AccountPage) {
6364
when (page) {
65+
AccountPage.BUY_AND_SELL_KIN -> AnalyticsManager.Screen.BuyAndSellKin
6466
AccountPage.DEPOSIT -> AnalyticsManager.Screen.Deposit
6567
AccountPage.WITHDRAW -> AnalyticsManager.Screen.Withdraw
6668
AccountPage.ACCESS_KEY -> AnalyticsManager.Screen.Backup
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package com.getcode.view.main.getKin
2+
3+
import android.content.Context
4+
import android.net.Uri
5+
import androidx.compose.foundation.Image
6+
import androidx.compose.foundation.clickable
7+
import androidx.compose.foundation.layout.Box
8+
import androidx.compose.foundation.layout.aspectRatio
9+
import androidx.compose.foundation.layout.fillMaxWidth
10+
import androidx.compose.foundation.layout.padding
11+
import androidx.compose.foundation.layout.size
12+
import androidx.compose.foundation.lazy.LazyColumn
13+
import androidx.compose.foundation.lazy.items
14+
import androidx.compose.material.MaterialTheme
15+
import androidx.compose.material.Text
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.remember
19+
import androidx.compose.ui.Alignment
20+
import androidx.compose.ui.Modifier
21+
import androidx.compose.ui.draw.clip
22+
import androidx.compose.ui.layout.ContentScale
23+
import androidx.compose.ui.platform.LocalContext
24+
import androidx.compose.ui.res.painterResource
25+
import androidx.compose.ui.res.stringResource
26+
import androidx.compose.ui.unit.dp
27+
import androidx.constraintlayout.compose.ConstraintLayout
28+
import androidx.hilt.navigation.compose.hiltViewModel
29+
import com.getcode.R
30+
import com.getcode.view.components.ButtonState
31+
import com.getcode.view.components.CodeButton
32+
import kotlinx.collections.immutable.toImmutableList
33+
34+
@Composable
35+
fun BuyAndSellKin() {
36+
val context = LocalContext.current
37+
val viewModel = hiltViewModel<BuyAndSellKinViewModel>()
38+
39+
val state by remember { viewModel.state }
40+
41+
ConstraintLayout(
42+
modifier = Modifier
43+
.fillMaxWidth()
44+
.padding(horizontal = 20.dp),
45+
) {
46+
val (topSection) = createRefs()
47+
48+
LazyColumn(
49+
modifier = Modifier
50+
.fillMaxWidth()
51+
.constrainAs(topSection) {
52+
top.linkTo(parent.top)
53+
start.linkTo(parent.start)
54+
end.linkTo(parent.end)
55+
},
56+
) {
57+
item {
58+
Text(
59+
text = stringResource(R.string.title_buyAndSellKin),
60+
style = MaterialTheme.typography.h1,
61+
modifier = Modifier.padding(vertical = 15.dp),
62+
)
63+
}
64+
item {
65+
Text(
66+
text = stringResource(R.string.subtitle_buySellDescription),
67+
style = MaterialTheme.typography.body1,
68+
modifier = Modifier.padding(vertical = 30.dp),
69+
)
70+
}
71+
72+
items(state.items.toImmutableList(), key = { it.link }) { item ->
73+
74+
VideoThumbnail(
75+
context = context,
76+
imageResId = item.imageResId,
77+
link = item.link,
78+
onVideoClick = { context, link ->
79+
viewModel.openVideo(
80+
context = context,
81+
link = link,
82+
)
83+
},
84+
)
85+
86+
CodeButton(
87+
onClick = {
88+
viewModel.openVideo(
89+
context = context,
90+
link = item.link,
91+
)
92+
},
93+
text = stringResource(id = item.buttonTextResId),
94+
buttonState = ButtonState.Filled,
95+
)
96+
97+
CodeButton(
98+
modifier = Modifier.padding(bottom = 30.dp),
99+
onClick = {
100+
viewModel.shareVideo(
101+
context = context,
102+
link = item.link,
103+
)
104+
},
105+
text = stringResource(id = R.string.action_shareVideo),
106+
buttonState = ButtonState.Subtle,
107+
isPaddedVertical = false,
108+
)
109+
}
110+
}
111+
}
112+
}
113+
114+
@Composable
115+
private fun VideoThumbnail(
116+
context: Context,
117+
imageResId: Int,
118+
link: Uri,
119+
onVideoClick: (Context, Uri) -> Unit,
120+
) {
121+
Box(
122+
modifier = Modifier
123+
.fillMaxWidth()
124+
.padding(bottom = 10.dp)
125+
.clip(MaterialTheme.shapes.small)
126+
.clickable { onVideoClick(context, link) },
127+
128+
) {
129+
Image(
130+
modifier = Modifier
131+
.aspectRatio(16f / 9f)
132+
.fillMaxWidth()
133+
.align(Alignment.CenterStart),
134+
contentScale = ContentScale.Fit,
135+
painter = painterResource(id = imageResId),
136+
contentDescription = "Video Thumbnail",
137+
)
138+
139+
Image(
140+
modifier = Modifier
141+
.size(70.dp)
142+
.align(Alignment.Center),
143+
painter = painterResource(id = R.drawable.youtube),
144+
contentDescription = "Youtube Logo",
145+
)
146+
}
147+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package com.getcode.view.main.getKin
2+
3+
import android.content.Context
4+
import android.content.Intent
5+
import android.net.Uri
6+
import androidx.compose.runtime.Immutable
7+
import androidx.compose.runtime.State
8+
import androidx.compose.runtime.mutableStateOf
9+
import com.getcode.R
10+
import com.getcode.view.BaseViewModel
11+
import dagger.hilt.android.lifecycle.HiltViewModel
12+
import javax.inject.Inject
13+
import kotlinx.collections.immutable.ImmutableList
14+
import kotlinx.collections.immutable.toImmutableList
15+
16+
@Immutable
17+
data class BuyAndSellKinUiModel(
18+
val items: ImmutableList<BuyAndSellKinItem>
19+
)
20+
21+
data class BuyAndSellKinItem(
22+
val imageResId: Int,
23+
val buttonTextResId: Int,
24+
val link: Uri
25+
)
26+
27+
@HiltViewModel
28+
class BuyAndSellKinViewModel @Inject constructor() : BaseViewModel() {
29+
private val _state = mutableStateOf(
30+
BuyAndSellKinUiModel(
31+
items = listOf(
32+
BuyAndSellKinItem(
33+
imageResId = R.drawable.video_buy_kin_2x,
34+
buttonTextResId = R.string.action_learnHowToBuyKin,
35+
link = Uri.parse("https://www.youtube.com/watch?v=s2aqkF3dJcI")
36+
),
37+
BuyAndSellKinItem(
38+
imageResId = R.drawable.video_sell_kin_2x,
39+
buttonTextResId = R.string.action_learnHowToSellKin,
40+
link = Uri.parse("https://www.youtube.com/watch?v=cyb9Da_mV9I")
41+
)
42+
).toImmutableList()
43+
)
44+
)
45+
val state: State<BuyAndSellKinUiModel> = _state
46+
47+
fun shareVideo(context: Context, link: Uri) {
48+
val sendIntent = Intent().apply {
49+
action = Intent.ACTION_SEND
50+
putExtra(Intent.EXTRA_TEXT, link.toString())
51+
type = "text/plain"
52+
}
53+
val shareIntent = Intent.createChooser(sendIntent, null)
54+
context.startActivity(shareIntent)
55+
}
56+
57+
fun openVideo(context: Context, link: Uri) {
58+
val intent = Intent(Intent.ACTION_VIEW, link)
59+
if (intent.resolveActivity(context.packageManager) != null) {
60+
context.startActivity(intent)
61+
}
62+
}
63+
}

0 commit comments

Comments
 (0)