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

feat(font): automatically restart the app after loading external fonts #667

Merged
merged 1 commit into from
Mar 27, 2024
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 @@ -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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Loading