Skip to content

Commit 5416e4f

Browse files
committed
feat: Add sorting functionality for player statistics
1 parent 0b6067c commit 5416e4f

File tree

14 files changed

+557
-49
lines changed

14 files changed

+557
-49
lines changed

.github/workflows/release.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ permissions:
1010
contents: write
1111

1212
jobs:
13-
build:
13+
release:
1414
runs-on: ubuntu-latest
1515
steps:
1616
- name: Checkout project

PRIVACY_POLICY.md renamed to PRIVACY.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Welcome to the Brawlhalla Stats app for Android!
66

77
This open-source Android application is developed by NicKoehler.
8-
The source code is available on GitHub under the MIT License.
8+
The source code is available on GitHub under the GPL3 License.
99

1010
## Data Collection and Usage
1111

app/build.gradle.kts

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ android {
2020
applicationId = "com.nickoehler.brawlhalla"
2121
minSdk = 26
2222
targetSdk = 35
23-
versionCode = 1
24-
versionName = "0.0.1"
23+
versionCode = 2
24+
versionName = "0.0.2"
2525
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
2626
}
2727

@@ -117,4 +117,4 @@ dependencies {
117117
implementation(libs.androidx.room.ktx)
118118
implementation(libs.aboutlibraries.compose.m3)
119119
ksp(libs.androidx.room.compiler)
120-
}
120+
}

app/src/main/java/com/nickoehler/brawlhalla/MainActivity.kt

+4-9
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import com.nickoehler.brawlhalla.info.presentation.screens.InfoScreen
3838
import com.nickoehler.brawlhalla.info.presentation.screens.LicensesScreen
3939
import com.nickoehler.brawlhalla.legends.presentation.LegendsViewModel
4040
import com.nickoehler.brawlhalla.legends.presentation.screens.AdaptiveLegendsPane
41-
import com.nickoehler.brawlhalla.ranking.presentation.StatDetailAction
4241
import com.nickoehler.brawlhalla.ranking.presentation.StatDetailViewModel
4342
import com.nickoehler.brawlhalla.ranking.presentation.screens.AdaptiveRankingPane
4443
import com.nickoehler.brawlhalla.ranking.presentation.screens.StatDetailScreen
@@ -128,19 +127,15 @@ class MainActivity : ComponentActivity() {
128127

129128
StatDetailScreen(
130129
state,
131-
onStatDetailAction = { action ->
132-
statDetailViewModel.onStatDetailAction(action)
133-
if (action is StatDetailAction.SelectClan) {
134-
navController.navigate(
135-
Route.Clan(action.clanId)
136-
)
137-
}
138-
},
130+
onStatDetailAction = statDetailViewModel::onStatDetailAction,
139131
onBack = { navController.popBackStack() },
140132
events = statDetailViewModel.uiEvents,
141133
onPlayerSelection = { brawlhallaId ->
142134
navController.navigate(Route.Stat(brawlhallaId))
143135
},
136+
onClanSelection = { clanId ->
137+
navController.navigate(Route.Clan(clanId))
138+
}
144139
)
145140
}
146141
composable<Route.Rankings> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.nickoehler.brawlhalla.core.presentation.components
2+
3+
import androidx.compose.animation.core.animateFloatAsState
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.ColumnScope
9+
import androidx.compose.foundation.layout.Row
10+
import androidx.compose.foundation.layout.fillMaxWidth
11+
import androidx.compose.foundation.layout.padding
12+
import androidx.compose.foundation.shape.CircleShape
13+
import androidx.compose.material.icons.Icons
14+
import androidx.compose.material.icons.filled.KeyboardArrowDown
15+
import androidx.compose.material.icons.filled.Mode
16+
import androidx.compose.material3.DropdownMenu
17+
import androidx.compose.material3.Icon
18+
import androidx.compose.material3.IconButton
19+
import androidx.compose.material3.MaterialTheme
20+
import androidx.compose.material3.Surface
21+
import androidx.compose.material3.Text
22+
import androidx.compose.runtime.Composable
23+
import androidx.compose.runtime.getValue
24+
import androidx.compose.ui.Alignment
25+
import androidx.compose.ui.Modifier
26+
import androidx.compose.ui.draw.clip
27+
import androidx.compose.ui.draw.rotate
28+
import androidx.compose.ui.graphics.vector.ImageVector
29+
import androidx.compose.ui.tooling.preview.Preview
30+
import androidx.compose.ui.unit.dp
31+
import com.nickoehler.brawlhalla.ui.theme.BrawlhallaTheme
32+
33+
@Composable
34+
fun CustomSortDropDownMenu(
35+
modifier: Modifier = Modifier,
36+
reversed: Boolean,
37+
expanded: Boolean,
38+
icon: ImageVector,
39+
onSortClick: () -> Unit,
40+
onReversedClick: () -> Unit,
41+
selected: @Composable () -> Unit,
42+
content: @Composable (ColumnScope.() -> Unit),
43+
) {
44+
val rotation by animateFloatAsState(if (reversed) 180f else 0f)
45+
46+
Box(
47+
modifier = modifier,
48+
) {
49+
Row(
50+
modifier = Modifier.fillMaxWidth(),
51+
horizontalArrangement = Arrangement.SpaceBetween,
52+
verticalAlignment = Alignment.CenterVertically
53+
) {
54+
Row(
55+
modifier = Modifier
56+
.clip(CircleShape)
57+
.clickable { onSortClick() }
58+
.background(MaterialTheme.colorScheme.surfaceContainer)
59+
.padding(16.dp),
60+
horizontalArrangement = Arrangement.spacedBy(8.dp),
61+
verticalAlignment = Alignment.CenterVertically
62+
) {
63+
Icon(icon, null)
64+
selected()
65+
}
66+
IconButton(
67+
onReversedClick,
68+
modifier = Modifier
69+
.clip(CircleShape)
70+
.background(MaterialTheme.colorScheme.surfaceContainer)
71+
) {
72+
Icon(
73+
Icons.Default.KeyboardArrowDown,
74+
null,
75+
modifier = Modifier
76+
.rotate(rotation)
77+
)
78+
}
79+
}
80+
DropdownMenu(
81+
expanded = expanded,
82+
onDismissRequest = { onSortClick() }
83+
) {
84+
content()
85+
}
86+
}
87+
}
88+
89+
@Preview
90+
@Composable
91+
private fun CustomSortDropDownMenuPreview() {
92+
BrawlhallaTheme {
93+
Surface {
94+
CustomSortDropDownMenu(
95+
reversed = true,
96+
expanded = true,
97+
icon = Icons.Default.Mode,
98+
selected = {
99+
Text("test")
100+
},
101+
onSortClick = {},
102+
onReversedClick = {},
103+
) {
104+
Text("test")
105+
}
106+
}
107+
}
108+
}

app/src/main/java/com/nickoehler/brawlhalla/legends/presentation/models/FilterOptions.kt

-9
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,12 @@ package com.nickoehler.brawlhalla.legends.presentation.models
22

33
import android.content.Context
44
import com.nickoehler.brawlhalla.R
5-
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingLegendUi
6-
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingUi
7-
import com.nickoehler.brawlhalla.ranking.presentation.models.StatLegendUi
85

96
enum class FilterOptions {
107
WEAPONS,
118
STATS
129
}
1310

14-
sealed interface RankingModalType {
15-
data class StatLegend(val statLegend: StatLegendUi) : RankingModalType
16-
data class Team(val team: RankingUi.RankingTeamUi) : RankingModalType
17-
data class RankingLegend(val legend: RankingLegendUi) : RankingModalType
18-
}
19-
2011
fun FilterOptions.toLocalizedString(context: Context): String {
2112
return context.getString(
2213
when (this) {
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package com.nickoehler.brawlhalla.ranking.presentation
22

3-
import com.nickoehler.brawlhalla.legends.presentation.models.RankingModalType
43
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingFilterType
4+
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingModalType
5+
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingSortType
56
import com.nickoehler.brawlhalla.ranking.presentation.models.StatFilterType
67
import com.nickoehler.brawlhalla.ranking.presentation.models.StatType
78

89
sealed interface StatDetailAction {
910
data class SelectPlayer(val brawlhallaId: Int) : StatDetailAction
1011
data class SelectStatType(val stat: StatType) : StatDetailAction
11-
data class SelectClan(val clanId: Int) : StatDetailAction
1212
data class SelectRankingFilterType(val type: RankingFilterType) : StatDetailAction
1313
data class SelectStatFilterType(val type: StatFilterType) : StatDetailAction
1414
data class TogglePlayerFavorites(val brawlhallaId: Int, val name: String) : StatDetailAction
1515
data class SelectRankingModalType(val modalType: RankingModalType?) : StatDetailAction
16+
data class SortBy(val sortType: RankingSortType) : StatDetailAction
17+
data object StatLegendSortTypeReversed : StatDetailAction
18+
data object RankingLegendSortTypeReversed : StatDetailAction
19+
data object TeamSortTypeReversed : StatDetailAction
1620
}

app/src/main/java/com/nickoehler/brawlhalla/ranking/presentation/StatDetailState.kt

+11-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
package com.nickoehler.brawlhalla.ranking.presentation
22

33
import androidx.compose.runtime.Immutable
4-
import com.nickoehler.brawlhalla.legends.presentation.models.RankingModalType
4+
import com.nickoehler.brawlhalla.ranking.presentation.models.GeneralRankingSortType
55
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingDetailUi
66
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingFilterType
7+
import com.nickoehler.brawlhalla.ranking.presentation.models.RankingModalType
78
import com.nickoehler.brawlhalla.ranking.presentation.models.StatDetailUi
89
import com.nickoehler.brawlhalla.ranking.presentation.models.StatFilterType
10+
import com.nickoehler.brawlhalla.ranking.presentation.models.StatLegendSortType
911
import com.nickoehler.brawlhalla.ranking.presentation.models.StatType
1012

1113
@Immutable
@@ -22,4 +24,12 @@ data class StatDetailState(
2224
val selectedRankingFilterType: RankingFilterType = RankingFilterType.Stat,
2325
val rankingEnabled: Boolean = true,
2426
val modalType: RankingModalType? = null,
27+
28+
val statLegendSortType: StatLegendSortType = StatLegendSortType.Alpha,
29+
val rankedLegendSortType: GeneralRankingSortType = GeneralRankingSortType.Alpha,
30+
val teamSortType: GeneralRankingSortType = GeneralRankingSortType.Alpha,
31+
32+
val statLegendSortReversed: Boolean = false,
33+
val rankedLegendSortReversed: Boolean = false,
34+
val teamSortReversed: Boolean = false,
2535
)

0 commit comments

Comments
 (0)