Skip to content

Commit 08c1378

Browse files
authored
Highlights Search Screen UI (#90)
* Update build.gradle.kts (needed for Modifier.dropShadow) * xml files * Nav to HighlightsScreen * components * Screens * pull results lazycolumn out into separate component * Clean up * Focus on searchbar when HighlightsSearchScreen is launched * Searchbar functionality fixes * pr gradle fixes * pr RecentSearches fixes * pr search bar fixes * recent search item padding fix * Parameterize previews * recentsearches UI fix * Abstract results lazy column * clean up app/gradle * fix search bar clear icon animation * Animate recent searches to results * Refactor search bar * add parameters for functionality * small fixes, address PR comments
1 parent ecc898b commit 08c1378

18 files changed

Lines changed: 745 additions & 117 deletions

app/build.gradle.kts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -62,16 +62,15 @@ android {
6262

6363
dependencies {
6464
// Jetpack Compose dependencies
65-
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
66-
implementation("androidx.compose.material3:material3")
67-
implementation("androidx.compose.ui:ui:1.9.4")
68-
implementation("androidx.compose.ui:ui-tooling-preview:1.4.3")
65+
implementation(platform("androidx.compose:compose-bom:2025.11.01"))
66+
implementation("androidx.compose.ui:ui")
67+
implementation("androidx.compose.ui:ui-tooling-preview")
6968
implementation("androidx.activity:activity-compose")
7069
implementation("androidx.lifecycle:lifecycle-viewmodel-compose")
7170
implementation("androidx.navigation:navigation-compose:2.8.2")
7271
implementation(libs.material3)
7372
implementation("com.google.dagger:hilt-android:2.51.1")
74-
implementation(libs.androidx.material3)
73+
implementation(libs.androidx.foundation.layout)
7574
kapt("com.google.dagger:hilt-android-compiler:2.51.1")
7675
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
7776
implementation("com.google.accompanist:accompanist-pager:0.24.0-alpha")
@@ -80,15 +79,13 @@ dependencies {
8079
implementation(libs.androidx.core.ktx)
8180
implementation(libs.androidx.appcompat)
8281
implementation(libs.material)
83-
implementation("io.coil-kt:coil-compose:2.0.0")
8482
implementation(libs.androidx.activity)
8583
implementation(libs.androidx.constraintlayout)
8684
implementation(libs.androidx.runtime.android)
8785
testImplementation(libs.junit)
8886
debugImplementation("androidx.compose.ui:ui-tooling")
8987
androidTestImplementation(libs.androidx.junit)
9088
androidTestImplementation(libs.androidx.espresso.core)
91-
implementation(libs.apollo.runtime)
9289
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
9390
implementation(libs.apollo.runtime)
9491
implementation("io.coil-kt.coil3:coil-compose:3.1.0")
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
package com.cornellappdev.score.components.highlights
2+
3+
import androidx.compose.animation.AnimatedContent
4+
import androidx.compose.animation.fadeIn
5+
import androidx.compose.animation.fadeOut
6+
import androidx.compose.animation.slideInVertically
7+
import androidx.compose.animation.slideOutVertically
8+
import androidx.compose.animation.togetherWith
9+
import androidx.compose.foundation.layout.Arrangement
10+
import androidx.compose.foundation.layout.Column
11+
import androidx.compose.foundation.layout.Spacer
12+
import androidx.compose.foundation.layout.height
13+
import androidx.compose.foundation.layout.padding
14+
import androidx.compose.foundation.lazy.LazyColumn
15+
import androidx.compose.foundation.lazy.items
16+
import androidx.compose.material3.Text
17+
import androidx.compose.runtime.Composable
18+
import androidx.compose.ui.Modifier
19+
import androidx.compose.ui.tooling.preview.Preview
20+
import androidx.compose.ui.unit.dp
21+
import com.cornellappdev.score.R
22+
import com.cornellappdev.score.components.EmptyStateBox
23+
import com.cornellappdev.score.components.ScorePreview
24+
import com.cornellappdev.score.model.HighlightData
25+
import com.cornellappdev.score.theme.Style.bodyNormal
26+
import com.cornellappdev.score.util.highlightsList
27+
import com.cornellappdev.score.util.recentSearchList
28+
29+
sealed interface SearchResultsState {
30+
data object Recent : SearchResultsState
31+
data class Results(val items: List<HighlightData>) : SearchResultsState
32+
data object Empty : SearchResultsState
33+
}
34+
35+
@Composable
36+
fun HighlightsCardLazyColumn(
37+
recentSearchList: List<String>,
38+
query: String,
39+
highlightsList: List<HighlightData>,
40+
onItemClick: () -> Unit,
41+
onCloseClick: () -> Unit,
42+
numResultsHeader: (@Composable () -> Unit)? = null
43+
) {
44+
45+
Column(
46+
modifier = Modifier.padding(horizontal = 24.dp)
47+
) {
48+
/*todo: move to VM*/
49+
val resultsState: SearchResultsState =
50+
when {
51+
recentSearchList.isNotEmpty() && query.isEmpty() ->
52+
SearchResultsState.Recent
53+
54+
query.isNotEmpty() -> {
55+
val filtered = highlightsList.filter {
56+
it.title.contains(query, ignoreCase = true)
57+
}
58+
59+
if (filtered.isEmpty()) {
60+
SearchResultsState.Empty
61+
} else {
62+
SearchResultsState.Results(filtered)
63+
}
64+
}
65+
66+
else -> SearchResultsState.Recent
67+
}
68+
69+
70+
AnimatedContent(
71+
targetState = resultsState,
72+
transitionSpec = {
73+
(fadeIn() + slideInVertically { it / 8 }) togetherWith
74+
(fadeOut() + slideOutVertically { -it / 8 })
75+
},
76+
label = "SearchResultsAnimation"
77+
) { state ->
78+
79+
when (state) {
80+
SearchResultsState.Recent -> {
81+
RecentSearches(
82+
recentSearchList,
83+
onItemClick,
84+
onCloseClick
85+
)
86+
}
87+
88+
SearchResultsState.Empty -> {
89+
EmptyStateBox(
90+
icon = R.drawable.ic_kid_star,
91+
title = "No results yet."
92+
)
93+
}
94+
95+
is SearchResultsState.Results -> {
96+
Column {
97+
numResultsHeader?.invoke()
98+
99+
LazyColumn(
100+
verticalArrangement = Arrangement.spacedBy(16.dp)
101+
) {
102+
items(state.items) { item ->
103+
when (item) {
104+
is HighlightData.Video ->
105+
VideoHighlightCard(item.data, true)
106+
107+
is HighlightData.Article ->
108+
ArticleHighlightCard(item.data, true)
109+
}
110+
}
111+
}
112+
}
113+
}
114+
}
115+
}
116+
}
117+
}
118+
119+
/* Used to display number of results in on HighlightsSearchScreen*/
120+
@Composable
121+
fun HighlightsCardLazyColumnResultsHeader(
122+
size: Int
123+
) {
124+
Column {
125+
Text("$size Results", style = bodyNormal)
126+
Spacer(Modifier.height(16.dp))
127+
}
128+
}
129+
130+
@Preview
131+
@Composable
132+
private fun HighlightsCardLazyColumnSubScreenPreview() {
133+
ScorePreview {
134+
HighlightsCardLazyColumn(recentSearchList, "", highlightsList, {}, {})
135+
}
136+
}
137+
138+
@Preview
139+
@Composable
140+
private fun HighlightsCardLazyColumnSearchResultsPreview() {
141+
ScorePreview {
142+
HighlightsCardLazyColumn(
143+
recentSearchList, "hockey", highlightsList, {}, {},
144+
{ HighlightsCardLazyColumnResultsHeader(highlightsList.size) })
145+
}
146+
}

app/src/main/java/com/cornellappdev/score/components/highlights/HighlightsScreenHeader.kt

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package com.cornellappdev.score.components.highlights
2+
3+
import androidx.compose.foundation.layout.Column
4+
import androidx.compose.foundation.layout.Spacer
5+
import androidx.compose.foundation.layout.fillMaxWidth
6+
import androidx.compose.foundation.layout.height
7+
import androidx.compose.foundation.layout.padding
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.ui.Modifier
10+
import androidx.compose.ui.tooling.preview.Preview
11+
import androidx.compose.ui.unit.dp
12+
import com.cornellappdev.score.components.ScorePreview
13+
import com.cornellappdev.score.model.Sport
14+
import com.cornellappdev.score.util.sportList
15+
16+
@Composable
17+
fun HighlightsScreenSearchFilterBar(
18+
sportList: List<Sport>
19+
) {
20+
Column(modifier = Modifier.fillMaxWidth()) {
21+
HighlightsSearchBar(modifier = Modifier.padding(horizontal = 24.dp))
22+
Spacer(modifier = Modifier.height(16.dp))
23+
HighlightsFilterRow(sportList, {/*todo on filter selected*/ })
24+
}
25+
}
26+
27+
@Preview
28+
@Composable
29+
private fun HighlightsScreenSearchFilterBarPreview() {
30+
ScorePreview {
31+
HighlightsScreenSearchFilterBar(sportList)
32+
}
33+
}

0 commit comments

Comments
 (0)