Skip to content

feat: add burger menu for file renaming and relocation#619

Draft
LZando wants to merge 13 commits intocrosspoint-reader:masterfrom
LZando:burger-menu-clean
Draft

feat: add burger menu for file renaming and relocation#619
LZando wants to merge 13 commits intocrosspoint-reader:masterfrom
LZando:burger-menu-clean

Conversation

@LZando
Copy link

@LZando LZando commented Jan 29, 2026

What is the goal of this PR?

Introduce a burger (overflow) menu that allows users to rename files and change their location directly from the file item actions.

image

UI / Frontend

  • Added a burger (overflow) menu to file items for quick access to actions.
  • Implemented modals and related logic for file and folder renaming and moving.
  • Relaxed filename validation rules to support spaces
    (e.g., Philosophy of sd.epub).

Backend / Logic

  • BookCacheManager
    • Introduced a new utility that automatically migrates the cache folder
      (metadata, reading progress, pre-rendered chapters) when a book’s path changes.
  • Recursive migration
    • Moving a folder now triggers a recursive cache update for all contained books.
  • State persistence
    • Updated RecentBooksStore to automatically refresh file paths in the Recent Books list.
    • Updated CrossPointState to keep the last opened book in sync after path changes.

AI Usage

While CrossPoint does not restrict the use of AI tools for contributions, transparency is encouraged to provide proper context for reviewers.

Did you use AI tools to help write this code?
Answer: PARTIALLY

@lukestein
Copy link
Contributor

Closes #661 and #663

@lukestein
Copy link
Contributor

Closes #559

Copy link
Member

@daveallie daveallie left a comment

Choose a reason for hiding this comment

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

Small nit, fixed up a small bug when testing. Will fix this up to get it merged into this release

Comment on lines +16 to +19
if (CrossPointState::getInstance().openEpubPath == oldPath.c_str()) {
CrossPointState::getInstance().openEpubPath = newPath.c_str();
CrossPointState::getInstance().saveToFile();
}
Copy link
Member

Choose a reason for hiding this comment

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

For consistency, we should use APP_STATE instead of CrossPointState::getInstance() here.

daveallie
daveallie previously approved these changes Feb 5, 2026
@daveallie
Copy link
Member

After reading both implementations, going to merge #630.

If you'd like to update this to focus on the index migration, that can be done, otherwise, we can consider this solved and close it.

@daveallie daveallie dismissed their stale review February 5, 2026 12:55

As per comment, merging #630

daveallie pushed a commit that referenced this pull request Feb 5, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

This adds renaming and moving files to the File Manager

* **What changes are included?**

New `/move` and `/rename` endpoints, and corresponding modals and icons
added. Uses the `file.rename()` function, after sanity checking.

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).


Fixes #559, #661, #663. Only touches the File Manager, so low risk of
affecting other systems.

Simpler than #619, at the cost of not migrating the cache of renamed
books.

<img width="870" height="437" alt="image"
src="https://github.com/user-attachments/assets/73e0e750-dfc8-48e0-a7a6-9694470b7ded"
/>
<img width="575" height="318" alt="image"
src="https://github.com/user-attachments/assets/38c5fb19-c38a-436b-b3ad-75c1be7375ab"
/>
<img width="574" height="293" alt="image"
src="https://github.com/user-attachments/assets/1d2a2403-765d-473f-8c4f-c6968e9bbfeb"
/>


---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES**_

I used Codex for the implementation itself, and then carefully reviewed
the code myself. As this is a simple change and only to the webserver,
it is low risk.
@Tritlo
Copy link
Contributor

Tritlo commented Feb 5, 2026

Great @LZando should we work together on adding updated cache management on rename and move?

@LZando
Copy link
Author

LZando commented Feb 5, 2026

Great @LZando should we work together on adding updated cache management on rename and move?

I would love to work together, even though my availability for the next three weeks will be limited due to work, is it a problem?

@Tritlo
Copy link
Contributor

Tritlo commented Feb 5, 2026

no worries, just ping me when you're ready! Though I don't think I can contribute much, you are more familiar with the cache stuff.

@LZando
Copy link
Author

LZando commented Feb 5, 2026

no worries, just ping me when you're ready! Though I don't think I can contribute much, you are more familiar with the cache stuff.

I will be back with some architecture ideas

@LZando
Copy link
Author

LZando commented Feb 5, 2026

no worries, just ping me when you're ready! Though I don't think I can contribute much, you are more familiar with the cache stuff.

I’m back with two approaches.

  1. I was thinking that the file hash cannot be based on any information that the user can change inside the file.
    So the values we can rely on are:
  • File size
  • File hash

I tried to run a small script using a sparse hash, which uses the file size + the beginning and the end of the file. (in my test 4k of the head and 8kn of the tail where there is the ZIP Central Directory, which is unique to every specific compilation of a file.)

Pros of this approach:

  • Independence: With a sparse hash, we don’t care where the file is located or what its name is; the file’s properties are what determine the hash.

Cons of this approach:

  • Slower: The previous method was obviously faster because it only required hashing the path, so the SH in my test result slower 0.01ms (legacy) vs 55ms (Sparse), is possible to bring the 55ms to 20ms extracting less information but with an higher risk of collisions (10^-16 vs 10^-9, still hard it can happen).

Shouldn’t be a big deal on a enik device, but obv is important to pay attention to performance on ESP32.

  1. The other approach is closer to the solution I proposed in my PR: using a dictionary to store the book attributes. However, this could be problematic in the future because we would always need to keep the dictionary and the book data in sync.

Probably the first one is better because easier, what do you think?

@Tritlo
Copy link
Contributor

Tritlo commented Feb 7, 2026

Good points.

For such a low powered device, I don't think we should worry about collisions. For 10^-9, you'd need ~100 million samples to even have 10% chance of a collision. Given that there have only been ~130 million books written EVER, I think that should be fine.

@daveallie
Copy link
Member

Will move this one into draft while you two continue to collaborate, just so that that myself and other reviewers it's clear that this doesn't need additional review eyes.

@daveallie daveallie marked this pull request as draft February 9, 2026 09:21
@LZando
Copy link
Author

LZando commented Feb 11, 2026

Good points.

For such a low powered device, I don't think we should worry about collisions. For 10^-9, you'd need ~100 million samples to even have 10% chance of a collision. Given that there have only been ~130 million books written EVER, I think that should be fine.

Great! Give me two weeks and I will try to scratch the first version

Unintendedsideeffects pushed a commit to Unintendedsideeffects/crosspoint-reader that referenced this pull request Feb 17, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

This adds renaming and moving files to the File Manager

* **What changes are included?**

New `/move` and `/rename` endpoints, and corresponding modals and icons
added. Uses the `file.rename()` function, after sanity checking.

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).


Fixes crosspoint-reader#559, crosspoint-reader#661, crosspoint-reader#663. Only touches the File Manager, so low risk of
affecting other systems.

Simpler than crosspoint-reader#619, at the cost of not migrating the cache of renamed
books.

<img width="870" height="437" alt="image"
src="https://github.com/user-attachments/assets/73e0e750-dfc8-48e0-a7a6-9694470b7ded"
/>
<img width="575" height="318" alt="image"
src="https://github.com/user-attachments/assets/38c5fb19-c38a-436b-b3ad-75c1be7375ab"
/>
<img width="574" height="293" alt="image"
src="https://github.com/user-attachments/assets/1d2a2403-765d-473f-8c4f-c6968e9bbfeb"
/>


---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**YES**_

I used Codex for the implementation itself, and then carefully reviewed
the code myself. As this is a simple change and only to the webserver,
it is low risk.
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.

4 participants