From a0037ced2bbdca5946094a31098bb59cbd5c102c Mon Sep 17 00:00:00 2001 From: WuTofu <5987870+WuTofu@users.noreply.github.com> Date: Mon, 11 May 2026 21:45:38 +0800 Subject: [PATCH] feat: add font family deletion functionality (#1919) ## Summary * **What is the goal of this PR?** 1. Adds font family deletion support to the font download activity so users can remove installed font families directly from the download list. 2. Address an issue where a font family manually deleted in the file browser by user will show as "update" in the `FontDownloadActivity` * **What changes are included?** * Updated button hint label to show `Delete` when deletion is available. * Added confirmation before deleting a selected installed font family. * Refreshed font registry in `fetchAndParseManifest` (for the second goal above) --- ### 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? _**PARTIALLY**_ --- .github/workflows/release-fonts.yml | 4 +- docs/sd-card-fonts.md | 2 +- lib/I18n/translations/english.yaml | 4 +- lib/I18n/translations/swedish.yaml | 4 +- .../settings/FontDownloadActivity.cpp | 55 +++++++++++++++++-- .../settings/FontDownloadActivity.h | 3 + src/activities/settings/SettingsActivity.cpp | 4 +- 7 files changed, 63 insertions(+), 13 deletions(-) diff --git a/.github/workflows/release-fonts.yml b/.github/workflows/release-fonts.yml index 86bf5fb2..c95c0927 100644 --- a/.github/workflows/release-fonts.yml +++ b/.github/workflows/release-fonts.yml @@ -83,7 +83,7 @@ jobs: --title "$TITLE" \ --notes "Pre-built \`.cpfont\` font files for CrossPoint Reader. - Download individual files or use **Settings > System > Download Fonts** on the device. + Download individual files or use **Settings > System > Manage Fonts** on the device. See [SD Card Fonts documentation](https://github.com/${{ github.repository }}/blob/main/docs/sd-card-fonts.md) for details." @@ -103,4 +103,4 @@ jobs: This is revision **${{ steps.tags.outputs.revision }}** — see [\`${{ steps.tags.outputs.versioned }}\`](https://github.com/${{ env.FONTS_REPO }}/releases/tag/${{ steps.tags.outputs.versioned }}) for the immutable copy. - Download individual files or use **Settings > System > Download Fonts** on the device." + Download individual files or use **Settings > System > Manage fonts** on the device." diff --git a/docs/sd-card-fonts.md b/docs/sd-card-fonts.md index 39f56e5e..06295ead 100644 --- a/docs/sd-card-fonts.md +++ b/docs/sd-card-fonts.md @@ -10,7 +10,7 @@ There are three ways to install fonts: ### Option 1: Download from device (recommended) 1. Connect your CrossPoint reader to WiFi -2. Go to **Settings > System > Download Fonts** +2. Go to **Settings > System > Manage Fonts** 3. Browse available font families and tap to download 4. Downloaded fonts appear immediately in **Settings > Reader > Font Family** diff --git a/lib/I18n/translations/english.yaml b/lib/I18n/translations/english.yaml index e9c5a192..a0319d5c 100644 --- a/lib/I18n/translations/english.yaml +++ b/lib/I18n/translations/english.yaml @@ -311,8 +311,8 @@ STR_DELETE_CONFIRM: "Delete this server?" STR_OPDS_SERVERS: "OPDS Servers" STR_AUTO_TURN_ENABLED: "Auto Turn Enabled: " STR_AUTO_TURN_PAGES_PER_MIN: "Auto Turn (Pages Per Minute)" -STR_DOWNLOAD_FONTS: "Download Fonts" -STR_FONT_DOWNLOAD: "Font Download" +STR_MANAGE_FONTS: "Manage Fonts" +STR_FONT_BROWSER: "Font Browser" STR_LOADING_FONT_LIST: "Loading font list..." STR_NO_FONTS_AVAILABLE: "No fonts available" STR_FONT_INSTALLED: "Font installed!" diff --git a/lib/I18n/translations/swedish.yaml b/lib/I18n/translations/swedish.yaml index 3ab175c5..a2660e40 100644 --- a/lib/I18n/translations/swedish.yaml +++ b/lib/I18n/translations/swedish.yaml @@ -311,8 +311,8 @@ STR_DELETE_CONFIRM: "Vill du ta bort den här servern?" STR_OPDS_SERVERS: "OPDS-servrar" STR_AUTO_TURN_ENABLED: "Automatisk vändning aktiverad: " STR_AUTO_TURN_PAGES_PER_MIN: "Automatisk vändning (sidor per minut)" -STR_DOWNLOAD_FONTS: "Ladda ner teckensnitt" -STR_FONT_DOWNLOAD: "Nedladdning av teckensnitt" +STR_MANAGE_FONTS: "Hantera teckensnitt" +STR_FONT_BROWSER: "Teckensnittsbläddrare" STR_LOADING_FONT_LIST: "Laddar teckensnittslista..." STR_NO_FONTS_AVAILABLE: "Inga teckensnitt tillgängliga" STR_FONT_INSTALLED: "Teckensnitt installerat!" diff --git a/src/activities/settings/FontDownloadActivity.cpp b/src/activities/settings/FontDownloadActivity.cpp index a9dd9cef..3cbeaf7c 100644 --- a/src/activities/settings/FontDownloadActivity.cpp +++ b/src/activities/settings/FontDownloadActivity.cpp @@ -11,6 +11,7 @@ #include "MappedInputManager.h" #include "SdCardFontGlobals.h" #include "activities/network/WifiSelectionActivity.h" +#include "activities/util/ConfirmationActivity.h" #include "components/UITheme.h" #include "fontIds.h" #include "network/HttpDownloader.h" @@ -106,6 +107,7 @@ bool FontDownloadActivity::fetchAndParseManifest() { baseUrl_ = doc["baseUrl"] | ""; families_.clear(); + fontInstaller_.refreshRegistry(); JsonArray familiesArr = doc["families"].as(); families_.reserve(familiesArr.size()); @@ -304,6 +306,46 @@ void FontDownloadActivity::downloadFamily(ManifestFamily& family) { } } +void FontDownloadActivity::promptDeleteSelectedFamily() { + const int pendingDeleteFamilyIndex = familyIndexFromList(selectedIndex_); + if (pendingDeleteFamilyIndex < 0 || pendingDeleteFamilyIndex >= static_cast(families_.size())) { + return; + } + + std::string heading = tr(STR_DELETE); + const auto& family = families_[pendingDeleteFamilyIndex]; + std::string body = family.name; + startActivityForResult(std::make_unique(renderer, mappedInput, heading, body), + [this](const ActivityResult& result) { onDeleteConfirmationResult(result); }); +} + +void FontDownloadActivity::onDeleteConfirmationResult(const ActivityResult& result) { + if (result.isCancelled) { + requestUpdate(); + return; + } + + auto& family = families_[familyIndexFromList(selectedIndex_)]; + + if (fontInstaller_.deleteFamily(family.name.c_str()) != FontInstaller::Error::OK) { + RenderLock lock(*this); + state_ = ERROR; + errorMessage_ = "Failed to delete font"; + } else { + fontInstaller_.refreshRegistry(); + family.installed = false; + family.hasUpdate = false; + } + + requestUpdate(); +} + +bool FontDownloadActivity::isSelectedFamilyDeletable() const { + if (selectedIndex_ <= 0 || selectedIndex_ >= listItemCount()) return false; + const auto& family = families_[familyIndexFromList(selectedIndex_)]; + return family.installed && !family.hasUpdate; +} + // --- Input handling --- void FontDownloadActivity::loop() { @@ -341,9 +383,12 @@ void FontDownloadActivity::loop() { if (isDownloadAllSelected()) { downloadAll(); } else { - const auto& family = families_[familyIndexFromList(selectedIndex_)]; + auto& family = families_[familyIndexFromList(selectedIndex_)]; if (!family.installed || family.hasUpdate) { - downloadFamily(families_[familyIndexFromList(selectedIndex_)]); + downloadFamily(family); + } else { + promptDeleteSelectedFamily(); + return; } } requestUpdateAndWait(); @@ -403,7 +448,7 @@ void FontDownloadActivity::render(RenderLock&&) { renderer.clearScreen(); - GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_FONT_DOWNLOAD)); + GUI.drawHeader(renderer, Rect{0, metrics.topPadding, pageWidth, metrics.headerHeight}, tr(STR_FONT_BROWSER)); const auto lineHeight = renderer.getLineHeight(UI_10_FONT_ID); const auto contentTop = metrics.topPadding + metrics.headerHeight + metrics.verticalSpacing; @@ -446,7 +491,9 @@ void FontDownloadActivity::render(RenderLock&&) { return f.installed && !f.hasUpdate; }); - const auto labels = mappedInput.mapLabels(tr(STR_BACK), tr(STR_DOWNLOAD), tr(STR_DIR_UP), tr(STR_DIR_DOWN)); + const auto labels = + mappedInput.mapLabels(tr(STR_BACK), isSelectedFamilyDeletable() ? tr(STR_DELETE) : tr(STR_DOWNLOAD), + tr(STR_DIR_UP), tr(STR_DIR_DOWN)); GUI.drawButtonHints(renderer, labels.btn1, labels.btn2, labels.btn3, labels.btn4); } } else if (state_ == DOWNLOADING) { diff --git a/src/activities/settings/FontDownloadActivity.h b/src/activities/settings/FontDownloadActivity.h index 16d52fa9..2b8b1989 100644 --- a/src/activities/settings/FontDownloadActivity.h +++ b/src/activities/settings/FontDownloadActivity.h @@ -86,6 +86,9 @@ class FontDownloadActivity : public Activity { void downloadAll(); static bool computeFileCrc32(const char* path, uint32_t& outCrc); bool isDownloadAllSelected() const { return selectedIndex_ == 0 && !families_.empty(); } + bool isSelectedFamilyDeletable() const; + void promptDeleteSelectedFamily(); + void onDeleteConfirmationResult(const ActivityResult& result); int familyIndexFromList(int listIndex) const { return listIndex - 1; } int listItemCount() const { return families_.empty() ? 0 : static_cast(families_.size()) + 1; } size_t totalUninstalledSize() const; diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 9239ff91..adf99acd 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -57,9 +57,9 @@ void SettingsActivity::rebuildSettingsLists() { systemSettings.push_back(SettingInfo::Action(StrId::STR_CHECK_UPDATES, SettingAction::CheckForUpdates)); systemSettings.push_back(SettingInfo::Action(StrId::STR_SD_FIRMWARE_UPDATE, SettingAction::SdFirmwareUpdate)); systemSettings.push_back(SettingInfo::Action(StrId::STR_LANGUAGE, SettingAction::Language)); - // Insert "Download Fonts" right after the font family setting so users discover it naturally + // Insert "Manage Fonts" right after the font family setting so users discover it naturally readerSettings.insert(readerSettings.begin() + 1, - SettingInfo::Action(StrId::STR_DOWNLOAD_FONTS, SettingAction::DownloadFonts)); + SettingInfo::Action(StrId::STR_MANAGE_FONTS, SettingAction::DownloadFonts)); readerSettings.push_back(SettingInfo::Action(StrId::STR_CUSTOMISE_STATUS_BAR, SettingAction::CustomiseStatusBar)); // Update currentSettings pointer and count for the active category