Skip to content

refactor: route external links through a platform opener seam - #80

Merged
iamdarkle merged 5 commits into
flectar:mainfrom
springmin:pr4-opener
Oct 18, 2026
Merged

iamdarkle merged 5 commits into
flectar:mainfrom
springmin:pr4-opener

Conversation

@springmin

@springmin springmin commented Oct 17, 2026 •

Copy link
Copy Markdown
Contributor

Email links previously called webbrowser::open directly, which cannot launch a browser on hosts without desktop helper processes.

PlatformContext now carries a cloneable ExternalUrlOpener. Native hosts install their URL bridge on the context; the application uses it for email links and browser-based OAuth, including reconnection, calendar authorization, and retries. Host errors propagate without falling back to desktop launchers.

Email links retain their scheme allowlist and in-app mailto handling. OAuth validates HTTPS addresses before dispatch. Default desktop behavior is preserved, including the Linux portal and AppImage library-path handling for authorization.

Hosts migrating from the initial version of this PR replace set_external_url_opener(bridge::open_url) with:

platform.external_urls = flectar_mail::ExternalUrlOpener::new(bridge::open_url);

The callback must accept calls from the application event loop and OAuth worker threads. The contract and migration are documented in platform/README.md. The stacked OpenHarmony host in #85 needs this assignment after constructing its mutable context.

The dependency follow-up updates ammonia to patched version 4.1.8 in both lockfiles and the Flatpak source manifest, and documents three maintenance-notice exceptions for crates merged into zbus 6. Slint and desktop portal dependencies still require zbus 5; vulnerability findings and all other warnings remain denied.

Validation

  • Formatting and platform-boundary lint pass locally.
  • Workspace Clippy with all targets and warnings denied passes locally.
  • Regression coverage includes URL policy, error propagation, independent host instances, worker-thread dispatch, reader callbacks, in-app compose, and OAuth retries.
  • The URL-opener commit passed the full local suite (948 passed, zero failed, eight ignored), the build without default features, and all six build/lint/test CI jobs.
  • Both locked dependency graphs pass the RustSec audit after the dependency follow-up. Android lockfile metadata validation passes.
  • With patched ammonia, all core targets pass (611 passed, zero failed, two ignored), and core Clippy passes with warnings denied.
  • All 13 release tests and Blitz/Flatpak source verification pass locally.
  • Cross-platform CI is rerunning on the final commit.

Contribution and licensing

  • I have the right to submit this work.
  • Third-party dependencies/assets: none added.
  • Disclosed generative-tool assistance: the change was developed with an
    AI coding agent (LLM); I reviewed every line, ran the checks above, and
    tested the behavior as described.
  • No credentials, private mailbox data, signing material, or unnecessary
    personal information included.

Email links called webbrowser::open directly, which fails on platforms that
cannot spawn helper processes (there is no xdg-open and friends everywhere).
The provider authorization flow already had a platform-aware opener; this
generalizes the path for arbitrary external addresses:

- browser::set_external_url_opener() lets a platform integration install its
  own opener (first registration wins).
- browser::open_external() uses that opener when present and falls back to
  the webbrowser crate otherwise (no behavior change on desktop).
- open_email_link uses it instead of calling webbrowser directly.
@iamdarkle

Copy link
Copy Markdown
Member

Thanks for this contribution, the platform opener is a useful addition. I've moved it into PlatformContext, shared it with browser-based OAuth, and added regression coverage. CI is green; once I resolve the conflict with main in quality.yml and CI passes again, this is ready to merge.

For #85, please replace the global set_external_url_opener registration with platform.external_urls = ExternalUrlOpener::new(bridge::open_url); on the PlatformContext returned by app_private, and verify link opening and OAuth on a device

@iamdarkle
iamdarkle merged commit 31f5d0e into flectar:main Oct 18, 2026
7 checks passed
springmin added a commit to springmin/mail that referenced this pull request Oct 18, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
springmin added a commit to springmin/mail that referenced this pull request Oct 20, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
springmin added a commit to springmin/mail that referenced this pull request Oct 20, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
springmin added a commit to springmin/mail that referenced this pull request Oct 21, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
springmin added a commit to springmin/mail that referenced this pull request Oct 22, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
springmin added a commit to springmin/mail that referenced this pull request Oct 23, 2026
Tier-3 community port (maintainer: springmin), rebased onto the merged
document-provider abstraction (flectar#84) and the opener seam (flectar#80).

- platform/ohos: Slint backend (XComponent window adapter, software renderer
  with the experimental femtovg/wgpu path, input/IME, clipboard, system
  fonts), the NAPI cdylib that builds a PlatformContext (app-private paths,
  DocumentProvider over the ArkTS pickers, Asset Store credential store,
  loopback OAuth broker, external URL opener, notification publisher) and
  calls flectar_mail::run, the demo crate, the ArkTS shell and the build and
  packaging scripts (bundle name configurable, defaults to
  com.flectar.mail_ohos).
- src/platform/ohos.rs: PDFium directory, renderer name, thread priority,
  preview lifecycle, email font directory; OpenHarmony stays under the
  mobile capability alias.
- patches/fontique + crates/fontique: the Fontconfig opt-out as a patch queue
  applied by the platform/ohos workspace, verified from quality.yml.
- .github/workflows/ohos.yml: manually dispatched tier-3 workflow, unsigned by
  default, signing material only from the FLECTAR_OHOS_* secrets.
- src/documents.rs: run_request blocks the calling thread on mobile hosts;
  the picker covers the window, and keeping the presentation thread idle is
  what OpenHarmony needs (verified on device; desktop keeps the runtime
  request for the native dialog).
- The email renderer and the compose editor load platform::email_font_dir()
  and the Han fallback, so CJK mail bodies and composed text render with the
  platform fonts.
- New-mail notifications: a publisher seam fed by CoreEvent::MailNew; the host
  publishes through @kit.NotificationKit.
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