Skip to content

Commit

Permalink
feat(font): automatically restart the app after loading external fonts (
Browse files Browse the repository at this point in the history
  • Loading branch information
Ashinch committed Mar 27, 2024
1 parent cbc0e06 commit d749107
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 13 deletions.
Expand Up @@ -11,6 +11,7 @@ import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.ExternalFonts
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
import me.ash.reader.ui.ext.restart
import me.ash.reader.ui.theme.SystemTypography

sealed class BasicFontsPreference(val value: Int) : Preference() {
Expand All @@ -20,6 +21,9 @@ sealed class BasicFontsPreference(val value: Int) : Preference() {
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(DataStoreKeys.BasicFonts, value)
if (this@BasicFontsPreference == External) {
context.restart()
}
}
}

Expand Down
Expand Up @@ -10,6 +10,7 @@ import me.ash.reader.ui.ext.DataStoreKeys
import me.ash.reader.ui.ext.ExternalFonts
import me.ash.reader.ui.ext.dataStore
import me.ash.reader.ui.ext.put
import me.ash.reader.ui.ext.restart

sealed class ReadingFontsPreference(val value: Int) : Preference() {
object System : ReadingFontsPreference(0)
Expand All @@ -22,6 +23,9 @@ sealed class ReadingFontsPreference(val value: Int) : Preference() {
override fun put(context: Context, scope: CoroutineScope) {
scope.launch {
context.dataStore.put(DataStoreKeys.ReadingFonts, value)
if (this@ReadingFontsPreference == External) {
context.restart()
}
}
}

Expand Down
6 changes: 6 additions & 0 deletions app/src/main/java/me/ash/reader/ui/ext/ContextExt.kt
Expand Up @@ -21,6 +21,12 @@ import me.ash.reader.infrastructure.preference.OpenLinkPreference
import me.ash.reader.infrastructure.preference.OpenLinkSpecificBrowserPreference
import java.io.File

fun Context.restart() {
packageManager.getLaunchIntentForPackage(packageName)?.let {
startActivity(Intent.makeRestartActivityTask(it.component))
Runtime.getRuntime().exit(0)
}
}

fun Context.findActivity(): Activity? = when (this) {
is Activity -> this
Expand Down
8 changes: 8 additions & 0 deletions app/src/main/java/me/ash/reader/ui/ext/StringExt.kt
Expand Up @@ -5,6 +5,14 @@ import android.util.Base64
import java.math.BigInteger
import java.security.MessageDigest

object MimeType {

const val ANY = "*/*"
const val FONT = "font/ttf" // Not supported yet
const val OPML = "text/x-opml" // Not supported yet
const val JSON = "application/json"
}

fun String.formatUrl(): String {
if (this.startsWith("//")) {
return "https:$this"
Expand Down
Expand Up @@ -4,24 +4,45 @@ import android.content.Context
import android.os.Build
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.*
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.expandIn
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.shrinkOut
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsBottomHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material.icons.outlined.Check
import androidx.compose.material.icons.outlined.Palette
import androidx.compose.material.icons.automirrored.rounded.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
Expand All @@ -31,16 +52,39 @@ import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import androidx.navigation.NavHostController
import me.ash.reader.R
import me.ash.reader.infrastructure.preference.*
import me.ash.reader.ui.component.base.*
import me.ash.reader.infrastructure.preference.BasicFontsPreference
import me.ash.reader.infrastructure.preference.CustomPrimaryColorPreference
import me.ash.reader.infrastructure.preference.LocalBasicFonts
import me.ash.reader.infrastructure.preference.LocalCustomPrimaryColor
import me.ash.reader.infrastructure.preference.LocalDarkTheme
import me.ash.reader.infrastructure.preference.LocalThemeIndex
import me.ash.reader.infrastructure.preference.ThemeIndexPreference
import me.ash.reader.infrastructure.preference.not
import me.ash.reader.ui.component.base.BlockRadioButton
import me.ash.reader.ui.component.base.BlockRadioGroupButtonItem
import me.ash.reader.ui.component.base.DisplayText
import me.ash.reader.ui.component.base.DynamicSVGImage
import me.ash.reader.ui.component.base.FeedbackIconButton
import me.ash.reader.ui.component.base.RYScaffold
import me.ash.reader.ui.component.base.RYSwitch
import me.ash.reader.ui.component.base.RadioDialog
import me.ash.reader.ui.component.base.RadioDialogOption
import me.ash.reader.ui.component.base.Subtitle
import me.ash.reader.ui.component.base.TextFieldDialog
import me.ash.reader.ui.ext.ExternalFonts
import me.ash.reader.ui.ext.MimeType
import me.ash.reader.ui.ext.showToast
import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.svg.PALETTE
import me.ash.reader.ui.svg.SVGString
import me.ash.reader.ui.theme.palette.*
import me.ash.reader.ui.theme.palette.TonalPalettes
import me.ash.reader.ui.theme.palette.TonalPalettes.Companion.toTonalPalettes
import me.ash.reader.ui.theme.palette.checkColorHex
import me.ash.reader.ui.theme.palette.dynamic.extractTonalPalettesFromUserWallpaper
import me.ash.reader.ui.theme.palette.onDark
import me.ash.reader.ui.theme.palette.onLight
import me.ash.reader.ui.theme.palette.safeHexToColor

@Composable
fun ColorAndStylePage(
Expand All @@ -58,11 +102,11 @@ fun ColorAndStylePage(
var radioButtonSelected by remember { mutableStateOf(if (themeIndex > 4) 0 else 1) }
var fontsDialogVisible by remember { mutableStateOf(false) }

val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
uri?.let {
ExternalFonts(context, it, ExternalFonts.FontType.BasicFont).copyToInternalStorage()
BasicFontsPreference.External.put(context, scope)
}
} ?: context.showToast("Cannot get activity result with launcher")
}

RYScaffold(
Expand Down Expand Up @@ -218,7 +262,7 @@ fun ColorAndStylePage(
selected = it == fonts,
) {
if (it.value == BasicFontsPreference.External.value) {
launcher.launch("*/*")
launcher.launch(arrayOf(MimeType.FONT))
} else {
it.put(context, scope)
}
Expand Down
Expand Up @@ -59,6 +59,8 @@ import me.ash.reader.ui.component.base.RadioDialog
import me.ash.reader.ui.component.base.RadioDialogOption
import me.ash.reader.ui.component.base.Subtitle
import me.ash.reader.ui.ext.ExternalFonts
import me.ash.reader.ui.ext.MimeType
import me.ash.reader.ui.ext.showToast
import me.ash.reader.ui.page.common.RouteName
import me.ash.reader.ui.page.settings.SettingItem
import me.ash.reader.ui.theme.palette.onLight
Expand All @@ -82,11 +84,11 @@ fun ReadingStylePage(
var tonalElevationDialogVisible by remember { mutableStateOf(false) }
var fontsDialogVisible by remember { mutableStateOf(false) }

val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) { uri ->
uri?.let {
ExternalFonts(context, it, ExternalFonts.FontType.ReadingFont).copyToInternalStorage()
ReadingFontsPreference.External.put(context, scope)
}
} ?: context.showToast("Cannot get activity result with launcher")
}

RYScaffold(
Expand Down Expand Up @@ -298,7 +300,7 @@ fun ReadingStylePage(
selected = it == fonts,
) {
if (it.value == ReadingFontsPreference.External.value) {
launcher.launch("*/*")
launcher.launch(arrayOf(MimeType.FONT))
} else {
it.put(context, scope)
}
Expand Down

0 comments on commit d749107

Please sign in to comment.