core&ui: expose viewLang to UiContext#1166
Conversation
WalkthroughThis pull request migrates the source of language preference from user object properties to session-based UiContext. The change initializes Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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
packages/hydrooj/src/handler/home.tsESLint 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.tsESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox. packages/hydrooj/src/service/layers/base.tsESLint skipped: the ESLint configuration for this file references a package that is not available in the sandbox.
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
packages/ui-default/templates/problem_detail.html (1)
31-32:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winVerify that UiContext.viewLang is consistently initialized for all request types.
Same issue as in
partials/problem_description.html: the OG meta rendering relies onUiContext.viewLangwithout 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 winConsider adding a fallback for the
langattribute.When
UiContext.viewLangis undefined (e.g., for guest users or users without a language preference), thelangattribute 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 winVerify behavior when UiContext.viewLang is undefined.
If
UiContext.viewLangis undefined or null, the conditionk != UiContext.viewLangwill 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.viewLangis 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
📒 Files selected for processing (11)
packages/hydrooj/src/handler/home.tspackages/hydrooj/src/handler/user.tspackages/hydrooj/src/service/layers/base.tspackages/hydrooj/src/service/layers/user.tspackages/hydrooj/src/service/server.tspackages/ui-default/components/editor/index.tsxpackages/ui-default/components/monaco/loader.tspackages/ui-default/templates/layout/html5.htmlpackages/ui-default/templates/partials/problem_description.htmlpackages/ui-default/templates/problem_detail.htmlpackages/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 || ''; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if there are other initialization points for session.viewLang
rg -n 'session\.viewLang\s*=' --type=ts -C2Repository: 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.tsRepository: 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 -SRepository: 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 80Repository: 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 -SRepository: 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 -SRepository: 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.
Summary by CodeRabbit