The Problem

Privacy‑first PDF utilities are rare, and this repo attempts an offline‑only solution, but the codebase shows signs of maintainability debt that can slow feature work and increase risk of bugs.

What This Does

PaperKnifePlus is an Android PDF utility (merge, split, rotate, protect, image‑to‑PDF, rearrange, etc.) that processes files 100 % offline – no network calls, no telemetry.

  • Entry point: app/src/main/java/com/paperknifeplus/app/MainActivity.kt – the main Android activity that bootstraps the navigation graph and instantiates the UI component suite.
  • UI layer: 61 Kotlin files under app/src/main/java/com/paperknifeplus/app/ui/components/ each own a single function (e.g., MergeView.kt, SplitView.kt, ProtectView.kt, AboutView.kt). These composable‑style screens handle user interaction, invoke the data layer, and render the result.
  • Data layer: app/src/main/java/com/paperknifeplus/app/data/image/PdfPageFetcher.kt – fetches and manipulates PDF pages; it is called by multiple view components.
  • Theme & resources: app/src/main/java/com/paperknifeplus/app/ui/theme/Color.kt, Theme.kt, Type.kt plus font assets in res/font/.
  • Build: Gradle‑based (build.gradle.kts at root and app/build.gradle.kts). CI runs via GitHub Actions (.github/workflows/build.yml).
  • No backend: All PDF work occurs on the device; the repository contains no network‑related modules or API keys.

How It Is Wired

Execution flows from MainActivity.kt into the component stack. The activity sets up a navigation graph that directs touch events to the relevant view component. Each component calls PdfPageFetcher.kt for page‑level operations (extract, rotate, merge, split) and then updates its own UI (e.g., SuccessView.kt, LockedFilePrompt.kt).

  • Call graph: 45 Kotlin files analysed; 0 internal modules, 0 circular dependencies. The widest blast radius resides in MainActivity.kt – any change to the navigation graph ripples to every component that registers a destination.
  • Duplication: 598 repeated 6‑line blocks appear across 37 files, most notably in MainActivity.kt, SettingsView.kt, AboutView.kt, ProtectView.kt. The pattern is a copy‑paste of permission‑granting and file‑selection logic.
  • Oversized files: AboutView.kt, SignView.kt, WatermarkView.kt each exceed 600 lines, making local changes ripple widely.

How To Use It

  • Clone: git clone https://github.com/moses-y/PaperKnifePlus (verbatim URL).
  • Build: The repository uses Gradle but does not document a build command in the README. Typical invocation would be ./gradlew assembleDebug (run from the repo root), but this is not guaranteed to succeed without the Android SDK configured.
  • Run: No CLI or server start‑up is provided; the intended usage is to install the generated APK on an Android device or emulator. The README only lists a download link to the latest release APK.
  • Configuration: No environment variables, keys, or config files are required – the app runs offline by design.

Real‑World Use

A user opens the app, selects Merge, picks two PDFs from local storage, and taps “Merge”. MergeView.kt invokes PdfPageFetcher.kt to read the files, concatenates pages in memory, and returns a single PDF that is saved back to the device. No internet traffic occurs; the whole pipeline stays on‑device.

Code Health & Issues

  • High cognitive load – deep nesting: Max indentation depth 14 in MainActivity.kt, PdfPageFetcher.kt, AboutView.kt. Control flow is hard to follow; guard‑clause refactoring is recommended.
  • High clarity – duplicated code blocks: 598 repeated 6‑line blocks across 37 files. Extract shared helpers for permission handling, file selection, and PDF‑operation scaffolding.
  • Medium oversized files: AboutView.kt, SignView.kt, WatermarkView.kt each >600 lines; split into smaller, responsibility‑focused units.
  • SDLC observations: No test files detected; CI (GitHub Actions) present; licence GPL‑3.0‑or‑later included; no Dockerfile; no lockfile (Gradle version catalog present but lockfile not committed).

The Bottom Line

PaperKnifePlus delivers a solid offline PDF toolkit with a clear privacy stance, but the codebase suffers from nesting depth, copy‑paste duplication, and a few oversized files that raise maintenance risk. Teams looking for a quick, privacy‑first PDF utility can adopt the released APK immediately; those planning to extend or refactor the UI should budget time for nesting flattening and duplication removal.