Skip to content

Conversation

@chmurson
Copy link
Collaborator

@chmurson chmurson commented Oct 28, 2025

What?

  • clicking on note's label does not change the version anymore; it only happens when you click ⚠️ icon
  • both links; ⚠️ and note label have now proper href value and works nciely with "open in new tab" or copy url.
Screenshot 2025-10-28 at 23 14 05

Summary by CodeRabbit

  • Refactor

    • Centralized URL hash generation into a single utility and removed scattered inline encoding.
    • Simplified note linking/navigation by consolidating multiple handlers into a unified link generation approach.
    • Cleaned up and reorganized location-related constants and helpers for maintainability.
  • UX

    • Note links and navigation now use consistent, memoized hash-based links for more reliable navigation.

@netlify
Copy link

netlify bot commented Oct 28, 2025

Deploy Preview for graypaper-reader ready!

Name Link
🔨 Latest commit 236876c
🔍 Latest deploy log https://app.netlify.com/projects/graypaper-reader/deploys/6901421f7650ec0008418bbc
😎 Deploy Preview https://deploy-preview-335--graypaper-reader.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Oct 28, 2025

Walkthrough

Centralizes URL-hash construction into a new locationParamsToHash utility and exposes getHashFromLocationParams on the LocationContext. Adds types and constants for location encoding, new encoding helpers, and updates consumer components (Note, NoteLink) to compute and navigate via hashes instead of inlining encoding logic.

Changes

Cohort / File(s) Change Summary
Types & Constants
src/components/LocationProvider/types.ts, src/components/LocationProvider/utils/constants.ts
Add ILocationParams and SearchParams types; introduce constants (VERSION_SEGMENT_INDEX, SELECTION_SEGMENT_INDEX, SEGMENT_SEPARATOR, SELECTION_DECOMPOSE_PATTERN, SHORT_COMMIT_HASH_LENGTH, BASE64_VALIDATION_REGEX).
Encoding Utilities
src/components/LocationProvider/utils/encodePageNumberAndIndex.ts, src/components/LocationProvider/utils/locationParamsToHash.ts
Add encodePageNumberAndIndex for 3-byte hex encoding and locationParamsToHash to serialize location params + metadata into a URL hash string (includes internal serializeSearchParams).
LocationProvider Component
src/components/LocationProvider/LocationProvider.tsx
Remove inlined hash construction and legacy helpers; use locationParamsToHash for hash generation; add and expose getHashFromLocationParams in ILocationContext; update set/handler logic and dependency lists accordingly.
Consumers: Note & NoteLink
src/components/NoteManager/components/Note.tsx, src/components/NoteManager/components/NoteLink.tsx
Note.tsx now reads locationParams.version for version context. NoteLink.tsx computes memoized links via getHashFromLocationParams, replaces multiple click handlers with a single handleNoteLinkClick, and navigates by setting window.location.hash.

Sequence Diagram(s)

sequenceDiagram
    participant App
    participant NoteLink as NoteLink Component
    participant LocationContext as LocationContext
    participant Utils as Hash Utilities
    participant LocationProvider as LocationProvider

    App->>NoteLink: Render (locationParams)
    NoteLink->>LocationContext: getHashFromLocationParams(params)
    LocationContext->>Utils: locationParamsToHash(params, metadata)
    Utils->>Utils: encode version & selection, serialize search params
    Utils-->>LocationContext: hash string
    LocationContext-->>NoteLink: return hash
    NoteLink->>NoteLink: set href (memo)
    App->>NoteLink: User clicks link
    NoteLink->>NoteLink: handleNoteLinkClick (reads href)
    NoteLink->>App: window.location.hash = href
    App->>LocationProvider: hash change
    LocationProvider->>LocationProvider: extractSearchParams -> update locationParams
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Review locationParamsToHash and encodePageNumberAndIndex for correctness (byte/hex encoding, edge cases).
  • Confirm ILocationContext changes and dependency updates in LocationProvider.tsx.
  • Verify consumers (Note, NoteLink) compute and use hashes correctly and that navigation semantics remain unchanged.
  • Check type alignment between new ILocationParams and usage sites.

Possibly related PRs

Suggested reviewers

  • DrEverr
  • mateuszsikora

Poem

🐰 New hashes stitched with careful art,
A rabbit's code hops and does its part.
Links now compute, no scattered glue,
Versions and selections join the queue.
Hooray — navigation bounds anew!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The pull request title "qafix: improve click behaviour of single note" is directly aligned with the stated PR objectives, which focus on improving the click behavior of notes—specifically that label clicks no longer change the version, and both links now support proper href values with "open in new tab" and copy URL functionality. While the changeset includes substantial LocationProvider infrastructure refactoring (new types, constants, and utilities), these changes serve as the implementation mechanism to enable the primary user-facing improvement described in the title. The title clearly summarizes the main deliverable from a user perspective and would help developers scanning history understand the behavioral change introduced.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch improve-click-behaviour-of-single-note

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b8c6ed4 and 236876c.

📒 Files selected for processing (1)
  • src/components/LocationProvider/utils/locationParamsToHash.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/LocationProvider/utils/locationParamsToHash.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 28, 2025

Visual Regression Test Report ✅ Passed

Github run id: 18890908522

🔗 Artifacts: Download

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/components/NoteManager/components/Note.tsx (1)

105-143: Inconsistent version usage between mouse and keyboard handlers.

handleWholeNoteClick (line 118) uses locationParams.version while handleNoteEnter (line 139) uses note.original.version. This creates inconsistent behavior: clicking the note navigates to the current context version, but pressing Enter/Space navigates to the note's original version.

Apply this diff to align keyboard navigation with mouse navigation:

   setLocationParams({
-    version: note.original.version,
+    version: locationParams.version,
     selectionStart: note.original.selectionStart,
     selectionEnd: note.original.selectionEnd,
   });
🧹 Nitpick comments (2)
src/components/NoteManager/components/NoteLink.tsx (1)

76-94: Optimize memoization dependencies for better performance.

The currentVersionLink dependency array includes entire locationParams and note objects, causing re-computation when unrelated properties change. Consider depending only on the specific properties used.

Apply this diff to optimize dependencies:

   const currentVersionLink = useMemo(
     () =>
       getHashFromLocationParams({
         version: locationParams.version,
         selectionStart: note.original.selectionStart,
         selectionEnd: note.original.selectionEnd,
       }),
-    [locationParams, note, getHashFromLocationParams],
+    [locationParams.version, note.original.selectionStart, note.original.selectionEnd, getHashFromLocationParams],
   );

   const originalLink = useMemo(
     () =>
       getHashFromLocationParams({
         version: note.original.version,
         selectionStart: note.original.selectionStart,
         selectionEnd: note.original.selectionEnd,
       }),
-    [note, getHashFromLocationParams],
+    [note.original.version, note.original.selectionStart, note.original.selectionEnd, getHashFromLocationParams],
   );
src/components/LocationProvider/LocationProvider.tsx (1)

51-58: Consider aligning type signature with runtime check.

The function signature accepts ILocationParams but line 53 checks for undefined. While this defensive check is good for safety, the type signature could explicitly allow undefined to match the runtime behavior.

Apply this diff if you want the type to match the implementation:

