Skip to content

Commit 8855cb7

Browse files
authored
Merge branch 'SunkenSplash:main' into main
2 parents b335d11 + bc6eaf5 commit 8855cb7

File tree

7 files changed

+256
-113
lines changed

7 files changed

+256
-113
lines changed

app/src/main/java/com/sunkensplashstudios/VRCRoboScout/EventDivisionMatchesView.kt

Lines changed: 105 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,113 @@ class EventDivisionMatchesViewModel: ViewModel() {
5050
var division by mutableStateOf(Division())
5151
}
5252

53+
@Composable
54+
fun MatchesView(matchList: List<Match>) {
55+
val timeFormat = java.text.SimpleDateFormat("h:mm a", java.util.Locale.getDefault())
56+
Column(
57+
modifier = Modifier.verticalScroll(rememberScrollState())
58+
) {
59+
Card(
60+
modifier = Modifier.padding(10.dp),
61+
colors = CardColors(
62+
containerColor = MaterialTheme.colorScheme.surfaceContainer.copy(alpha = 0.5f),
63+
disabledContainerColor = Color.Unspecified.copy(alpha = 0.5f),
64+
contentColor = MaterialTheme.colorScheme.onSurface,
65+
disabledContentColor = Color.Unspecified
66+
)
67+
) {
68+
Column(
69+
modifier = Modifier.padding(horizontal = 5.dp, vertical = 0.dp)
70+
) {
71+
(matchList).forEach { match ->
72+
Row(
73+
verticalAlignment = Alignment.CenterVertically
74+
) {
75+
Column(
76+
modifier = Modifier.width(65.dp),
77+
verticalArrangement = Arrangement.spacedBy((-3).dp)
78+
) {
79+
Text(
80+
text = match.shortName,
81+
fontSize = 16.sp,
82+
fontWeight = FontWeight.Bold,
83+
color = MaterialTheme.colorScheme.onSurface
84+
)
85+
Text(
86+
text = match.startedDate?.let { timeFormat.format(it) }
87+
?: match.scheduledDate?.let { timeFormat.format(it) }
88+
?: "",
89+
fontSize = 12.sp,
90+
color = MaterialTheme.colorScheme.onSurface
91+
)
92+
}
93+
Spacer(modifier = Modifier.width(10.dp))
94+
Row(
95+
verticalAlignment = Alignment.CenterVertically
96+
) {
97+
Column(
98+
horizontalAlignment = Alignment.CenterHorizontally,
99+
modifier = Modifier.width(60.dp),
100+
verticalArrangement = Arrangement.spacedBy((-5).dp)
101+
) {
102+
match.redAlliance.members.forEach{ member ->
103+
Text(
104+
text = member.team.name,
105+
fontSize = 15.sp,
106+
color = allianceRed
107+
)
108+
}
109+
}
110+
Spacer(modifier = Modifier.width(20.dp))
111+
Text(
112+
match.redScore.toString(),
113+
fontSize = 18.sp,
114+
fontWeight = FontWeight.Bold,
115+
color = allianceRed,
116+
textAlign = TextAlign.Start,
117+
modifier = Modifier.width(50.dp)
118+
)
119+
Spacer(modifier = Modifier.weight(1f))
120+
Text(
121+
match.blueScore.toString(),
122+
fontSize = 18.sp,
123+
fontWeight = FontWeight.Bold,
124+
color = allianceBlue,
125+
textAlign = TextAlign.End,
126+
modifier = Modifier.width(50.dp)
127+
)
128+
Spacer(modifier = Modifier.width(20.dp))
129+
Column(
130+
horizontalAlignment = Alignment.CenterHorizontally,
131+
modifier = Modifier.width(60.dp),
132+
verticalArrangement = Arrangement.spacedBy((-5).dp)
133+
) {
134+
match.blueAlliance.members.forEach{ member ->
135+
Text(
136+
text = member.team.name,
137+
fontSize = 15.sp,
138+
color = allianceBlue
139+
)
140+
}
141+
}
142+
}
143+
}
144+
if (match != matchList.last()) {
145+
HorizontalDivider(
146+
thickness = 0.5.dp,
147+
color = MaterialTheme.colorScheme.secondary.copy(alpha = 0.1f),
148+
)
149+
}
150+
}
151+
}
152+
}
153+
}
154+
}
155+
53156
@OptIn(ExperimentalMaterial3Api::class)
54157
@Destination
55158
@Composable
56159
fun EventDivisionMatchesView(event: Event, division: Division, eventDivisionMatchesViewModel: EventDivisionMatchesViewModel = viewModel(), navController: NavController) {
57-
val timeFormat = java.text.SimpleDateFormat("h:mm a", java.util.Locale.getDefault())
58160

59161
var loading by remember { mutableStateOf(event.matches[division] == null) }
60162

@@ -113,108 +215,11 @@ fun EventDivisionMatchesView(event: Event, division: Division, eventDivisionMatc
113215
if (loading) {
114216
LoadingView()
115217
}
116-
else if ((event.matches[division] ?: listOf()).isEmpty()) {
218+
else if ((event.matches[division] ?: emptyList()).isEmpty()) {
117219
NoDataView()
118220
}
119221
else {
120-
Column(
121-
modifier = Modifier.verticalScroll(rememberScrollState())
122-
) {
123-
Card(
124-
modifier = Modifier.padding(10.dp),
125-
colors = CardColors(
126-
containerColor = MaterialTheme.colorScheme.surfaceContainer.copy(alpha = 0.5f),
127-
disabledContainerColor = Color.Unspecified.copy(alpha = 0.5f),
128-
contentColor = MaterialTheme.colorScheme.onSurface,
129-
disabledContentColor = Color.Unspecified
130-
)
131-
) {
132-
Column(
133-
modifier = Modifier.padding(horizontal = 5.dp, vertical = 0.dp)
134-
) {
135-
(event.matches[division] ?: emptyList()).forEach { match ->
136-
Row(
137-
verticalAlignment = Alignment.CenterVertically
138-
) {
139-
Column(
140-
modifier = Modifier.width(65.dp),
141-
verticalArrangement = Arrangement.spacedBy((-3).dp)
142-
) {
143-
Text(
144-
text = match.shortName,
145-
fontSize = 16.sp,
146-
fontWeight = FontWeight.Bold,
147-
color = MaterialTheme.colorScheme.onSurface
148-
)
149-
Text(
150-
text = match.startedDate?.let { timeFormat.format(it) }
151-
?: match.scheduledDate?.let { timeFormat.format(it) }
152-
?: "",
153-
fontSize = 12.sp,
154-
color = MaterialTheme.colorScheme.onSurface
155-
)
156-
}
157-
Spacer(modifier = Modifier.width(10.dp))
158-
Row(
159-
verticalAlignment = Alignment.CenterVertically
160-
) {
161-
Column(
162-
horizontalAlignment = Alignment.CenterHorizontally,
163-
modifier = Modifier.width(60.dp),
164-
verticalArrangement = Arrangement.spacedBy((-5).dp)
165-
) {
166-
match.redAlliance.members.forEach{ member ->
167-
Text(
168-
text = member.team.name,
169-
fontSize = 15.sp,
170-
color = allianceRed
171-
)
172-
}
173-
}
174-
Spacer(modifier = Modifier.width(20.dp))
175-
Text(
176-
match.redScore.toString(),
177-
fontSize = 18.sp,
178-
fontWeight = FontWeight.Bold,
179-
color = allianceRed,
180-
textAlign = TextAlign.Start,
181-
modifier = Modifier.width(50.dp)
182-
)
183-
Spacer(modifier = Modifier.weight(1f))
184-
Text(
185-
match.blueScore.toString(),
186-
fontSize = 18.sp,
187-
fontWeight = FontWeight.Bold,
188-
color = allianceBlue,
189-
textAlign = TextAlign.End,
190-
modifier = Modifier.width(50.dp)
191-
)
192-
Spacer(modifier = Modifier.width(20.dp))
193-
Column(
194-
horizontalAlignment = Alignment.CenterHorizontally,
195-
modifier = Modifier.width(60.dp),
196-
verticalArrangement = Arrangement.spacedBy((-5).dp)
197-
) {
198-
match.blueAlliance.members.forEach{ member ->
199-
Text(
200-
text = member.team.name,
201-
fontSize = 15.sp,
202-
color = allianceBlue
203-
)
204-
}
205-
}
206-
}
207-
}
208-
if (match != event.matches[division]?.last()) {
209-
HorizontalDivider(
210-
thickness = 0.5.dp,
211-
color = MaterialTheme.colorScheme.secondary.copy(alpha = 0.1f),
212-
)
213-
}
214-
}
215-
}
216-
}
217-
}
222+
MatchesView(event.matches[division] ?: emptyList())
218223
}
219224
}
220225
}
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package com.sunkensplashstudios.VRCRoboScout
2+
3+
import androidx.compose.foundation.clickable
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.fillMaxSize
6+
import androidx.compose.foundation.layout.padding
7+
import androidx.compose.material.icons.Icons
8+
import androidx.compose.material.icons.automirrored.filled.ArrowBackIos
9+
import androidx.compose.material3.CenterAlignedTopAppBar
10+
import androidx.compose.material3.ExperimentalMaterial3Api
11+
import androidx.compose.material3.Icon
12+
import androidx.compose.material3.MaterialTheme
13+
import androidx.compose.material3.Scaffold
14+
import androidx.compose.material3.Text
15+
import androidx.compose.material3.TopAppBarDefaults
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.LaunchedEffect
18+
import androidx.compose.runtime.getValue
19+
import androidx.compose.runtime.mutableStateOf
20+
import androidx.compose.runtime.remember
21+
import androidx.compose.runtime.setValue
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.text.font.FontWeight
24+
import androidx.compose.ui.unit.dp
25+
import androidx.lifecycle.ViewModel
26+
import androidx.lifecycle.viewmodel.compose.viewModel
27+
import androidx.navigation.NavController
28+
import com.ramcosta.composedestinations.annotation.Destination
29+
import com.sunkensplashstudios.VRCRoboScout.ui.theme.*
30+
import kotlinx.coroutines.CoroutineScope
31+
import kotlinx.coroutines.Dispatchers
32+
import kotlinx.coroutines.launch
33+
import kotlinx.coroutines.withContext
34+
35+
class EventTeamMatchesViewModel: ViewModel() {
36+
var event by mutableStateOf(Event())
37+
var team by mutableStateOf(Team())
38+
var loading by mutableStateOf(true)
39+
var matches by mutableStateOf(listOf<Match>())
40+
}
41+
42+
@OptIn(ExperimentalMaterial3Api::class)
43+
@Destination
44+
@Composable
45+
fun EventTeamMatchesView(event: Event, team: Team, eventTeamMatchesViewModel: EventTeamMatchesViewModel = viewModel(), navController: NavController) {
46+
47+
fun updateMatches() {
48+
if (eventTeamMatchesViewModel.matches.isEmpty()) {
49+
eventTeamMatchesViewModel.loading = true
50+
}
51+
CoroutineScope(Dispatchers.Default).launch {
52+
eventTeamMatchesViewModel.matches = team.matchesAt(event)
53+
withContext(Dispatchers.Main) {
54+
eventTeamMatchesViewModel.loading = false
55+
}
56+
}
57+
}
58+
59+
LaunchedEffect(Unit) {
60+
eventTeamMatchesViewModel.event = event
61+
eventTeamMatchesViewModel.team = team
62+
}
63+
64+
Scaffold(
65+
topBar = {
66+
CenterAlignedTopAppBar(
67+
colors = TopAppBarDefaults.topAppBarColors(
68+
containerColor = MaterialTheme.colorScheme.topContainer,
69+
titleContentColor = MaterialTheme.colorScheme.onTopContainer,
70+
),
71+
title = {
72+
Text("${eventTeamMatchesViewModel.team.number} Match List", fontWeight = FontWeight.Bold)
73+
},
74+
navigationIcon = {
75+
Icon(
76+
Icons.AutoMirrored.Filled.ArrowBackIos,
77+
contentDescription = "Back",
78+
modifier = Modifier.padding(10.dp).clickable {
79+
navController.navigateUp()
80+
},
81+
tint = MaterialTheme.colorScheme.onTopContainer
82+
)
83+
}
84+
)
85+
}
86+
) { padding ->
87+
Column(
88+
modifier = Modifier
89+
.padding(padding)
90+
.fillMaxSize()
91+
) {
92+
var update by remember { mutableStateOf(true) }
93+
94+
if (update) {
95+
update = false
96+
updateMatches()
97+
}
98+
99+
if (eventTeamMatchesViewModel.loading) {
100+
LoadingView()
101+
}
102+
else if ((eventTeamMatchesViewModel.matches).isEmpty()) {
103+
NoDataView()
104+
}
105+
else {
106+
MatchesView(eventTeamMatchesViewModel.matches)
107+
}
108+
}
109+
}
110+
}

app/src/main/java/com/sunkensplashstudios/VRCRoboScout/EventView.kt

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ import com.ramcosta.composedestinations.navigation.navigate
5353
import com.sunkensplashstudios.VRCRoboScout.destinations.EventDivisionViewDestination
5454
import com.sunkensplashstudios.VRCRoboScout.destinations.EventInformationViewDestination
5555
import com.sunkensplashstudios.VRCRoboScout.destinations.EventSkillsRankingsViewDestination
56+
import com.sunkensplashstudios.VRCRoboScout.destinations.EventTeamMatchesViewDestination
5657
import com.sunkensplashstudios.VRCRoboScout.destinations.EventTeamsViewDestination
5758
import com.sunkensplashstudios.VRCRoboScout.ui.theme.*
5859

@@ -69,7 +70,7 @@ class EventViewModel: ViewModel() {
6970
@OptIn(ExperimentalMaterial3Api::class)
7071
@Destination
7172
@Composable
72-
fun EventView(eventViewModel: EventViewModel = viewModel(), navController: NavController, event: Event) {
73+
fun EventView(eventViewModel: EventViewModel = viewModel(), navController: NavController, event: Event, team: Team? = null) {
7374

7475
fun getEventViewModel() {
7576
if (eventViewModelStore.getEventViewModel(event) != null) {
@@ -241,6 +242,30 @@ fun EventView(eventViewModel: EventViewModel = viewModel(), navController: NavCo
241242
contentDescription = "Show Event Teams"
242243
)
243244
}
245+
if (team != null) {
246+
HorizontalDivider(
247+
thickness = 0.5.dp,
248+
color = MaterialTheme.colorScheme.secondary.copy(alpha = 0.1f),
249+
)
250+
Row(
251+
horizontalArrangement = Arrangement.SpaceBetween,
252+
verticalAlignment = Alignment.CenterVertically,
253+
modifier = Modifier.clickable {
254+
navController.navigate(
255+
EventTeamMatchesViewDestination(eventViewModel.event, team)
256+
)
257+
}
258+
) {
259+
Text("${team.number} Match List")
260+
Spacer(modifier = Modifier.weight(1.0f))
261+
Icon(
262+
Icons.AutoMirrored.Filled.ArrowForwardIos,
263+
modifier = Modifier.size(15.dp),
264+
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.3f),
265+
contentDescription = "Show ${team.number} Match List"
266+
)
267+
}
268+
}
244269
}
245270
}
246271
Spacer(modifier = Modifier.height(10.dp))

app/src/main/java/com/sunkensplashstudios/VRCRoboScout/FavoritesView.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,7 @@ fun FavoritesView(favoritesViewModel: FavoritesViewModel = viewModels["favorites
257257
.padding(5.dp)
258258
.clickable {
259259
navController.navigate(
260-
EventViewDestination(
261-
event
262-
)
260+
EventViewDestination(event)
263261
)
264262
}
265263
) {

0 commit comments

Comments
 (0)