feat: add long-press on HomeActivity for book management and archive browsing

Long-press Confirm on a recent book opens the BookManageMenuActivity.
Long-press Confirm on Browse Files navigates directly to /.archive/.
Wires onMyLibraryOpenWithPath callback through main.cpp to HomeActivity.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
cottongin
2026-02-21 02:59:35 -05:00
parent 390f10f30d
commit 1c19899aa3
3 changed files with 87 additions and 4 deletions

View File

@@ -13,12 +13,14 @@
#include <cstring>
#include <vector>
#include "BookManageMenuActivity.h"
#include "CrossPointSettings.h"
#include "CrossPointState.h"
#include "MappedInputManager.h"
#include "RecentBooksStore.h"
#include "components/UITheme.h"
#include "fontIds.h"
#include "util/BookManager.h"
#include "util/StringUtils.h"
int HomeActivity::getMenuItemCount() const {
@@ -205,7 +207,32 @@ void HomeActivity::loop() {
requestUpdate();
});
// Long-press Confirm: manage menu for recent books, or browse archive for Browse Files
if (mappedInput.isPressed(MappedInputManager::Button::Confirm) && mappedInput.getHeldTime() >= LONG_PRESS_MS &&
!ignoreNextConfirmRelease) {
if (selectorIndex < static_cast<int>(recentBooks.size())) {
// Long-press on a recent book → manage menu
ignoreNextConfirmRelease = true;
openManageMenu(recentBooks[selectorIndex].path);
return;
}
// Check if Browse Files is selected
const int menuSelectedIndex = selectorIndex - static_cast<int>(recentBooks.size());
if (menuSelectedIndex == 0) {
// Long-press on Browse Files → go to archive folder
ignoreNextConfirmRelease = true;
onMyLibraryOpenWithPath("/.archive");
return;
}
}
if (mappedInput.wasReleased(MappedInputManager::Button::Confirm)) {
if (ignoreNextConfirmRelease) {
ignoreNextConfirmRelease = false;
return;
}
// Calculate dynamic indices based on which options are available
int idx = 0;
int menuSelectedIndex = selectorIndex - static_cast<int>(recentBooks.size());
@@ -215,7 +242,7 @@ void HomeActivity::loop() {
const int fileTransferIdx = idx++;
const int settingsIdx = idx;
if (selectorIndex < recentBooks.size()) {
if (selectorIndex < static_cast<int>(recentBooks.size())) {
onSelectBook(recentBooks[selectorIndex].path);
} else if (menuSelectedIndex == myLibraryIdx) {
onMyLibraryOpen();
@@ -278,3 +305,48 @@ void HomeActivity::render(Activity::RenderLock&&) {
loadRecentCovers(metrics.homeCoverHeight);
}
}
void HomeActivity::openManageMenu(const std::string& bookPath) {
const bool isArchived = BookManager::isArchived(bookPath);
const std::string capturedPath = bookPath;
enterNewActivity(new BookManageMenuActivity(
renderer, mappedInput, capturedPath, isArchived,
[this, capturedPath](BookManageMenuActivity::Action action) {
exitActivity();
bool success = false;
switch (action) {
case BookManageMenuActivity::Action::ARCHIVE:
success = BookManager::archiveBook(capturedPath);
break;
case BookManageMenuActivity::Action::UNARCHIVE:
success = BookManager::unarchiveBook(capturedPath);
break;
case BookManageMenuActivity::Action::DELETE:
success = BookManager::deleteBook(capturedPath);
break;
case BookManageMenuActivity::Action::DELETE_CACHE:
success = BookManager::deleteBookCache(capturedPath);
break;
case BookManageMenuActivity::Action::REINDEX:
success = BookManager::reindexBook(capturedPath, false);
break;
case BookManageMenuActivity::Action::REINDEX_FULL:
success = BookManager::reindexBook(capturedPath, true);
break;
}
{
RenderLock lock(*this);
GUI.drawPopup(renderer, success ? tr(STR_DONE) : tr(STR_ACTION_FAILED));
}
requestUpdateAndWait();
// Reload recents since the book may have been removed/archived
recentBooks.clear();
recentsLoaded = false;
coverRendered = false;
requestUpdate();
},
[this] {
exitActivity();
requestUpdate();
}));
}

View File

@@ -20,8 +20,14 @@ class HomeActivity final : public ActivityWithSubactivity {
bool coverBufferStored = false; // Track if cover buffer is stored
uint8_t* coverBuffer = nullptr; // HomeActivity's own buffer for cover image
std::vector<RecentBook> recentBooks;
// Long-press state
bool ignoreNextConfirmRelease = false;
static constexpr unsigned long LONG_PRESS_MS = 700;
const std::function<void(const std::string& path)> onSelectBook;
const std::function<void()> onMyLibraryOpen;
const std::function<void(const std::string& path)> onMyLibraryOpenWithPath;
const std::function<void()> onRecentsOpen;
const std::function<void()> onSettingsOpen;
const std::function<void()> onFileTransferOpen;
@@ -33,16 +39,20 @@ class HomeActivity final : public ActivityWithSubactivity {
void freeCoverBuffer(); // Free the stored cover buffer
void loadRecentBooks(int maxBooks);
void loadRecentCovers(int coverHeight);
void openManageMenu(const std::string& bookPath);
public:
explicit HomeActivity(GfxRenderer& renderer, MappedInputManager& mappedInput,
const std::function<void(const std::string& path)>& onSelectBook,
const std::function<void()>& onMyLibraryOpen, const std::function<void()>& onRecentsOpen,
const std::function<void()>& onMyLibraryOpen,
const std::function<void(const std::string& path)>& onMyLibraryOpenWithPath,
const std::function<void()>& onRecentsOpen,
const std::function<void()>& onSettingsOpen, const std::function<void()>& onFileTransferOpen,
const std::function<void()>& onOpdsBrowserOpen)
: ActivityWithSubactivity("Home", renderer, mappedInput),
onSelectBook(onSelectBook),
onMyLibraryOpen(onMyLibraryOpen),
onMyLibraryOpenWithPath(onMyLibraryOpenWithPath),
onRecentsOpen(onRecentsOpen),
onSettingsOpen(onSettingsOpen),
onFileTransferOpen(onFileTransferOpen),