-  const handleSetLocationParams = useCallback(
-    (newParams?: ILocationParams) => {
+  const handleSetLocationParams = useCallback(
+    (newParams: ILocationParams | undefined) => {
       if (!newParams) return;
       const hash = locationParamsToHash(newParams, metadata);
       window.location.hash = hash;
     },
     [metadata],
   );

Alternatively, if undefined should never be passed, remove the check and keep the current signature.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6502258 and b8c6ed4.

📒 Files selected for processing (7)
  • src/components/LocationProvider/LocationProvider.tsx (3 hunks)
  • src/components/LocationProvider/types.ts (1 hunks)
  • src/components/LocationProvider/utils/constants.ts (1 hunks)
  • src/components/LocationProvider/utils/encodePageNumberAndIndex.ts (1 hunks)
  • src/components/LocationProvider/utils/locationParamsToHash.ts (1 hunks)
  • src/components/NoteManager/components/Note.tsx (2 hunks)
  • src/components/NoteManager/components/NoteLink.tsx (4 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx}

⚙️ CodeRabbit configuration file

When reviewing Tailwind CSS classes, ensure they follow Tailwind 4.x conventions and suggest modern 4.x alternatives for deprecated patterns.

Files:

  • src/components/LocationProvider/utils/encodePageNumberAndIndex.ts
  • src/components/NoteManager/components/Note.tsx
  • src/components/LocationProvider/utils/constants.ts
  • src/components/NoteManager/components/NoteLink.tsx
  • src/components/LocationProvider/utils/locationParamsToHash.ts
  • src/components/LocationProvider/types.ts
  • src/components/LocationProvider/LocationProvider.tsx
🧬 Code graph analysis (5)
src/components/NoteManager/components/Note.tsx (1)
src/components/LocationProvider/LocationProvider.tsx (1)
  • useLocationContext (28-34)
src/components/NoteManager/components/NoteLink.tsx (2)
src/components/LocationProvider/LocationProvider.tsx (2)
  • LocationContext (26-26)
  • ILocationContext (15-20)
src/components/Outline/OutlineLink.tsx (1)
  • OutlineLink (4-54)
src/components/LocationProvider/utils/locationParamsToHash.ts (4)
src/components/LocationProvider/types.ts (2)
  • ILocationParams (3-7)
  • SearchParams (9-14)
src/components/MetadataProvider/MetadataProvider.tsx (1)
  • IMetadataContext (21-29)
src/components/LocationProvider/utils/constants.ts (4)
  • SHORT_COMMIT_HASH_LENGTH (5-5)
  • VERSION_SEGMENT_INDEX (1-1)
  • SELECTION_SEGMENT_INDEX (2-2)
  • SEGMENT_SEPARATOR (3-3)
src/components/LocationProvider/utils/encodePageNumberAndIndex.ts (1)
  • encodePageNumberAndIndex (1-4)
src/components/LocationProvider/types.ts (1)
shared/links-metadata/src/types.ts (1)
  • ISelectionParams (30-33)
src/components/LocationProvider/LocationProvider.tsx (3)
src/components/LocationProvider/types.ts (1)
  • ILocationParams (3-7)
shared/links-metadata/src/types.ts (2)
  • ISynctexBlock (21-28)
  • ISelectionParams (30-33)
src/components/LocationProvider/utils/locationParamsToHash.ts (1)
  • locationParamsToHash (11-37)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: visual-tests
🔇 Additional comments (11)
src/components/LocationProvider/types.ts (1)

1-14: LGTM! Clean type definitions.

The type definitions are well-structured and provide a clear contract for location parameters and search params. The use of Partial<ISelectionParams> for optional selection data is appropriate.

src/components/NoteManager/components/Note.tsx (1)

58-58: LGTM! Proper context usage.

Extracting locationParams alongside setLocationParams enables version access throughout the component, aligning with the centralized location state management.

src/components/LocationProvider/utils/locationParamsToHash.ts (1)

39-48: LGTM! Clean search params serialization.

The helper properly filters out falsy values and constructs the query string only when parameters exist.

src/components/LocationProvider/utils/constants.ts (1)

1-6: LGTM! Well-defined constants.

The constants are appropriately named and the values are correct. The SELECTION_DECOMPOSE_PATTERN properly matches 6-character hex segments, and the SHORT_COMMIT_HASH_LENGTH aligns with git's default behavior.

src/components/NoteManager/components/NoteLink.tsx (3)

25-25: LGTM! Updated to use hash-based navigation.

Correctly extracts locationParams and getHashFromLocationParams from context, aligning with the new centralized hash generation approach.


45-50: LGTM! Consolidated click handler.

The unified handler properly prevents default navigation and updates the hash programmatically, enabling smooth client-side navigation.


96-134: LGTM! Proper integration of hash-based navigation.

The computed links are correctly used in href attributes and the click handlers properly handle navigation through hash updates.

src/components/LocationProvider/LocationProvider.tsx (4)

5-13: LGTM! Clean import organization.

All necessary types, constants, and utilities are properly imported to support the centralized hash generation approach.


15-20: LGTM! Extended context interface.

Adding getHashFromLocationParams to the public API enables consumers to compute hashes without duplicating encoding logic, promoting consistency across the application.


60-66: LGTM! Proper memoization and delegation.

The getHashFromLocationParams function is correctly memoized and delegates to the centralized locationParamsToHash utility.


169-180: LGTM! Context properly updated.

The context value correctly includes getHashFromLocationParams and the dependency array is properly updated to include it.

@chmurson chmurson merged commit cbc02c7 into main Oct 28, 2025
9 checks passed
@chmurson chmurson deleted the improve-click-behaviour-of-single-note branch October 28, 2025 22:27
@coderabbitai coderabbitai bot mentioned this pull request Dec 31, 2025
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.

1 participant