Skip to content

core&ui: expose viewLang to UiContext#1166

Open
renbaoshuo wants to merge 1 commit into
hydro-dev:masterfrom
renbaoshuo:refactor-viewlang
Open

core&ui: expose viewLang to UiContext#1166
renbaoshuo wants to merge 1 commit into
hydro-dev:masterfrom
renbaoshuo:refactor-viewlang

Conversation

@renbaoshuo
Copy link
Copy Markdown
Contributor

@renbaoshuo renbaoshuo commented May 24, 2026

Summary by CodeRabbit

  • Refactor
    • Standardized language preference handling throughout the application to consistently use session-based language settings across the UI, editors, and content rendering for improved coherence.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 24, 2026

Walkthrough

This pull request migrates the source of language preference from user object properties to session-based UiContext. The change initializes viewLang in the session from authenticated user documents and settings updates, propagates it to request handlers via UiContext, and updates backend translation logic and frontend components to consume from the session context instead of the user object.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change across all modified files: exposing viewLang to UiContext, which involves refactoring how viewLang is accessed throughout the codebase (from UserContext to UiContext).
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/hydrooj/src/handler/home.ts

ESLint skipped: missing config or dependency (missing-dependency). The ESLint configuration references a package that is not available in the sandbox.

packages/hydrooj/src/handler/user.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

packages/hydrooj/src/service/layers/base.ts

ESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.

  • 4 others

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

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

Copy link
Copy Markdown

@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

♻️ Duplicate comments (1)
packages/ui-default/templates/problem_detail.html (1)

31-32: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Verify that UiContext.viewLang is consistently initialized for all request types.

Same issue as in partials/problem_description.html: the OG meta rendering relies on UiContext.viewLang without a fallback. If undefined, the meta tags may not render with the expected language.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-default/templates/problem_detail.html` around lines 31 - 32,
Ensure preferredLang has a safe fallback so OG/meta rendering never receives
undefined: update the template logic that sets preferredLang (currently using
handler.request.query.lang or UiContext.viewLang) to include a final default
(e.g., a site default or 'en') when UiContext.viewLang is unset; verify the same
change or initialization occurs where OG/meta uses UiContext.viewLang (see
preferredLang, handler.request.query.lang, UiContext.viewLang and the
pdoc.content|content usage) so renderredContent always gets a concrete language
value.
🧹 Nitpick comments (2)
packages/ui-default/templates/layout/html5.html (1)

9-9: ⚡ Quick win

Consider adding a fallback for the lang attribute.

When UiContext.viewLang is undefined (e.g., for guest users or users without a language preference), the lang attribute will be empty. While this is valid HTML, providing a fallback to a default language or browser language would improve accessibility and SEO.

💡 Suggested improvement
-<html data-page="{{ page_name }}" data-layout="{{ layout_name }}" class="layout--{{ layout_name }} page--{{ page_name }} theme--{{ theme }} nojs" data-mantine-color-scheme="{{ 'dark' if theme.includes('dark') else 'light' }}" lang="{{ UiContext.viewLang }}" data-app="Hydro">
+<html data-page="{{ page_name }}" data-layout="{{ layout_name }}" class="layout--{{ layout_name }} page--{{ page_name }} theme--{{ theme }} nojs" data-mantine-color-scheme="{{ 'dark' if theme.includes('dark') else 'light' }}" lang="{{ UiContext.viewLang or 'en' }}" data-app="Hydro">

Or use the system default language instead of hardcoding 'en'.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-default/templates/layout/html5.html` at line 9, The html
element's lang attribute uses UiContext.viewLang directly and can be empty;
change the template to provide a fallback (e.g., fall back to
UiContext.systemLang or a default like 'en') so lang="{{ UiContext.viewLang }}"
becomes a conditional expression that uses UiContext.viewLang if present,
otherwise UiContext.systemLang or a hardcoded default; update the html tag
template line (the lang attribute on the html element) to use that fallback
expression to ensure a non-empty language value.
packages/ui-default/templates/problem_edit.html (1)

55-57: ⚡ Quick win

Verify behavior when UiContext.viewLang is undefined.

If UiContext.viewLang is undefined or null, the condition k != UiContext.viewLang will evaluate to true for all languages, meaning no language tabs will be filtered out. This could result in the user's current language appearing in both the default tab and the additional language tabs.

Confirm this is the intended behavior or add a fallback to ensure consistent tab filtering.

