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

RUN-85/create developer options fragment #181

Merged
merged 2 commits into from
Nov 28, 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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class SharedPreferencesRepository private constructor(context: Context) {
var language: String
var lastRunTime: Long
var lastDivination: Long = 0
var switcherNames: Set<String> = setOf()

init {
val appVersion = context.packageManager.getPackageInfo(context.packageName, 0).versionCode
Expand Down Expand Up @@ -92,6 +93,22 @@ class SharedPreferencesRepository private constructor(context: Context) {
editor.putLong("last_run", lastRunTime)
editor.apply()
RunarLogger.logDebug("last_run $lastRunTime")

if (preferences.contains(SWITCHER_NAMES_PREF)) {
val receivedSwitcherNames = preferences.getStringSet(SWITCHER_NAMES_PREF, setOf())
switcherNames = receivedSwitcherNames?.toSet() ?: setOf()
} else {
initDeveloperSwitchers()
}
}

private fun initDeveloperSwitchers() {
val switchers = mapOf(
Pair("test", false)
)
switcherNames = switchers.keys
putSwitcherNames(switcherNames)
putSwitcherStates(switchers)
}

fun getLibHash(lng: String): String {
Expand Down Expand Up @@ -141,8 +158,43 @@ class SharedPreferencesRepository private constructor(context: Context) {
editor.apply()
}

private fun putSwitcherNames(names: Set<String>) {
preferences.edit().apply {
putStringSet(SWITCHER_NAMES_PREF, names)
apply()
}
}

private fun putSwitcherStates(states: Map<String, Boolean>) {
preferences.edit().apply {
states.forEach {
putBoolean(it.key, it.value)
}
apply()
}
}

fun putSwitcherState(key: String, state: Boolean) {
preferences.edit().apply {
putBoolean(key, state)
apply()
}
}

fun switcherStates(): MutableMap<String, Boolean> {
val result: MutableMap<String, Boolean> = mutableMapOf()
val keys = preferences.getStringSet(SWITCHER_NAMES_PREF, setOf()) ?: setOf()
keys.forEach {
result[it] = preferences.getBoolean(it, false)
}
return result
}


companion object {

private const val SWITCHER_NAMES_PREF = "switcher_names"

@Volatile
private lateinit var sharedPreferencesRepository: SharedPreferencesRepository

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ class MainActivity : AppCompatActivity(), Navigator, AudioManager.OnAudioFocusCh
R.id.generatorFragment -> View.VISIBLE
R.id.favouriteFragment -> View.VISIBLE
R.id.settingsFragment -> View.VISIBLE
R.id.developerOptionsFragment -> View.VISIBLE
else -> View.GONE
}
binding.bottomNavigationBar.visibility = bottomNavBarVisibility
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
package com.tnco.runar.ui.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.dimensionResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.fragment.app.Fragment
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import com.tnco.runar.R
import com.tnco.runar.ui.viewmodel.DeveloperOptionsViewModel

class DeveloperOptionsFragment : Fragment() {

override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = ComposeView(requireContext()).apply {
setContent {
DeveloperOptionsScreen(findNavController())
}
}
}

@Composable
private fun DeveloperOptionsScreen(navController: NavController) {
val viewModel: DeveloperOptionsViewModel = viewModel()
val fontSize by viewModel.fontSize.observeAsState(0f)
val devSwitcherStates = viewModel.devSwitcherStates

@Composable
fun TopBar() = TopAppBar(
title = {
Text(
text = stringResource(id = R.string.developer_options_title),
color = colorResource(id = R.color.library_top_bar_header_2),
fontFamily = FontFamily(Font(R.font.roboto_medium)),
style = TextStyle(fontSize = with(LocalDensity.current) { fontSize.toSp() })
)
},
backgroundColor = colorResource(id = R.color.library_top_bar),
navigationIcon = { TopBarIcon(navController) }
)

@Composable
fun Switchers() {
devSwitcherStates.forEach { switcher ->
SwitcherMenuItem(
fontSize = fontSize,
header = switcher.key,
checkAction = {
viewModel.putSwitcherState(switcher.key, it)
},
state = devSwitcherStates[switcher.key] ?: false
) {
viewModel.putSwitcherState(
switcher.key,
devSwitcherStates[switcher.key]?.not() ?: false
)
}
}
}

Scaffold(
topBar = {
TopBar()
},
backgroundColor = colorResource(id = R.color.settings_top_app_bar)
) { paddingValues ->
val scrollState = rememberScrollState()
Column(
Modifier
.verticalScroll(state = scrollState, enabled = true)
.padding(
start = dimensionResource(id = R.dimen.settings_padding_left),
top = dimensionResource(id = R.dimen.settings_padding_top),
bottom = paddingValues.calculateBottomPadding()
)
) {
Switchers()
}
}
}

@Composable
private fun TopBarIcon(navController: NavController) {
IconButton(onClick = { navController.popBackStack() }) {
Icon(
painter = painterResource(id = R.drawable.ic_library_back_arrow_2),
tint = colorResource(id = R.color.library_top_bar_fav),
contentDescription = "arrow"
)
}
}

@Composable
private fun SwitcherMenuItem(
fontSize: Float,
header: String,
checkAction: ((Boolean) -> Unit),
state: Boolean,
clickAction: () -> Unit
) {
Row(
Modifier
.aspectRatio(7.5f)
.clickable(onClick = clickAction)
) {
Column(
Modifier
.fillMaxSize()
.weight(335f)
) {
Row(
Modifier.fillMaxSize(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = header,
color = colorResource(id = R.color.library_item_header),
fontFamily = FontFamily(Font(R.font.roboto_regular)),
style = TextStyle(fontSize = with(LocalDensity.current) { fontSize.toSp() })
)
Switch(
checked = state,
onCheckedChange = checkAction,
colors = SwitchDefaults.colors(
checkedThumbColor = colorResource(id = R.color.switcher_checked_thumb),
checkedTrackColor = colorResource(id = R.color.switcher_checked_back),
uncheckedThumbColor = colorResource(id = R.color.switcher_unchecked_thumb),
uncheckedTrackColor = colorResource(id = R.color.switcher_unchecked_back),
)
)
}
}
Spacer(
Modifier
.fillMaxSize()
.weight(9f)
)
}
}
17 changes: 15 additions & 2 deletions app/src/main/java/com/tnco/runar/ui/fragment/SettingsFragment.kt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import androidx.fragment.app.viewModels
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController
import androidx.navigation.fragment.findNavController
import com.tnco.runar.BuildConfig
import com.tnco.runar.R
import com.tnco.runar.ui.Navigator
import com.tnco.runar.ui.viewmodel.SettingsViewModel
Expand Down Expand Up @@ -85,7 +86,6 @@ private fun Bars(navigator: Navigator, navController: NavController) {

val context = LocalContext.current


Scaffold(
topBar = {
TopAppBar(
Expand All @@ -108,7 +108,8 @@ private fun Bars(navigator: Navigator, navController: NavController) {
.verticalScroll(state = scrollState, enabled = true)
.padding(
start = dimensionResource(id = R.dimen.settings_padding_left),
top = dimensionResource(id = R.dimen.settings_padding_top)
top = dimensionResource(id = R.dimen.settings_padding_top),
bottom = paddingValues.calculateBottomPadding()
)
) {
LangMenuItem(
Expand Down Expand Up @@ -168,6 +169,18 @@ private fun Bars(navigator: Navigator, navController: NavController) {
}
)
DividerItem()
if (BuildConfig.DEBUG) {
SimpleMenuItem(
fontSize = fontSize!!,
header = stringResource(id = R.string.developer_options_title),
clickAction = {
val direction = SettingsFragmentDirections
.actionSettingsFragmentToDeveloperOptionsFragment()
navController.navigate(direction)
}
)
DividerItem()
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.tnco.runar.ui.viewmodel

import androidx.compose.runtime.snapshots.SnapshotStateMap
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.tnco.runar.repository.SharedDataRepository
import com.tnco.runar.repository.SharedPreferencesRepository

class DeveloperOptionsViewModel : ViewModel() {

private val preferencesRepository = SharedPreferencesRepository.get()
val fontSize: LiveData<Float> = MutableLiveData(SharedDataRepository.fontSize)

private var _devSwitcherStates: MutableMap<String, Boolean> = switcherStatesFromRepository()
val devSwitcherStates: Map<String, Boolean>
get() = _devSwitcherStates

fun putSwitcherState(key: String, state: Boolean) {
_devSwitcherStates[key] = state
preferencesRepository.putSwitcherState(key, state)
}

private fun switcherStatesFromRepository() = SnapshotStateMap<String, Boolean>().apply {
val states = preferencesRepository.switcherStates()
states.forEach {
put(it.key, it.value)
}
}
}
10 changes: 8 additions & 2 deletions app/src/main/res/navigation/settings.xml
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/settings"
app:startDestination="@id/settingsFragment">

<fragment
android:id="@+id/settingsFragment"
android:name="com.tnco.runar.ui.fragment.SettingsFragment"
android:label="SettingsFragment" >
android:label="SettingsFragment">
<action
android:id="@+id/action_settingsFragment_to_aboutAppFragment"
app:destination="@id/aboutAppFragment" />
<action
android:id="@+id/action_settingsFragment_to_developerOptionsFragment"
app:destination="@id/developerOptionsFragment" />
</fragment>
<fragment
android:id="@+id/aboutAppFragment"
android:name="com.tnco.runar.ui.fragment.AboutAppFragment"
android:label="AboutAppFragment" />
<fragment
android:id="@+id/developerOptionsFragment"
android:name="com.tnco.runar.ui.fragment.DeveloperOptionsFragment"
android:label="DeveloperOptionsFragment" />

</navigation>
1 change: 1 addition & 0 deletions app/src/main/res/values-ru/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
<string name="onboarding_txt">Показать стр. приветствия</string>
<string name="rate_app_txt">Оценить приложение</string>
<string name="about_app_txt">О приложении</string>
<string name="developer_options_title">Для разработчиков</string>
<string name="about_txt">Версия приложения 0.14–5\n\nRunar — это приложение для гадания на скандинавских рунах и изучения скандинавской мифологии и сказок. Содержит 8 видов рунных раскладов, толкования рун. В разделе Библиотека вы можете почитать скандинавские саги и сказки.\n\nС разрешения правообладателей, в приложении использованы следующие музыкальные композиции:\n- Лёдъ (использованы композиции - \"Черная Ладья\", \"Мать моя сказала\"), https://lyod1.bandcamp.com/releases \n- Danheim (использованы композиции - \"Runar\", \"Kala\"), https://danheimmusic.com</string>
<string name="library_top_bar_header">Библиотека</string>

Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<string name="onboarding_txt">Show onboard page</string>
<string name="rate_app_txt">Rate the application</string>
<string name="about_app_txt">About</string>
<string name="developer_options_title">Developer Options</string>
<string name="about_txt">Application version 0.14–5\n\nRunar is an app for reading Scandinavian runes and studying mythology and fairy tales. Contains 8 types of rune layouts and runes interpretation. In the Library section you can read Scandinavian sagas and fairy tales.\n\nWith the permission of the copyright holders, the following musical compositions are used in the application:\n- Lyod (tracks \"Black rook\", \"My mother told\"), https://lyod1.bandcamp.com/releases \n- Danheim (tracks \"Runar\", \"Kala\"), https://danheimmusic.com</string>
<string name="library_top_bar_header">Library</string>
<string name="fav_dialog_text">Do you really want to delete your favorite layouts?</string>
Expand Down