Update v1.0.49 (#330)
* Added PDF top tab strip visibility toggle and fixed WebView hit test NPE * Refactored desktop reader screens and state management into specialized components * Added image gallery to reader sidebar and refactored desktop PDF UI components * Implemented EPUB image gallery * Refactored reader and library models to use shared common types, centralizing file type resolution and texture management while removing redundant mapping logic * Standardized UI styling and refactored app navigation layout * Implemented auto-hiding reader chrome and activity tracking in desktop * Refactored reader panels into distinct left and right modal layers with platform-specific sizing and keyboard navigation support. * Added PPTX support for desktop and refactored parsing into a shared module * Implement paid AI features and account management for the desktop application. * Implement AI Hub and enhanced Cloud TTS integration for Desktop * Implement streaming support for AI definition and summarization features * Implement support for password-protected PDFs and file actions in the desktop reader. * Implement cloud synchronization for desktop using Firestore and Google Drive * Implement PDF reflow and "Text View" for the desktop reader * Refactor OPDS logic to use SharedOpdsController * Optimize PDF tile rendering performance * Implement two-page spread support for PDF pagination * Implement two-page spread support for the PDF viewer * Improved shared spread zoom in PDF viewer * Improve PDF spread navigation with fling support and configurable page gaps * Add brightness control to PDF and EPUB readers * Refactor folder synchronization to use shared logic engine * Implement safe string formatting and validation for localized resources * Implement TTS chunk skip navigation * Implement deep-linking and playback controls for TTS media sessions * Implement start index for TTS playback * Improve TTS navigation, prefetching, and notification duration reporting * Implement TTS mini playback bar for background reading * Implement multi-window reader support for the desktop application * Improve desktop modal window management and visibility syncing * Implement localized string support for Desktop and shared UI * Implement language selection and persistence for Desktop * Implement plural string support for Desktop and migrate hardcoded counts to plurals.xml * Implement localized banner messages and UI strings using resource-backed SharedText * Implement compact badge styling for small book covers * Refactor PDF native interaction and improve HTML import memory safety * fix language persistence * Refactor reader overflow menus to use section-based logic * Refactor PDF layout remapping and improve text box interaction * Improve CFI resolution and TTS resume accuracy using dynamic chunk offsets * Centralize PDF annotation export mapping and improve metadata handling * Add support for threaded comments in PDF highlight annotations * Flatten highlight comments into a single thread for PDF export and allow author editing * Integrate page slider into reader chrome and persist toggle state * Handle fragments and queries in EPUB chapter paths * Implement dynamic, theme-aware coloring for the reader slider * Implement customizable app-wide font preference * Implement one-hand zoom gestures in the PDF viewer * Implement File Information dialog for PDF and EPUB readers * Bump version to 1.0.49 (53) * Refactor PDF reader logic into modular components * Add ProGuard rules to prevent R8 optimization issues in EPUB reader screens * Add option to use PDF filenames as display names * Fix preservation of PDF filename display preference in library projection
This commit is contained in:
parent
dc5196526f
commit
9510293ac3
245 changed files with 37538 additions and 12460 deletions
193
app/src/main/java/com/aryan/reader/ReaderBrightness.kt
Normal file
193
app/src/main/java/com/aryan/reader/ReaderBrightness.kt
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
package com.aryan.reader
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Slider
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.core.content.edit
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
private const val READER_PREFS_NAME = "reader_prefs"
|
||||
private const val PREF_READER_BRIGHTNESS_USE_SYSTEM = "reader_brightness_use_system"
|
||||
private const val PREF_READER_BRIGHTNESS_VALUE = "reader_brightness_value"
|
||||
private const val DEFAULT_CUSTOM_BRIGHTNESS = 0.75f
|
||||
private const val MIN_CUSTOM_BRIGHTNESS = 0.05f
|
||||
|
||||
data class ReaderBrightnessSettings(
|
||||
val useSystemBrightness: Boolean = true,
|
||||
val customBrightness: Float = DEFAULT_CUSTOM_BRIGHTNESS
|
||||
) {
|
||||
val safeCustomBrightness: Float
|
||||
get() = customBrightness.coerceIn(MIN_CUSTOM_BRIGHTNESS, 1f)
|
||||
}
|
||||
|
||||
fun loadReaderBrightnessSettings(context: Context): ReaderBrightnessSettings {
|
||||
val prefs = context.getSharedPreferences(READER_PREFS_NAME, Context.MODE_PRIVATE)
|
||||
return ReaderBrightnessSettings(
|
||||
useSystemBrightness = prefs.getBoolean(PREF_READER_BRIGHTNESS_USE_SYSTEM, true),
|
||||
customBrightness = prefs.getFloat(PREF_READER_BRIGHTNESS_VALUE, DEFAULT_CUSTOM_BRIGHTNESS)
|
||||
.coerceIn(MIN_CUSTOM_BRIGHTNESS, 1f)
|
||||
)
|
||||
}
|
||||
|
||||
fun saveReaderBrightnessSettings(context: Context, settings: ReaderBrightnessSettings) {
|
||||
context.getSharedPreferences(READER_PREFS_NAME, Context.MODE_PRIVATE).edit {
|
||||
putBoolean(PREF_READER_BRIGHTNESS_USE_SYSTEM, settings.useSystemBrightness)
|
||||
putFloat(PREF_READER_BRIGHTNESS_VALUE, settings.safeCustomBrightness)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ReaderBrightnessEffect(
|
||||
window: Window?,
|
||||
settings: ReaderBrightnessSettings
|
||||
) {
|
||||
DisposableEffect(window) {
|
||||
val originalBrightness = window?.attributes?.screenBrightness
|
||||
?: WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
onDispose {
|
||||
window?.setReaderBrightness(originalBrightness)
|
||||
}
|
||||
}
|
||||
|
||||
LaunchedEffect(window, settings) {
|
||||
val brightness = if (settings.useSystemBrightness) {
|
||||
WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE
|
||||
} else {
|
||||
settings.safeCustomBrightness
|
||||
}
|
||||
window?.setReaderBrightness(brightness)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ReaderBrightnessSheet(
|
||||
settings: ReaderBrightnessSettings,
|
||||
onSettingsChange: (ReaderBrightnessSettings) -> Unit,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true)
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismiss,
|
||||
sheetState = sheetState
|
||||
) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(horizontal = 24.dp, vertical = 8.dp)
|
||||
.padding(bottom = 32.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.reader_brightness_title),
|
||||
style = MaterialTheme.typography.titleLarge,
|
||||
fontWeight = FontWeight.Bold
|
||||
)
|
||||
TextButton(onClick = onDismiss) {
|
||||
Text(stringResource(R.string.action_done))
|
||||
}
|
||||
}
|
||||
|
||||
HorizontalDivider()
|
||||
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
text = stringResource(R.string.reader_brightness_system),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.reader_brightness_system_desc),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
Switch(
|
||||
checked = settings.useSystemBrightness,
|
||||
onCheckedChange = { useSystem ->
|
||||
onSettingsChange(settings.copy(useSystemBrightness = useSystem))
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth(),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.reader_brightness_custom),
|
||||
style = MaterialTheme.typography.titleMedium
|
||||
)
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.reader_brightness_percent,
|
||||
(settings.safeCustomBrightness * 100f).roundToInt()
|
||||
),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
Slider(
|
||||
value = settings.safeCustomBrightness,
|
||||
onValueChange = { brightness ->
|
||||
onSettingsChange(
|
||||
settings.copy(
|
||||
useSystemBrightness = false,
|
||||
customBrightness = brightness.coerceIn(MIN_CUSTOM_BRIGHTNESS, 1f)
|
||||
)
|
||||
)
|
||||
},
|
||||
valueRange = MIN_CUSTOM_BRIGHTNESS..1f
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.reader_brightness_custom_desc),
|
||||
style = MaterialTheme.typography.bodySmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
}
|
||||
|
||||
Spacer(Modifier.height(4.dp))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun Window.setReaderBrightness(brightness: Float) {
|
||||
attributes = attributes.apply {
|
||||
screenBrightness = brightness
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue