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

Add the new Preferences API for EPUB #141

Merged
merged 105 commits into from
Sep 7, 2022
Merged

Add the new Preferences API for EPUB #141

merged 105 commits into from
Sep 7, 2022

Conversation

mickael-menu
Copy link
Member

@mickael-menu mickael-menu commented Jul 27, 2022

Changelog

Added

Navigator

  • Support for custom fonts with the EPUB navigator.
  • New EPUB user settings, as part of the revamped Settings API.
    • backgroundColor - Default page background color.
    • textColor - Default page text color.
    • textNormalization - Normalize font style, weight and variants using a specific strategy (force bold, accessibility).
    • imageFilter - Filter applied to images in dark theme (darken, invert colors)
    • language - Language of the publication content.
    • readingProgression - Direction of the reading progression across resources, e.g. RTL.
    • typeScale - Scale applied to all element font sizes.
    • paragraphIndent - Text indentation for paragraphs.
    • paragraphSpacing - Vertical margins for paragraphs.
    • hyphens - Enable hyphenation.
    • ligatures - Enable ligatures in Arabic.

Changed

Navigator

  • The EPUB user settings API got revamped.

Deprecated

Streamer

  • The local HTTP server is not needed anymore to render EPUB publications.

Screenshots

Review notes

The Settings API is split in three PRs to help the review. They should be merged into each other starting with 1/3, but should be reviewed in reverse order:

Start by checking out the documentation for an overview:

What happens when you change the user settings?

epub-settings

  1. When the user interacts with the user settings interface, the app submits a new set of Preferences to the EPUB navigator.
  2. The EPUB navigator updates its current EpubSettings using the submitted Preferences object.
    • If the app observes navigator.settings, the user interface will be updated to reflect the changes.
  3. The new EpubSettings are used to update the current ReadiumCss properties and the ViewPager (e.g. if the reading progression changes).
  4. When the ReadiumCss object changes, all the loaded WebViews receive JavaScript instructions to update the CSS variables.

Settings types

The navigator/settings package hosts the generic Setting types and building blocks. It is not tied to Navigator itself and could be used with other configurable components, such as the TTS synthesizer.

  • Configurable is to be implemented by a configurable component, such as the EpubNavigatorFragment.
    • Instead of having an object holding a List<Setting<*, *>>, there's a Settings empty marker interface that each Configurable implementer is supposed to implement as a data class holding Setting properties. This helps with discoverability of available settings, improve type-safety and two different Configurable implementers probably offer very different settings anyways.
  • A Setting object associates a setting key and its current value. It also has:
    • A coder which converts the value from/to JSON. It's implicit if the value type is @Serializable.
    • A bunch of extras type-specific constraints (e.g. a range of values).
    • A validator which is used to make sure only a valid value can be given (e.g. part of a range, or part of an enum).
    • An activator which can be used to activate a setting when it has dependencies. For example, the letterSpacing setting requires the publisherStyles setting to be disabled.

EpubSettings

EpubSettings is the EPUB-specific implementation of Configurable.Settings. It's a sealed class split in Reflowable and FixedLayout settings.

To update an EpubSettings object, you can provide a Preferences object to update() which will return the new updated EpubSettings object.

Each setting has an equivalent "prototype setting" which is a constant setting used as the template (default value, constraints) for creating or modifying a setting. For example, the EpubSettings.Reflowable.FONT_SIZE prototype setting is used to generate the settings.fontSize.

Readium CSS adapter

The ReadiumCss is a type-safe representation of the Readium CSS API. Each ReadiumCss object represents a state of the CSS variables and is used to inject them in the HTML resources, as well as the stylesheets.

The ReadiumCss object can be updated by passing the current EpubSettings object to update().

This is a low level internal API. The app is expected to use the Preferences and EpubSettings objects instead. However, the user can customize the --RS variables with EpubNavigatorFragment.Configuration.readiumCssRsProperties if the EPUB settings are too limited.

Missing stuff

@mickael-menu mickael-menu mentioned this pull request Jul 27, 2022
@mickael-menu mickael-menu force-pushed the feature/settings branch 2 times, most recently from 914dac8 to 5f69f9c Compare July 27, 2022 12:49
private fun onSettingsChange(previous: EpubSettings, new: EpubSettings) {
if (new !is EpubSettings.Reflowable) return

if ((previous as? EpubSettings.Reflowable)?.fontSize?.value != new.fontSize.value) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The font size is not configured using Readium CSS, as it doesn't work well if we don't disable publisher styles. See readium/mobile#1 (comment)

Instead we use the native WebSettings.textZoom.

@mickael-menu mickael-menu changed the title 3/3 Settings API Add the new Settings API for EPUB Sep 7, 2022
@mickael-menu mickael-menu merged commit 60b64b7 into develop Sep 7, 2022
@mickael-menu mickael-menu deleted the feature/settings branch September 7, 2022 14:04
@mickael-menu mickael-menu changed the title Add the new Settings API for EPUB Add the new Preferences API for EPUB Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants