Skip to content

Commit cd4b381

Browse files
authored
Merge pull request #9 from mohdaquib/feature/ui-update
Feature/UI update
2 parents 919ceb7 + f26388d commit cd4b381

18 files changed

Lines changed: 1750 additions & 750 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ local.properties
1818
/.idea/misc.xml
1919
.claude/
2020
.idea/
21-
.kotlin/errors/
21+
.kotlin/errors/
22+
/.idea/deploymentTargetSelector.xml

.idea/deploymentTargetSelector.xml

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ androidx-startup-runtime = { group = "androidx.startup", name = "startup-runtime
2626
androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" }
2727
androidx-compose-ui = { group = "androidx.compose.ui", name = "ui" }
2828
androidx-compose-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" }
29+
androidx-compose-ui-text-google-fonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts" }
2930
androidx-compose-ui-unit = { group = "androidx.compose.ui", name = "ui-unit" }
3031
androidx-compose-ui-util = { group = "androidx.compose.ui", name = "ui-util" }
3132
androidx-compose-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }

sample/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dependencies {
4848
implementation(platform(libs.androidx.compose.bom))
4949
implementation(libs.androidx.compose.ui)
5050
implementation(libs.androidx.compose.ui.graphics)
51+
implementation(libs.androidx.compose.ui.text.google.fonts)
5152
implementation(libs.androidx.compose.ui.tooling.preview)
5253
implementation(libs.androidx.compose.material3)
5354
testImplementation(libs.junit)

sample/src/androidTest/java/com/composea11yscanner/sample/FixedScreenAccessibilityTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package com.composea11yscanner.sample
22

3-
import androidx.compose.material3.MaterialTheme
43
import androidx.compose.runtime.Composable
54
import androidx.compose.ui.test.junit4.createComposeRule
65
import androidx.compose.ui.test.onRoot
76
import androidx.compose.ui.unit.Density
87
import com.composea11yscanner.core.model.ScannerConfig
98
import com.composea11yscanner.rules.ScannerRules
9+
import com.composea11yscanner.sample.ui.theme.ScannerTheme
1010
import com.composea11yscanner.ui.A11yScanner
1111
import org.junit.Assert.assertEquals
1212
import org.junit.Rule
@@ -40,7 +40,7 @@ class FixedScreenAccessibilityTest {
4040

4141
private fun assertNoScannerIssues(content: @Composable () -> Unit) {
4242
composeRule.setContent {
43-
MaterialTheme {
43+
ScannerTheme {
4444
content()
4545
}
4646
}
Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
package com.composea11yscanner.sample
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.background
5+
import androidx.compose.foundation.clickable
6+
import androidx.compose.foundation.layout.Arrangement
7+
import androidx.compose.foundation.layout.Box
8+
import androidx.compose.foundation.layout.Column
9+
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.fillMaxSize
11+
import androidx.compose.foundation.layout.fillMaxWidth
12+
import androidx.compose.foundation.layout.height
13+
import androidx.compose.foundation.layout.heightIn
14+
import androidx.compose.foundation.layout.padding
15+
import androidx.compose.foundation.layout.size
16+
import androidx.compose.foundation.shape.RoundedCornerShape
17+
import androidx.compose.material3.Button
18+
import androidx.compose.material3.MaterialTheme
19+
import androidx.compose.material3.Text
20+
import androidx.compose.runtime.Composable
21+
import androidx.compose.ui.Alignment
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.draw.clip
24+
import androidx.compose.ui.draw.drawBehind
25+
import androidx.compose.ui.geometry.Offset
26+
import androidx.compose.ui.graphics.Brush
27+
import androidx.compose.ui.graphics.Color
28+
import androidx.compose.ui.graphics.painter.ColorPainter
29+
import androidx.compose.ui.semantics.Role
30+
import androidx.compose.ui.semantics.contentDescription
31+
import androidx.compose.ui.semantics.semantics
32+
import androidx.compose.ui.text.font.FontWeight
33+
import androidx.compose.ui.unit.dp
34+
35+
@Composable
36+
fun BrokenFeedScreen(onViewFixed: (() -> Unit)? = null) {
37+
BrokenScreenCard(
38+
title = "Market Pulse",
39+
subtitle = "Live financial news and price movers",
40+
) {
41+
MarketFilters()
42+
43+
FinancialNewsCard(
44+
monogram = "A",
45+
logoColor = Color(0xFF6C63FF),
46+
headline = "Apex Bank rallies as mobile deposits hit quarterly record",
47+
priceChange = "+4.8%",
48+
isPositive = true,
49+
timestamp = "2m ago",
50+
chartStart = Color(0xFF26385F),
51+
chartEnd = Color(0xFF121826),
52+
description = "Open market story",
53+
)
54+
FinancialNewsCard(
55+
monogram = "N",
56+
logoColor = Color(0xFFFF4D6A),
57+
headline = "NovaPay slips after analysts flag rising card loss reserves",
58+
priceChange = "-2.1%",
59+
isPositive = false,
60+
timestamp = "11m ago",
61+
chartStart = Color(0xFF4B2332),
62+
chartEnd = Color(0xFF161923),
63+
description = "Open market story",
64+
)
65+
onViewFixed?.let {
66+
Button(onClick = it, modifier = Modifier.fillMaxWidth().heightIn(min = 48.dp)) {
67+
Text("View Fixed Version")
68+
}
69+
}
70+
}
71+
}
72+
73+
@Composable
74+
fun FixedFeedScreen(onViewBroken: (() -> Unit)? = null) {
75+
BrokenScreenCard(
76+
title = "Market Pulse",
77+
subtitle = "Accessible financial news and price movers",
78+
) {
79+
MarketFilters()
80+
81+
FixedFinancialNewsCard(
82+
monogram = "A",
83+
logoColor = Color(0xFF6C63FF),
84+
headline = "Apex Bank rallies as mobile deposits hit quarterly record",
85+
priceChange = "+4.8%",
86+
isPositive = true,
87+
timestamp = "2m ago",
88+
chartStart = Color(0xFF26385F),
89+
chartEnd = Color(0xFF121826),
90+
description = "Open Apex Bank market story",
91+
)
92+
FixedFinancialNewsCard(
93+
monogram = "N",
94+
logoColor = Color(0xFFFF4D6A),
95+
headline = "NovaPay slips after analysts flag rising card loss reserves",
96+
priceChange = "-2.1%",
97+
isPositive = false,
98+
timestamp = "11m ago",
99+
chartStart = Color(0xFF4B2332),
100+
chartEnd = Color(0xFF161923),
101+
description = "Open NovaPay market story",
102+
)
103+
104+
onViewBroken?.let {
105+
Button(onClick = it, modifier = Modifier.fillMaxWidth().heightIn(min = 48.dp)) {
106+
Text("View Broken Version")
107+
}
108+
}
109+
}
110+
}
111+
112+
@Composable
113+
private fun MarketFilters() {
114+
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
115+
MarketFilterChip("All", selected = true)
116+
MarketFilterChip("Stocks", selected = false)
117+
MarketFilterChip("Crypto", selected = false)
118+
}
119+
}
120+
121+
@Composable
122+
private fun FinancialNewsCard(
123+
monogram: String,
124+
logoColor: Color,
125+
headline: String,
126+
priceChange: String,
127+
isPositive: Boolean,
128+
timestamp: String,
129+
chartStart: Color,
130+
chartEnd: Color,
131+
description: String,
132+
) {
133+
Box(
134+
modifier = Modifier
135+
.fillMaxWidth()
136+
.height(146.dp)
137+
.clip(RoundedCornerShape(8.dp))
138+
.semantics { contentDescription = description }
139+
.clickable { },
140+
) {
141+
Image(
142+
painter = ColorPainter(chartStart),
143+
contentDescription = description,
144+
modifier = Modifier.fillMaxSize(),
145+
)
146+
ChartOverlay(chartStart = chartStart, chartEnd = chartEnd, isFixed = false)
147+
FinancialNewsContent(
148+
monogram = monogram,
149+
logoColor = logoColor,
150+
headline = headline,
151+
priceChange = priceChange,
152+
isPositive = isPositive,
153+
timestamp = timestamp,
154+
useScrim = false,
155+
)
156+
}
157+
}
158+
159+
@Composable
160+
private fun FixedFinancialNewsCard(
161+
monogram: String,
162+
logoColor: Color,
163+
headline: String,
164+
priceChange: String,
165+
isPositive: Boolean,
166+
timestamp: String,
167+
chartStart: Color,
168+
chartEnd: Color,
169+
description: String,
170+
) {
171+
Box(
172+
modifier = Modifier
173+
.fillMaxWidth()
174+
.height(146.dp)
175+
.clip(RoundedCornerShape(8.dp))
176+
.background(Color(0xFF121826))
177+
.drawBehind { drawChart(chartStart, chartEnd, isFixed = true) }
178+
.semantics { contentDescription = description }
179+
.clickable(
180+
role = Role.Button,
181+
onClick = {},
182+
),
183+
) {
184+
FinancialNewsContent(
185+
monogram = monogram,
186+
logoColor = logoColor,
187+
headline = headline,
188+
priceChange = priceChange,
189+
isPositive = isPositive,
190+
timestamp = timestamp,
191+
useScrim = true,
192+
)
193+
}
194+
}
195+
196+
@Composable
197+
private fun ChartOverlay(chartStart: Color, chartEnd: Color, isFixed: Boolean) {
198+
Box(
199+
modifier = Modifier
200+
.fillMaxSize()
201+
.drawBehind { drawChart(chartStart, chartEnd, isFixed) },
202+
)
203+
}
204+
205+
private fun androidx.compose.ui.graphics.drawscope.DrawScope.drawChart(
206+
chartStart: Color,
207+
chartEnd: Color,
208+
isFixed: Boolean,
209+
) {
210+
drawRect(
211+
brush = Brush.linearGradient(
212+
colors = listOf(chartStart.copy(alpha = if (isFixed) 0.45f else 0.35f), chartEnd),
213+
start = Offset.Zero,
214+
end = Offset(size.width, size.height),
215+
),
216+
)
217+
repeat(5) { index ->
218+
val y = size.height * (0.24f + index * 0.13f)
219+
drawLine(
220+
color = Color.White.copy(alpha = if (isFixed) 0.08f else 0.09f),
221+
start = Offset(0f, y + index * 12f),
222+
end = Offset(size.width, y - 48f),
223+
strokeWidth = 2.5f,
224+
)
225+
}
226+
drawLine(
227+
color = Color(0xFF00D4AA).copy(alpha = if (isFixed) 0.28f else 0.34f),
228+
start = Offset(0f, size.height * 0.78f),
229+
end = Offset(size.width, size.height * 0.34f),
230+
strokeWidth = 5f,
231+
)
232+
}
233+
234+
@Composable
235+
private fun FinancialNewsContent(
236+
monogram: String,
237+
logoColor: Color,
238+
headline: String,
239+
priceChange: String,
240+
isPositive: Boolean,
241+
timestamp: String,
242+
useScrim: Boolean,
243+
) {
244+
Row(
245+
modifier = Modifier
246+
.fillMaxWidth()
247+
.then(if (useScrim) Modifier.background(Color.Black.copy(alpha = 0.54f)) else Modifier)
248+
.padding(14.dp),
249+
horizontalArrangement = Arrangement.SpaceBetween,
250+
verticalAlignment = Alignment.Top,
251+
) {
252+
Row(
253+
modifier = Modifier.weight(1f),
254+
horizontalArrangement = Arrangement.spacedBy(10.dp),
255+
) {
256+
Box(
257+
modifier = Modifier
258+
.size(42.dp)
259+
.background(logoColor, RoundedCornerShape(21.dp)),
260+
contentAlignment = Alignment.Center,
261+
) {
262+
Text(
263+
text = monogram,
264+
color = Color.White,
265+
style = MaterialTheme.typography.titleMedium,
266+
fontWeight = FontWeight.Bold,
267+
)
268+
}
269+
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
270+
Text(
271+
text = headline,
272+
color = if (useScrim) Color.White else Color(0xFF8B949E),
273+
style = MaterialTheme.typography.titleMedium,
274+
fontWeight = FontWeight.Bold,
275+
)
276+
Text(
277+
text = timestamp,
278+
color = if (useScrim) Color(0xFFD0D7DE) else Color(0xFF6E7681),
279+
style = MaterialTheme.typography.bodySmall,
280+
)
281+
}
282+
}
283+
Box(
284+
modifier = Modifier
285+
.background(
286+
color = if (isPositive) Color(0xFF164E3F) else Color(0xFF5A1D2A),
287+
shape = RoundedCornerShape(14.dp),
288+
)
289+
.padding(horizontal = 9.dp, vertical = 5.dp),
290+
contentAlignment = Alignment.Center,
291+
) {
292+
Text(
293+
text = priceChange,
294+
color = if (isPositive) Color(0xFF00D4AA) else Color(0xFFFF4D6A),
295+
style = MaterialTheme.typography.labelMedium,
296+
fontWeight = FontWeight.Bold,
297+
)
298+
}
299+
}
300+
}

0 commit comments

Comments
 (0)