🛡️ Suggested defensive check
-              {% for k, v in statementLangs %}{% if k != UiContext.viewLang %}
+              {% for k, v in statementLangs %}{% if UiContext.viewLang and k != UiContext.viewLang %}
                <li class="section__tab-header-item" data-lang="{{ k }}">{{ v }}</li>
              {% endif %}{% endfor %}

This ensures the filter only applies when UiContext.viewLang is defined.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui-default/templates/problem_edit.html` around lines 55 - 57, The
template's loop over statementLangs can duplicate the current language when
UiContext.viewLang is undefined; update the conditional in the for-loop so the
exclusion only runs when UiContext.viewLang is defined (e.g., check
UiContext.viewLang is truthy before comparing), i.e. change the condition around
the block that uses UiContext.viewLang so you only filter out k when
UiContext.viewLang is present, ensuring the default/current tab isn't also
rendered in the extra language tabs; refer to the for-loop iterating
statementLangs and the UiContext.viewLang check to locate where to add the
guard.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/hydrooj/src/handler/user.ts`:
- Line 36: Existing sessions lack session.viewLang so i18n falls back; when
handling requests where this.session.uid exists but this.session.viewLang is
missing/empty, read the user document's viewLang (udoc.viewLang) and assign it
to this.session.viewLang (and persist the session if your store requires).
Update the initialization path that runs per-request (or session bootstrap) —
not just the login handler — to backfill session.viewLang from the user record,
or alternatively run a one-time migration to populate stored sessions from
user.viewLang for all sessions.

---

Duplicate comments:
In `@packages/ui-default/templates/problem_detail.html`:
- Around line 31-32: Ensure preferredLang has a safe fallback so OG/meta
rendering never receives undefined: update the template logic that sets
preferredLang (currently using handler.request.query.lang or UiContext.viewLang)
to include a final default (e.g., a site default or 'en') when
UiContext.viewLang is unset; verify the same change or initialization occurs
where OG/meta uses UiContext.viewLang (see preferredLang,
handler.request.query.lang, UiContext.viewLang and the pdoc.content|content
usage) so renderredContent always gets a concrete language value.

---

Nitpick comments:
In `@packages/ui-default/templates/layout/html5.html`:
- Line 9: The html element's lang attribute uses UiContext.viewLang directly and
can be empty; change the template to provide a fallback (e.g., fall back to
UiContext.systemLang or a default like 'en') so lang="{{ UiContext.viewLang }}"
becomes a conditional expression that uses UiContext.viewLang if present,
otherwise UiContext.systemLang or a hardcoded default; update the html tag
template line (the lang attribute on the html element) to use that fallback
expression to ensure a non-empty language value.

In `@packages/ui-default/templates/problem_edit.html`:
- Around line 55-57: The template's loop over statementLangs can duplicate the
current language when UiContext.viewLang is undefined; update the conditional in
the for-loop so the exclusion only runs when UiContext.viewLang is defined
(e.g., check UiContext.viewLang is truthy before comparing), i.e. change the
condition around the block that uses UiContext.viewLang so you only filter out k
when UiContext.viewLang is present, ensuring the default/current tab isn't also
rendered in the extra language tabs; refer to the for-loop iterating
statementLangs and the UiContext.viewLang check to locate where to add the
guard.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 32dc4324-b387-488f-985f-55e063f162f1

📥 Commits

Reviewing files that changed from the base of the PR and between ce14b98 and f4dcb47.

📒 Files selected for processing (11)
  • packages/hydrooj/src/handler/home.ts
  • packages/hydrooj/src/handler/user.ts
  • packages/hydrooj/src/service/layers/base.ts
  • packages/hydrooj/src/service/layers/user.ts
  • packages/hydrooj/src/service/server.ts
  • packages/ui-default/components/editor/index.tsx
  • packages/ui-default/components/monaco/loader.ts
  • packages/ui-default/templates/layout/html5.html
  • packages/ui-default/templates/partials/problem_description.html
  • packages/ui-default/templates/problem_detail.html
  • packages/ui-default/templates/problem_edit.html

if (udoc._id !== 0) await user.setById(udoc._id, { loginat: new Date(), loginip: this.request.ip });
this.context.HydroContext.user = udoc;
this.session.viewLang = '';
this.session.viewLang = udoc.viewLang || '';
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if there are other initialization points for session.viewLang
rg -n 'session\.viewLang\s*=' --type=ts -C2

Repository: hydro-dev/Hydro

