Skip to content

[FEATURE] Named settings profiles #98

Description

@egdels

Named settings profiles

Split out from RFC #95 by @mikenrafter.

Problem

MakeACopy has one set of settings. Someone who scans receipts in the morning
and book chapters in the evening changes OCR language, aspect ratio, output
format and edge-detection behaviour every time they switch.

Proposal

Let the user save the current settings under a name and switch between saved
profiles with one tap.

  • A profile captures the user-facing preferences: camera options, crop aspect
    ratio and snapping, OCR language and preprocessing, layout and
    post-processing options, PDF and JPEG output options, cleanup, focus and
    exposure.
  • A profile picker in the options dialog, showing the active profile by name.
  • Create, rename, duplicate, delete.
  • Export a profile to a file and import one, via the system file picker, so
    profiles can be shared between devices.
  • Switching profiles first saves the current settings into the profile being
    left, then applies the selected one, so no change is lost.

Profiles hold preferences only. They never own scanned pages, the batch queue,
or the document library.

Foundation in main

The settings were restructured before this request so that profiles can be
built without a hand-written list of keys:

  • de.schliweb.makeacopy.settings.SettingsCatalog lists every user-facing
    preference with its file, key, type, default and group. SettingsCatalogTest
    scans the sources and fails when a preference is written anywhere without
    being listed. A profile is a snapshot of this catalog.
  • OptionsDialogFragment is the one options dialog (Scan, Camera, OCR, Export,
    Library, App). The OCR, Export and Library screens open it at their own group
    and see only that group and the ones after it. The options themselves live in
    OcrOptionsPanel, ExportOptionsPanel and LibraryOptionsPanel, which read
    from and write to SharedPreferences.

Design

  1. Scope. Add a scope to each catalog entry: PROFILE or DEVICE. Scan,
    Camera, OCR, Export, Crop and Library settings are PROFILE, including the
    inbox folder URI, so a "books" profile and a "notes" profile can export to
    different folders. App language, accessibility mode and the active profile
    id are DEVICE and stay out of profiles. A PROFILE entry can additionally
    be marked deviceBound; it is stored in the profile but omitted from the
    exported file and ignored on import. The inbox folder URI is the first such
    entry: it is a storage permission of this device and means nothing on
    another one. inbox_enabled travels with the profile but only takes effect
    once a folder is chosen.
  2. Snapshot. SettingsSnapshot.capture(context) and
    apply(context, snapshot) iterate SettingsCatalog.ALL by type. No key is
    named twice; a new catalog entry is in the snapshot automatically.
  3. File format. Versioned JSON: {"version": 1, "app": "<versionName>", "settings": {...}}. On import, unknown keys are ignored and missing keys are
    filled from the catalog defaults, so older exports stay readable.
  4. Storage. A Room entity SettingsProfile(id, name, json, createdAt, updatedAt) with a regular, non-destructive migration. The active profile id
    is a DEVICE preference.
  5. Picker. A row at the top of the options dialog, above the groups:
    "Profile: ▾". It is offered only when the dialog is opened from the
    camera screen, because switching a profile changes Scan and Camera settings,
    which the later screens must not touch for the current document. From the
    other screens the row shows the name without a menu, or is hidden.
    Selecting a profile loads its values into the dialog's controls (the panels
    can read from a SharedPreferences implementation backed by the snapshot),
    Confirm writes them and marks the profile active, Cancel changes nothing.
    Before applying, the settings being left are saved into the previous
    profile.
  6. Menu. Switch, save as, rename, duplicate, delete, export, import. With
    no profiles saved yet, the row offers only "Save as profile…".
  7. Import/export through the storage access framework, file suffix
    .makeacopy-profile.json. Separate PR.

Acceptance criteria

  • A fresh install behaves exactly as today. Profiles only appear once the user
    creates one.
  • Every PROFILE setting in SettingsCatalog is part of the snapshot; there
    is no separate key list to maintain.
  • Plain-JVM unit tests cover snapshot round trip (via a SharedPreferences
    fake), JSON round trip, and importing a file of an older version.
  • Exported profile files are versioned so older exports can still be imported
    after the schema changes.
  • Storage in the existing Room database with a proper migration; no
    destructive migration.
  • The picker is only offered from the camera screen.
  • A profile exported on one device and imported on another never carries a
    folder URI; after the import, inbox mode waits for a folder to be chosen.
  • All new strings are translated before release.

Reference

The fork linked in #95 has an implementation with a Room entity, a snapshot
helper covering 37 preference keys, a bottom-sheet picker and SAF import and
export. It is a reference for scope, not a base for the code.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions