This commit is contained in:
@@ -7,9 +7,7 @@ import androidx.annotation.StringRes
|
|||||||
import androidx.compose.foundation.layout.*
|
import androidx.compose.foundation.layout.*
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.*
|
import androidx.compose.material.icons.filled.*
|
||||||
import androidx.compose.material.icons.outlined.Calculate
|
import androidx.compose.material.icons.outlined.*
|
||||||
import androidx.compose.material.icons.outlined.List
|
|
||||||
import androidx.compose.material.icons.outlined.Settings
|
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
@@ -27,12 +25,24 @@ import androidx.navigation.compose.rememberNavController
|
|||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import me.zobrist.tichucounter.domain.TopBarAction
|
||||||
|
import me.zobrist.tichucounter.repository.GameRepository
|
||||||
|
import me.zobrist.tichucounter.ui.MainViewModel
|
||||||
import me.zobrist.tichucounter.ui.counter.*
|
import me.zobrist.tichucounter.ui.counter.*
|
||||||
|
import me.zobrist.tichucounter.ui.history.HistoryList
|
||||||
|
import me.zobrist.tichucounter.ui.history.HistoryViewModel
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class MainActivity : BaseActivity() {
|
class MainActivity : BaseActivity() {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var gameRepository: GameRepository
|
||||||
|
|
||||||
private val counterViewModel: CounterViewModel by viewModels()
|
private val counterViewModel: CounterViewModel by viewModels()
|
||||||
|
private val historyViewModel: HistoryViewModel by viewModels()
|
||||||
|
private val mainViewModel: MainViewModel by viewModels()
|
||||||
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -52,7 +62,7 @@ class MainActivity : BaseActivity() {
|
|||||||
|
|
||||||
MaterialTheme() {
|
MaterialTheme() {
|
||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = { TopBar(drawerState, scope) }) {
|
topBar = { TopBar(drawerState, scope, mainViewModel.topBarActions) }) {
|
||||||
|
|
||||||
NavHost(
|
NavHost(
|
||||||
navController = navController,
|
navController = navController,
|
||||||
@@ -61,16 +71,18 @@ class MainActivity : BaseActivity() {
|
|||||||
) {
|
) {
|
||||||
composable("counter") {
|
composable("counter") {
|
||||||
Counter(counterViewModel)
|
Counter(counterViewModel)
|
||||||
|
mainViewModel.setActions(listOf(undoAction, newGameAction))
|
||||||
}
|
}
|
||||||
composable("history") {
|
composable("history") {
|
||||||
Column() {
|
HistoryList(historyViewModel)
|
||||||
Text("History")
|
mainViewModel.setActions(emptyList())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
composable("settings") {
|
composable("settings") {
|
||||||
Column() {
|
Column() {
|
||||||
Text("Settings")
|
Text("Settings")
|
||||||
}
|
}
|
||||||
|
mainViewModel.setActions(emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -79,11 +91,15 @@ class MainActivity : BaseActivity() {
|
|||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@Composable
|
@Composable
|
||||||
private fun TopBar(drawerState: DrawerState, scope: CoroutineScope) {
|
private fun TopBar(
|
||||||
|
drawerState: DrawerState,
|
||||||
|
scope: CoroutineScope,
|
||||||
|
actions: List<TopBarAction>
|
||||||
|
) {
|
||||||
CenterAlignedTopAppBar(
|
CenterAlignedTopAppBar(
|
||||||
title = {
|
title = {
|
||||||
Text(
|
Text(
|
||||||
"Centered TopAppBar",
|
stringResource(R.string.app_name),
|
||||||
maxLines = 1,
|
maxLines = 1,
|
||||||
overflow = TextOverflow.Ellipsis
|
overflow = TextOverflow.Ellipsis
|
||||||
)
|
)
|
||||||
@@ -97,11 +113,13 @@ class MainActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
actions = {
|
actions = {
|
||||||
IconButton(onClick = { /* doSomething() */ }) {
|
actions.forEach {
|
||||||
Icon(
|
IconButton(onClick = { it.action() }) {
|
||||||
imageVector = Icons.Filled.Favorite,
|
Icon(
|
||||||
contentDescription = "Localized description"
|
imageVector = it.imageVector,
|
||||||
)
|
contentDescription = null
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -160,4 +178,9 @@ class MainActivity : BaseActivity() {
|
|||||||
object Settings : Screen("settings", Icons.Outlined.Settings, R.string.menu_settings)
|
object Settings : Screen("settings", Icons.Outlined.Settings, R.string.menu_settings)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private val undoAction = TopBarAction(Icons.Outlined.Undo) { mainViewModel.undoLastRound() }
|
||||||
|
private val newGameAction = TopBarAction(Icons.Outlined.Add) { mainViewModel.newGame() }
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package me.zobrist.tichucounter.domain
|
||||||
|
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
|
|
||||||
|
class TopBarAction(val imageVector: ImageVector, val action: () -> Unit)
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package me.zobrist.tichucounter.ui
|
||||||
|
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.lifecycle.ViewModel
|
||||||
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import me.zobrist.tichucounter.domain.TopBarAction
|
||||||
|
import me.zobrist.tichucounter.repository.GameRepository
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
@HiltViewModel
|
||||||
|
class MainViewModel @Inject constructor(private val gameRepository: GameRepository) : ViewModel() {
|
||||||
|
|
||||||
|
var topBarTitle by mutableStateOf("")
|
||||||
|
var topBarActions by mutableStateOf(emptyList<TopBarAction>())
|
||||||
|
private set
|
||||||
|
|
||||||
|
fun setActions(actions: List<TopBarAction>) {
|
||||||
|
topBarActions = actions
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setTitle(title: String) {
|
||||||
|
topBarTitle = title
|
||||||
|
}
|
||||||
|
|
||||||
|
fun undoLastRound() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
gameRepository.revertLastRound()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun newGame() {
|
||||||
|
viewModelScope.launch {
|
||||||
|
gameRepository.newGame()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,126 +0,0 @@
|
|||||||
package me.zobrist.tichucounter.ui.history
|
|
||||||
|
|
||||||
|
|
||||||
import android.os.Bundle
|
|
||||||
import android.view.LayoutInflater
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.compose.foundation.layout.Column
|
|
||||||
import androidx.compose.foundation.layout.Row
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
|
||||||
import androidx.compose.foundation.layout.padding
|
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
|
||||||
import androidx.compose.foundation.lazy.items
|
|
||||||
import androidx.compose.material3.Card
|
|
||||||
import androidx.compose.material3.MaterialTheme
|
|
||||||
import androidx.compose.material3.Text
|
|
||||||
import androidx.compose.runtime.Composable
|
|
||||||
import androidx.compose.ui.Modifier
|
|
||||||
import androidx.compose.ui.platform.ComposeView
|
|
||||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.fragment.app.Fragment
|
|
||||||
import androidx.fragment.app.activityViewModels
|
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
|
||||||
import me.zobrist.tichucounter.data.GameAndScore
|
|
||||||
import java.text.DateFormat
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A fragment representing a list of Items.
|
|
||||||
*/
|
|
||||||
@AndroidEntryPoint
|
|
||||||
class HistoryFragment : Fragment() {
|
|
||||||
|
|
||||||
private val viewModel: HistoryFragmentViewModel by activityViewModels()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
|
||||||
inflater: LayoutInflater,
|
|
||||||
container: ViewGroup?,
|
|
||||||
savedInstanceState: Bundle?
|
|
||||||
): View {
|
|
||||||
return ComposeView(requireContext()).apply {
|
|
||||||
// Dispose of the Composition when the view's LifecycleOwner
|
|
||||||
// is destroyed
|
|
||||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
|
||||||
setContent {
|
|
||||||
MaterialTheme {
|
|
||||||
HistoryList(viewModel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun HistoryList(viewModel: HistoryFragmentViewModel) {
|
|
||||||
HistoryList(viewModel.gameAndHistory)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun HistoryList(games: List<GameAndScore>) {
|
|
||||||
LazyColumn {
|
|
||||||
items(games) {
|
|
||||||
HistoryListItem(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Composable
|
|
||||||
fun HistoryListItem(game: GameAndScore) {
|
|
||||||
val format =
|
|
||||||
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
|
|
||||||
|
|
||||||
Card(
|
|
||||||
modifier = Modifier
|
|
||||||
.fillMaxWidth()
|
|
||||||
.padding(all = 4.dp),
|
|
||||||
) {
|
|
||||||
Column(
|
|
||||||
Modifier
|
|
||||||
.padding(all = 12.dp),
|
|
||||||
) {
|
|
||||||
Row() {
|
|
||||||
Text(
|
|
||||||
text = game.nameA,
|
|
||||||
style = MaterialTheme.typography.headlineSmall
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = game.scoreA.toString(),
|
|
||||||
style = MaterialTheme.typography.headlineSmall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Row() {
|
|
||||||
Text(
|
|
||||||
text = game.nameB,
|
|
||||||
style = MaterialTheme.typography.headlineSmall
|
|
||||||
)
|
|
||||||
Text(
|
|
||||||
text = game.scoreB.toString(),
|
|
||||||
style = MaterialTheme.typography.headlineSmall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
Row() {
|
|
||||||
Text(
|
|
||||||
text = format.format(game.modified),
|
|
||||||
style = MaterialTheme.typography.labelSmall
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Preview
|
|
||||||
@Composable
|
|
||||||
private fun HistoryListPreview() {
|
|
||||||
val tempData = listOf<GameAndScore>(
|
|
||||||
GameAndScore(false, "abc", "def", Date(), Date(), 1, 10, 50),
|
|
||||||
GameAndScore(true, "ADTH", "dogfg", Date(), Date(), 2, 20, 60),
|
|
||||||
GameAndScore(false, "TeamA3", "TeamB3", Date(), Date(), 3, 30, 70),
|
|
||||||
GameAndScore(false, "TeamA4", "TeamB4", Date(), Date(), 4, 40, 80),
|
|
||||||
GameAndScore(false, "TeamA5", "TeamB5", Date(), Date(), 5, 50, 90)
|
|
||||||
)
|
|
||||||
HistoryList(tempData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package me.zobrist.tichucounter.ui.history
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
import androidx.compose.foundation.lazy.items
|
||||||
|
import androidx.compose.material3.Card
|
||||||
|
import androidx.compose.material3.MaterialTheme
|
||||||
|
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 me.zobrist.tichucounter.data.GameAndScore
|
||||||
|
import java.text.DateFormat
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryList(viewModel: HistoryViewModel) {
|
||||||
|
HistoryList(viewModel.gameAndHistory)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryList(games: List<GameAndScore>) {
|
||||||
|
LazyColumn {
|
||||||
|
items(games) {
|
||||||
|
HistoryListItem(it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun HistoryListItem(game: GameAndScore) {
|
||||||
|
val format =
|
||||||
|
DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT, Locale.getDefault())
|
||||||
|
|
||||||
|
Card(
|
||||||
|
modifier = Modifier
|
||||||
|
.fillMaxWidth()
|
||||||
|
.padding(all = 4.dp),
|
||||||
|
) {
|
||||||
|
Column(
|
||||||
|
Modifier
|
||||||
|
.padding(all = 12.dp),
|
||||||
|
) {
|
||||||
|
Row() {
|
||||||
|
Text(
|
||||||
|
text = game.nameA,
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = game.scoreA.toString(),
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Row() {
|
||||||
|
Text(
|
||||||
|
text = game.nameB,
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
Text(
|
||||||
|
text = game.scoreB.toString(),
|
||||||
|
style = MaterialTheme.typography.headlineSmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Row() {
|
||||||
|
Text(
|
||||||
|
text = format.format(game.modified),
|
||||||
|
style = MaterialTheme.typography.labelSmall
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Preview
|
||||||
|
@Composable
|
||||||
|
private fun HistoryListPreview() {
|
||||||
|
val tempData = listOf<GameAndScore>(
|
||||||
|
GameAndScore(false, "abc", "def", Date(), Date(), 1, 10, 50),
|
||||||
|
GameAndScore(true, "ADTH", "dogfg", Date(), Date(), 2, 20, 60),
|
||||||
|
GameAndScore(false, "TeamA3", "TeamB3", Date(), Date(), 3, 30, 70),
|
||||||
|
GameAndScore(false, "TeamA4", "TeamB4", Date(), Date(), 4, 40, 80),
|
||||||
|
GameAndScore(false, "TeamA5", "TeamB5", Date(), Date(), 5, 50, 90)
|
||||||
|
)
|
||||||
|
HistoryList(tempData)
|
||||||
|
}
|
||||||
@@ -13,7 +13,7 @@ import javax.inject.Inject
|
|||||||
|
|
||||||
|
|
||||||
@HiltViewModel
|
@HiltViewModel
|
||||||
class HistoryFragmentViewModel @Inject constructor(
|
class HistoryViewModel @Inject constructor(
|
||||||
private val gameDao: GameDao
|
private val gameDao: GameDao
|
||||||
) : ViewModel() {
|
) : ViewModel() {
|
||||||
|
|
||||||
Reference in New Issue
Block a user