Length of output: 1541


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Find all reads of session.viewLang (to understand fallback behavior when it's missing)
rg -n 'session\.viewLang' --type=ts -S

# 2) Inspect the auth/login flow around where session.viewLang is set from udoc
sed -n '1,120p' packages/hydrooj/src/handler/user.ts

Repository: hydro-dev/Hydro

Length of output: 6410


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the UI context mapping for session.viewLang
sed -n '1,120p' packages/hydrooj/src/service/layers/base.ts

# Inspect where $set.viewLang is persisted from session.viewLang
sed -n '280,360p' packages/hydrooj/src/handler/user.ts

# Inspect where the user changes view language (misc handler)
sed -n '1,120p' packages/hydrooj/src/handler/misc.ts

# Inspect home handler for any language backfill logic
sed -n '400,480p' packages/hydrooj/src/handler/home.ts

# Find all reads of UiContext.viewLang to see default behavior when it's missing
rg -n 'UiContext\.viewLang' packages/hydrooj/src --type=ts -S

Repository: hydro-dev/Hydro

Length of output: 15335


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Get full set of assignments to session.viewLang
rg -n "session\.viewLang\s*=" packages/hydrooj/src --type=ts -S

# 2) Count how often viewLang is referenced in TS (beyond session.UiContext mapping)
rg -n "\bviewLang\b" packages/hydrooj/src --type=ts -S | wc -l

# 3) See where viewLang is referenced in HTML templates (sample)
rg -n "\bviewLang\b" packages/hydrooj/src -g'*.html' -S | head -n 80

# 4) Count viewLang references in any templates under packages/hydrooj/src (broader sample)
rg -n "\bviewLang\b" packages/hydrooj/src -S | head -n 80

Repository: hydro-dev/Hydro

Length of output: 445


🏁 Script executed:

#!/bin/bash
set +euo pipefail

# 1) All reads/usages of UiContext.viewLang (TS + templates)
rg -n "UiContext\.viewLang|ctx\.HydroContext\.UiContext\.viewLang|viewLang" packages/hydrooj/src -S

# 2) Specifically look for session.viewLang being used (reads)
rg -n "session\.viewLang" packages/hydrooj/src -S

# 3) Search across the hydrooj package for templates/static usage (HTML/JS/CSS etc.)
rg -n "UiContext\.viewLang|session\.viewLang|viewLang" packages/hydrooj -S

Repository: hydro-dev/Hydro

Length of output: 3579


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect how session.viewLang is used for language selection (fallback behavior)
sed -n '130,210p' packages/hydrooj/src/service/server.ts

# Inspect other backfill/propagation points for viewLang into session (or from request)
sed -n '280,360p' packages/hydrooj/src/handler/user.ts
sed -n '480,560p' packages/hydrooj/src/handler/user.ts

# Inspect base layer mapping of UiContext.viewLang (already saw line 47 but show surrounding)
sed -n '1,90p' packages/hydrooj/src/service/layers/base.ts

# Inspect misc language switch (confirm persistence)
sed -n '1,80p' packages/hydrooj/src/handler/misc.ts

# Inspect user login success session initialization already known (show surrounding)
sed -n '1,70p' packages/hydrooj/src/handler/user.ts

# See if UiContext.viewLang is referenced anywhere outside base/server
rg -n "UiContext\.viewLang" packages/hydrooj -S

Repository: hydro-dev/Hydro

Length of output: 21487


Backfill session.viewLang for already-authenticated users to prevent i18n fallback
packages/hydrooj/src/handler/user.ts sets this.session.viewLang = udoc.viewLang || '' on login, but existing session records won’t be updated automatically. Language selection uses this.session?.viewLang, and there’s no request-time backfill from user.viewLang when session.viewLang is missing/empty, so users with pre-existing sessions will fall back to Accept-Language/server.language until they re-login or change language.

Consider populating session.viewLang from the user document during session initialization (when uid is present but viewLang is absent), or doing a one-time session migration to update stored session docs.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/hydrooj/src/handler/user.ts` at line 36, Existing sessions lack
session.viewLang so i18n falls back; when handling requests where
this.session.uid exists but this.session.viewLang is missing/empty, read the
user document's viewLang (udoc.viewLang) and assign it to this.session.viewLang
(and persist the session if your store requires). Update the initialization path
that runs per-request (or session bootstrap) — not just the login handler — to
backfill session.viewLang from the user record, or alternatively run a one-time
migration to populate stored sessions from user.viewLang for all sessions.

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