Files
Crosspoint/src/activities/reader/KOReaderSyncActivity.h
T

115 lines
3.8 KiB
C++

#pragma once
#include <Epub.h>
#include <memory>
#include "ChapterXPathIndexer.h"
#include "CrossPointState.h"
#include "KOReaderSyncClient.h"
#include "ProgressMapper.h"
#include "activities/Activity.h"
/**
* Activity for syncing reading progress with KOReader sync server.
*
* This activity is launched as a standalone replacement screen, not as a
* child activity of the reader. The reader persists a compact handoff record,
* is destroyed to reclaim memory before WiFi/TLS work begins, and a fresh
* reader instance is reopened after sync completes or is cancelled.
*
* Shared pipeline:
* 1. Connect to WiFi (if not connected)
* 2. Optionally sync NTP (if stale)
* 3. Calculate document hash
*
* Intent-specific behavior:
* - COMPARE: fetch remote progress, show full comparison screen, let user
* choose Apply or Upload.
* - PULL_REMOTE: fetch and map remote progress, show success feedback, then
* persist an applied SyncResult for the reopened reader.
* - PUSH_LOCAL: compute local mapping, warm session with GET, then upload via
* reused connection to avoid a second full TLS handshake.
*/
class KOReaderSyncActivity final : public Activity {
public:
explicit KOReaderSyncActivity(GfxRenderer& renderer, MappedInputManager& mappedInput, const std::string& epubPath,
int currentSpineIndex, int currentPage, int totalPagesInSpine,
uint16_t paragraphIndex = 0, bool hasParagraphIndex = false, uint32_t xhtmlSeekHint = 0,
KOReaderSyncIntentState syncIntent = KOReaderSyncIntentState::COMPARE)
: Activity("KOReaderSync", renderer, mappedInput),
epubPath(epubPath),
currentSpineIndex(currentSpineIndex),
currentPage(currentPage),
totalPagesInSpine(totalPagesInSpine),
localParagraphIndex(paragraphIndex),
hasLocalParagraphIndex(hasParagraphIndex),
localXhtmlSeekHint(xhtmlSeekHint),
syncIntent(syncIntent),
remoteProgress{},
remotePosition{},
localProgress{} {}
void onEnter() override;
void onExit() override;
void loop() override;
void render(RenderLock&&) override;
bool preventAutoSleep() override { return state == CONNECTING || state == SYNCING; }
private:
enum State {
WIFI_SELECTION,
CONNECTING,
SYNCING,
SHOWING_RESULT,
UPLOADING,
UPLOAD_COMPLETE,
APPLY_COMPLETE,
NO_REMOTE_PROGRESS,
SYNC_FAILED,
NO_CREDENTIALS
};
std::shared_ptr<Epub> epub;
std::string epubPath;
int currentSpineIndex;
int currentPage;
int totalPagesInSpine;
uint16_t localParagraphIndex;
bool hasLocalParagraphIndex;
uint32_t localXhtmlSeekHint;
KOReaderSyncIntentState syncIntent = KOReaderSyncIntentState::COMPARE;
State state = WIFI_SELECTION;
std::string statusMessage;
std::string documentHash;
// Remote progress data
bool hasRemoteProgress = false;
bool remotePositionMapped = false;
KOReaderProgress remoteProgress;
CrossPointPosition remotePosition;
// Local progress as KOReader format (for display)
KOReaderPosition localProgress;
std::string remoteChapterLabel;
std::string localChapterLabel;
// Selection in result screen (0=Apply, 1=Upload)
int selectedOption = 0;
// Timestamp when completion state was entered (for auto-close)
unsigned long uploadCompleteTime = 0;
bool closeRequested = false;
void onWifiSelectionComplete(bool success);
void performSync();
void performUpload();
void closeCancelled();
void resumeReader(KOReaderSyncOutcomeState outcome, const SyncResult* appliedResult = nullptr);
bool ensureEpubLoadedForMapping();
void releaseEpubForMapping();
bool computeLocalProgressAndChapter();
void computeRemoteChapter();
bool ensureRemotePositionMapped(bool closeSessionBeforeMapping = true);
};