Skip to content

Add format-aware monograph reader selection and dual-format indexing#3991

Draft
Copilot wants to merge 3 commits into
masterfrom
copilot/add-choose-format-dropdown
Draft

Add format-aware monograph reader selection and dual-format indexing#3991
Copilot wants to merge 3 commits into
masterfrom
copilot/add-choose-format-dropdown

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 31, 2026

Monographs with both public EPUB and PDF featured representatives always resolved to EPUB, with no user-facing way to select format. This change adds a format-selection flow (reader_format) to reader/ToC behavior and updates indexing to include accessibility metadata and ToCs from both ebook formats.

  • Reader format selection + visibility gating

    • Added reader_ebook_id_for_format(format_param) while preserving existing reader_ebook_id EPUB-preferred behavior.
    • Added both_ebook_formats_public? to detect when EPUB+PDF reps both exist and are publicly visible.
    • Sanitized and threaded @reader_format (epub|pdf only) in MonographCatalogController.
    • Updated reader_links_display visibility checks to evaluate the selected ebook format, not implicit EPUB.
  • Catalog UI updates

    • Added a Choose Format dropdown (left of Read Book) when both ebook formats are public and reader UI is shown.
    • Dropdown links set reader_format on the monograph catalog URL.
    • Updated Read Book link target to resolve via selected format while preserving princess_de_cleves routing behavior.
    • Added monograph_catalog.index.choose_format locale string.
  • ToC format-awareness

    • Updated _index_epub_toc to select EPUB/PDF presenter based on @reader_format.
    • Updated ToC entry links to route into the selected ebook.
    • Kept fallback behavior to default reader ebook when needed.
  • Indexer: include both formats

    • maybe_index_accessibility_metadata now indexes both EPUB and PDF metadata when present and writes multivalued reader_ebook_format_sim.
    • table_of_contents now aggregates titles from both EPUB and PDF ToCs and de-duplicates for table_of_contents_tesim.
  • Spec updates

    • Added/updated presenter specs for reader_ebook_id_for_format and both_ebook_formats_public?.
    • Added controller specs for reader_format sanitization and format-aware reader visibility behavior.
    • Updated indexer specs to assert dual-format accessibility indexing and combined ToC indexing.
    • Updated view specs for choose-format rendering and format-aware read-link behavior.
def reader_ebook_id_for_format(format_param = nil)
  epub_id_val = nil
  pdf_id_val = nil

  featured_representatives.each do |fr|
    epub_id_val = fr.file_set_id if fr.kind == 'epub'
    pdf_id_val = fr.file_set_id if fr.kind == 'pdf_ebook'
  end

  if format_param == 'pdf' && pdf_id_val.present?
    pdf_id_val
  else
    epub_id_val || pdf_id_val
  end
end
Original prompt

Overview

When a Monograph has both an EPUB and a PDF FeaturedRepresentative (each with a public FileSet), users should be able to choose which format to read. Currently the system always silently prefers the EPUB. This PR introduces:

  1. A "Choose Format" dropdown button — shown to the left of "Read Book" when both EPUB and PDF are available and public.
  2. A ?reader_format=pdf URL parameter — selecting PDF from the dropdown appends this param to the reader URL, and all presenter / ToC logic respects it.
  3. Indexing both formats' accessibility metadata in MonographIndexer#maybe_index_accessibility_metadata.
  4. Indexing both ebooks' ToCs in MonographIndexer#table_of_contents (the table_of_contents_tesim field is multivalued and is only used for Monograph discovery at the Press level).

Detailed Changes

1. New presenter method: both_ebook_formats_public?

Add to app/presenters/concerns/featured_representatives/monograph_presenter.rb:

# Returns true when both an EPUB and a PDF ebook FeaturedRepresentative exist
# AND the corresponding FileSets are both publicly visible.
# Used to decide whether to show the "Choose Format" dropdown.
def both_ebook_formats_public?
  return false unless epub? && pdf_ebook?
  epub_doc = featured_representative_docs.find { |doc| doc.id == epub_id }
  pdf_doc  = featured_representative_docs.find { |doc| doc.id == pdf_ebook_id }
  epub_doc&.fetch('visibility_ssi', nil) == 'open' &&
    pdf_doc&.fetch('visibility_ssi', nil) == 'open'
end

2. Update reader_ebook_id to respect ?reader_format=pdf

The presenter currently has no knowledge of the request. Pass the optional format preference into reader_ebook_id (or add a separate preferred_reader_ebook_id(format: nil) helper). The cleanest approach that avoids threading request through the presenter is to add a new method and keep the original for backwards compatibility:

def reader_ebook_id_for_format(format_param = nil)
  epub_id_val = nil
  pdf_id_val  = nil
  featured_representatives.each do |fr|
    epub_id_val = fr.file_set_id if fr.kind == 'epub'
    pdf_id_val  = fr.file_set_id if fr.kind == 'pdf_ebook'
  end
  if format_param == 'pdf' && pdf_id_val.present?
    pdf_id_val
  else
    epub_id_val || pdf_id_val
  end
end

3. Thread reader_format param through MonographCatalogController

In monograph_auth_for (and reader_links_display), expose @reader_format = params[:reader_format] and set it on the instance. Pass it to view helpers where needed.

Update reader_links_display to use reader_ebook_id_for_format(@reader_format) when checking visibility:

def reader_links_display
  return :not_shown if @monograph_presenter.tombstone? || @monograph_presenter.subdomain == 'ee' || !@monograph_presenter.reader_ebook?

  return :linked if valid_share_link?

  # Use the format-aware ebook ID for visibility check
  ebook_id = @monograph_presenter.reader_ebook_id_for_format(@reader_format)
  ebook_doc = @monograph_presenter.featured_representative_docs.find { |doc| doc.id == ebook_id }
  return :not_shown unless ebook_doc&.fetch('visibility_ssi', nil) == 'open'

  if @monograph_presenter.access_level(@actor_product_ids, @allow_read_product_ids).show? &&
     @monograph_presenter.access_level(@actor_product_ids, @allow_read_product_ids).level == :restricted
    :not_linked
  else
    :linked
  end
end

4. Update _read_download_buy.html.erb — add "Choose Format" dropdown

Insert the new dropdown before the Read Book button (i.e. it appears to the left of it). Show it only when @monograph_presenter.both_ebook_formats_public? and the reader is shown (not tombstoned, not ee press, etc.).

<%# Choose Format dropdown — only shown when both EPUB and PDF are public %>
<% if @monograph_presenter.both_ebook_formats_public? && @reader_links_display != :not_shown %>
  <div class="btn-group btn-group-lg" id="monograph-choose-format-group">
    <button type="button"
            id="monograph-choose-format-btn"
            aria-haspopup="true"
            class="btn btn-default dropdown-toggle"
            data-toggle="dropdown"
            aria-expanded="false">
      <%= t('monograph_catalog.index.choose_format', default: 'Choose Format') %>
      <span class="caret"></span>
    </button>
    <ul class="dropdown-menu" role="menu">
      <li role="menuitem">
        <a href="<%= monograph_catalog_path(@monograph_presenter.id, reader_format: 'epub') %>"
           data-turbolinks="false">EPUB</a>
      </li>
      <li role="menuitem">
        <a href="<%= monograph_catalog_path(@monograph_presenter.id, reader_format: 'pdf') %>"
           data-turbolinks="false">PDF</a>
      </li>
    </ul>
  </div>
<% end %>

5. Update the Read Book button href to carry reader_format through to the reader

The Read Book button currently links directly to epub_path(@monograph_presenter.reader_ebook). When `@reader_format ==...

This pull request was created from Copilot chat.

Copilot AI self-assigned this May 31, 2026
Copilot AI review requested due to automatic review settings May 31, 2026 20:02
Copilot AI review requested due to automatic review settings May 31, 2026 20:02
Copilot AI requested review from Copilot and removed request for Copilot May 31, 2026 20:14
Copilot AI changed the title [WIP] Add choose format dropdown for EPUB and PDF Add format-aware monograph reader selection and dual-format indexing May 31, 2026
Copilot AI requested a review from conorom May 31, 2026 20:15
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