Skip to content
This repository was archived by the owner on Mar 6, 2024. It is now read-only.

Commit 3a412f6

Browse files
authored
Merge pull request #41 from dropbox/device-limits
Add device limits screen
2 parents dd25b85 + e4a4a1f commit 3a412f6

File tree

19 files changed

+374
-22
lines changed

19 files changed

+374
-22
lines changed

samples/discovery/android/Discovery/src/main/kotlin/com/dropbox/componentbox/discovery/discovery/home/ui/HomeScreen.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package com.dropbox.componentbox.discovery.discovery.home.ui
22

33
import androidx.compose.runtime.Composable
44
import com.dropbox.componentbox.compose.ComponentBoxLoadingView
5+
import com.dropbox.componentbox.discovery.discovery.iap.ui.DeviceLimitsScreen
56
import com.dropbox.componentbox.discovery.discovery.scaffold.ScaffoldCallback
67

78
@Composable
89
fun HomeScreen(callback: ScaffoldCallback){
910
callback.setTitle("Home")
1011

11-
ComponentBoxLoadingView()
12+
DeviceLimitsScreen(callback)
1213
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,262 @@
1+
@file:OptIn(ExperimentalMaterialApi::class)
2+
3+
package com.dropbox.componentbox.discovery.discovery.iap.ui
4+
5+
import androidx.annotation.DrawableRes
6+
import androidx.annotation.StringRes
7+
import androidx.compose.foundation.Image
8+
import androidx.compose.foundation.background
9+
import androidx.compose.foundation.clickable
10+
import androidx.compose.foundation.layout.*
11+
import androidx.compose.foundation.lazy.LazyColumn
12+
import androidx.compose.material.*
13+
import androidx.compose.runtime.Composable
14+
import androidx.compose.ui.Alignment
15+
import androidx.compose.ui.Modifier
16+
import androidx.compose.ui.graphics.Color
17+
import androidx.compose.ui.graphics.RectangleShape
18+
import androidx.compose.ui.layout.ContentScale
19+
import androidx.compose.ui.res.painterResource
20+
import androidx.compose.ui.res.stringResource
21+
import androidx.compose.ui.text.TextStyle
22+
import androidx.compose.ui.text.font.FontWeight
23+
import androidx.compose.ui.unit.dp
24+
import com.dropbox.componentbox.discovery.android.R
25+
import com.dropbox.componentbox.discovery.discovery.scaffold.LeadingNavigationIconButton
26+
import com.dropbox.componentbox.discovery.discovery.scaffold.ScaffoldCallback
27+
import com.dropbox.componentbox.samples.discovery.color.faintText
28+
import com.dropbox.componentbox.samples.discovery.color.successFill
29+
30+
31+
@Composable
32+
fun getBenefits() = listOf(
33+
Benefit(
34+
icon = BenefitIcon(res = R.drawable.info, tint = MaterialTheme.colors.onBackground),
35+
text = BenefitText(
36+
res = R.string.device_limits_benefit_one,
37+
style = MaterialTheme.typography.body1,
38+
fontWeight = FontWeight.Bold
39+
)
40+
),
41+
42+
Benefit(
43+
icon = BenefitIcon(res = R.drawable.ic_dig_checkmark_circle_fill, tint = MaterialTheme.colors.successFill),
44+
text = BenefitText(
45+
res = R.string.device_limits_benefit_two,
46+
style = MaterialTheme.typography.body1,
47+
fontWeight = FontWeight.Normal
48+
)
49+
),
50+
51+
Benefit(
52+
icon = BenefitIcon(res = R.drawable.ic_dig_checkmark_circle_fill, tint = MaterialTheme.colors.successFill),
53+
text = BenefitText(
54+
res = R.string.device_limits_benefit_three,
55+
style = MaterialTheme.typography.body1,
56+
fontWeight = FontWeight.Normal
57+
)
58+
),
59+
60+
Benefit(
61+
icon = BenefitIcon(res = R.drawable.ic_dig_checkmark_circle_fill, tint = MaterialTheme.colors.successFill),
62+
text = BenefitText(
63+
res = R.string.device_limits_benefit_four,
64+
style = MaterialTheme.typography.body1,
65+
fontWeight = FontWeight.Normal
66+
)
67+
)
68+
)
69+
70+
71+
@Composable
72+
fun DeviceLimitsScreen(callback: ScaffoldCallback) {
73+
callback.setTitle("3 of 3 devices linked")
74+
callback.setLeadingNavigationIconButton(LeadingNavigationIconButton(R.drawable.ic_dig_close_line) {})
75+
callback.setTopBarActions(listOf())
76+
callback.enableSheetGestures()
77+
callback.setBottomSheet { BottomSheet() }
78+
79+
80+
val benefits = getBenefits()
81+
82+
Column(
83+
modifier = Modifier.fillMaxSize(),
84+
verticalArrangement = Arrangement.SpaceBetween,
85+
horizontalAlignment = Alignment.CenterHorizontally
86+
) {
87+
88+
LazyColumn(
89+
modifier = Modifier
90+
.fillMaxWidth()
91+
.background(color = MaterialTheme.colors.secondary),
92+
verticalArrangement = Arrangement.SpaceBetween,
93+
horizontalAlignment = Alignment.CenterHorizontally
94+
) {
95+
96+
item {
97+
Image(
98+
painter = painterResource(id = R.drawable.devices_room),
99+
contentDescription = null,
100+
modifier = Modifier
101+
.fillMaxWidth()
102+
.heightIn(min = 250.dp, max = 320.dp)
103+
.padding(0.dp),
104+
contentScale = ContentScale.Crop,
105+
alignment = Alignment.TopCenter
106+
)
107+
}
108+
109+
item {
110+
Surface(
111+
modifier = Modifier
112+
.fillMaxWidth(), color = MaterialTheme.colors.background, elevation = 12.dp
113+
) {
114+
115+
Column(modifier = Modifier.padding(16.dp)) {
116+
Text(
117+
text = stringResource(id = R.string.device_limits_title),
118+
style = MaterialTheme.typography.h4,
119+
fontWeight = FontWeight.Bold,
120+
modifier = Modifier.padding(bottom = 16.dp)
121+
)
122+
123+
benefits.forEach { benefit ->
124+
benefit.Inflate()
125+
}
126+
}
127+
}
128+
129+
}
130+
}
131+
132+
133+
134+
135+
136+
137+
Surface(
138+
modifier = Modifier
139+
.fillMaxWidth()
140+
.padding(0.dp), color = MaterialTheme.colors.background
141+
) {
142+
143+
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
144+
Button(
145+
onClick = {},
146+
modifier = Modifier.fillMaxWidth(),
147+
colors = ButtonDefaults.buttonColors(backgroundColor = MaterialTheme.colors.primary),
148+
shape = RectangleShape
149+
) {
150+
Row(
151+
modifier = Modifier.fillMaxWidth(),
152+
horizontalArrangement = Arrangement.Center,
153+
verticalAlignment = Alignment.CenterVertically
154+
) {
155+
Text(
156+
text = "Try free for 30 days",
157+
color = MaterialTheme.colors.onPrimary,
158+
style = MaterialTheme.typography.button,
159+
fontWeight = FontWeight.Bold
160+
)
161+
}
162+
163+
}
164+
165+
166+
Row(
167+
modifier = Modifier
168+
.fillMaxWidth()
169+
.padding(0.dp)
170+
.clickable {
171+
callback.expandBottomSheet()
172+
},
173+
horizontalArrangement = Arrangement.Center,
174+
verticalAlignment = Alignment.CenterVertically,
175+
) {
176+
Text(
177+
text = "Subscription details",
178+
color = MaterialTheme.colors.faintText,
179+
style = MaterialTheme.typography.button,
180+
fontWeight = FontWeight.Normal,
181+
modifier = Modifier.padding(end = 8.dp)
182+
)
183+
184+
Icon(
185+
painter = painterResource(id = R.drawable.chevron_up),
186+
modifier = Modifier.size(16.dp),
187+
tint = MaterialTheme.colors.primary,
188+
contentDescription = null
189+
)
190+
}
191+
}
192+
}
193+
}
194+
}
195+
196+
197+
@Composable
198+
private fun BottomSheet() {
199+
Column(
200+
modifier = Modifier
201+
.fillMaxWidth()
202+
.background(MaterialTheme.colors.background)
203+
.padding(16.dp)
204+
) {
205+
206+
207+
Row(modifier = Modifier.fillMaxWidth()) {
208+
Text(
209+
text = "Subscription details",
210+
style = MaterialTheme.typography.h5,
211+
modifier = Modifier.padding(end = 16.dp)
212+
)
213+
214+
Icon(
215+
painter = painterResource(id = R.drawable.chevron_down),
216+
contentDescription = null,
217+
modifier = Modifier.size(20.dp),
218+
tint = MaterialTheme.colors.primary
219+
)
220+
}
221+
222+
223+
Text(
224+
text = "This subscription automatically renews after the 30-day free trial. You can turn off auto-renew at least 24 hours before your billing period ends.\n" +
225+
"\n" +
226+
"By upgrading your account, you agree to Dropbox’sTerms of Service and Privacy Policy."
227+
)
228+
}
229+
}
230+
231+
232+
data class BenefitIcon(
233+
@DrawableRes val res: Int,
234+
val tint: Color
235+
)
236+
237+
data class BenefitText(
238+
@StringRes val res: Int,
239+
val style: TextStyle,
240+
val fontWeight: FontWeight
241+
)
242+
243+
data class Benefit(
244+
val icon: BenefitIcon,
245+
val text: BenefitText
246+
)
247+
248+
@Composable
249+
fun Benefit.Inflate() {
250+
Row(modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically) {
251+
Icon(
252+
painter = painterResource(id = icon.res),
253+
contentDescription = null,
254+
tint = icon.tint,
255+
modifier = Modifier
256+
.size(32.dp)
257+
.padding(end = 16.dp)
258+
)
259+
260+
Text(text = stringResource(id = text.res), style = text.style, fontWeight = text.fontWeight)
261+
}
262+
}

samples/discovery/android/Discovery/src/main/kotlin/com/dropbox/componentbox/discovery/discovery/scaffold/ScaffoldCallback.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,11 @@ import androidx.compose.runtime.Composable
44

55
interface ScaffoldCallback {
66
fun setTitle(value: String)
7+
fun setLeadingNavigationIconButton(value: LeadingNavigationIconButton)
78
fun setTopBarActions(value: List<@Composable () -> Unit>)
9+
fun setBottomSheet(content: @Composable () -> Unit)
10+
fun expandBottomSheet()
11+
fun collapseBottomSheet()
12+
fun enableSheetGestures()
13+
fun disableSheetGestures()
814
}

0 commit comments

Comments
 (0)