Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
give broadcasters live feedback as they edit the form whether the nam…
…e will be translated
  • Loading branch information
allanjoseph98 committed Jan 31, 2026
commit 6c5c493b4ef0cd26116df3a68c03ba787c2b0d30
1 change: 1 addition & 0 deletions modules/coreI18n/src/main/key.scala
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ object I18nKey:
val `liveboard`: I18nKey = "broadcast:liveboard"
val `communityBroadcast`: I18nKey = "broadcast:communityBroadcast"
val `createdAndManagedBy`: I18nKey = "broadcast:createdAndManagedBy"
val `automaticallyTranslated`: I18nKey = "broadcast:automaticallyTranslated"
val `roundX`: I18nKey = "broadcast:roundX"
val `defaultRoundNameHelp`: I18nKey = "broadcast:defaultRoundNameHelp"
val `openTournament`: I18nKey = "broadcast:openTournament"
Expand Down
4 changes: 4 additions & 0 deletions modules/relay/src/main/ui/RelayFormUi.scala
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ final class RelayFormUi(helpers: Helpers, ui: RelayUi, pageMenu: RelayMenuUi):
Page(title)
.css("bits.relay.form")
.js(List(Esm("bits.flatpickr"), Esm("bits.relayForm")).map(some))
.js(esmInit("bits.broadcastForm.i18nCheck"))
.i18n(_.broadcast)
.wrap: body =>
main(cls := "page page-menu")(
navigationMenu(nav),
Expand Down Expand Up @@ -446,6 +448,8 @@ Hanna Marie ; Kozul, Zdenko"""),
Page(title)
.css("bits.relay.form")
.js(Esm("bits.relayForm"))
.js(esmInit("bits.broadcastForm.i18nCheck"))
.i18n(_.broadcast)
.wrap: body =>
main(cls := "page page-menu")(
menu.fold(pageMenu(_), navigationMenu),
Expand Down
1 change: 1 addition & 0 deletions translation/source/broadcast.xml
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
<string name="liveboard">Live board</string>
<string name="communityBroadcast">Community broadcast</string>
<string name="createdAndManagedBy">Created and managed by %s.</string>
<string name="automaticallyTranslated">This name will be automatically translated.</string>
<string name="roundX">Round %s</string>
<string name="defaultRoundNameHelp">Keeping the default name will automatically translate it to all other languages.</string>
<string name="openTournament">Open</string>
Expand Down
2 changes: 2 additions & 0 deletions ui/@types/lichess/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@ interface I18n {
allBroadcastsByMonth: string;
/** All teams */
allTeams: string;
/** This name will be automatically translated. */
automaticallyTranslated: string;
/** Back to live move */
backToLiveMove: string;
/** Boards */
Expand Down
53 changes: 53 additions & 0 deletions ui/bits/src/bits.broadcastForm.i18nCheck.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { Checkmark } from 'lib/licon';
export default function initModule(): void {
site.load.then(() => {
const nameInput = document.querySelector<HTMLInputElement>('#form3-name');
if (!nameInput) return;
const isRoundEdit = location.pathname.startsWith('/broadcast/round/');
const groupName = document.querySelector('.relay-form__subnav__group')?.textContent;

// Must be in sync with file://./../../../modules/relay/src/main/RelayI18n.scala
const regexes = [
/^Round (\d+)$/i,
/^Game (\d+)$/i,
/^blitz$/i,
/^rapid$/i,
/^classical$/i,
/^open$/i,
/^women$/i,
/^boys$/i,
/^girls$/i,
/^boys\s+u(\d+)$/i,
/^girls\s+u(\d+)$/i,
/^quarter[- ]?finals$/i,
/^semi[- ]?finals$/i,
/^finals$/i,
/^tiebreaks$/i,
];
const helpEl = document.createElement('small');
helpEl.classList.add('form-help');
helpEl.innerHTML = `${i18n.broadcast.automaticallyTranslated}<br>`;
helpEl.setAttribute('data-icon', Checkmark);
nameInput.insertAdjacentElement('afterend', helpEl);
const checkAndToggle = (name: string) => {
const isTranslatable =
!!name && name.split(/\s+\|\s+/).every(token => regexes.some(re => re.test(token)));
isTranslatable ? (helpEl.style.visibility = 'visible') : (helpEl.style.visibility = 'hidden');
};
const getShortName = () =>
isRoundEdit
? nameInput.value
: groupName
? nameInput.value.startsWith(groupName)
? nameInput.value.slice(groupName.length).replace(/^[^\da-z]*/i, '')
: nameInput.value
: false;
// Initial load
const shortName = getShortName();
!!shortName && checkAndToggle(shortName);
nameInput?.addEventListener('input', () => {
const shortName = getShortName();
!!shortName && checkAndToggle(shortName);
});
});
}
Loading