Prepare v0.4 release and open source docs

This commit is contained in:
Akshay Kolli
2026-06-29 23:42:39 -07:00
parent 085d7a16dc
commit 504bd2d39a
58 changed files with 5076 additions and 923 deletions

View File

@@ -4,9 +4,13 @@ Bundle ID: `net.akkolli.ihatepdfs`
Current App Store build values:
- `CFBundleShortVersionString`: `0.3.0`
- `CFBundleVersion`: `4`
- `CFBundleShortVersionString`: `0.4.0`
- `CFBundleVersion`: `6`
- Privacy policy URL: `https://www.akkolli.net/ihatepdfs/privacy`
- Marketing/support URL: `https://www.akkolli.net/ihatepdfs`
Paste-ready metadata, review notes, privacy answers, and screenshot guidance live in `docs/APP_STORE_COPY.md`.
The general release checklist is in `docs/RELEASE.md`.
## Required Apple Developer Items
@@ -33,12 +37,24 @@ PROVISIONING_PROFILE="$HOME/Downloads/IHatePDFs_AppStore.provisionprofile" \
scripts/make-app-store-pkg.sh
```
The package is written to `dist/IHatePDFs-v0.3-macos-appstore.pkg`.
The package is written to `dist/IHatePDFs-v0.4-macos-appstore.pkg`.
The script derives the App Store application identifier and team identifier from the provisioning profile before signing. It also clears download quarantine metadata from the bundle before packaging, because App Store Connect rejects packages that contain quarantine extended attributes.
The script derives the App Store application identifier and team identifier from the provisioning profile before signing. It builds the App Store app in a temporary staging directory, so the direct-download `dist/I Hate PDFs.app` remains a clean app bundle without an embedded provisioning profile. It also clears download quarantine metadata from the staged bundle before packaging, because App Store Connect rejects packages that contain quarantine extended attributes.
If macOS opens a Keychain private-key access prompt during `codesign`, approve it, preferably with Always Allow for the selected signing certificate, and rerun the command. The build cannot finish unattended until the private key for the selected application signing certificate is allowed.
Before uploading, verify that the package matches the current build number:
```sh
REQUIRE_APP_STORE_PKG=1 scripts/verify-release-artifacts.sh
```
This catches stale package files, bundle-ID mismatches, missing embedded provisioning profiles, missing sandbox/user-selected-file entitlements, and app/package version mismatches.
Use `pkgutil --check-signature` and App Store Connect or Transporter validation for this App Store package. A local `spctl -t install` assessment is a Developer ID distribution check and may reject a package signed with the Mac App Store `3rd Party Mac Developer Installer` identity even when the package signature is valid for App Store upload.
## Upload
Upload the `.pkg` with Transporter. You can also set `VALIDATE_WITH_ALTOOL=1` when running `scripts/make-app-store-pkg.sh` if you want the script to perform an `altool` validation after packaging. After App Store Connect processes the build, select it in the app version, finish metadata, answer App Privacy, fill review notes, and submit for review.
Keep `CFBundleShortVersionString` as `0.3.0` and `CFBundleVersion` as `4` for this upload. Increment `BUILD_NUMBER` in `scripts/release-version.sh` before uploading another build for the same version.
Keep `CFBundleShortVersionString` as `0.4.0` and `CFBundleVersion` as `6` for the next upload. Increment `BUILD_NUMBER` in `scripts/release-version.sh` before uploading another build for the same version.

97
docs/APP_STORE_COPY.md Normal file
View File

@@ -0,0 +1,97 @@
# App Store Copy
Use this as the source of truth when filling out App Store Connect for `net.akkolli.ihatepdfs`.
## URLs
- Marketing URL: `https://www.akkolli.net/ihatepdfs`
- Support URL: `https://www.akkolli.net/ihatepdfs`
- Privacy Policy URL: `https://www.akkolli.net/ihatepdfs/privacy`
## Copyright
`2026 Akshay Kolli`
## App Information
- Name: `I Hate PDFs`
- Subtitle: `A small PDF review app`
- Category: `Productivity`
- Secondary category: `Education`
## Promotional Text
Read, highlight, comment, and review local PDFs without accounts, cloud upload, or heavyweight document management.
## Description
I Hate PDFs is a small native macOS app for reading and reviewing local PDF files.
Open a PDF, highlight important text, add comments, write free-text notes, and review everything from a compact comments sidebar. The app writes standard PDF annotations so your saved files can be opened in common PDF readers like Preview and Adobe Acrobat.
The app is intentionally lightweight. It uses native macOS document behavior, keeps your PDFs on your Mac, and does not require an account.
Features:
- Open local PDF files from disk, Finder, drag and drop, or recent documents.
- Read with native PDFKit scrolling, zoom, fit-to-width, fit-to-page, page navigation, and search.
- Highlight selected text without opening an unnecessary comment box.
- Add selected-text comments, underline comments, and free-text notes.
- Press Return to save comments and Shift-Return to insert a new line.
- Review annotations in a comments sidebar with search, filters, replies, edit, delete, and click-to-navigate.
- Customize highlight and comment colors from Settings.
- Save annotations directly into a PDF after an overwrite warning, or use Save As for a separate annotated copy.
- Share the saved PDF through the native macOS share sheet.
Privacy:
I Hate PDFs does not collect analytics, does not require sign-in, and does not upload your documents. Your PDFs stay on your Mac unless you choose to share them.
## Keywords
pdf,reader,annotate,highlight,comments,review,professor,academic,documents,notes
## What's New
Keeps the app focused on fast local PDF reading and annotation, with recent PDFs, focused open behavior, sidebar polish, bookmarks, highlight sorting, and Settings for annotation colors.
## App Review Notes
I Hate PDFs is a local macOS PDF reader and annotation utility.
No account is required. The reviewer can test with any local `.pdf` file. The app asks for user-selected file access only when opening, saving, or sharing a PDF.
Suggested review path:
1. Launch the app.
2. Open or drag in any PDF.
3. Select text and add a highlight or comment.
4. Open the comments sidebar to review annotations.
5. Save As to create an annotated copy.
6. Open Settings with Command-, or File > Settings... to change annotation colors.
7. Open Bookmarks and Highlights from the sidebar controls to verify the review views.
## App Privacy Answers
Recommended App Privacy summary:
- Data collection: no data collected.
- Tracking: no tracking.
- Third-party advertising: no.
- User account required: no.
The app works with user-selected local PDF files. It does not transmit documents to a server and does not include analytics.
## Screenshot Checklist
Use real bitmap screenshots, not drawn SVG mockups.
Required minimum set:
- Empty window with the Open PDF action and compact Recent PDFs area.
- Main reading view with a PDF page dominant.
- Highlight or comment editor popover on selected text.
- Comments sidebar with several annotations and at least one reply.
- Settings window showing color controls.
Capture light-mode screenshots first. Add dark-mode screenshots if they make the product quality clearer.

