Skip to content

feat: Themed language screen#1020

Merged
osteotek merged 1 commit intocrosspoint-reader:masterfrom
CaptainFrito:feature/lyra-language-screen
Feb 23, 2026
Merged

feat: Themed language screen#1020
osteotek merged 1 commit intocrosspoint-reader:masterfrom
CaptainFrito:feature/lyra-language-screen

Conversation

@CaptainFrito
Copy link
Contributor

Summary

Added theme support to the language screen

IMG_8139 Medium

Additional Context


AI Usage

Did you use AI tools to help write this code? NO

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 20, 2026

📝 Walkthrough

Walkthrough

Navigation in LanguageSelectActivity moved from direct input polling to an event-driven ButtonNavigator; rendering switched from manual per-item drawing to GUI.drawList and GUI.drawHeader, with layout computed from shared metrics and lambdas supplying item text and selection marker.

Changes

Cohort / File(s) Summary
LanguageSelectActivity refactor
src/activities/settings/LanguageSelectActivity.h, src/activities/settings/LanguageSelectActivity.cpp
Added ButtonNavigator member; migrated navigation to onNextRelease/onPreviousRelease using nextIndex/previousIndex. Replaced manual per-item rendering and header drawing with GUI.drawList and GUI.drawHeader. Layout now uses shared metrics (topPadding, headerHeight, verticalSpacing, buttonHintsHeight). Current-language marker provided via lambda to drawList.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Activity as LanguageSelectActivity
    participant Navigator as ButtonNavigator
    participant GUI
    participant Renderer as drawList

    User->>Activity: press navigation button
    Activity->>Navigator: forward button event
    Navigator->>Activity: onNextRelease / onPreviousRelease
    Activity->>Activity: update currentIndex (nextIndex/previousIndex)
    Activity->>Activity: requestUpdate()
    Activity->>GUI: drawHeader(), compute contentTop/contentHeight
    GUI->>Renderer: drawList(items lambda, selection lambda)
    Renderer->>Activity: call item-label lambda for visible items
    Renderer->>Activity: call selection-marker lambda for currentIndex
    GUI-->>Activity: rendered frame
    Activity-->>User: updated UI shown
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • daveallie
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: Themed language screen' is directly related to the main change: adding theme support to the language selection screen through GUI improvements and rendering migration.
Description check ✅ Passed The description accurately describes the changeset as adding theme support to the language screen, with supporting visual evidence from a screenshot of the themed language selection interface.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 22b96ec and 9eef16f.

📒 Files selected for processing (2)
  • src/activities/settings/LanguageSelectActivity.cpp
  • src/activities/settings/LanguageSelectActivity.h
🧰 Additional context used
🧬 Code graph analysis (1)
src/activities/settings/LanguageSelectActivity.cpp (1)
lib/I18n/I18n.cpp (2)
  • getInstance (15-18)
  • getInstance (15-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (2)
src/activities/settings/LanguageSelectActivity.h (1)

10-33: LGTM: ButtonNavigator integration is clean.
The private member addition and include are straightforward and don’t alter public APIs.

src/activities/settings/LanguageSelectActivity.cpp (1)

33-41: No action needed. onNextRelease/onPreviousRelease are polling functions, not callback registrations. They check button state each frame and immediately invoke the lambda if released—they do not accumulate handlers. This per-frame polling pattern is correct and intended for the activity loop.

Likely an incorrect or invalid review comment.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/activities/settings/LanguageSelectActivity.cpp`:
- Around line 64-70: Add a defensive guard for empty language lists before
calling GUI.drawList: check the total item count (use I18N.getLanguageCount() or
the existing totalItems) and if it is 0, avoid calling GUI.drawList (either
return early or render the same empty-list handling used in
RecentBooksActivity/MyLibraryActivity) instead of attempting to draw the list;
keep the selectedIndex handling unchanged and preserve the currentLang logic for
non-empty cases.

@CaptainFrito CaptainFrito force-pushed the feature/lyra-language-screen branch from 9eef16f to 000a43c Compare February 22, 2026 10:35
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9eef16f and 000a43c.

📒 Files selected for processing (2)
  • src/activities/settings/LanguageSelectActivity.cpp
  • src/activities/settings/LanguageSelectActivity.h
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/activities/settings/LanguageSelectActivity.h
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2026-02-12T06:57:35.955Z
Learnt from: CaptainFrito
Repo: crosspoint-reader/crosspoint-reader PR: 725
File: src/activities/network/CalibreConnectActivity.cpp:218-264
Timestamp: 2026-02-12T06:57:35.955Z
Learning: In src/activities/network/CalibreConnectActivity.cpp, button hints (« Exit) are intentionally omitted from the SERVER_STARTING and ERROR states—only the SERVER_RUNNING state displays navigation hints. This is a deliberate design decision by the author.

Applied to files:

  • src/activities/settings/LanguageSelectActivity.cpp
🧬 Code graph analysis (1)
src/activities/settings/LanguageSelectActivity.cpp (1)
lib/I18n/I18n.cpp (2)
  • getInstance (15-18)
  • getInstance (15-15)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: cppcheck
🔇 Additional comments (1)
src/activities/settings/LanguageSelectActivity.cpp (1)

33-42: LGTM!

The event-driven navigation using ButtonNavigator is cleanly implemented. The lambdas correctly capture this and update the selection index with proper boundary handling via nextIndex/previousIndex.

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/activities/settings/LanguageSelectActivity.cpp`:
- Around line 59-70: Add a defensive guard before calling GUI.drawList in
LanguageSelectActivity so an empty language list is handled like
RecentBooksActivity/MyLibraryActivity: check the language count (use
getLanguageCount() or totalItems) and if it is zero, skip or render an
appropriate empty-state instead of calling GUI.drawList; keep existing header
rendering (GUI.drawHeader) and preserve
selectedIndex/I18N.getLanguageName/I18N.getLanguage usage when the list is
non-empty.

@lukestein
Copy link
Contributor

No code review but tested on device and seems to work great!

@CaptainFrito CaptainFrito force-pushed the feature/lyra-language-screen branch from 000a43c to f1999f8 Compare February 23, 2026 08:14
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
src/activities/settings/LanguageSelectActivity.cpp (1)

67-70: Clean drawList implementation with appropriate lambdas.

The rendering correctly uses GUI.drawList with lambdas to supply language names and the "Set" marker for the current selection. This approach cleanly separates data retrieval from rendering logic.

Regarding the empty-list guard suggested in a previous review: since getLanguageCount() returns a compile-time constant from a hardcoded enum (always 8 languages), adding a guard provides minimal practical value here. If you prefer consistency with other list-based activities, you could add it, but it's not strictly necessary for this case.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/activities/settings/LanguageSelectActivity.cpp` around lines 67 - 70, The
current GUI.drawList call using lambdas (GUI.drawList, I18N.getLanguageName) is
fine; no code change required because getLanguageCount() is a compile-time
constant (always 8). If you prefer consistency with other activities, add an
optional empty-list guard: call getLanguageCount() (or a wrapper) into
totalItems, if totalItems == 0 skip calling GUI.drawList and render an
empty-state message instead; otherwise invoke GUI.drawList exactly as currently
written, keeping the lambdas for names and the "Set" marker.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@src/activities/settings/LanguageSelectActivity.cpp`:
- Around line 67-70: The current GUI.drawList call using lambdas (GUI.drawList,
I18N.getLanguageName) is fine; no code change required because
getLanguageCount() is a compile-time constant (always 8). If you prefer
consistency with other activities, add an optional empty-list guard: call
getLanguageCount() (or a wrapper) into totalItems, if totalItems == 0 skip
calling GUI.drawList and render an empty-state message instead; otherwise invoke
GUI.drawList exactly as currently written, keeping the lambdas for names and the
"Set" marker.
ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 000a43c and f1999f8.

📒 Files selected for processing (2)
  • src/activities/settings/LanguageSelectActivity.cpp
  • src/activities/settings/LanguageSelectActivity.h
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/activities/settings/LanguageSelectActivity.h
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: cppcheck
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2026-02-12T06:57:35.955Z
Learnt from: CaptainFrito
Repo: crosspoint-reader/crosspoint-reader PR: 725
File: src/activities/network/CalibreConnectActivity.cpp:218-264
Timestamp: 2026-02-12T06:57:35.955Z
Learning: In src/activities/network/CalibreConnectActivity.cpp, button hints (« Exit) are intentionally omitted from the SERVER_STARTING and ERROR states—only the SERVER_RUNNING state displays navigation hints. This is a deliberate design decision by the author.

Applied to files:

  • src/activities/settings/LanguageSelectActivity.cpp
📚 Learning: 2026-02-23T06:18:08.408Z
Learnt from: raygan
Repo: crosspoint-reader/crosspoint-reader PR: 1116
File: src/activities/settings/WallabagSettingsActivity.cpp:57-75
Timestamp: 2026-02-23T06:18:08.408Z
Learning: When navigating from a settings activity to KeyboardEntryActivity (e.g., KOReaderSettingsActivity, WallabagSettingsActivity), call exitActivity() on the parent before calling enterNewActivity(new KeyboardEntryActivity(...)). The KeyboardEntryActivity should then call exitActivity() via its callbacks to return to the parent. Note: ConfirmationActivity does not require exitActivity() before entering KeyboardEntryActivity. Apply this pattern to similar settings activities in this module.

Applied to files:

  • src/activities/settings/LanguageSelectActivity.cpp
🧬 Code graph analysis (1)
src/activities/settings/LanguageSelectActivity.cpp (1)
lib/I18n/I18n.cpp (2)
  • getInstance (15-18)
  • getInstance (15-15)
🔇 Additional comments (2)
src/activities/settings/LanguageSelectActivity.cpp (2)

33-42: LGTM!

Clean migration to event-driven navigation using ButtonNavigator. The lambda-based handlers with static index calculation methods follow a good pattern for list navigation with wrapping support.


59-65: LGTM!

The metrics-driven layout calculations correctly position the content area between the header and button hints. Using UITheme::getInstance().getMetrics() properly integrates with the theming system.

@osteotek osteotek merged commit a6aead6 into crosspoint-reader:master Feb 23, 2026
6 checks passed
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 23, 2026
## Summary

Added theme support to the language screen

![IMG_8139
Medium](https://github.com/user-attachments/assets/08fe06b4-d8ed-41fe-9584-8b90488eebae)


## Additional Context

---

### AI Usage

Did you use AI tools to help write this code? _**NO**_
@ariel-lindemann
Copy link
Contributor

@CaptainFrito, thanks for the new screen, it looks very nice!

I noticed you changed the localisation string form STR_ON_MARKER to STR_SET and I wondered if there is a particular reason for that. Is it because of the brackets so it looks nicer?

Because the new string is translated quite diffferently in the translations, since "set" is a bit ambiguous . Currently this is also the only place in the code this is used as far as I could tell. So translators also lacked context maybe. At least for the languages I understand it looks a bit off.

I thought I'd check with you before I open a PR. My proposal would be to make a string called Selected which is less ambuguous and it matches the button (Select)

@CaptainFrito
Copy link
Contributor Author

@CaptainFrito, thanks for the new screen, it looks very nice!

I noticed you changed the localisation string form STR_ON_MARKER to STR_SET and I wondered if there is a particular reason for that. Is it because of the brackets so it looks nicer?

Because the new string is translated quite diffferently in the translations, since "set" is a bit ambiguous . Currently this is also the only place in the code this is used as far as I could tell. So translators also lacked context maybe. At least for the languages I understand it looks a bit off.

I thought I'd check with you before I open a PR. My proposal would be to make a string called Selected which is less ambuguous and it matches the button (Select)

Thanks for the feedback! I only changed it to try to reduce the number of different strings we have in the app, and Set is already used elsewhere. But I understand if it's not suitable we can change it back, or change STR_ON_MARKER to something else :)

@ariel-lindemann
Copy link
Contributor

Ok, thank you that helps. I'll open a PR later today and we can discuss the rest there

lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 24, 2026
## Summary

Added theme support to the language screen

![IMG_8139
Medium](https://github.com/user-attachments/assets/08fe06b4-d8ed-41fe-9584-8b90488eebae)


## Additional Context

---

### AI Usage

Did you use AI tools to help write this code? _**NO**_
lukestein pushed a commit to lukestein/crosspoint-reader that referenced this pull request Feb 24, 2026
## Summary

Added theme support to the language screen

![IMG_8139
Medium](https://github.com/user-attachments/assets/08fe06b4-d8ed-41fe-9584-8b90488eebae)


## Additional Context

---

### AI Usage

Did you use AI tools to help write this code? _**NO**_
el pushed a commit to el/crosspoint-reader that referenced this pull request Feb 24, 2026
## Summary

Added theme support to the language screen

![IMG_8139
Medium](https://github.com/user-attachments/assets/08fe06b4-d8ed-41fe-9584-8b90488eebae)


## Additional Context

---

### AI Usage

Did you use AI tools to help write this code? _**NO**_
el pushed a commit to el/crosspoint-reader that referenced this pull request Feb 24, 2026
## Summary

Added theme support to the language screen

![IMG_8139
Medium](https://github.com/user-attachments/assets/08fe06b4-d8ed-41fe-9584-8b90488eebae)


## Additional Context

---

### AI Usage

Did you use AI tools to help write this code? _**NO**_
znelson pushed a commit that referenced this pull request Feb 27, 2026
## Summary

* **What is the goal of this PR?** (e.g., Implements the new feature for
file uploading.)

Fixes a clarity issue regarding the translation string `STR_SET`. The
issue lies in the fact that the english word can have different
meanings.

The only time the string is used is in the language selectio screen,
where it has the meaning of _selected_. (As in _The language has been
**set** to French_).

Another meaning can be _configured_. (As in _The KOReader username has
been __set__). This is the meaning many of the translations have taken.
The reason that the string is right above `STR_NOT_SET` (which is meant
as _not configured_).

With this PR I propose to explicitly use the term "_Selected_". There
are two good reasons for this:
+ it removes the confusion and the misleading translations
+ it is consistent with the button label `Select`, communicating the
link between the two (the row will be marked `Selected` if you press the
buttpn `Select`. Much clearer than now)

* **What changes are included?**

Removed the unused strings and added translations for the new string
`STR_SELECTED` for the languages I know.

tagging the translators for feedback:
fr: @Spigaw @CaptainFrito 
de: @DavidOrtmann
cs: @brbla 
pt: @yagofarias
it: @andreaturchet @fargolinux
ru: @madebyKir @mrtnvgr 
es: @yeyeto2788 @Skrzakk @pablohc 
sv: @dawiik
ca: @angeldenom 
uj: @mirus-ua 
be: @dexif 

## Additional Context

* Add any other information that might be helpful for the reviewer
(e.g., performance implications, potential risks,
  specific areas to focus on).

the Issue was introduced in #1020. Previously, if a language was
selected it was marked with `[ON]` (`STR_ON_MARKER`). I considered
reverting it back to that, but the solution I described above seemed
superior.

---

### 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: Егор Мартынов <[email protected]>
Co-authored-by: Mirus <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants