diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index bb8d7957a2818c5378d258a5d144b629ad313492..8fe6b1f8cbd1c0e3ed3657a079a63b702130ea7e 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -1,17 +1,17 @@ <?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="deploymentTargetDropDown"> - <targetSelectedWithDropDown> + <runningDeviceTargetSelectedWithDropDown> <Target> - <type value="QUICK_BOOT_TARGET" /> + <type value="RUNNING_DEVICE_TARGET" /> <deviceKey> <Key> - <type value="VIRTUAL_DEVICE_PATH" /> - <value value="C:\Users\flyinpancake\.android\avd\Pixel_2_API_30.avd" /> + <type value="SERIAL_NUMBER" /> + <value value="BH901SF58Z" /> </Key> </deviceKey> </Target> - </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2021-12-07T18:39:24.097532400Z" /> + </runningDeviceTargetSelectedWithDropDown> + <timeTargetWasSelectedWithDropDown value="2021-12-14T14:31:07.475808Z" /> </component> </project> \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 55bc8a9a62c562249374913545b70c0fe8442c91..974d01916b38447562616854a09e5863c8bd6f05 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -26,6 +26,8 @@ <entry key="../../../../layout/compose-model-1638879424123.xml" value="0.15625" /> <entry key="../../../../layout/compose-model-1638892987664.xml" value="0.1570945945945946" /> <entry key="../../../../layout/compose-model-1638894001064.xml" value="0.165" /> + <entry key="../../../../layout/compose-model-1639493007794.xml" value="0.45692567567567566" /> + <entry key="../../../../layout/compose-model-1639493742130.xml" value="0.22596153846153846" /> <entry key="app/src/main/res/layout/activity_create_character.xml" value="0.16510416666666666" /> <entry key="app/src/main/res/layout/activity_main.xml" value="0.16510416666666666" /> <entry key="app/src/main/res/layout/activity_profile.xml" value="0.165" /> diff --git a/app/build.gradle b/app/build.gradle index cc9fdff0cb0a036d0de29a8873a3207b5d01796b..c1f2f0b725892d15df2b34a1e86741dba0809ad0 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,8 +40,8 @@ android { jvmTarget = '1.8' useIR = true } - compileSdkVersion 31 - buildToolsVersion '31.0.0' + compileSdkVersion 32 + buildToolsVersion '32.0.0' packagingOptions { resources { @@ -50,7 +50,7 @@ android { } composeOptions { kotlinCompilerExtensionVersion compose_version - kotlinCompilerVersion '1.5.21' + kotlinCompilerVersion '1.6.0' } } diff --git a/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt index 183d9c943c71eeff5606d1612276084687ff77c6..69f9456ee18f16f4f468a55b0f4ba6fdf75186a5 100644 --- a/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt +++ b/app/src/main/java/com/flyinpancake/dndspells/CreateCharacterActivity.kt @@ -9,7 +9,9 @@ import androidx.compose.material.* import androidx.compose.material.icons.Icons import androidx.compose.material.icons.outlined.Add import androidx.compose.material.icons.outlined.ArrowBack +import androidx.compose.material.icons.outlined.Edit import androidx.compose.runtime.* +import androidx.compose.runtime.livedata.observeAsState import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource @@ -21,6 +23,7 @@ import androidx.navigation.findNavController import com.flyinpancake.dndspells.model.DndCharacter import com.flyinpancake.dndspells.ui.theme.DndSpellsTheme import com.flyinpancake.dndspells.viewmodel.CharacterViewModel +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch lateinit var characterViewModel: CharacterViewModel @@ -29,17 +32,34 @@ fun addNewCharacter(character: DndCharacter) { characterViewModel.insert(character) } +fun updateCharacter(character: DndCharacter) { + characterViewModel.update(character) +} + @ExperimentalMaterialApi class CreateCharacterActivity : ComponentActivity() { + companion object { + val KEY_CHARACTER_NAME = "KEY_CHARACTER_NAME" + } + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) characterViewModel = ViewModelProvider(this).get(CharacterViewModel::class.java) + val characterName = intent.getStringExtra(KEY_CHARACTER_NAME) + + setContent { + var dndCharacter = characterName?.let { characterViewModel.get(it).observeAsState(DndCharacter()).value } ?: DndCharacter() + val editMode = dndCharacter.name.isBlank() MyApp { - CreateCharacterScreenContent() + CreateCharacterScreenContent( + editMode, + character = dndCharacter, + onChangeDndCharacter = { dndCharacter = it } + ) } } } @@ -47,57 +67,108 @@ class CreateCharacterActivity : ComponentActivity() { @ExperimentalMaterialApi @Composable -fun CreateCharacterScreenContent() { +fun CreateCharacterScreenContent( + isCreateMode: Boolean = true, + character: DndCharacter = DndCharacter(), + onChangeDndCharacter: (DndCharacter) -> Unit = {} +) { val scope = rememberCoroutineScope() val scaffoldState = rememberScaffoldState() val activity = (LocalContext.current as? Activity) - var dndCharacter by remember { - mutableStateOf(DndCharacter()) + val topText: String = when (isCreateMode) { + true -> "Create Your Character" + false -> "Modify Your Character" } - val characterErrorText = stringResource(R.string.character_error) Scaffold( scaffoldState = scaffoldState, modifier = Modifier.fillMaxSize(), topBar = { - DndTopBar("Create Your Character") + DndTopBar(topText) }, content = { Column { CharacterDetailList( - dndCharacter = dndCharacter, - onChangeDndCharacter = { dndCharacter = it } + dndCharacter = character, + onChangeDndCharacter = { + onChangeDndCharacter(it) + } ) } }, floatingActionButton = { - ExtendedFloatingActionButton( - text = { - Text(stringResource(R.string.add_new_character)) - }, - onClick = { - val validation = validateCharacter(dndCharacter) - if (validation){ - addNewCharacter(dndCharacter) - activity?.finish() - } - scope.launch { - scaffoldState.snackbarHostState.showSnackbar(characterErrorText) - } - }, - icon = { - Icon(Icons.Outlined.Add, contentDescription = null) - } - ) + if (isCreateMode) { + CreateCharacterFloatingActionButton( + dndCharacter = character, + activity = activity, + scope = scope, + scaffoldState = scaffoldState + ) + } else { + EditCharacterFloatingActionButton( + dndCharacter = character, + activity = activity, + scope = scope, + scaffoldState = scaffoldState + ) + } } ) } +@Composable +fun EditCharacterFloatingActionButton(dndCharacter: DndCharacter, activity: Activity?, scope: CoroutineScope, scaffoldState: ScaffoldState) { + val characterErrorText = stringResource(R.string.character_error) + + ExtendedFloatingActionButton( + text = { + Text(stringResource(R.string.modify_character)) + }, + onClick = { + val validation = validateCharacter(dndCharacter) + if (validation){ + updateCharacter(dndCharacter) + activity?.finish() + } + scope.launch { + scaffoldState.snackbarHostState.showSnackbar(characterErrorText) + } + }, + icon = { + Icon(Icons.Outlined.Edit, contentDescription = null) + } + ) +} + +@Composable +fun CreateCharacterFloatingActionButton(dndCharacter: DndCharacter, activity: Activity?, scope: CoroutineScope, scaffoldState: ScaffoldState) { + val characterErrorText = stringResource(R.string.character_error) + + ExtendedFloatingActionButton( + text = { + Text(stringResource(R.string.add_new_character)) + }, + onClick = { + val validation = validateCharacter(dndCharacter) + if (validation){ + addNewCharacter(dndCharacter) + activity?.finish() + } + scope.launch { + scaffoldState.snackbarHostState.showSnackbar(characterErrorText) + } + }, + icon = { + Icon(Icons.Outlined.Add, contentDescription = null) + } + ) +} + fun validateCharacter(dndCharacter: DndCharacter): Boolean { //General shit @@ -130,18 +201,16 @@ fun CharacterDetailList( ) { val ddoptions = DndCharacter.DndClass.values().toList().subList(0, 11) - var characterName by remember { mutableStateOf(dndCharacter.name) } - var characterClass = dndCharacter.dndClass + var characterClass by remember { mutableStateOf(dndCharacter.dndClass)} var characterLevel by remember { mutableStateOf(dndCharacter.level) } - var level by remember { mutableStateOf(0) } + var level by remember { mutableStateOf(dndCharacter.level) } Column { OutlinedTextField( - value = characterName, + value = dndCharacter.name, onValueChange = { - characterName = it - dndCharacter.name = characterName + dndCharacter.name = it onChangeDndCharacter(dndCharacter) }, modifier = modifier @@ -157,7 +226,8 @@ fun CharacterDetailList( onClassChange = { dndCharacter.dndClass = it onChangeDndCharacter(dndCharacter) - } + }, + starterClass = dndCharacter.dndClass ) LevelSlider( @@ -221,10 +291,11 @@ fun LevelSlider(onValueChange: (Int) -> Unit ) { fun ClassSelector( modifier: Modifier, ddoptions: List<DndCharacter.DndClass>, - onClassChange: (DndCharacter.DndClass) -> Unit + onClassChange: (DndCharacter.DndClass) -> Unit, + starterClass: DndCharacter.DndClass ) { var expandedState by remember { mutableStateOf(false) } - var selectedOption by remember { mutableStateOf(DndCharacter.DndClass.None) } + var selectedOption by remember { mutableStateOf(starterClass) } ExposedDropdownMenuBox( expanded = expandedState, diff --git a/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt b/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt index be50d3eb7565a8359f07dbcfd0944b84bc756487..a0d05446a67de70441a125458203303373c66271 100644 --- a/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt +++ b/app/src/main/java/com/flyinpancake/dndspells/MainActivity.kt @@ -79,6 +79,14 @@ class MainActivity : AppCompatActivity(), MainMenuRecyclerViewAdapter.SpellListI startActivity(intent, option.toBundle()) } + @OptIn(ExperimentalMaterialApi::class) + override fun onItemLongClick(character: DndCharacter, binding: RecyclerviewMainMenuRowBinding) { + val intent = Intent(this, CreateCharacterActivity::class.java) + intent.putExtra(CreateCharacterActivity.KEY_CHARACTER_NAME, character.name) + + startActivity(intent) + } + override fun onCreateOptionsMenu(menu: Menu): Boolean { menuInflater.inflate(R.menu.menu_main, menu) return super.onCreateOptionsMenu(menu) @@ -188,5 +196,17 @@ class MainActivity : AppCompatActivity(), MainMenuRecyclerViewAdapter.SpellListI ) } + override fun onRequestPermissionsResult( + requestCode: Int, + permissions: Array<out String>, + grantResults: IntArray + ) { + if (requestCode == PERMISSION_REQUEST_READ_EXTERNAL_STORAGE) + if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) + openSpellsFile() + + super.onRequestPermissionsResult(requestCode, permissions, grantResults) + } + } \ No newline at end of file diff --git a/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt b/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt index 135f197dae58cbe430d5810da42db7e77f215c97..c12a8449e2e92010881f666c82a2aa3a526bed69 100644 --- a/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt +++ b/app/src/main/java/com/flyinpancake/dndspells/adapter/MainMenuRecyclerViewAdapter.kt @@ -26,6 +26,7 @@ class MainMenuRecyclerViewAdapter : interface SpellListItemClickListener { fun onItemClick(character: DndCharacter, binding: RecyclerviewMainMenuRowBinding) + fun onItemLongClick(character: DndCharacter, binding: RecyclerviewMainMenuRowBinding) } inner class MainMenuViewHolder(val binding: RecyclerviewMainMenuRowBinding) : @@ -37,6 +38,10 @@ class MainMenuRecyclerViewAdapter : itemView.setOnClickListener { character?.let { character -> itemClickListener?.onItemClick(character, binding) } } + itemView.setOnLongClickListener { + character?.let { character -> itemClickListener?.onItemLongClick(character, binding)} + true + } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 90deca73cca7485df005aa26c0286e12194fb42e..cedd03aad4eb3bf3ee03b28d4ab0f27808c6660c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -19,4 +19,5 @@ <string name="title_activity_select_spells">SelectSpellsActivity</string> <string name="select_spells">\" - select spells\"</string> <string name="title_activity_ruinable">RuinableActivity</string> + <string name="modify_character">Modify Character</string> </resources> \ No newline at end of file diff --git a/build.gradle b/build.gradle index bf3070d9aa38c1cedbbe22039b88d8dea1fe818e..910dc1b231d7db66fda085ab792ef47c7a73cd00 100644 --- a/build.gradle +++ b/build.gradle @@ -11,7 +11,7 @@ buildscript { } dependencies { - classpath "com.android.tools.build:gradle:7.0.3" + classpath 'com.android.tools.build:gradle:7.0.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-serialization:$kotlin_version"