working and rendering, but pretty bad
This commit is contained in:
parent
04820240dc
commit
5b587d4c63
@ -30,19 +30,48 @@ import timber.log.Timber
|
||||
import java.nio.charset.Charset
|
||||
import nl.siegmann.epublib.domain.MediaType
|
||||
import nl.siegmann.epublib.domain.Resource
|
||||
import inhale.rip.epook.data.Settings
|
||||
|
||||
// Update the JavaScript for accurate page calculation
|
||||
private const val PAGE_CALCULATION_JS = """
|
||||
(function() {
|
||||
const content = document.body;
|
||||
const contentWidth = content.scrollWidth;
|
||||
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
|
||||
const pageWidth = window.innerWidth;
|
||||
const totalPages = Math.max(1, Math.ceil(contentWidth / pageWidth));
|
||||
console.log('Content width:', contentWidth, 'Page width:', pageWidth, 'Total pages:', totalPages);
|
||||
return totalPages;
|
||||
const totalWidth = document.documentElement.scrollWidth;
|
||||
const currentPage = Math.floor(scrollLeft / pageWidth) + 1;
|
||||
const totalPages = Math.max(1, Math.ceil(totalWidth / pageWidth));
|
||||
return JSON.stringify({
|
||||
currentPage: currentPage,
|
||||
totalPages: totalPages
|
||||
});
|
||||
})();
|
||||
"""
|
||||
|
||||
// Add this function to handle chapter navigation
|
||||
private const val SCROLL_TO_CHAPTER_JS = """
|
||||
function scrollToChapter(chapterIndex) {
|
||||
const chapter = document.getElementById('chapter_' + chapterIndex);
|
||||
if (chapter) {
|
||||
chapter.scrollIntoView({ behavior: 'smooth', block: 'start' });
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
"""
|
||||
|
||||
// Add this to track WebView scroll position
|
||||
class WebViewScrollClient : WebViewClient() {
|
||||
var onPageLoaded: ((WebView) -> Unit)? = null
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
view?.let { webView ->
|
||||
onPageLoaded?.invoke(webView)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ReaderScreen(
|
||||
@ -70,6 +99,7 @@ fun ReaderScreen(
|
||||
var totalPages by remember { mutableStateOf(1) }
|
||||
var bookContent by remember { mutableStateOf("") }
|
||||
var webViewRef by remember { mutableStateOf<WebView?>(null) }
|
||||
var webViewClient = remember { WebViewScrollClient() }
|
||||
|
||||
// Move processChapterHtml outside the Composable
|
||||
fun processChapterHtml(rawHtml: String, chapterIndex: Int): String {
|
||||
@ -104,7 +134,8 @@ fun ReaderScreen(
|
||||
Timber.d("📚 Resource href: ${resource.href}")
|
||||
Timber.d("📚 Resource media type: ${resource.mediaType}")
|
||||
|
||||
if (resource.mediaType == MediaType.XHTML) {
|
||||
if (resource.mediaType.toString().contains("application/xhtml+xml") ||
|
||||
resource.mediaType.toString().contains("text/html")) {
|
||||
val rawHtml = String(resource.data, Charset.forName("UTF-8"))
|
||||
Timber.d("📚 Raw HTML length: ${rawHtml.length}")
|
||||
|
||||
@ -166,237 +197,235 @@ fun ReaderScreen(
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
BackHandler(enabled = showSettings || showChapterList) {
|
||||
when {
|
||||
showSettings -> showSettings = false
|
||||
showChapterList -> showChapterList = false
|
||||
BackHandler {
|
||||
scope.launch {
|
||||
settingsStore.saveSettings(Settings(
|
||||
currentPage = currentPage,
|
||||
fontSize = fontSize,
|
||||
lineHeight = lineHeight,
|
||||
padding = padding,
|
||||
fontFamily = fontFamily,
|
||||
isDarkMode = isDarkMode
|
||||
))
|
||||
}
|
||||
onNavigateBack()
|
||||
}
|
||||
|
||||
// Update the calculateCurrentPage function to use a callback
|
||||
fun calculateCurrentPage(webView: WebView) {
|
||||
webView.evaluateJavascript("""
|
||||
(function() {
|
||||
const height = document.documentElement.scrollHeight;
|
||||
const scrollTop = document.documentElement.scrollTop;
|
||||
const clientHeight = document.documentElement.clientHeight;
|
||||
const totalPages = Math.ceil(height / clientHeight);
|
||||
const currentPage = Math.ceil((scrollTop + clientHeight) / clientHeight);
|
||||
return JSON.stringify({currentPage: currentPage, totalPages: totalPages});
|
||||
})()
|
||||
""".trimIndent()) { result ->
|
||||
result?.let {
|
||||
try {
|
||||
val jsonStr = result.removeSurrounding("\"")
|
||||
val regex = """.*"currentPage":(\d+).*"totalPages":(\d+).*""".toRegex()
|
||||
regex.find(jsonStr)?.let { matchResult ->
|
||||
val (current, total) = matchResult.destructured
|
||||
// Update state values
|
||||
scope.launch {
|
||||
currentPage = current.toInt()
|
||||
totalPages = total.toInt()
|
||||
Timber.d("📚 Current page: $currentPage of $totalPages")
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error calculating current page")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
AnimatedVisibility(
|
||||
visible = showControls,
|
||||
enter = slideInVertically() + fadeIn(),
|
||||
exit = slideOutVertically() + fadeOut()
|
||||
) {
|
||||
TopAppBar(
|
||||
title = {
|
||||
Column {
|
||||
Text("Chapter ${currentChapter + 1}")
|
||||
Text(
|
||||
"Page $currentPage of $totalPages",
|
||||
style = MaterialTheme.typography.bodyMedium
|
||||
)
|
||||
}
|
||||
},
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onNavigateBack) {
|
||||
Icon(Icons.AutoMirrored.Filled.ArrowBack, "Back")
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
IconButton(onClick = { showChapterList = true }) {
|
||||
Icon(Icons.Default.List, "Chapters")
|
||||
}
|
||||
IconButton(onClick = { showSettings = true }) {
|
||||
Icon(Icons.Default.Settings, "Settings")
|
||||
}
|
||||
IconButton(onClick = { isDarkMode = !isDarkMode }) {
|
||||
Icon(
|
||||
if (isDarkMode) Icons.Default.LightMode else Icons.Default.DarkMode,
|
||||
"Toggle theme"
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
// Update webViewClient callback
|
||||
webViewClient.onPageLoaded = { webView ->
|
||||
calculateCurrentPage(webView)
|
||||
}
|
||||
|
||||
// Update the HTML content creation
|
||||
fun createHtmlContent(): String = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
html {
|
||||
scroll-snap-type: x mandatory;
|
||||
overflow-x: scroll;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
body {
|
||||
font-family: '$fontFamily';
|
||||
font-size: ${fontSize}px;
|
||||
line-height: ${lineHeight};
|
||||
padding: ${padding}px;
|
||||
margin: 0;
|
||||
background-color: ${if (isDarkMode) "#1c1c1c" else "#ffffff"};
|
||||
color: ${if (isDarkMode) "#ffffff" else "#000000"};
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: fit-content;
|
||||
}
|
||||
.chapter {
|
||||
width: calc(100vw - ${padding * 2}px);
|
||||
height: calc(100vh - ${padding * 2}px);
|
||||
overflow: hidden;
|
||||
scroll-snap-align: start;
|
||||
break-inside: avoid;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
$bookContent
|
||||
<script>$SCROLL_TO_CHAPTER_JS</script>
|
||||
</body>
|
||||
</html>
|
||||
""".trimIndent()
|
||||
|
||||
// Update chapter navigation
|
||||
fun navigateToChapter(index: Int) {
|
||||
webViewRef?.evaluateJavascript("scrollToChapter($index);") { result ->
|
||||
if (result == "true") {
|
||||
currentChapter = index
|
||||
showChapterList = false
|
||||
}
|
||||
}
|
||||
) { padding ->
|
||||
Box(modifier = Modifier.padding(padding)) {
|
||||
AndroidView(
|
||||
factory = { context ->
|
||||
WebView(context).apply {
|
||||
settings.apply {
|
||||
javaScriptEnabled = true
|
||||
useWideViewPort = true
|
||||
loadWithOverviewMode = true
|
||||
defaultFontSize = fontSize.toInt()
|
||||
Timber.d("📚 WebView settings configured")
|
||||
}
|
||||
|
||||
webViewClient = object : WebViewClient() {
|
||||
override fun onPageStarted(view: WebView?, url: String?, favicon: android.graphics.Bitmap?) {
|
||||
super.onPageStarted(view, url, favicon)
|
||||
Timber.d("📚 WebView page load started")
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
Timber.d("📚 WebView page load finished")
|
||||
|
||||
// Add a slight delay to ensure content is fully laid out
|
||||
view?.postDelayed({
|
||||
Timber.d("📚 Starting page calculation")
|
||||
view.evaluateJavascript(PAGE_CALCULATION_JS) { result ->
|
||||
try {
|
||||
val pages = result.toInt()
|
||||
Timber.d("📚 Page calculation complete - Total pages: $pages")
|
||||
totalPages = pages
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "📚 Error calculating pages")
|
||||
}
|
||||
}
|
||||
|
||||
// Log the current HTML content for debugging
|
||||
view.evaluateJavascript(
|
||||
"(function() { return document.documentElement.outerHTML; })()",
|
||||
) { result ->
|
||||
Timber.d("📚 Current HTML content length: ${result.length}")
|
||||
Timber.d("📚 First 100 chars of HTML: ${result.take(100)}")
|
||||
}
|
||||
|
||||
// Scroll to last position
|
||||
view.evaluateJavascript(
|
||||
"window.scrollTo({left: (${currentPage - 1}) * window.innerWidth, behavior: 'auto'})",
|
||||
null
|
||||
)
|
||||
}, 500)
|
||||
}
|
||||
|
||||
override fun onReceivedError(
|
||||
view: WebView?,
|
||||
errorCode: Int,
|
||||
description: String?,
|
||||
failingUrl: String?
|
||||
) {
|
||||
super.onReceivedError(view, errorCode, description, failingUrl)
|
||||
Timber.e("📚 WebView error: $errorCode - $description")
|
||||
}
|
||||
}
|
||||
|
||||
Timber.d("📚 Loading content into WebView")
|
||||
loadDataWithBaseURL(
|
||||
null,
|
||||
"""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
<style>$css</style>
|
||||
</head>
|
||||
<body>$bookContent</body>
|
||||
</html>
|
||||
""".trimIndent(),
|
||||
"text/html",
|
||||
"UTF-8",
|
||||
null
|
||||
)
|
||||
webViewRef = this
|
||||
}
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.pointerInput(Unit) {
|
||||
detectTapGestures { offset ->
|
||||
val screenWidth = this.size.width.toFloat()
|
||||
when {
|
||||
offset.x < screenWidth * 0.3f && currentPage > 1 -> {
|
||||
currentPage--
|
||||
webViewRef?.evaluateJavascript(
|
||||
"window.scrollTo({left: (${currentPage - 1}) * window.innerWidth, behavior: 'smooth'})",
|
||||
null
|
||||
)
|
||||
}
|
||||
offset.x > screenWidth * 0.7f && currentPage < totalPages -> {
|
||||
currentPage++
|
||||
webViewRef?.evaluateJavascript(
|
||||
"window.scrollTo({left: (${currentPage - 1}) * window.innerWidth, behavior: 'smooth'})",
|
||||
null
|
||||
)
|
||||
}
|
||||
else -> {
|
||||
showControls = !showControls
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// Settings sheet
|
||||
if (showSettings) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showSettings = false }
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(16.dp)
|
||||
) {
|
||||
Text("Reading Settings", style = MaterialTheme.typography.titleLarge)
|
||||
Spacer(modifier = Modifier.height(16.dp))
|
||||
|
||||
Text("Font Size: $fontSize", style = MaterialTheme.typography.bodyMedium)
|
||||
Slider(
|
||||
value = fontSize,
|
||||
onValueChange = {
|
||||
fontSize = it
|
||||
// Update WebView font size
|
||||
webViewRef?.evaluateJavascript(
|
||||
"document.body.style.fontSize = '${fontSize}px'",
|
||||
null
|
||||
)
|
||||
},
|
||||
valueRange = 12f..24f,
|
||||
steps = 11
|
||||
)
|
||||
|
||||
// Similar sliders for lineHeight, padding, brightness
|
||||
// Font family selector
|
||||
// Color theme selector
|
||||
}
|
||||
// Update the WebView setup
|
||||
AndroidView(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
factory = { context ->
|
||||
WebView(context).apply {
|
||||
settings.apply {
|
||||
javaScriptEnabled = true
|
||||
defaultFontSize = fontSize.toInt()
|
||||
domStorageEnabled = true
|
||||
allowFileAccess = true
|
||||
allowContentAccess = true
|
||||
}
|
||||
}
|
||||
|
||||
// Chapter list
|
||||
if (showChapterList) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = { showChapterList = false }
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
items(chapters) { chapter ->
|
||||
ListItem(
|
||||
headlineContent = { Text(chapter) },
|
||||
modifier = Modifier.clickable {
|
||||
// Navigate to chapter
|
||||
webViewRef?.evaluateJavascript(
|
||||
"document.getElementById('chapter_$currentChapter').scrollIntoView()",
|
||||
null
|
||||
)
|
||||
showChapterList = false
|
||||
|
||||
webViewClient = webViewClient
|
||||
|
||||
setOnScrollChangeListener { _, _, _, _, _ ->
|
||||
evaluateJavascript(PAGE_CALCULATION_JS) { result ->
|
||||
result?.let {
|
||||
try {
|
||||
val jsonStr = result.removeSurrounding("\"")
|
||||
val regex = """.*"currentPage":(\d+).*"totalPages":(\d+).*""".toRegex()
|
||||
regex.find(jsonStr)?.let { matchResult ->
|
||||
val (current, total) = matchResult.destructured
|
||||
scope.launch {
|
||||
currentPage = current.toInt()
|
||||
totalPages = total.toInt()
|
||||
}
|
||||
}
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e, "Error calculating page")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Brightness overlay
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(Color.Black.copy(alpha = 1f - brightness))
|
||||
},
|
||||
update = { webView ->
|
||||
webViewRef = webView
|
||||
val htmlContent = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<style>
|
||||
body {
|
||||
font-family: '$fontFamily';
|
||||
font-size: ${fontSize}px;
|
||||
line-height: ${lineHeight};
|
||||
padding: ${padding}px;
|
||||
margin: 0;
|
||||
background-color: ${if (isDarkMode) "#1c1c1c" else "#ffffff"};
|
||||
color: ${if (isDarkMode) "#ffffff" else "#000000"};
|
||||
}
|
||||
img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 1em auto;
|
||||
}
|
||||
.chapter {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
$bookContent
|
||||
<script>$SCROLL_TO_CHAPTER_JS</script>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
webView.loadDataWithBaseURL(
|
||||
"file:///android_asset/",
|
||||
htmlContent,
|
||||
"text/html",
|
||||
"UTF-8",
|
||||
null
|
||||
)
|
||||
}
|
||||
)
|
||||
|
||||
// Update chapter list dialog
|
||||
if (showChapterList) {
|
||||
AlertDialog(
|
||||
onDismissRequest = { showChapterList = false },
|
||||
title = { Text("Chapters") },
|
||||
text = {
|
||||
LazyColumn {
|
||||
items(chapters) { chapter ->
|
||||
Text(
|
||||
text = chapter,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable {
|
||||
val index = chapters.indexOf(chapter)
|
||||
navigateToChapter(index)
|
||||
}
|
||||
.padding(16.dp)
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
confirmButton = {
|
||||
TextButton(onClick = { showChapterList = false }) {
|
||||
Text("Close")
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// Save reading progress when leaving
|
||||
DisposableEffect(Unit) {
|
||||
onDispose {
|
||||
scope.launch {
|
||||
settingsStore.saveLastPosition(bookId, currentPage)
|
||||
settingsStore.saveSettings(Settings(
|
||||
currentPage = currentPage,
|
||||
fontSize = fontSize,
|
||||
lineHeight = lineHeight,
|
||||
padding = padding,
|
||||
fontFamily = fontFamily,
|
||||
isDarkMode = isDarkMode
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,83 +2,94 @@ package inhale.rip.epook.data
|
||||
|
||||
import android.content.Context
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.datastore.preferences.core.floatPreferencesKey
|
||||
import androidx.datastore.preferences.core.intPreferencesKey
|
||||
import androidx.datastore.preferences.core.stringPreferencesKey
|
||||
import androidx.datastore.preferences.core.*
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.first
|
||||
|
||||
private val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
|
||||
data class Settings(
|
||||
val currentPage: Int = 1,
|
||||
val fontSize: Float = 16f,
|
||||
val lineHeight: Float = 1.5f,
|
||||
val padding: Float = 16f,
|
||||
val fontFamily: String = "Roboto",
|
||||
val isDarkMode: Boolean = false
|
||||
)
|
||||
|
||||
class SettingsStore(private val context: Context) {
|
||||
private object PreferencesKeys {
|
||||
val CURRENT_PAGE = intPreferencesKey("current_page")
|
||||
val FONT_SIZE = floatPreferencesKey("font_size")
|
||||
val LINE_HEIGHT = floatPreferencesKey("line_height")
|
||||
val PADDING = floatPreferencesKey("padding")
|
||||
val FONT_FAMILY = stringPreferencesKey("font_family")
|
||||
fun lastPositionKey(bookId: String) = intPreferencesKey("last_position_$bookId")
|
||||
val IS_DARK_MODE = booleanPreferencesKey("is_dark_mode")
|
||||
}
|
||||
|
||||
suspend fun getFontSize(): Float {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.FONT_SIZE] ?: 16f
|
||||
}.first()
|
||||
return context.dataStore.data.first()[PreferencesKeys.FONT_SIZE] ?: 16f
|
||||
}
|
||||
|
||||
suspend fun getLineHeight(): Float {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.LINE_HEIGHT] ?: 1.5f
|
||||
}.first()
|
||||
return context.dataStore.data.first()[PreferencesKeys.LINE_HEIGHT] ?: 1.5f
|
||||
}
|
||||
|
||||
suspend fun getPadding(): Float {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.PADDING] ?: 16f
|
||||
}.first()
|
||||
}
|
||||
|
||||
suspend fun updateFontSize(size: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.FONT_SIZE] = size
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateLineHeight(height: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.LINE_HEIGHT] = height
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updatePadding(padding: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.PADDING] = padding
|
||||
}
|
||||
return context.dataStore.data.first()[PreferencesKeys.PADDING] ?: 16f
|
||||
}
|
||||
|
||||
suspend fun getFontFamily(): String {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.FONT_FAMILY] ?: "Roboto"
|
||||
}.first()
|
||||
return context.dataStore.data.first()[PreferencesKeys.FONT_FAMILY] ?: "Roboto"
|
||||
}
|
||||
|
||||
suspend fun updateFontFamily(family: String) {
|
||||
suspend fun updateFontSize(value: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.FONT_FAMILY] = family
|
||||
preferences[PreferencesKeys.FONT_SIZE] = value
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun getLastPosition(bookId: String): Int? {
|
||||
return context.dataStore.data.map { preferences ->
|
||||
preferences[PreferencesKeys.lastPositionKey(bookId)]
|
||||
}.first()
|
||||
suspend fun updateLineHeight(value: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.LINE_HEIGHT] = value
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveLastPosition(bookId: String, position: Int) {
|
||||
suspend fun updatePadding(value: Float) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.lastPositionKey(bookId)] = position
|
||||
preferences[PreferencesKeys.PADDING] = value
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun updateFontFamily(value: String) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.FONT_FAMILY] = value
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun loadSettings(): Settings {
|
||||
return context.dataStore.data.first().let { preferences ->
|
||||
Settings(
|
||||
currentPage = preferences[PreferencesKeys.CURRENT_PAGE] ?: 1,
|
||||
fontSize = preferences[PreferencesKeys.FONT_SIZE] ?: 16f,
|
||||
lineHeight = preferences[PreferencesKeys.LINE_HEIGHT] ?: 1.5f,
|
||||
padding = preferences[PreferencesKeys.PADDING] ?: 16f,
|
||||
fontFamily = preferences[PreferencesKeys.FONT_FAMILY] ?: "Roboto",
|
||||
isDarkMode = preferences[PreferencesKeys.IS_DARK_MODE] ?: false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun saveSettings(settings: Settings) {
|
||||
context.dataStore.edit { preferences ->
|
||||
preferences[PreferencesKeys.CURRENT_PAGE] = settings.currentPage
|
||||
preferences[PreferencesKeys.FONT_SIZE] = settings.fontSize
|
||||
preferences[PreferencesKeys.LINE_HEIGHT] = settings.lineHeight
|
||||
preferences[PreferencesKeys.PADDING] = settings.padding
|
||||
preferences[PreferencesKeys.FONT_FAMILY] = settings.fontFamily
|
||||
preferences[PreferencesKeys.IS_DARK_MODE] = settings.isDarkMode
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user