Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Color Themes, and Main Menu overhaul #16

Merged
merged 9 commits into from Jan 11, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions android-app/app/build.gradle
Expand Up @@ -91,4 +91,7 @@ dependencies {

// Coroutine
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'

//Accompanist
implementation 'com.google.accompanist:accompanist-systemuicontroller:0.22.0-rc'
}
Expand Up @@ -35,6 +35,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import com.nimtome.app.CharacterDetailsActivity.Companion.KEY_NAME
import com.nimtome.app.DndApplication.Companion.colorPalette
import com.nimtome.app.model.DndCharacter
import com.nimtome.app.model.Spell
import com.nimtome.app.ui.components.DndTopBar
Expand Down Expand Up @@ -65,7 +66,8 @@ class CharacterDetailsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DndSpellsTheme {
DndSpellsTheme(darkColors = colorPalette.darkColors,
lightColors = colorPalette.lightColors) {
// A surface container using the 'background' color from the theme
val viewModel = ViewModelProvider(this)
val nameInDb = intent.getStringExtra(KEY_NAME) ?: ""
Expand All @@ -86,7 +88,7 @@ class CharacterDetailsActivity : ComponentActivity() {
@Composable
fun CharacterDetailContent(
character: DndCharacter = DndCharacter(),
spells: List<Spell> = listOf()
spells: List<Spell> = listOf(),
) {
val activity = (LocalContext.current as? Activity)

Expand Down
Expand Up @@ -7,7 +7,6 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -33,6 +32,7 @@ import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.outlined.Menu
import androidx.compose.material.rememberBackdropScaffoldState
import androidx.compose.material3.CenterAlignedTopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
Expand All @@ -48,14 +48,18 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.core.content.ContextCompat
import androidx.lifecycle.ViewModelProvider
import com.nimtome.app.DndApplication.Companion.colorPalette
import com.nimtome.app.model.DndCharacter
import com.nimtome.app.model.Spell
import com.nimtome.app.model.SpellImporter
import com.nimtome.app.ui.components.CharacterCard
import com.nimtome.app.ui.components.ColorPaletteSelector
import com.nimtome.app.ui.components.EditCharacterCard
import com.nimtome.app.ui.components.MainMenuContentSelector
import com.nimtome.app.ui.components.MainMenuElement
import com.nimtome.app.ui.components.MainMenuSpellCard
import com.nimtome.app.ui.theme.CARD_INNER_FILL_RATIO
import com.nimtome.app.ui.theme.CharacterListTopbarColors
import com.nimtome.app.ui.theme.ColorPalette
import com.nimtome.app.ui.theme.DndSpellsTheme
import com.nimtome.app.viewmodel.CharacterViewModel
import com.nimtome.app.viewmodel.SpellViewModel
Expand All @@ -77,22 +81,22 @@ class CharacterListActivity : ComponentActivity() {
GlobalScope.launch {
withContext(Dispatchers.IO) {
val resolver = this@CharacterListActivity.contentResolver

resolver.openInputStream(uri)?.let { inputStream ->
val importer = SpellImporter()
val spellList = importer.importSpells(inputStream)

// Show snakbar
spellsViewModel.nuke()
spellList.forEach { spell ->
spellsViewModel.insert(spell)
runCatching {
resolver.openInputStream(uri)?.let { inputStream ->
val importer = SpellImporter()
val spellList = importer.importSpells(inputStream)

//TODO Show snakbar
spellsViewModel.nuke()
spellList.forEach { spell ->
spellsViewModel.insert(spell)
}
}
}
}
}
}
}

private val getFilePermission =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
if (isGranted) {
Expand All @@ -111,8 +115,12 @@ class CharacterListActivity : ComponentActivity() {

val characterList by characterViewModel.allCharacters.observeAsState()
val spellList by spellsViewModel.allSpells.observeAsState()
var colorPalette by remember { mutableStateOf(colorPalette) }

DndSpellsTheme {
DndSpellsTheme(
darkColors = colorPalette.darkColors,
lightColors = colorPalette.lightColors
) {
Surface(color = MaterialTheme.colors.background) {
MainActivityContent(
characterList = characterList,
Expand Down Expand Up @@ -142,6 +150,11 @@ class CharacterListActivity : ComponentActivity() {
.putExtra(SpellDetailsActivity.KEY_SPELL_NAME, it.name)
)
},
colors = colorPalette,
onColorsChange = {
colorPalette = it
DndApplication.colorPalette = it
}
)
if (showDialog.value)
StorageAccessRationaleDialog(
Expand Down Expand Up @@ -184,15 +197,11 @@ class CharacterListActivity : ComponentActivity() {
}
}

enum class MainMenuElements {
CHARACTERS,
SPELLS,
}

@Composable
private fun StorageAccessRationaleDialog(
closeDialog: () -> Unit,
importSpells: () -> Unit
importSpells: () -> Unit,
) {

AlertDialog(
Expand Down Expand Up @@ -222,8 +231,6 @@ private fun StorageAccessRationaleDialog(
)
}

private const val CARD_FILL_RATIO = .8f

@Suppress("UnusedPrivateMember")
@ExperimentalMaterialApi
@Composable
Expand All @@ -236,19 +243,21 @@ private fun MainActivityContent(
modifyCharacter: (DndCharacter) -> Unit = {},
openSpellDetails: (Spell) -> Unit = {},
modifySpell: (Spell) -> Unit = {},
colors: ColorPalette,
onColorsChange: (ColorPalette) -> Unit,
) {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBackdropScaffoldState(initialValue = BackdropValue.Concealed)

var menuSelection by remember { mutableStateOf(MainMenuElements.CHARACTERS) }
var menuSelection by remember { mutableStateOf(MainMenuElement.CHARACTERS) }

var isEditMode by remember { mutableStateOf(false) }

BackdropScaffold(
appBar = {
CenterAlignedTopAppBar(
title = { Text(text = "D&D spells") },
colors = CharacterListTopbarColors(),
colors = TopAppBarDefaults.centerAlignedTopAppBarColors(containerColor = MaterialTheme.colors.primary),
navigationIcon = {
IconButton(onClick = { scaffoldState.switch(scope) }) {
Icon(Icons.Outlined.Menu, "Open Menu")
Expand All @@ -270,32 +279,26 @@ private fun MainActivityContent(
backLayerContent = {
Column(
Modifier
.fillMaxWidth(CARD_FILL_RATIO)
.selectableGroup()
.fillMaxWidth()
.selectableGroup(),
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(verticalAlignment = Alignment.CenterVertically) {
androidx.compose.material3.RadioButton(
selected = menuSelection == MainMenuElements.SPELLS,
onClick = { menuSelection = MainMenuElements.SPELLS }
)
MainMenuContentSelector(
modifier = Modifier.fillMaxWidth(CARD_INNER_FILL_RATIO),
selectedElement = menuSelection,
onSelectedElementChanged = { menuSelection = it },
)

Text("Spells")
}
Spacer(modifier = Modifier.padding(bottom = 5.dp))

Row(verticalAlignment = Alignment.CenterVertically) {
androidx.compose.material3.RadioButton(
selected = menuSelection == MainMenuElements.CHARACTERS,
onClick = { menuSelection = MainMenuElements.CHARACTERS }
)

Text("Characters")
}
ColorPaletteSelector(modifier = Modifier.fillMaxWidth(CARD_INNER_FILL_RATIO), selected = colors, onChanged = onColorsChange)

Spacer(modifier = Modifier.padding(bottom = 15.dp))
}
},
frontLayerContent = {
if (menuSelection == MainMenuElements.CHARACTERS)
if (menuSelection == MainMenuElement.CHARACTERS)
CharacterList(
list = characterList,
isEditMode = isEditMode,
Expand Down Expand Up @@ -335,7 +338,7 @@ private fun CharacterList(
list: List<DndCharacter>?,
isEditMode: Boolean,
onClick: (DndCharacter) -> Unit = {},
onEditClick: (DndCharacter) -> Unit
onEditClick: (DndCharacter) -> Unit,
) {
if (list == null) {
CircularProgressIndicator()
Expand Down Expand Up @@ -423,22 +426,12 @@ private fun SpellList(
@Composable
fun CharacterListPreview() {
DndSpellsTheme {
var showDialog by remember {
mutableStateOf(false)
}
MainActivityContent(
characterList = listOf(sampleCharacter),
spellList = sampleSpells,
importSpells = {},
addCharacter = {},
modifyCharacter = {},
importSpells = { },
colors = ColorPalette.Purple,
onColorsChange = { }
)
if (showDialog)
StorageAccessRationaleDialog(
importSpells = {},
closeDialog = {
showDialog = false
},
)
}
}
Expand Up @@ -39,6 +39,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LiveData
import androidx.lifecycle.ViewModelProvider
import com.nimtome.app.DndApplication.Companion.colorPalette
import com.nimtome.app.model.DndCharacter
import com.nimtome.app.model.DndClass
import com.nimtome.app.ui.components.ClassSelector
Expand Down Expand Up @@ -180,7 +181,7 @@ fun EditCharacterFloatingActionButton(
dndCharacter: DndCharacter,
activity: CreateCharacterActivity?,
scope: CoroutineScope,
scaffoldState: ScaffoldState
scaffoldState: ScaffoldState,
) {
val characterErrorText = stringResource(R.string.character_error)

Expand All @@ -205,7 +206,7 @@ fun CreateCharacterFloatingActionButton(
dndCharacter: DndCharacter,
activity: Activity?,
scope: CoroutineScope,
scaffoldState: ScaffoldState
scaffoldState: ScaffoldState,
) {
val characterErrorText = stringResource(R.string.character_error)

Expand Down Expand Up @@ -243,7 +244,7 @@ fun validateCharacter(dndCharacter: DndCharacter): Boolean {
fun CharacterDetailList(
modifier: Modifier = Modifier,
dndCharacter: DndCharacter,
onChangeDndCharacter: (DndCharacter) -> Unit
onChangeDndCharacter: (DndCharacter) -> Unit,
) {
val classList = DndClass.values().toList().subList(0, DndClass.values().size - 1)

Expand Down Expand Up @@ -283,7 +284,7 @@ fun CharacterDetailList(

@Composable
fun MyApp(component: @Composable () -> Unit) {
DndSpellsTheme {
DndSpellsTheme(darkColors = colorPalette.darkColors, lightColors = colorPalette.lightColors) {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
component()
Expand Down
23 changes: 23 additions & 0 deletions android-app/app/src/main/java/com/nimtome/app/DndApplication.kt
@@ -1,9 +1,11 @@
package com.nimtome.app

import android.app.Application
import android.content.SharedPreferences
import androidx.room.Room
import com.nimtome.app.database.CharacterDatabase
import com.nimtome.app.database.SpellDatabase
import com.nimtome.app.ui.theme.ColorPalette

class DndApplication : Application() {

Expand All @@ -12,6 +14,25 @@ class DndApplication : Application() {
private set
lateinit var spellDatabase: SpellDatabase
private set
lateinit var sharedPreferences: SharedPreferences
private set
private const val SP_ID_MAIN = "com.nimtome.nimtome.main"
private const val SP_COLOR_THEME = "COLOR_THEME"

var colorPalette: ColorPalette
get() {
return ColorPalette.valueOf(
sharedPreferences
.getString(SP_COLOR_THEME, ColorPalette.Purple.name)
?: ColorPalette.Purple.name
)
}
set(value) {
with(sharedPreferences.edit()) {
putString(SP_COLOR_THEME, value.name)
apply()
}
}
}

override fun onCreate() {
Expand All @@ -26,6 +47,8 @@ class DndApplication : Application() {
CharacterDatabase::class.java,
"character_database",
).fallbackToDestructiveMigration().build()

sharedPreferences = getSharedPreferences(SP_ID_MAIN, MODE_PRIVATE)
super.onCreate()
}
}
Expand Up @@ -77,7 +77,7 @@ class SelectSpellsActivity : ComponentActivity() {
fun SelectSpellsContent(
spells: List<Spell>,
character: DndCharacter,
updateCharacter: (DndCharacter) -> Unit = {}
updateCharacter: (DndCharacter) -> Unit = {},
) {
val scope = rememberCoroutineScope()
val scaffoldState = rememberBottomSheetScaffoldState()
Expand Down Expand Up @@ -148,7 +148,7 @@ fun SelectSpellsContent(
private fun SpellCardWithCheckBox(
spell: Spell,
checked: Boolean,
onCheck: (Boolean) -> Unit
onCheck: (Boolean) -> Unit,
) {
Card(
modifier = Modifier
Expand Down
Expand Up @@ -24,6 +24,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModelProvider
import com.nimtome.app.DndApplication.Companion.colorPalette
import com.nimtome.app.model.Spell
import com.nimtome.app.ui.components.DndTopBar
import com.nimtome.app.ui.theme.DndSpellsTheme
Expand All @@ -46,7 +47,8 @@ class SpellDetailsActivity : ComponentActivity() {
.observeAsState(Spell())
.value

DndSpellsTheme {
DndSpellsTheme(darkColors = colorPalette.darkColors,
lightColors = colorPalette.lightColors) {
// A surface container using the 'background' color from the theme
Surface(color = MaterialTheme.colors.background) {
SpellDetails(spell = spell)
Expand Down
Expand Up @@ -29,6 +29,6 @@ interface CharacterDao {

@Delete
fun deleteCharacter(
character: RoomCharacter
character: RoomCharacter,
)
}