DEV Community

NodeLane
NodeLane

Posted on

Bringing a desktop comic reader extension to Android: the interaction changes

A desktop comic reader can fit inside a phone viewport and still be awkward to use. Buttons may be technically visible but hard to hit, settings can cover the page, and a two-column comparison can make both versions unreadable.

I'm building NodeLane Comics, an open-source browser extension. It now has an Android Firefox entry point. This is a follow-up about the interaction decisions behind that work, rather than another product introduction.

1. A narrow window is not necessarily a phone

I wanted to keep the existing React components and reading workflow. A second mobile application tree would also mean a second place to maintain imports, translation state, and reading-position recovery.

The phone stylesheet is loaded after the desktop styles. Its outer gate combines a bounded device width with a coarse pointer or lack of hover:

@media (max-device-width: 1000px) and (pointer: coarse),
       (max-device-width: 1000px) and (hover: none) {
  @media (max-width: 700px),
         (max-width: 1000px) and (max-height: 500px) {
    .nc-app {
      --nc-phone-gutter: 12px;
      --nc-phone-gap: 8px;
      --nc-phone-hit: 44px;
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

This is the gate used by this project, not a universal device-detection recipe. The intention is to keep a narrow desktop window, a desktop extension popup, and a touch-enabled laptop from automatically receiving the full phone layout.

The compact landscape case matters too: a phone rotated sideways has more width, but very little height.

Implementation: phone.css

2. Touch targets need space; decoration can give some back

The mobile layout reduces panel padding and visual decoration without shrinking the controls people need to hit. Reader controls use 44px targets, and touch-oriented inputs keep a 16px minimum font size.

Navigation and page progress sit above the comic. Reading and translation controls sit below it. The directory and reading settings become full-screen drawers; translation settings use a bottom panel.

One small but important detail: hiding the controls should not change the comic's position. The reader keeps the relevant canvas space reserved, so bringing the controls back does not move the content underneath them. A tap can reveal tools; finger scrolling should not trigger desktop mouse-edge behavior.

This is less about making everything large and more about deciding what deserves the limited space.

3. Original/translation comparison should preserve readable text

On a desktop, two pages side by side are useful. On a narrow phone, squeezing each page into half the screen can defeat the point of comparison.

The narrow-screen layout preserves a readable page width and allows horizontal viewing instead. Switching back to the original remains available, and the existing reading-position restoration is retained.

I did not add a separate mobile translation workflow. The UI still consumes the same page-level results and failures. A layout change should not silently become a second implementation of task submission or recovery.

4. File import is a browser-and-OS interaction

The starting point remains a normal file input, not a custom imitation of the Android picker:

<input
  type="file"
  multiple
  accept={COMIC_ACCEPT}
  onChange={e => chooseFiles(Array.from(e.target.files ?? []))}
/>
Enter fullscreen mode Exit fullscreen mode

This shortened excerpt shows the existing import path. The supported collection includes CBZ/ZIP, CBR/RAR, PDF, and DRM-free MOBI/EPUB; the extension is not a loose-image organizer.

For a first mobile check, a small known CBZ is more useful than a huge archive. It separates basic picker/import problems from memory pressure, parsing time, and unusually complex files.

Original sample comic opened in Firefox on an Android emulator

Evidence boundary: this is an existing tutorial capture from Android 14 and Firefox 157.0.1, with a temporarily loaded Mozilla-signed 0.10.3 extension. The project's original sample was packaged as a one-page CBZ and imported through the real file picker. It illustrates the Android reading path, not the latest layout or verified permanent store installation, sign-in, or translation.

5. Missing desktop APIs must not prevent the reader from starting

Responsive CSS does not solve browser-extension compatibility.

Firefox Android may lack desktop capabilities such as commands, context menus, or separate browser windows. Initialization must tolerate those missing capabilities. For the Drive connection flow, the implementation can use a normal tab instead of requiring a separate window, while retaining the existing authorization message bridge.

The same principle applies to image handling: where OffscreenCanvas is unavailable, the extension has a native canvas fallback. That is a capability fallback, not permission to assume that authorization or processing succeeded.

A practical self-hosting detail belongs in the mobile instructions as well: localhost on a phone is the phone, not the computer running a translation service.

6. Keep resource use bounded, and name what a test proves

A comic reader can contain many large images. The mobile work keeps the existing bounded image window and virtualized shelf instead of rendering or decoding an entire library at once. The stylesheet does not add viewport polling or a second set of data requests.

I do not have a before/after device performance benchmark to claim here. Preserving those limits is a design constraint, not proof that every phone will handle a large PDF equally well.

There are also several different kinds of validation:

  • A narrow-screen browser test can check layout, target sizes, and position restoration.
  • An Android emulator can exercise the actual browser and file picker.
  • A physical device is still needed to check its installation path, keyboard, background behavior, authorization callbacks, and real reading workload.

Those should not be collapsed into a single “mobile works” checkbox. iOS / Orion remains compatibility work in progress, not a supported platform announcement.

Try the reading path

The Android Firefox guide has the official extension listing and setup steps. This is a Firefox extension, not a NodeLane APK, and the store's compatibility checks still apply.

Reading local originals does not require a NodeLane account. Official translation is optional, needs sign-in and an internet connection, and is subject to the current allowance or paid plan. A self-hosted translation service is another option.

For feedback, I'm especially interested in three concrete things: which file format failed to import, which control was hard to reach, and whether opening settings or switching page versions moved the reading position.

What desktop interaction did you have to rethink most when bringing an existing web app to touch screens?


AI assisted the English drafting of this article. The implementation details were checked against the project code and documentation; unverified device and service behavior is called out above.

Top comments (0)