View File

@@ -21,7 +21,8 @@ Status: Pass for the current version 1 implementation direction, with manual vis
- Platform fit: The app is macOS-only, targets macOS 13 or newer, uses SwiftUI/AppKit/PDFKit, and ships as a normal `.app` bundle inside a `.dmg`.
- Window and toolbar: Primary document controls live in the titlebar toolbar, grouped by opening/sharing, navigation, zoom, annotation, search, and saving.
- Menus and shortcuts: File, View, and Annotate commands are available through native command menus with standard keyboard shortcuts where appropriate.
- Sidebars: Page thumbnails, annotation list, and comments review are optional sidebars. The default open-PDF state is single-pane reading, and sidebars open only when requested or restored from user preference.
- Sidebars: Page thumbnails, annotation list, and comments review are optional sidebars. The default open-PDF state is single-pane reading, and sidebars open only when requested.
- Responsive layout: Compact windows use a compact toolbar/status treatment and keep sidebars mutually exclusive; regular and wide windows can show both sidebars while preserving a usable PDF reading width.
- Comments review: The comments sidebar uses a compact review-stream layout with a visible total count, add-comment affordance, collapsible page groups, hidden search/filter controls, and connected reply threads.
- Color and appearance: The UI uses system colors and materials, so light mode, dark mode, and automatic appearance inherit from macOS.
- Typography: Text uses system fonts and native SwiftUI controls; no custom brand typography is used in the reading interface.
@@ -33,6 +34,6 @@ Status: Pass for the current version 1 implementation direction, with manual vis
- Run the app on both Apple Silicon and Intel hardware.
- Verify contrast and focus states in light and dark mode.
- Verify toolbar and sidebar behavior at narrow and wide window sizes.
- Verify toolbar and sidebar behavior at compact, regular, and wide window sizes.
- Verify keyboard-only operation for opening, searching, navigating, annotating, saving, and reviewing comments.
- Verify VoiceOver labels for toolbar buttons and sidebar controls.

View File

@@ -24,6 +24,8 @@ Every change should aim for the smallest final app that still delivers the requi
The release DMG should stay as small as practical. Treat size growth as a product regression, not just a packaging detail.
Hard release-size budget: each direct-download per-architecture installer must be under 400 KB, measured as fewer than 400,000 bytes. Universal builds may be larger, but they do not satisfy the small-download budget. Run `scripts/make-tiny-archives.sh` before release; it builds and checks `IHatePDFs-v<version>-macos-arm64.tar.xz` and `IHatePDFs-v<version>-macos-x86_64.tar.xz` by default.
Before merging release-impacting work, compare:
```sh

View File

@@ -0,0 +1,35 @@
# Functionality Audit
Date: 2026-06-29
## Current Build Scope
I Hate PDFs v0.4 is a small native macOS PDF reader and annotation app. The shipping scope is:
- Local PDF opening, recent documents, drag/drop, close-current-PDF, and focused reader startup.
- PDFKit reading, page navigation, zoom, fit controls, search, and responsive sidebars.
- Highlights, underline comments, selected-text comments, free text, replies, review state, filters, grouped comments, bookmarks, and highlight sorting.
- Settings for highlight and comment colors.
- Save, Save As, native Share, overwrite warnings, unsent reply-draft warnings, and empty temporary annotation cleanup.
- Lightweight release packaging with `.app`, `.dmg`, tiny per-architecture archives, and App Store package scripts.
## Removed Scope
The experimental Fill & Sign and PDF signing work has been removed from source, tests, scripts, settings, menus, and release docs for v0.4. This includes custom flat fill marks, form-field scanning/navigation, form choice editing, Keychain-backed PDF signing, signature validation/inspection, and signed-document save branching.
## Verification
Run before release:
```sh
swift build
swift test
swift scripts/verify-sample-pdf.swift
swift scripts/verify-pdf-annotations.swift
scripts/build-app.sh
scripts/make-dmg.sh
scripts/make-tiny-archives.sh
scripts/verify-release-artifacts.sh
```
Manual QA remains documented in `docs/QA.md`.

View File

@@ -2,6 +2,25 @@
Run this checklist before tagging a public release.
## Latest v0.4 Automated QA Run
Completed on 2026-06-29:
- `swift build`
- `swift test`
Before release, also run:
```sh
swift scripts/verify-sample-pdf.swift
swift scripts/verify-pdf-annotations.swift
swift build -c release --product IHatePDFs
scripts/build-app.sh
scripts/make-dmg.sh
scripts/make-tiny-archives.sh
scripts/verify-release-artifacts.sh
```
## Test Files
Use at least:
@@ -14,51 +33,36 @@ Use at least:
## App Workflow
1. Open the PDF in I Hate PDFs.
2. Close the PDF, then drag a `.pdf` file onto the empty no-document window and verify it opens.
3. Open Settings from File > Settings... and with Command-, then verify highlight color, comment color, and opacity changes can be edited and reset.
4. Select text and add a highlight; verify no comment popover opens.
5. Select text and add a comment; verify the comment color matches the Settings value.
6. In the comment box, press Shift-Return and verify it inserts a new line, then press Return and verify the comment is saved.
7. Add an underline with a comment.
8. Select text, right-click, and add a comment from the context menu.
9. Add free text directly on the page.
10. Open the comments sidebar and verify count, grouping, search, filters, edit, delete, reply, and click-to-navigate.
11. Quit and reopen the same PDF at the same approximate window width and verify the app restores that PDF's sidebar state; then open a different PDF and verify it starts in focused single-pane reading unless that document has its own saved state.
12. Add at least one reply and verify the comments sidebar presents the thread like a clean review/chat stream, with a visible connector line from the parent comment to the reply.
13. Hover a comment row and verify the corresponding PDF text is highlighted; click both the parent comment text and the reply text in the sidebar and verify the PDF view navigates to and selects the corresponding annotation.
14. Click on commented text and underlined text and verify the comment popover opens; then click the line below or nearby whitespace and verify no popover opens.
15. Verify highlights, comment markers, hidden page-level replies, and selected sidebar rows use muted native-feeling colors in light mode and do not visually overpower the document.
16. Switch the app to dark mode and verify the reading background, comments sidebar, editor popover, connector lines, selected rows, text fields, and annotation markers remain legible and restrained.
17. Save As an annotated copy.
18. Reopen the annotated copy in I Hate PDFs and verify the annotations and comments remain.
19. Save over a disposable original and verify the overwrite warning appears.
20. Add an annotation and verify the window shows the native macOS unsaved/edited document indicator until the PDF is saved.
21. Search for a word, close the search toolbar, and verify the match highlights disappear; repeat after opening a different PDF to confirm stale search highlights do not carry over.
22. Type an invalid page number and an out-of-range page number in the page field, and verify the app restores the current page number with a clear status message; also verify previous/next page controls disable at the first and last pages.
23. Apply comment filters or search text that hide every comment, verify the empty state offers Clear Filters, and verify page counts include visible replies.
24. Collapse a page group in the comments sidebar, search for a comment on that page, and verify the matching results are shown while the filter is active.
25. Start typing a sidebar reply, click Reply on a different comment, and verify the original draft remains until you send or cancel it.
26. Click one comment row, then click Reply on a different comment or reply, and verify the sidebar selection and PDF highlight move to the reply target.
27. Click one comment row, then click Edit or the review-status chip on a different row, and verify the sidebar selection and PDF highlight move to the edited or reviewed row.
28. Set a comments-sidebar filter and collapse a page group, then open another PDF and verify the comments sidebar starts unfiltered with page groups expanded.
29. In Settings, choose very low-opacity highlight and comment colors, add each annotation type, and verify saved annotations remain visibly readable.
30. Start typing a sidebar reply without sending it, then close or replace the PDF and verify the app asks before discarding the draft and the window shows the edited indicator while the draft exists.
31. Start typing a sidebar reply without sending it, choose Share, and verify the app warns that the draft will not be included unless it is sent first.
32. Start typing a sidebar reply, delete the comment thread it belongs to, and verify the app asks before discarding the reply draft.
33. Add replies to a comment, delete the parent comment from both the sidebar and the popover path in separate runs, and verify the whole thread is removed each time.
34. Hover a comment row until the matching PDF annotation highlights, then hide the comments sidebar or apply a filter that removes the row and verify the hover highlight clears.
35. Hover and click a sidebar reply, and verify the PDF scrolls to and highlights the visible parent annotation rather than jumping to a hidden reply marker.
36. Search for a word with matches, edit the search field without pressing Return, and verify old PDF match highlights clear and previous/next search buttons disable until the new query is submitted.
37. Start typing a sidebar reply without sending it, choose Save As, and verify the app warns that the draft will not be included unless it is sent first.
38. Create a new selected-text comment or free text, leave its popover empty, choose Save before closing the popover, and verify the temporary empty annotation is discarded instead of saved.
39. Start typing a sidebar reply with no other unsaved annotation changes and verify the status bar shows a reply draft instead of presenting the PDF as clean.
40. Search for a word with matches, step through results, and verify the status bar reports the current match position; then search for text that is not present and verify PDF match highlights clear.
41. Open comments search and verify the field is focused immediately; enter a search, hide the search controls, and verify the search icon still indicates an active hidden filter.
42. Select a comment row, apply a comments-sidebar filter or search that hides that row, and verify the PDF selection highlight clears instead of lingering on the page.
43. Create a new selected-text comment or free text, leave its popover empty, choose Share, and verify the temporary empty annotation is discarded before any Save and Share output is written.
44. Select a comment or annotation row, hide the only sidebar that shows that row, and verify the PDF selection highlight clears; repeat while the left Annotations sidebar is visible and verify the selection stays visible there.
45. Select a comment row, collapse its page group in the comments sidebar, and verify the PDF selection highlight clears; then search/filter comments and verify matching page groups expand while filtering.
1. Open a PDF and verify it starts in focused single-pane reading: the PDF is fit to the available window width and all sidebars are hidden.
2. Close the PDF, then drag a `.pdf` file onto the empty window and verify it opens.
3. Open one or more PDFs, close the current PDF, and verify recent PDFs appear in the empty window and File > Open Recent.
4. Open Settings from File > Settings... and with Command-, then verify highlight and comment colors can be edited and reset.
5. Select text and add a highlight; verify no comment popover opens.
6. Select text and add a comment; verify the comment color matches the Settings value.
7. In the comment box, press Shift-Return and verify it inserts a new line, then press Return and verify the comment is saved.
8. Add an underline with a comment.
9. Select text, right-click, and add a comment from the context menu.
10. Add free text directly on the page.
11. Open the comments sidebar and verify count, grouping, search, filters, edit, delete, reply, and click-to-navigate.
12. Open Pages, Marks, Comments, Highlights, and Bookmarks sidebars, then close and reopen the PDF; verify the reopened document returns to focused single-pane reading with sidebars hidden.
13. Open Bookmarks, click the right-sidebar toolbar icon, and verify the right sidebar closes instead of switching to Comments; click it again and verify Bookmarks reopens.
14. Resize the same document through compact, regular, and wide widths; verify compact windows keep sidebars mutually exclusive while regular and wide windows can show both sidebars without shrinking the PDF below a usable reading width.
15. Hover and drag the divider between the PDF and each sidebar and verify the resize cursor/hover affordance is easy to grab without an oversized visual handle.
16. Add at least one reply and verify the comments sidebar presents the thread clearly.
17. Hover a comment row and verify the corresponding PDF text is highlighted; click parent and reply rows and verify the PDF navigates correctly.
18. Click commented text and underlined text and verify the comment popover opens; click nearby whitespace and verify no popover opens.
19. Switch the app to dark mode and verify the reading background, sidebars, editor popover, selected rows, text fields, and annotation markers remain legible.
20. Save As an annotated copy.
21. Reopen the annotated copy in I Hate PDFs and verify annotations and comments remain.
22. Save over a disposable original and verify the overwrite warning appears.
23. Add an annotation and verify the window shows the native macOS unsaved/edited document indicator until the PDF is saved.
24. Search for a word, close the search toolbar, and verify match highlights disappear.
25. Type invalid and out-of-range page numbers and verify the app restores the current page number with a clear status message.
26. Apply comment filters or search text that hide every comment, verify the empty state offers Clear Filters, and verify page counts include visible replies.
27. Start typing a sidebar reply, click Reply on a different comment, and verify the original draft remains until sent or canceled.
28. Hide a sidebar or apply a filter that removes the selected row and verify the PDF selection highlight clears.
29. Start typing a sidebar reply without sending it, then close, replace, save, or share the PDF and verify the app warns before omitting or discarding the draft.
30. Create a new selected-text comment or free text, leave its popover empty, choose Save or Share, and verify the temporary empty annotation is discarded.
## External Readers
@@ -69,36 +73,6 @@ swift scripts/verify-sample-pdf.swift
swift scripts/verify-pdf-annotations.swift
```
These checks generate an annotated PDF, reopen it with PDFKit, and inspect the raw PDF annotation dictionaries for standard `/Highlight`, `/Underline`, `/Text`, `/FreeText`, `/Contents`, `/QuadPoints`, `/IRT`, `/RT`, and `/Parent` entries.
These checks generate an annotated PDF, reopen it with PDFKit, and inspect raw PDF annotation dictionaries for standard `/Highlight`, `/Underline`, `/Text`, `/FreeText`, `/Contents`, `/QuadPoints`, `/IRT`, `/RT`, and `/Parent` entries.
For Preview interoperability, exported markup comments should keep the comment text on the parent annotation's standard `/Contents` key and should not depend on PDFKit-generated `/Popup` links for highlights or underlines.
Open the saved annotated copy in:
- macOS Preview
- Adobe Acrobat Reader
- Safari, Chrome, and Firefox PDF viewers where annotations are supported
Verify:
- Highlighted text remains highlighted.
- Underlined text remains underlined.
- Selected-text comments remain attached to the referenced text.
- Highlight and selected-text comments can be opened.
- Free text remains visible on the page.
- Existing text, images, layout, bookmarks, and prior annotations remain intact.
## Visual QA Screenshots
Capture current screenshots in `docs/screenshots` for:
- `no-document.png`
- `default-reading.png`
- `highlight-comment-popover.png`
- `selected-text-comment-popover.png`
- `comments-sidebar.png`, including at least one reply thread with a visible connector line
- `dark-mode-reading.png`
## Known Version 1 Limitation
PDFKit rejects object-valued `/IRT` reply relationships through its public API. Replies created in this app are saved as standard `/Text` annotations with string `/IRT` and `/RT` reply keys, but the reply annotation is hidden on the PDF page so it appears as a threaded sidebar reply instead of a second page icon. Full cross-reader reply-thread presentation must be verified and improved with a lower-level PDF writer if needed.
For Preview, Acrobat Reader, and browser PDF viewers, verify exported markup comments keep their comment text on the parent annotation's standard `/Contents` key and do not depend on PDFKit-generated `/Popup` links for highlights or underlines.

68
docs/RELEASE.md Normal file
View File

@@ -0,0 +1,68 @@
# Release Workflow
Use this checklist when preparing a new public version.
## Version Source
The release version lives in one place:
```sh
scripts/release-version.sh
```
For a new app version, update `APP_VERSION` and reset or increment `BUILD_NUMBER`.
For another upload of the same app version, leave `APP_VERSION` alone and increment
`BUILD_NUMBER`.
`RELEASE_VERSION` defaults to the app version without a trailing `.0`, so `0.4.0`
produces release artifacts named with `v0.4`.
## Required Checks
Run these before tagging or uploading:
```sh
swift test
swift scripts/verify-sample-pdf.swift
swift scripts/verify-pdf-annotations.swift
scripts/build-app.sh
BUILD_APP=0 scripts/make-dmg.sh
scripts/make-tiny-archives.sh
scripts/verify-release-artifacts.sh
```
`scripts/make-tiny-archives.sh` builds per-architecture direct-download archives and
fails if either archive is `>= 400,000` bytes.
For signature changes, also run:
```sh
USE_TEMP_SIGNING_KEYCHAIN=1 scripts/verify-pdf-signatures.sh
scripts/prepare-acrobat-qa.sh
```
Finish the manual reader checks in `docs/QA.md` before public distribution.
## Direct Download
The direct-download release artifacts are generated under `dist/`:
- `I Hate PDFs.app`
- `IHatePDFs-v<release>-macos.dmg`
- `IHatePDFs-v<release>-macos-arm64.tar.xz`
- `IHatePDFs-v<release>-macos-x86_64.tar.xz`
`dist/` and root package/archive extensions are ignored so generated outputs do not
pollute source control.
## App Store
Use `docs/APP_STORE.md` for signing identities, provisioning profile setup, and the
upload package command. After building the App Store package, run:
```sh
REQUIRE_APP_STORE_PKG=1 scripts/verify-release-artifacts.sh
```
Do not change App Store entitlements unless a shipped feature requires the new
capability.

