Fixed bottom != bottom
This commit is contained in:
@@ -13,7 +13,7 @@ android {
|
|||||||
minSdk = 26
|
minSdk = 26
|
||||||
targetSdk = 34
|
targetSdk = 34
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0.0"
|
||||||
|
|
||||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@@ -39,6 +39,7 @@ android {
|
|||||||
}
|
}
|
||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose = true
|
compose = true
|
||||||
|
buildConfig = true
|
||||||
}
|
}
|
||||||
|
|
||||||
composeOptions {
|
composeOptions {
|
||||||
@@ -148,4 +149,8 @@ dependencies {
|
|||||||
implementation("com.google.android.material:material:1.11.0")
|
implementation("com.google.android.material:material:1.11.0")
|
||||||
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
implementation("androidx.recyclerview:recyclerview:1.3.2")
|
||||||
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
implementation("androidx.legacy:legacy-support-v4:1.0.0")
|
||||||
|
|
||||||
|
// Add these dependencies
|
||||||
|
implementation("org.json:json:20231013")
|
||||||
|
implementation("com.jakewharton.timber:timber:5.0.1")
|
||||||
}
|
}
|
||||||
@@ -74,6 +74,7 @@ fun ReaderScreen(
|
|||||||
|
|
||||||
val backgroundColor = MaterialTheme.colorScheme.background.toArgb()
|
val backgroundColor = MaterialTheme.colorScheme.background.toArgb()
|
||||||
val textColor = MaterialTheme.colorScheme.onBackground.toArgb()
|
val textColor = MaterialTheme.colorScheme.onBackground.toArgb()
|
||||||
|
val primaryColor = MaterialTheme.colorScheme.primary.toArgb()
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
try {
|
try {
|
||||||
@@ -213,23 +214,173 @@ fun ReaderScreen(
|
|||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<style>
|
<style>
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=${currentSettings.fontFamily.replace(" ", "+")}&display=swap');
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--text-color: #${textColor.toString(16)};
|
||||||
|
--bg-color: #${backgroundColor.toString(16)};
|
||||||
|
--accent-color: #${primaryColor.toString(16)};
|
||||||
|
}
|
||||||
|
|
||||||
|
html {
|
||||||
|
scroll-behavior: smooth;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
font-kerning: normal;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: ${currentSettings.fontFamily};
|
font-family: '${currentSettings.fontFamily}', system-ui, -apple-system, serif;
|
||||||
font-size: ${currentSettings.fontSize}px;
|
font-size: ${currentSettings.fontSize}px;
|
||||||
line-height: ${currentSettings.lineHeight};
|
line-height: ${currentSettings.lineHeight};
|
||||||
padding: ${currentSettings.padding}px;
|
padding: ${currentSettings.padding}px max(${currentSettings.padding}px, env(safe-area-inset-right)) ${currentSettings.padding}px max(${currentSettings.padding}px, env(safe-area-inset-left));
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: min(100%, 45em);
|
||||||
|
background-color: var(--bg-color);
|
||||||
|
color: var(--text-color);
|
||||||
|
text-align: justify;
|
||||||
|
text-rendering: optimizeLegibility;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
font-feature-settings: "kern" 1, "liga" 1, "clig" 1, "calt" 1;
|
||||||
|
hyphens: auto;
|
||||||
|
-webkit-hyphens: auto;
|
||||||
|
word-wrap: break-word;
|
||||||
|
hanging-punctuation: first;
|
||||||
|
padding-bottom: calc(${currentSettings.padding}px + 100px);
|
||||||
|
}
|
||||||
|
|
||||||
|
#content-wrapper {
|
||||||
|
min-height: 100vh;
|
||||||
|
padding-bottom: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: #${backgroundColor.toString(16)};
|
text-indent: 1.5em;
|
||||||
color: #${textColor.toString(16)};
|
min-height: 1.5em;
|
||||||
|
orphans: 2;
|
||||||
|
widows: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
line-height: 1.2;
|
||||||
|
margin: 2em 0 1em 0;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: -0.01em;
|
||||||
|
page-break-after: avoid;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
display: block;
|
||||||
|
margin: 1.5em auto;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
blockquote {
|
||||||
|
margin: 1.5em 0;
|
||||||
|
padding: 0.5em 1em;
|
||||||
|
border-left: 3px solid var(--text-color);
|
||||||
|
opacity: 0.8;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
hr {
|
||||||
|
margin: 2em auto;
|
||||||
|
width: 50%;
|
||||||
|
border: none;
|
||||||
|
border-top: 1px solid var(--text-color);
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
margin: 1.5em 0;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.95em;
|
||||||
|
}
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
padding: 0.75em;
|
||||||
|
border: 1px solid var(--text-color);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: inherit;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid var(--accent-color);
|
||||||
|
opacity: 0.9;
|
||||||
|
transition: opacity 0.2s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* First paragraph after headings shouldn't be indented */
|
||||||
|
h1 + p, h2 + p, h3 + p, h4 + p, h5 + p, h6 + p,
|
||||||
|
blockquote p, li p {
|
||||||
|
text-indent: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Lists styling */
|
||||||
|
ul, ol {
|
||||||
|
padding-left: 1.5em;
|
||||||
|
margin: 1em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
li {
|
||||||
|
margin: 0.5em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Small caps and dropcaps support */
|
||||||
|
.smallcaps {
|
||||||
|
font-variant: small-caps;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropcap {
|
||||||
|
float: left;
|
||||||
|
font-size: 3em;
|
||||||
|
line-height: 1;
|
||||||
|
margin: 0 0.1em 0 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Poetry/verse support */
|
||||||
|
.verse {
|
||||||
|
white-space: pre-line;
|
||||||
|
text-align: left;
|
||||||
|
text-indent: 0;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Footnotes */
|
||||||
|
.footnote {
|
||||||
|
font-size: 0.9em;
|
||||||
|
opacity: 0.8;
|
||||||
|
border-top: 1px solid var(--text-color);
|
||||||
|
margin-top: 2em;
|
||||||
|
padding-top: 1em;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
${String(resource.data, Charset.defaultCharset())}
|
<div id="content-wrapper">
|
||||||
|
${String(resource.data, Charset.defaultCharset())}
|
||||||
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
webView.loadDataWithBaseURL(null, html, "text/html", "UTF-8", null)
|
webView.loadDataWithBaseURL(
|
||||||
|
"file:///android_asset/",
|
||||||
|
html,
|
||||||
|
"text/html",
|
||||||
|
"UTF-8",
|
||||||
|
null
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -246,33 +397,62 @@ fun ReaderScreen(
|
|||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp),
|
.padding(16.dp),
|
||||||
color = MaterialTheme.colorScheme.surface.copy(alpha = 0.9f),
|
color = MaterialTheme.colorScheme.surface.copy(alpha = 0.95f),
|
||||||
tonalElevation = 3.dp
|
tonalElevation = 3.dp,
|
||||||
|
shape = MaterialTheme.shapes.large
|
||||||
) {
|
) {
|
||||||
Row(
|
Row(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(16.dp)
|
.padding(horizontal = 24.dp, vertical = 16.dp)
|
||||||
.fillMaxWidth(),
|
.fillMaxWidth(),
|
||||||
horizontalArrangement = Arrangement.SpaceBetween,
|
horizontalArrangement = Arrangement.SpaceBetween,
|
||||||
verticalAlignment = Alignment.CenterVertically
|
verticalAlignment = Alignment.CenterVertically
|
||||||
) {
|
) {
|
||||||
IconButton(
|
// Previous Chapter Button
|
||||||
|
FilledTonalButton(
|
||||||
onClick = { if (currentChapterIndex > 0) currentChapterIndex-- },
|
onClick = { if (currentChapterIndex > 0) currentChapterIndex-- },
|
||||||
enabled = currentChapterIndex > 0
|
enabled = currentChapterIndex > 0,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) {
|
||||||
Icon(Icons.AutoMirrored.Filled.NavigateBefore, "Previous chapter")
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
Icons.AutoMirrored.Filled.NavigateBefore,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(20.dp)
|
||||||
|
)
|
||||||
|
Spacer(Modifier.width(4.dp))
|
||||||
|
Text("Back")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Chapter Counter
|
||||||
Text(
|
Text(
|
||||||
text = "${currentChapterIndex + 1}/${chapters.size}",
|
text = "${currentChapterIndex + 1} / ${chapters.size}",
|
||||||
style = MaterialTheme.typography.titleMedium
|
style = MaterialTheme.typography.titleMedium,
|
||||||
|
modifier = Modifier.padding(horizontal = 16.dp)
|
||||||
)
|
)
|
||||||
|
|
||||||
IconButton(
|
// Next Chapter Button
|
||||||
|
FilledTonalButton(
|
||||||
onClick = { if (currentChapterIndex < chapters.size - 1) currentChapterIndex++ },
|
onClick = { if (currentChapterIndex < chapters.size - 1) currentChapterIndex++ },
|
||||||
enabled = currentChapterIndex < chapters.size - 1
|
enabled = currentChapterIndex < chapters.size - 1,
|
||||||
|
modifier = Modifier.weight(1f)
|
||||||
) {
|
) {
|
||||||
Icon(Icons.AutoMirrored.Filled.NavigateNext, "Next chapter")
|
Row(
|
||||||
|
horizontalArrangement = Arrangement.Center,
|
||||||
|
verticalAlignment = Alignment.CenterVertically
|
||||||
|
) {
|
||||||
|
Text("Next")
|
||||||
|
Spacer(Modifier.width(4.dp))
|
||||||
|
Icon(
|
||||||
|
Icons.AutoMirrored.Filled.NavigateNext,
|
||||||
|
contentDescription = null,
|
||||||
|
modifier = Modifier.size(20.dp)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user