Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 4 additions & 7 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,15 @@ android {

dependencies {
// Jetpack Compose dependencies
implementation(platform("androidx.compose:compose-bom:2024.09.00"))
implementation("androidx.compose.material3:material3")
implementation("androidx.compose.ui:ui:1.9.4")
implementation("androidx.compose.ui:ui-tooling-preview:1.4.3")
implementation(platform("androidx.compose:compose-bom:2025.11.01"))
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.activity:activity-compose")
implementation("androidx.lifecycle:lifecycle-viewmodel-compose")
implementation("androidx.navigation:navigation-compose:2.8.2")
implementation(libs.material3)
implementation("com.google.dagger:hilt-android:2.51.1")
implementation(libs.androidx.material3)
implementation(libs.androidx.foundation.layout)
kapt("com.google.dagger:hilt-android-compiler:2.51.1")
implementation("androidx.hilt:hilt-navigation-compose:1.0.0")
implementation("com.google.accompanist:accompanist-pager:0.24.0-alpha")
Expand All @@ -80,15 +79,13 @@ dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.appcompat)
implementation(libs.material)
implementation("io.coil-kt:coil-compose:2.0.0")
implementation(libs.androidx.activity)
implementation(libs.androidx.constraintlayout)
implementation(libs.androidx.runtime.android)
testImplementation(libs.junit)
debugImplementation("androidx.compose.ui:ui-tooling")
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
implementation(libs.apollo.runtime)
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.1")
implementation(libs.apollo.runtime)
implementation("io.coil-kt.coil3:coil-compose:3.1.0")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package com.cornellappdev.score.components.highlights

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.cornellappdev.score.R
import com.cornellappdev.score.components.EmptyStateBox
import com.cornellappdev.score.components.ScorePreview
import com.cornellappdev.score.model.HighlightData
import com.cornellappdev.score.theme.Style.bodyNormal
import com.cornellappdev.score.util.highlightsList
import com.cornellappdev.score.util.recentSearchList

@Composable
fun HighlightsCardLazyColumn(
recentSearchList: List<String>,
query: String,
highlightsList: List<HighlightData>,
numResultsHeader: (@Composable () -> Unit)? = null
) {
Column(
modifier = Modifier.padding(horizontal = 24.dp)
) {
if (recentSearchList.isNotEmpty() && query.isEmpty()) { //start state: no search attempted yet
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: It could be potentially worth considering using something like animatedcontent here to have more control over the transition between recent searches content and the search results

RecentSearches(recentSearchList)
} else if (query.isNotEmpty()) { //filtering - will pull this out to the viewmodel when i do that, just here for sanity check rn
val filteredList = highlightsList.filter {
it.title.contains(query, ignoreCase = true)
}
if (filteredList.isEmpty()) {
EmptyStateBox(
icon = R.drawable.ic_kid_star,
title = "No results yet.",
)
} else {
numResultsHeader?.invoke()
LazyColumn(
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(highlightsList) { item ->
when (item) {
is HighlightData.Video -> VideoHighlightCard(item.data, true)
is HighlightData.Article -> ArticleHighlightCard(item.data, true)
}
}
}
}
}
}
}

/* Used to display number of results in on HighlightsSearchScreen*/
@Composable
fun HighlightsCardLazyColumnNumResultsHeader(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: probably don't need to abbreviate num or can potentially just remove num

size: Int
) {
Column {
Text("$size Results", style = bodyNormal)
Spacer(Modifier.height(16.dp))
}
}

@Preview
@Composable
private fun HighlightsCardLazyColumnSubScreenPreview() {
ScorePreview {
HighlightsCardLazyColumn(recentSearchList, "", highlightsList)
}
}

@Preview
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: might be good to have a preview or preview parameter where we can see the highlights list as well instead of just recent searches

@Composable
private fun HighlightsCardLazyColumnSearchResultsPreview() {
ScorePreview {
HighlightsCardLazyColumn(
recentSearchList, "", highlightsList,
{ HighlightsCardLazyColumnNumResultsHeader(highlightsList.size) })
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package com.cornellappdev.score.components.highlights

import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.cornellappdev.score.components.ScorePreview
import com.cornellappdev.score.model.Sport
import com.cornellappdev.score.theme.Style.bodyMedium
import com.cornellappdev.score.util.sportList

@Composable
fun HighlightsScreenSearchFilterBar(
sportList: List<Sport>
) {
val focusManager = LocalFocusManager.current
var isFocused by remember { mutableStateOf(true) } //todo: should probably be handled by viewModel
Column(modifier = Modifier.fillMaxWidth()) {
Row(
modifier = Modifier
.padding(horizontal = 24.dp)
.clip(shape = RoundedCornerShape(100.dp))
.onFocusChanged { focusState ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this ideal to have here or if we can just pass in some sort of onFocus function/logic to the search bar component

if (focusState.isFocused && !isFocused) {
/*todo clear the highlight rows and show recent searches*/
}
},
horizontalArrangement = Arrangement.spacedBy(12.dp),
verticalAlignment = Alignment.CenterVertically
) {
HighlightsSearchBar(
onSearchClick = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is needed here if we have the focus change detection in the search bar itself? Maybe you can pass in an onFocus function?

isFocused = true
},
modifier = Modifier
.weight(1f)
.onFocusChanged { state ->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is necessary if we have the logic in the text field?

// When the search bar loses focus, hide cancel
if (!state.isFocused) {
isFocused = !isFocused
}
}
)

AnimatedVisibility(
isFocused
) {
Text(
"Cancel",
style = bodyMedium,
modifier = Modifier.clickable {
isFocused = true;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be false?

focusManager.clearFocus(force = true)
/*todo: clear the text in the search bar*/
}
)
}
}
Spacer(modifier = Modifier.height(16.dp))
HighlightsFilterRow(sportList, {/*todo on filter selected*/ })
}
}

@Preview
@Composable
private fun HighlightsScreenSearchFilterBarActivePreview() {
ScorePreview {
HighlightsScreenSearchFilterBar(sportList)
}
}

@Preview
@Composable
private fun HighlightsScreenSearchFilterBarInactivePreview() {
ScorePreview {
HighlightsScreenSearchFilterBar(sportList)
}
}
Loading
Loading