feat: separate into "Download All" and "Update All" in font manager (#1955)

## Summary

* **What is the goal of this PR?**  
Separate the font manager's combined `Download / Update All` action into
separate `Download All` and `Update All` rows

* **What changes are included?**  
- Updated multiple i18n translation files to add `STR_UPDATE_ALL` and
adjust `STR_DOWNLOAD_ALL` text.
- Added separate handlers: `downloadAll()` for fonts that have been
installed and `updateAll()` for fonts with updates.
  - `Download All` and `Update All` are only shown when applicable.

---

### 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**_
This commit is contained in:
WuTofu
2026-05-12 12:17:01 -05:00
committed by GitHub
parent 8d1b86a893
commit bc6e090aa8
6 changed files with 90 additions and 22 deletions
@@ -173,7 +173,7 @@ bool FontDownloadActivity::fetchAndParseManifest() {
void FontDownloadActivity::downloadAll() {
for (size_t i = 0; i < families_.size(); i++) {
if (families_[i].installed && !families_[i].hasUpdate) continue;
if (families_[i].installed) continue;
downloadFamily(families_[i]);
if (state_ == ERROR) return;
}
@@ -184,10 +184,59 @@ void FontDownloadActivity::downloadAll() {
}
}
size_t FontDownloadActivity::totalUninstalledSize() const {
void FontDownloadActivity::updateAll() {
for (size_t i = 0; i < families_.size(); i++) {
if (!families_[i].hasUpdate) continue;
downloadFamily(families_[i]);
if (state_ == ERROR) return;
}
{
RenderLock lock(*this);
state_ = COMPLETE;
}
}
bool FontDownloadActivity::showDownloadAllRow() const {
for (const auto& f : families_) {
if (!f.installed) return true;
}
return false;
}
bool FontDownloadActivity::showUpdateAllRow() const {
for (const auto& f : families_) {
if (f.hasUpdate) return true;
}
return false;
}
int FontDownloadActivity::specialRowCount() const {
return (showDownloadAllRow() ? 1 : 0) + (showUpdateAllRow() ? 1 : 0);
}
bool FontDownloadActivity::isDownloadAllRow(int index) const { return showDownloadAllRow() && index == 0; }
bool FontDownloadActivity::isUpdateAllRow(int index) const {
return showUpdateAllRow() && index == (showDownloadAllRow() ? 1 : 0);
}
int FontDownloadActivity::listItemCount() const {
return families_.empty() ? 0 : static_cast<int>(families_.size()) + specialRowCount();
}
size_t FontDownloadActivity::totalDownloadSize() const {
size_t total = 0;
for (const auto& f : families_) {
if (!f.installed || f.hasUpdate) total += f.totalSize;
if (!f.installed) total += f.totalSize;
}
return total;
}
size_t FontDownloadActivity::totalUpdateSize() const {
size_t total = 0;
for (const auto& f : families_) {
if (f.hasUpdate) total += f.totalSize;
}
return total;
}
@@ -299,6 +348,7 @@ void FontDownloadActivity::downloadFamily(ManifestFamily& family) {
fontInstaller_.refreshRegistry();
family.installed = true;
family.hasUpdate = false;
{
RenderLock lock(*this);
@@ -341,7 +391,8 @@ void FontDownloadActivity::onDeleteConfirmationResult(const ActivityResult& resu
}
bool FontDownloadActivity::isSelectedFamilyDeletable() const {
if (selectedIndex_ <= 0 || selectedIndex_ >= listItemCount()) return false;
if (isDownloadAllRow(selectedIndex_) || isUpdateAllRow(selectedIndex_)) return false;
if (selectedIndex_ < specialRowCount() || selectedIndex_ >= listItemCount()) return false;
const auto& family = families_[familyIndexFromList(selectedIndex_)];
return family.installed && !family.hasUpdate;
}
@@ -380,8 +431,10 @@ void FontDownloadActivity::loop() {
if (mappedInput.wasPressed(MappedInputManager::Button::Confirm)) {
if (!families_.empty()) {
if (isDownloadAllSelected()) {
if (isDownloadAllRow(selectedIndex_)) {
downloadAll();
} else if (isUpdateAllRow(selectedIndex_)) {
updateAll();
} else {
auto& family = families_[familyIndexFromList(selectedIndex_)];
if (!family.installed || family.hasUpdate) {
@@ -467,18 +520,21 @@ void FontDownloadActivity::render(RenderLock&&) {
Rect{0, contentTop, pageWidth, pageHeight - contentTop - metrics.buttonHintsHeight - metrics.verticalSpacing},
listItemCount(), selectedIndex_,
[this](int index) -> std::string {
if (index == 0) {
return std::string(tr(STR_DOWNLOAD_ALL)) + " (" + formatSize(totalUninstalledSize()) + ")";
if (isDownloadAllRow(index)) {
return std::string(tr(STR_DOWNLOAD_ALL)) + " (" + formatSize(totalDownloadSize()) + ")";
}
if (isUpdateAllRow(index)) {
return std::string(tr(STR_UPDATE_ALL)) + " (" + formatSize(totalUpdateSize()) + ")";
}
return families_[familyIndexFromList(index)].name;
},
[this](int index) -> std::string {
if (index == 0) return "";
if (isDownloadAllRow(index) || isUpdateAllRow(index)) return "";
return families_[familyIndexFromList(index)].description;
},
nullptr,
[this](int index) -> std::string {
if (index == 0) return "";
if (isDownloadAllRow(index) || isUpdateAllRow(index)) return "";
const auto& f = families_[familyIndexFromList(index)];
if (f.hasUpdate) return tr(STR_UPDATE_AVAILABLE);
if (f.installed) return tr(STR_INSTALLED);
@@ -486,14 +542,16 @@ void FontDownloadActivity::render(RenderLock&&) {
},
true,
[this](int index) -> bool {
if (index == 0) return false;
if (isDownloadAllRow(index) || isUpdateAllRow(index)) return false;
const auto& f = families_[familyIndexFromList(index)];
return f.installed && !f.hasUpdate;
});
const auto labels =
mappedInput.mapLabels(tr(STR_BACK), isSelectedFamilyDeletable() ? tr(STR_DELETE) : tr(STR_DOWNLOAD),
tr(STR_DIR_UP), tr(STR_DIR_DOWN));
const auto labels = mappedInput.mapLabels(tr(STR_BACK),
isSelectedFamilyDeletable() ? tr(STR_DELETE)
: isUpdateAllRow(selectedIndex_) ? tr(STR_UPDATE)
: 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) {