Skip to content

iOS/Android: mirror web Media Overlay text→audio fallback #139

Description

@ddfreiling

Context

The web side recently gained a fallback in textLocatorToAudioLocator (flutter_readium/web/_scripts/Audio/syncNarration.ts): when a text Locator's fragment / cssSelector is set but no SyncNarrationItem.textId matches, we now fall back to the first item in the matching resource. Without the fallback, tapping a ToC entry whose fragment points at a section heading or anchor that isn't itself a Sync Narration item (e.g. chap1.xhtml#title) only moved the visual reader — the audio player kept playing wherever it was.

iOS and Android have the same logic gap in FlutterMediaOverlay.itemFromLocator / findItemFromLocator. They already have a "no fragments + HTML → first item by href" path, but it's only reached when getTextId() returns nil / null. When textId is set but doesn't match any item, both early-return with no match and the audio nav is left alone.

Files / lines

Suggested fix

When findItemFromTextId returns nil/null, fall through to the existing items.first(where: textFile == href) / items.firstOrNull { it.textFile == href.path } line instead of returning early. Mirrors the web fix and the "no fragments + HTML" fallback both natives already have for the no-fragment case. Add a debug/warn log when the fallback fires so unmatched fragments stay discoverable.

Test scenario

  1. Open a Media Overlay EPUB whose ToC entries include fragments pointing at section headings without sync data (e.g. chap1.xhtml#title where title is an <h2 id="title"> and only <p> paragraphs have narration items).
  2. Start audio playback.
  3. Tap that ToC entry.
  4. Expected: visual reader scrolls to the section, audio resumes at the start of the matched resource.
  5. Actual (today): visual reader scrolls to the section, audio keeps playing wherever it was.

Why a follow-up

Discovered while fixing the web equivalent in the feat/web-feature-parity branch; kept scoped to web there to avoid expanding that PR into native code paths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions