Skip to content

Import notes from My Notes (one-way hand-off) #46

Description

@pasichDev

Encly is the successor of My Notes. My Notes will get a page that introduces Encly and hands all its data over in one tap. This issue is the Encly side: receive that hand-off and import it into the vault.

One way only. My Notes → Encly. Encly never exports to or accepts requests from My Notes; it exposes no provider and nothing readable.

Counterpart: pasichDev/MyNotes#167. This one ships first: My Notes can only offer the button once an Encly release can receive.

Hand-off contract (shared with My Notes)

  • My Notes starts com.pasich.encly.action.IMPORT_FROM_MY_NOTES with an explicit package, startActivityForResult, and a content:// URI from its own FileProvider with FLAG_GRANT_READ_URI_PERMISSION.
  • The URI is a ZIP with handoff.json (format mynotes-handoff, schema: 1); attachment files are not sent. It carries raw My Notes data and Encly does the mapping, so the Encly block format stays private to Encly.
  • handoff.json: notes (incl. trashed), tags, tasks and task categories. Each record has a stable id (My Notes sync_metadata.stableId, or mynotes:<type>:<id> when missing), so a second hand-off adds nothing twice.
  • Result: RESULT_OK with counts (notes, tasks, tags, skipped) or RESULT_CANCELED with a reason code.

Encly side

  • Exported ImportFromMyNotesActivity for that action only.

  • Trust check before reading anything: getCallingPackage() == "com.pasich.mynotes" and PackageManager.hasSigningCertificate(…, CERT_INPUT_SHA256) against the pinned My Notes Play signing certificate. <queries><package android:name="com.pasich.mynotes" /></queries>. Anything else is refused without reading the URI.

  • Vault must be unlocked (normal PIN / biometric flow); then a preview: N notes, M tasks, K tags, what will not come over. Import only after the user confirms.

  • Strict parsing with size limits (total bytes, records, note length); unknown schema → "update Encly".

  • Mapping into the existing BackupImporter MERGE path (one transaction, uid-based skip):

    • plain note (valueJson empty) → one TEXT block per paragraph
    • Editor.js paragraph → TEXT, Headers/header level 1–4 → H1–H4, list unordered/ordered → LIST_BULLET/LIST_NUMBER (nested items flattened), checklist → LIST_CHECK, delimiter → SEPARATOR, spacer dropped
    • inline HTML (<b>, <mark>, <code>, <br>, entities) → plain text; no raw HTML reaches the vault
    • tag name → Encly tag (created once, matched by name); task category → tag
    • trashed notes → Encly trash; reminders dropped (Encly has none by design)
    • image / attaches: not imported; the preview says how many attachments stay in My Notes
  • Result screen + setResult counts; the temporary copy is wiped.

  • Tests: mapper per block type, malformed/oversized input, wrong caller, wrong certificate, repeat hand-off imports nothing.

  • Strings in all 9 locales; CHANGELOG; PRIVACY.md (data arrives on## Decided

  • Attachments and images are not imported (Encly has no attachment blocks); the preview and the result show how many were skipped.

Later

  • Pin the My Notes Play app signing certificate SHA-256 (Play Console → My Notes → App signing) when the work starts.

Activity

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

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions