Skip to content

Multiple Reversals completed implementation #807

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Christopher-Shiu
Copy link
Contributor

@Christopher-Shiu Christopher-Shiu commented May 1, 2025

Issue #804
Transferred code from different branch
and fixed small errors with letter loading

Summary by CodeRabbit

  • New Features
    • Added support for displaying and interacting with multiple reversal language tabs in the lexicon interface.
  • Refactor
    • Updated components and internal logic to handle arrays of reversal languages instead of a single language.
  • Bug Fixes
    • Improved error handling and data loading for reversal word lists.

Issue sillsdev#804
Transferred code from different branch
and fixed small errors with letter loading
Copy link
Contributor

coderabbitai bot commented May 1, 2025

Walkthrough

This update refactors the handling of reversal languages across the lexicon components and page logic. The main change is shifting from supporting a single reversal language to supporting multiple reversal languages, represented as an array. Component props, rendering logic, and data-fetching conditions are updated to work with arrays of reversal languages. The logic for identifying reversal writing systems is also refined to use a specific property. Additionally, the word list loading logic is improved for robustness and flexibility.

Changes

File(s) Change Summary
src/lib/components/LexiconLanguageTabs.svelte Changed prop from reversalLanguage (string) to reversalLanguages (array). Updated rendering to iterate over reversalLanguages and generate a tab for each. Accessibility attributes and event handlers now reference the current language in the loop.
src/lib/components/LexiconListViewHeader.svelte Changed exported prop from reversalLanguage (string) to reversalLanguages (array). Updated child component prop accordingly.
src/routes/lexicon/+page.svelte Initialized word lists as empty arrays. Introduced reversalLanguageList for all reversal languages. Refactored word-fetching and letter data loading logic to support multiple reversal languages and improved error handling. Updated component props to pass arrays instead of single values.
src/routes/lexicon/+page.ts Changed filter logic for reversal writing systems: now selects systems with a reversalFilename property instead of excluding those with 'main' in their type.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant LexiconListViewHeader
    participant LexiconLanguageTabs
    participant LexiconPage

    User->>LexiconListViewHeader: Selects a language tab
    LexiconListViewHeader->>LexiconLanguageTabs: Passes reversalLanguages array
    LexiconLanguageTabs->>User: Renders tabs for each reversal language
    User->>LexiconPage: Triggers language change
    LexiconPage->>LexiconPage: Checks if selected language is in reversalLanguageList
    LexiconPage->>LexiconPage: Loads and filters word data for selected language
    LexiconPage->>User: Displays updated word list
Loading

Possibly related PRs

  • Feature/display reversals/685 #802: Introduced the original LexiconLanguageTabs component with a single reversal language prop; this PR directly builds upon and generalizes that implementation.

Suggested reviewers

  • chrisvire

Poem

In the lexicon garden, tabs now bloom in rows,
Each reversal language, a petal that glows.
No longer just one, but many to see—
A bouquet of words for you and for me!
With arrays and with care, we hop through the code,
🐇✨ Multiple languages now lighten the load!

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 2

🔭 Outside diff range comments (4)
src/routes/lexicon/+page.ts (2)

24-30: ⚠️ Potential issue

reversalWritingSystems length is never falsy – adjust the guard

Array objects are always truthy, so the current test will never throw even when no reversal systems exist.

-if (!reversalWritingSystems) {
-    throw new Error('Reversal language not found');
-}
+if (reversalWritingSystems.length === 0) {
+    throw new Error('Reversal language not found');
+}

39-48: 🛠️ Refactor suggestion

Keep reversal-index loading consistent with the new filter rule

The loop still loads indexes for every non-main writing system, even those without reversalFilename.
To avoid unnecessary fetches (and 404s) restrict the loop to the same reversalWritingSystems list:

-for (const [key, ws] of Object.entries(dictionaryConfig.writingSystems)) {
-    if (!ws.type.includes('main')) {
+for (const [key, ws] of reversalWritingSystems) {
src/routes/lexicon/+page.svelte (2)

31-35: ⚠️ Potential issue

Only first reversal alphabet is used — multi-language support is incomplete

alphabets.reversal is set from reversalAlphabets[0], so any additional reversal languages are silently ignored. Down-stream logic (sorting, letter strip) will malfunction once a user switches to a second reversal language. Consider storing reversal alphabets in a map keyed by writing-system id and selecting the alphabet that matches selectedLanguage.


198-205: 🛠️ Refactor suggestion

Scroll-to-bottom detector only works for first reversal language

selectedLanguage === reversalLanguage restricts infinite-scroll to the very first reversal language. Replace the equality check with membership in the new reversalLanguageList.

-(selectedLanguage === reversalLanguage && reversalWordsList.length > 0)
+reversalLanguageList.includes(selectedLanguage) && reversalWordsList.length > 0
🧹 Nitpick comments (2)
src/lib/components/LexiconListViewHeader.svelte (1)

5-12: Consider typing & default-value safety for exported props

A number of exported props (alphabet, reversalLanguages, etc.) default to non-null values while others (selectedLanguage, vernacularLanguage) do not. In production builds it’s easy to forget passing a required prop – especially now that reversalLanguages is an array and may be empty for some dictionaries.

Adding simple runtime guards or TypeScript typings (using lang="ts") will fail fast and save debugging time.

- export let selectedLanguage;
- export let vernacularLanguage;
+/** Currently selected language (display name ‑ required) */
+export let selectedLanguage: string;
+/** Vernacular language display name (required) */
+export let vernacularLanguage: string;
src/lib/components/LexiconLanguageTabs.svelte (1)

28-46: Add keyed {#each} block to prevent DOM re-ordering glitches

Because the array can be re-created when the store updates, Svelte may recycle DOM nodes in unexpected ways. Keying the loop makes tab state deterministic and (bonus) removes a React-style warning in dev-mode.

-{#each reversalLanguages as lang}
+{#each reversalLanguages as lang (lang)}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0868371 and a99b8a0.

📒 Files selected for processing (4)
  • src/lib/components/LexiconLanguageTabs.svelte (2 hunks)
  • src/lib/components/LexiconListViewHeader.svelte (2 hunks)
  • src/routes/lexicon/+page.svelte (7 hunks)
  • src/routes/lexicon/+page.ts (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test
  • GitHub Check: lint

Comment on lines 38 to 44
let defaultReversalKey = Object.keys(reversalAlphabets[0])[0];
let loadedReversalLetters = new Set();
let reversalWordsList;
let vernacularWordsList;
let reversalWordsList = [];
let vernacularWordsList = [];
let selectedLanguage = vernacularLanguage;
const reversalLanguageList = Object.values(reversalLanguages[0]);
let scrollContainer;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

defaultReversalKey & reversalLanguageList assume a single language

Both variables are derived from the first element of their arrays, causing incorrect fetch paths and “language not found” behaviour when the user picks another reversal language. You can compute them on demand:

-const defaultReversalKey = Object.keys(reversalAlphabets[0])[0];
-const reversalLanguageList = Object.values(reversalLanguages[0]);
+const reversalAlphabetMap = Object.fromEntries(
+    reversalAlphabets.flatMap((obj) => Object.entries(obj))
+);
+const reversalLanguageMap = Object.fromEntries(
+    reversalLanguages.flatMap((obj) => Object.entries(obj))
+);
+const getKeyByLang = (lang) =>
+    Object.keys(reversalLanguageMap).find((k) => reversalLanguageMap[k] === lang);

This map can then drive loadLetterData, handleLetterChange, scrolling logic, etc.

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +81 to +90
let fileIndex = 1;
let moreFiles = true;
let newWords = [];

const index = reversalIndexes[defaultReversalKey];
const files = index[letter] || [];
for (const file of files) {
const reversalFile = `${base}/reversal/${defaultReversalKey}/${file}`;
const response = await fetch(reversalFile);
if (response.ok) {
const data = await response.json();
const currentFileWords = Object.entries(data).map(([word, entries]) => {
return {
word: word,
indexes: entries.map((entry) => entry.index),
vernacularWords: entries
.map((entry) => {
const foundWord = vernacularWordsList.find(
(vw) => vw.id === entry.index
);
if (foundWord) {
return {
name: foundWord.name,
homonymIndex: foundWord.homonym_index || 0
};
} else {
console.log(
`Index ${entry.index} not found in vernacularWordsList`
while (moreFiles) {
try {
const response = await fetch(
`${base}/reversal/${defaultReversalKey}/${letter}-${String(fileIndex).padStart(3, '0')}.json`
);
if (response.ok) {
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Letter data is always fetched from the first reversal language

loadLetterData hard-codes defaultReversalKey; if the UI is on a different language the wrong files are requested.

-`${base}/reversal/${defaultReversalKey}/${letter}-${String(fileIndex).padStart(3,'0')}.json`
+const langKey = getKeyByLang(selectedLanguage);
+`${base}/reversal/${langKey}/${letter}-${String(fileIndex).padStart(3,'0')}.json`

Coupled with the previous comment this will correctly download the right reversal index set.

Committable suggestion skipped: line range outside the PR's diff.

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.

1 participant