Skip to content

Commit

Permalink
Merge pull request #16 from Nimtome/feature/accompanist-systemuicontr…
Browse files Browse the repository at this point in the history
…oller

Color Themes, and Main Menu overhaul
  • Loading branch information
FlyinPancake committed Jan 11, 2022
2 parents ba8b035 + a7f3b12 commit 8048427
Show file tree
Hide file tree
Showing 23 changed files with 419 additions and 125 deletions.
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,
)
}

0 comments on commit 8048427

Please sign in to comment.