## Summary
* Definition and use of a central LOG function, that can later be
extended or completely be removed (for public use where debugging
information may not be required) to save flash by suppressing the
-DENABLE_SERIAL_LOG like in the slim branch
* **What changes are included?**
## Additional Context
* By using the central logger the usual:
```
#include <HardwareSerial.h>
...
Serial.printf("[%lu] [WCS] Obfuscating/deobfuscating %zu bytes\n", millis(), data.size());
```
would then become
```
#include <Logging.h>
...
LOG_DBG("WCS", "Obfuscating/deobfuscating %zu bytes", data.size());
```
You do have ``LOG_DBG`` for debug messages, ``LOG_ERR`` for error
messages and ``LOG_INF`` for informational messages. Depending on the
verbosity level defined (see below) soe of these message types will be
suppressed/not-compiled.
* The normal compilation (default) will create a firmware.elf file of
42.194.356 bytes, the same code via slim will create 42.024.048 bytes -
170.308 bytes less
* Firmware.bin : 6.469.984 bytes for default, 6.418.672 bytes for slim -
51.312 bytes less
### 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? _NO_
---------
Co-authored-by: Xuan Son Nguyen <son@huggingface.co>
139 lines
3.9 KiB
C++
139 lines
3.9 KiB
C++
#include "ReaderActivity.h"
|
|
|
|
#include <HalStorage.h>
|
|
|
|
#include "Epub.h"
|
|
#include "EpubReaderActivity.h"
|
|
#include "Txt.h"
|
|
#include "TxtReaderActivity.h"
|
|
#include "Xtc.h"
|
|
#include "XtcReaderActivity.h"
|
|
#include "activities/util/FullScreenMessageActivity.h"
|
|
#include "util/StringUtils.h"
|
|
|
|
std::string ReaderActivity::extractFolderPath(const std::string& filePath) {
|
|
const auto lastSlash = filePath.find_last_of('/');
|
|
if (lastSlash == std::string::npos || lastSlash == 0) {
|
|
return "/";
|
|
}
|
|
return filePath.substr(0, lastSlash);
|
|
}
|
|
|
|
bool ReaderActivity::isXtcFile(const std::string& path) {
|
|
return StringUtils::checkFileExtension(path, ".xtc") || StringUtils::checkFileExtension(path, ".xtch");
|
|
}
|
|
|
|
bool ReaderActivity::isTxtFile(const std::string& path) {
|
|
return StringUtils::checkFileExtension(path, ".txt") ||
|
|
StringUtils::checkFileExtension(path, ".md"); // Treat .md as txt files (until we have a markdown reader)
|
|
}
|
|
|
|
std::unique_ptr<Epub> ReaderActivity::loadEpub(const std::string& path) {
|
|
if (!Storage.exists(path.c_str())) {
|
|
LOG_ERR("READER", "File does not exist: %s", path.c_str());
|
|
return nullptr;
|
|
}
|
|
|
|
auto epub = std::unique_ptr<Epub>(new Epub(path, "/.crosspoint"));
|
|
if (epub->load()) {
|
|
return epub;
|
|
}
|
|
|
|
LOG_ERR("READER", "Failed to load epub");
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<Xtc> ReaderActivity::loadXtc(const std::string& path) {
|
|
if (!Storage.exists(path.c_str())) {
|
|
LOG_ERR("READER", "File does not exist: %s", path.c_str());
|
|
return nullptr;
|
|
}
|
|
|
|
auto xtc = std::unique_ptr<Xtc>(new Xtc(path, "/.crosspoint"));
|
|
if (xtc->load()) {
|
|
return xtc;
|
|
}
|
|
|
|
LOG_ERR("READER", "Failed to load XTC");
|
|
return nullptr;
|
|
}
|
|
|
|
std::unique_ptr<Txt> ReaderActivity::loadTxt(const std::string& path) {
|
|
if (!Storage.exists(path.c_str())) {
|
|
LOG_ERR("READER", "File does not exist: %s", path.c_str());
|
|
return nullptr;
|
|
}
|
|
|
|
auto txt = std::unique_ptr<Txt>(new Txt(path, "/.crosspoint"));
|
|
if (txt->load()) {
|
|
return txt;
|
|
}
|
|
|
|
LOG_ERR("READER", "Failed to load TXT");
|
|
return nullptr;
|
|
}
|
|
|
|
void ReaderActivity::goToLibrary(const std::string& fromBookPath) {
|
|
// If coming from a book, start in that book's folder; otherwise start from root
|
|
const auto initialPath = fromBookPath.empty() ? "/" : extractFolderPath(fromBookPath);
|
|
onGoToLibrary(initialPath);
|
|
}
|
|
|
|
void ReaderActivity::onGoToEpubReader(std::unique_ptr<Epub> epub) {
|
|
const auto epubPath = epub->getPath();
|
|
currentBookPath = epubPath;
|
|
exitActivity();
|
|
enterNewActivity(new EpubReaderActivity(
|
|
renderer, mappedInput, std::move(epub), [this, epubPath] { goToLibrary(epubPath); }, [this] { onGoBack(); }));
|
|
}
|
|
|
|
void ReaderActivity::onGoToXtcReader(std::unique_ptr<Xtc> xtc) {
|
|
const auto xtcPath = xtc->getPath();
|
|
currentBookPath = xtcPath;
|
|
exitActivity();
|
|
enterNewActivity(new XtcReaderActivity(
|
|
renderer, mappedInput, std::move(xtc), [this, xtcPath] { goToLibrary(xtcPath); }, [this] { onGoBack(); }));
|
|
}
|
|
|
|
void ReaderActivity::onGoToTxtReader(std::unique_ptr<Txt> txt) {
|
|
const auto txtPath = txt->getPath();
|
|
currentBookPath = txtPath;
|
|
exitActivity();
|
|
enterNewActivity(new TxtReaderActivity(
|
|
renderer, mappedInput, std::move(txt), [this, txtPath] { goToLibrary(txtPath); }, [this] { onGoBack(); }));
|
|
}
|
|
|
|
void ReaderActivity::onEnter() {
|
|
ActivityWithSubactivity::onEnter();
|
|
|
|
if (initialBookPath.empty()) {
|
|
goToLibrary(); // Start from root when entering via Browse
|
|
return;
|
|
}
|
|
|
|
currentBookPath = initialBookPath;
|
|
|
|
if (isXtcFile(initialBookPath)) {
|
|
auto xtc = loadXtc(initialBookPath);
|
|
if (!xtc) {
|
|
onGoBack();
|
|
return;
|
|
}
|
|
onGoToXtcReader(std::move(xtc));
|
|
} else if (isTxtFile(initialBookPath)) {
|
|
auto txt = loadTxt(initialBookPath);
|
|
if (!txt) {
|
|
onGoBack();
|
|
return;
|
|
}
|
|
onGoToTxtReader(std::move(txt));
|
|
} else {
|
|
auto epub = loadEpub(initialBookPath);
|
|
if (!epub) {
|
|
onGoBack();
|
|
return;
|
|
}
|
|
onGoToEpubReader(std::move(epub));
|
|
}
|
|
}
|