53
docs/WORKFLOW_AUDIT.md Normal file
View File

@@ -0,0 +1,53 @@
# Workflow Audit
Date: 2026-06-29
This file records the intended v0.4 user flow. It is the source of truth when checking whether a feature matches the product workflow before changing or releasing it.
## Current Capabilities
1. Open local PDFs from an open panel, drag/drop, recent documents, and file URLs.
2. Start each opened PDF in focused reading: sidebars hidden, PDF fit to available width, previous document sidebar state ignored.
3. Read with PDFKit scrolling, page navigation, zoom, fit width, fit page, two-page continuous view, and search.
4. Use a responsive layout across compact, regular, and wide Mac windows.
5. Use the left sidebar for page thumbnails and annotation marks.
6. Use the right sidebar for Comments, Highlights, and Bookmarks; the right-sidebar toolbar button is a visibility toggle for the active right mode.
7. Highlight selected text, use highlighter mode, and choose highlight colors.
8. Add selected-text comments, underline comments, and free-text annotations.
9. Use PDF-view shortcuts `H`, `U`, and `C` without conflicting with Command-C.
10. Edit/delete annotations and comment threads through anchored popovers and sidebar controls.
11. Review comments with search, filters, page grouping, collapsed groups, review state, replies, hover highlighting, edit/delete, and navigation.
12. Review highlights sorted by color or page.
13. Add, remove, and navigate per-document bookmarks.
14. Configure highlight and comment colors in Settings.
15. Save, Save As, Share, warn for unsent reply drafts, discard empty temporary editors, and warn before overwriting originals.
16. Package a small native app through the release scripts, DMG script, tiny archive script, and App Store package script.
## Removed From v0.4
The experimental Fill & Sign, custom form-field navigation, form choice popover, PDF signing, signature inspection, signed-document save safeguards, signature QA scripts, and related tests were removed from v0.4. Revisit that work later as a smaller design from scratch.
## Workflow Decisions
- Opened PDFs intentionally reset to focused single-pane reading with sidebars hidden. Opening a PDF should maximize the reading area and leave comments, highlights, bookmarks, page thumbnails, and annotation marks closed until the user asks for them.
- Plain Highlight is standalone. Selected-text Comment and Underline open the anchored editor.
- The visible Save toolbar icon is intentionally absent. Save remains available from the File menu and keyboard shortcut; Share remains visible.
- Compact windows intentionally make left and right sidebars mutually exclusive to preserve usable PDF width.
- Sidebar resize handles should be easy to grab through hover/cursor affordance without becoming large visual dividers.
## Regression Coverage
- Focused reading layout after opening a PDF.
- Returning to the empty-window workflow after closing a PDF.
- Compact one-sidebar-at-a-time behavior.
- Page sidebar toggle closing the active Marks sidebar instead of switching to Pages first.
- Right-sidebar toolbar toggle closing and reopening the current right mode without switching tabs.
- Regular-width ability to show navigation and review sidebars together.
- Save availability for clean, dirty, and reply-draft-only states.
## Manual QA Gaps
- Real Finder drag/drop, menu disabled states, visual Settings interaction, alert button flows, native share picker, popover text focus, and sidebar resize affordances need UI automation or manual QA.
- Preview, Acrobat Reader, and browser PDF-viewer checks remain external interoperability gates even though raw PDF structure checks exist.
- Cross-reader reply-thread display is not fully proven because PDFKit public APIs do not provide reliable object-valued `/IRT` writing. Primary annotation comments remain standard `/Contents`.
- Screenshot docs still need recapture before public marketing or release use.

View File

@@ -1,22 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="760" height="920" viewBox="0 0 760 920" role="img" aria-label="I Hate PDFs comments sidebar screenshot">
<rect width="760" height="920" fill="#f5f5f7"/>
<rect x="80" y="60" width="600" height="800" rx="10" fill="#fbfbfd" stroke="#c9c9ce"/>
<text x="118" y="118" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="26" fill="#202124">Comments</text>
<text x="118" y="146" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="14" fill="#606166">4 total</text>
<rect x="118" y="176" width="524" height="34" rx="7" fill="#ffffff" stroke="#d1d1d6"/>
<text x="136" y="198" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#7a7a80">Search comments</text>
<rect x="118" y="242" width="524" height="1" fill="#d8d8dd"/>
<text x="118" y="282" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="17" font-weight="600" fill="#202124">Page 2</text>
<rect x="118" y="306" width="524" height="154" rx="8" fill="#ffffff" stroke="#d5d5da"/>
<text x="140" y="344" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="14" font-weight="600" fill="#202124">Highlight</text>
<text x="140" y="374" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#606166">Professor</text>
<text x="140" y="406" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="15" fill="#202124">This is the core passage for Friday's discussion.</text>
<rect x="150" y="480" width="492" height="86" rx="8" fill="#f1f8f8" stroke="#c8dddd"/>
<text x="172" y="516" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" font-weight="600" fill="#202124">Reply</text>
<text x="172" y="546" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#606166">Add this to the lecture notes.</text>
<text x="118" y="624" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="17" font-weight="600" fill="#202124">Page 5</text>
<rect x="118" y="648" width="524" height="118" rx="8" fill="#ffffff" stroke="#d5d5da"/>
<text x="140" y="686" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="14" font-weight="600" fill="#202124">Note</text>
<text x="140" y="716" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#606166">Professor</text>
<text x="140" y="748" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="15" fill="#202124">Compare this footnote with the appendix.</text>
</svg>

Before

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -1,23 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="1440" height="920" viewBox="0 0 1440 920" role="img" aria-label="I Hate PDFs main window screenshot">
<rect width="1440" height="920" fill="#f5f5f7"/>
<rect x="40" y="40" width="1360" height="840" rx="10" fill="#fbfbfd" stroke="#c9c9ce"/>
<rect x="40" y="40" width="1360" height="52" rx="10" fill="#ececf0"/>
<circle cx="68" cy="66" r="7" fill="#ff5f57"/>
<circle cx="92" cy="66" r="7" fill="#febc2e"/>
<circle cx="116" cy="66" r="7" fill="#28c840"/>
<rect x="64" y="116" width="210" height="724" fill="#f1f1f4"/>
<rect x="308" y="132" width="650" height="692" fill="#ffffff" stroke="#d1d1d6"/>
<rect x="358" y="190" width="550" height="14" fill="#d8d8dd"/>
<rect x="358" y="228" width="480" height="14" fill="#d8d8dd"/>
<rect x="358" y="266" width="520" height="14" fill="#f7dc55" opacity="0.75"/>
<rect x="358" y="304" width="470" height="14" fill="#d8d8dd"/>
<rect x="358" y="342" width="510" height="14" fill="#d8d8dd"/>
<rect x="996" y="116" width="364" height="724" fill="#f7f7f9"/>
<text x="1020" y="158" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="24" fill="#202124">Comments</text>
<rect x="1020" y="190" width="316" height="118" rx="8" fill="#ffffff" stroke="#d5d5da"/>
<text x="1040" y="226" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="15" fill="#202124">Highlight</text>
<text x="1040" y="254" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#606166">Discuss this claim in class.</text>
<rect x="1020" y="326" width="316" height="118" rx="8" fill="#ffffff" stroke="#d5d5da"/>
<text x="1040" y="362" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="15" fill="#202124">Note</text>
<text x="1040" y="390" font-family="-apple-system, BlinkMacSystemFont, sans-serif" font-size="13" fill="#606166">Connect to the seminar reading.</text>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 522 KiB