Skip to content

Commit

Permalink
GH-42 Adjust font size in the application (#52)
Browse files Browse the repository at this point in the history
* GH-42 Settings page

* GH-42 Scale fonts

* GH-42 Fix up layouts
  • Loading branch information
GrzegorzSmardzewskiAllegro authored Oct 18, 2023
1 parent c9fc6fd commit b546ead
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 61 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package net.dzikoysk.presenceofmind.components

import androidx.compose.runtime.Composable
import androidx.compose.runtime.ProvidableCompositionLocal
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.TextUnit
import androidx.compose.ui.unit.sp

val LocalFontScale: ProvidableCompositionLocal<Float> = compositionLocalOf { 1f }

@Composable
fun Int.scaledSp(): TextUnit =
with(LocalDensity.current) {
(this@scaledSp / this.fontScale).sp
}
(this@scaledSp / LocalDensity.current.fontScale * LocalFontScale.current).sp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import androidx.core.content.edit
import net.dzikoysk.presenceofmind.BuildConfig

private const val DEFAULT_AVATAR = "https://avatars.githubusercontent.com/u/75123628?s=200&v=4"
private const val DEFAULT_FONT_SCALE = 1f

sealed interface PresenceRepository {

Expand All @@ -17,6 +18,8 @@ sealed interface PresenceRepository {
fun setAvatarUrl(url: String)
fun getAvatarUrl(): String

fun setFontScale(size: Float)
fun getFontScale(): Float
}

class SharedPreferencesPresenceRepository(
Expand All @@ -27,6 +30,7 @@ class SharedPreferencesPresenceRepository(
private val lightModeId = "light-mode-$version"
private val latestVersionCodeId = "latest-version-code-$version"
private val avatarUrlId = "avatar-url-$version"
private val fontScaleId = "font-scale-$version"

private fun setProperty(modifier: SharedPreferences.Editor.() -> Unit): Unit =
sharedPreferences.edit(commit = true) { modifier(this) }
Expand All @@ -40,13 +44,16 @@ class SharedPreferencesPresenceRepository(
override fun setAvatarUrl(url: String) = setProperty { putString(avatarUrlId, url) }
override fun getAvatarUrl(): String = sharedPreferences.getString(avatarUrlId, DEFAULT_AVATAR).takeUnless { it.isNullOrEmpty() }?: DEFAULT_AVATAR

override fun setFontScale(size: Float) = setProperty { putFloat(fontScaleId, size) }
override fun getFontScale(): Float = sharedPreferences.getFloat(fontScaleId, DEFAULT_FONT_SCALE)
}

class InMemoryPresenceRepository : PresenceRepository {

private var lightMode = true
private var latestVersionCode = BuildConfig.VERSION_CODE
private var avatarUrl = DEFAULT_AVATAR
private var fontSize: Float = DEFAULT_FONT_SCALE

override fun setColorMode(isLightMode: Boolean) { this.lightMode = isLightMode }
override fun isLightMode(): Boolean = lightMode
Expand All @@ -57,5 +64,7 @@ class InMemoryPresenceRepository : PresenceRepository {
override fun setAvatarUrl(url: String) { this.avatarUrl = url }
override fun getAvatarUrl(): String = avatarUrl

override fun setFontScale(size: Float) { this.fontSize = size }
override fun getFontScale(): Float = this.fontSize
}

Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package net.dzikoysk.presenceofmind.pages

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.tooling.preview.Preview
import net.dzikoysk.presenceofmind.components.LocalFontScale
import net.dzikoysk.presenceofmind.createDefaultTasks
import net.dzikoysk.presenceofmind.model.presence.InMemoryPresenceRepository
import net.dzikoysk.presenceofmind.model.presence.PresenceOfMindTheme
Expand Down Expand Up @@ -38,21 +40,25 @@ fun Router(
page: Page
) {
PresenceOfMindTheme(lightTheme = presenceRepository.isLightMode()) {
val currentPage = remember { mutableStateOf(page) }
CompositionLocalProvider(LocalFontScale provides presenceRepository.getFontScale()) {
val currentPage = remember { mutableStateOf(page) }

when (currentPage.value) {
Page.DASHBOARD ->
Dashboard(
presenceRepository = presenceRepository,
taskService = taskService,
restartActivity = restartActivity,
changePage = { currentPage.value = it }
)
Page.SETTINGS ->
Settings(
presenceRepository = presenceRepository,
changePage = { currentPage.value = it }
)
when (currentPage.value) {
Page.DASHBOARD ->
Dashboard(
presenceRepository = presenceRepository,
taskService = taskService,
restartActivity = restartActivity,
changePage = { currentPage.value = it }
)

Page.SETTINGS ->
Settings(
presenceRepository = presenceRepository,
restartActivity = restartActivity,
changePage = { currentPage.value = it },
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,11 @@ fun Dashboard(
openMenu = { openMenu.value = true }
)
TodayLabel(
modifier = Modifier.padding(start = 16.dp)
modifier = Modifier
.padding(start = 16.dp)
.weight(1f, fill = false)
)
Row(
modifier = Modifier.weight(2f),
horizontalArrangement = Arrangement.End
) {
ChangeThemeButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,46 +7,51 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextDecoration
import androidx.compose.ui.text.withStyle
import androidx.compose.ui.tooling.preview.Preview
import net.dzikoysk.presenceofmind.components.scaledSp
import java.time.Instant
import java.time.ZoneId
import java.time.format.DateTimeFormatter
import java.util.Locale

@Composable
@Preview(showBackground = true)
fun TodayLabel(modifier: Modifier = Modifier) {
val todayFormatter = remember {
DateTimeFormatter.ofPattern("E dd.MM")
.withLocale(Locale.UK)
.withZone(ZoneId.systemDefault())
}

val fontSize = 13.scaledSp()
val style = SpanStyle(
fontWeight = FontWeight.Bold,
fontSize = 13.scaledSp()
)

Column(modifier) {
Text(
buildAnnotatedString {
withStyle(style.copy(color = Color(0xFF777777))) {
append("Today is ")
}
withStyle(style.copy(textDecoration = TextDecoration.Underline)) {
append(todayFormatter.format(Instant.now()))
}
}
)
Row {
Text(
text = "Today is ",
fontWeight = FontWeight.Bold,
color = Color(0xFF777777),
fontSize = fontSize
)
Text(
text = todayFormatter.format(Instant.now()),
fontWeight = FontWeight.Bold,
textDecoration = TextDecoration.Underline,
fontSize = fontSize
)
}
Row {
Text(
text = "Suggested activities for you:",
fontWeight = FontWeight.Bold,
color = Color(0xFF777777),
fontSize = fontSize
AnnotatedString(
"Suggested activities for you:",
style.copy(color = Color(0xFF777777))
)
)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package net.dzikoysk.presenceofmind.pages.dashboard.list.attributes

import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Checkbox
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale
import androidx.compose.ui.unit.TextUnit
Expand Down Expand Up @@ -40,22 +40,17 @@ fun ChecklistAttributeRenderer(
)
}

Box(modifier = Modifier.padding(start = 3.dp)) {
Column(modifier = Modifier.padding(start = 3.dp)) {
checklistAttribute.list
.sortedBy { it.done }
.forEachIndexed { idx, subtask ->
Row(
modifier = Modifier.padding(top = (30 * idx).dp),
horizontalArrangement = Arrangement.SpaceBetween,
) {
ChecklistEntryRenderer(
task = task,
checklistAttribute = checklistAttribute,
entry = subtask,
fontSize = fontSize,
updateTask = updateTask
)
}
.forEach { subtask ->
ChecklistEntryRenderer(
task = task,
checklistAttribute = checklistAttribute,
entry = subtask,
fontSize = fontSize,
updateTask = updateTask
)
}
}
}
Expand All @@ -68,7 +63,7 @@ fun ChecklistEntryRenderer(
fontSize: TextUnit,
updateTask: UpdateTask
) {
Row {
Row(verticalAlignment = Alignment.CenterVertically) {
Checkbox(
checked = entry.done,
onCheckedChange = {
Expand All @@ -84,8 +79,7 @@ fun ChecklistEntryRenderer(
)
DescriptionMarkdown(
description = entry.description,
fontSize = fontSize,
modifier = Modifier.padding(top = 15.dp)
fontSize = fontSize
)
}
}
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
package net.dzikoysk.presenceofmind.pages.settings

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentWidth
import androidx.compose.material.Icon
import androidx.compose.material.Slider
import androidx.compose.material.Text
import androidx.compose.material.TextField
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import net.dzikoysk.presenceofmind.R
import net.dzikoysk.presenceofmind.components.NumberField
import net.dzikoysk.presenceofmind.components.scaledSp
import net.dzikoysk.presenceofmind.model.presence.InMemoryPresenceRepository
import net.dzikoysk.presenceofmind.model.presence.PresenceRepository
import net.dzikoysk.presenceofmind.pages.Page
import kotlin.math.roundToInt

@Preview(showBackground = false)
@Composable
Expand All @@ -32,22 +44,27 @@ fun SettingsPreview() {
@Composable
fun Settings(
presenceRepository: PresenceRepository = InMemoryPresenceRepository(),
restartActivity: () -> Unit = {},
changePage: (Page) -> Unit = {}
) {
val avatarUrl = remember { mutableStateOf(presenceRepository.getAvatarUrl()) }
val fontSize = remember { mutableStateOf(presenceRepository.getFontScale()) }

Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
.padding(horizontal = 16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp, Alignment.Top)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.padding(vertical = 24.dp)
.clickable {
presenceRepository.setAvatarUrl(avatarUrl.value)
presenceRepository.setFontScale(fontSize.value)
changePage(Page.DASHBOARD)
restartActivity()
}
) {
Icon(
Expand All @@ -72,9 +89,32 @@ fun Settings(

TextField(
value = avatarUrl.value,
onValueChange = { avatarUrl.value = it }
onValueChange = { avatarUrl.value = it }
)
}
}

Row {
Column {
Text(
fontSize = 15.scaledSp(),
text = "Font scale",
modifier = Modifier.padding(bottom = 5.dp)
)

Slider(
value = fontSize.value,
onValueChange = { fontSize.value = it.roundFontSize() },
valueRange = 1f..2f,
steps = 10
)

Text(
text = fontSize.value.toString()
)
}
}
}
}
}
private fun Float.roundFontSize(): Float =
(this * 10).roundToInt() / 10f

0 comments on commit b546ead

Please sign in to comment.