mirror of
https://github.com/fabrice404/olympics-calendar.git
synced 2025-12-13 14:49:46 +00:00
refactor translations
This commit is contained in:
@ -18,7 +18,7 @@ export default [
|
||||
{
|
||||
rules: {
|
||||
"comma-dangle": ["error", "always-multiline"],
|
||||
complexity: ["error", 8],
|
||||
complexity: ["error", 15],
|
||||
quotes: ["error", "double"],
|
||||
semi: ["error", "always"],
|
||||
},
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
"scripts": {
|
||||
"start": "find ./cache/**/*.html -mmin +10 -exec rm -f {} \\; | DEBUG=paris2024:* ts-node src/index.ts",
|
||||
"dev": "DEBUG=paris2024:* nodemon src/index.ts",
|
||||
"build": "tsc",
|
||||
"lint": "eslint . --fix",
|
||||
"test": "vitest run --coverage"
|
||||
},
|
||||
|
||||
@ -3,7 +3,7 @@ import autoprefixer from "autoprefixer";
|
||||
import postcss from "postcss";
|
||||
import tailwindcss from "tailwindcss";
|
||||
|
||||
import { Event, NOC, Sport } from "./types";
|
||||
import { Event, Medal, NOC, Sport } from "./types";
|
||||
import { getAllSportsKeys, getSportIcon } from "./sports";
|
||||
import { existsSync, writeFileSync } from "fs";
|
||||
import { hasFile, readFile, saveFile } from "./io";
|
||||
@ -20,6 +20,7 @@ export class Calendar {
|
||||
private events: Event[] = [];
|
||||
private nocs: string[] = [];
|
||||
private sports: Sport[] = [];
|
||||
private medals: Medal[] = [];
|
||||
|
||||
constructor(language: string) {
|
||||
this.language = language;
|
||||
@ -164,8 +165,8 @@ export class Calendar {
|
||||
DTSTAMP: startDateUtc.replace(/[:-]/g, ""),
|
||||
DTSTART: startDateUtc.replace(/[:-]/g, ""),
|
||||
DTEND: endDateUtc.replace(/[:-]/g, ""),
|
||||
DESCRIPTION: `Paris 2024 - ${translate.openingCeremony.get(this.language)}`,
|
||||
SUMMARY: `Paris 2024 - ${translate.openingCeremony.get(this.language)}`,
|
||||
DESCRIPTION: `Paris 2024 - {{translate_openingCeremony}}`,
|
||||
SUMMARY: `Paris 2024 - {{translate_openingCeremon}}`,
|
||||
LOCATION: "Paris",
|
||||
_COMPETITORS: [],
|
||||
_GENDER: "",
|
||||
@ -307,10 +308,10 @@ export class Calendar {
|
||||
|
||||
calendars.push(`<div class="${accordionClass}">`);
|
||||
calendars.push(` <input type="radio" name="accordion" checked="checked">`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">${translate.allSports.get(this.language)}</div>`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">{{translate_allSports}}</div>`);
|
||||
calendars.push(` <div class="collapse-content text-center">`)
|
||||
calendars.push(` <div>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('general/general', '${this.language}');">${translate.fullSchedule.get(this.language)}</button>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('general/general', '${this.language}');">{{translate_fullSchedule}}</button>`);
|
||||
calendars.push(` </div>`);
|
||||
for (const noc of this.nocs.sort()) {
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('general/${noc}', '${this.language}');">${getNOCFlag(noc)} ${noc}</button>`);
|
||||
@ -320,10 +321,10 @@ export class Calendar {
|
||||
|
||||
calendars.push(`<div class="${accordionClass}">`);
|
||||
calendars.push(` <input type="radio" name="accordion">`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">🏅 ${translate.medalEvents.get(this.language)}</div>`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">🏅 {{translate_medalEvents}</div>`);
|
||||
calendars.push(` <div class="collapse-content text-center">`)
|
||||
calendars.push(` <div>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('medals/general', '${this.language}');">${translate.fullSchedule.get(this.language)}</button>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('medals/general', '${this.language}');">{{translate_fullSchedule}}</button>`);
|
||||
calendars.push(` </div>`);
|
||||
for (const noc of this.nocs.sort()) {
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('medals/${noc}', '${this.language}');">${getNOCFlag(noc)} ${noc}</button>`);
|
||||
@ -333,7 +334,7 @@ export class Calendar {
|
||||
|
||||
calendars.push(`<div class="${accordionClass}">`);
|
||||
calendars.push(` <input type="radio" name="accordion">`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">📅 ${translate.todaysEvents.get(this.language)}</div>`);
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">📅 {{translate_todaysEvents}}</div>`);
|
||||
calendars.push(` <div class="collapse-content text-center">`)
|
||||
for (const noc of this.nocs.sort()) {
|
||||
calendars.push(` <a class="${buttonClass}" href="./today.html?noc=${noc}">${getNOCFlag(noc)} ${noc}</a>`);
|
||||
@ -347,8 +348,8 @@ export class Calendar {
|
||||
calendars.push(` <div class="collapse-title text-xl font-medium">${getSportIcon(sport.key)} ${sport.name}</div>`);
|
||||
calendars.push(` <div class="collapse-content text-center">`)
|
||||
calendars.push(` <div>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('${sport.key}/general', '${this.language}');">${translate.fullSchedule.get(this.language)}</button>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('${sport.key}/medals', '${this.language}');">🏅 ${translate.medalEvents.get(this.language)}</button>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('${sport.key}/general', '${this.language}');">{{translate_fullSchedule}}</button>`);
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('${sport.key}/medals', '${this.language}');">🏅 {{translate_medalEvents}}</button>`);
|
||||
calendars.push(` </div>`);
|
||||
for (const noc of sport.NOCS.sort()) {
|
||||
calendars.push(` <button class="${buttonClass}" onclick="showModal('${sport.key}/${noc}', '${this.language}');">${getNOCFlag(noc)} ${noc}</button>`);
|
||||
@ -358,11 +359,10 @@ export class Calendar {
|
||||
}
|
||||
|
||||
const template = readFile(`${__dirname}/index/template.html`);
|
||||
const output = template
|
||||
.replace("{{calendars}}", calendars.join("\r\n"))
|
||||
.replace(/\{\{title}}/gi, translate.calendars.get(this.language)!)
|
||||
.replace("{{disclaimer}}", translate.disclaimer.get(this.language)!)
|
||||
;
|
||||
const output = translate.translate(
|
||||
template.replace("{{calendars}}", calendars.join("\r\n")),
|
||||
this.language,
|
||||
);
|
||||
saveFile(
|
||||
this.language === "en" ?
|
||||
"docs/index.html" :
|
||||
@ -390,9 +390,9 @@ export class Calendar {
|
||||
content.push(` ${event._MEDAL ? "🏅" : ""}`);
|
||||
content.push(` ${sport.name.toUpperCase()}`);
|
||||
if (event._GENDER === "M") {
|
||||
content.push(` <span class=\"text-xs align-middle bg-blue-400 text-white py-1 px-2 rounded-xl\">${translate.genderMen.get(this.language)}</span>`);
|
||||
content.push(` <span class=\"text-xs align-middle bg-blue-400 text-white py-1 px-2 rounded-xl\">{{translate_genderMen}}</span>`);
|
||||
} else if (event._GENDER === "W") {
|
||||
content.push(` <span class=\"text-xs align-middle bg-pink-400 text-white py-1 px-2 rounded-xl\">${translate.genderWomen.get(this.language)}</span>`);
|
||||
content.push(` <span class=\"text-xs align-middle bg-pink-400 text-white py-1 px-2 rounded-xl\">{{translate_genderWomen}}</span>`);
|
||||
}
|
||||
content.push(" </div>");
|
||||
content.push(` <div>${event._UNITNAME}</div>`);
|
||||
@ -417,12 +417,10 @@ export class Calendar {
|
||||
}
|
||||
|
||||
const template = readFile(`${__dirname}/today/template.html`);
|
||||
const output = template
|
||||
.replace("{{events}}", content.join("\r\n"))
|
||||
.replace(/\{\{title}}/gi, translate.todaysEvents.get(this.language)!)
|
||||
.replace("{{disclaimer}}", translate.disclaimer.get(this.language)!)
|
||||
.replace("{{noEventToday}}", translate.noEventToday.get(this.language)!)
|
||||
;
|
||||
const output = translate.translate(
|
||||
template.replace("{{events}}", content.join("\r\n")),
|
||||
this.language,
|
||||
);
|
||||
saveFile(
|
||||
this.language === "en" ?
|
||||
"docs/today.html" :
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
<html data-theme="cmyk">
|
||||
|
||||
<head>
|
||||
<title>Paris 2024 - {{title}}</title>
|
||||
<title>Paris 2024 - {{translate_calendars}}</title>
|
||||
<link href="https://fabrice404.github.io/olympics-calendar/style.css?refresh=20240730" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Paris 2024 - {{title}}">
|
||||
<meta name="keywords" content="Paris 2024 - {{title}}">
|
||||
<meta name="description" content="Paris 2024 - {{translate_calendars}}">
|
||||
<meta name="keywords" content="Paris 2024 - {{translate_calendars}}">
|
||||
<meta name="author" content="Fabrice LAMANT">
|
||||
</head>
|
||||
|
||||
@ -22,6 +22,10 @@
|
||||
</svg>
|
||||
</div>
|
||||
<ul tabindex="0" class="menu menu-sm dropdown-content bg-base-100 rounded-box z-50 mt-3 w-52 p-2 shadow">
|
||||
<li><a href="./index.html">{{translate_calendars}}</a></li>
|
||||
<li><a href="./today.html">{{translate_todaysEvents}}</a></li>
|
||||
<li><a href="./medals.html">{{translate_medalsTable}}</a></li>
|
||||
<hr />
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/index.html">English</a></li>
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/ja/index.html">日本語</a></li>
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/ko/index.html">한국어</a></li>
|
||||
@ -33,7 +37,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-center">
|
||||
<a class="btn btn-ghost text-xl" href="./">Paris 2024 - {{title}}</a>
|
||||
<a class="btn btn-ghost text-xl" href="./">Paris 2024 - {{translate_calendars}}</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
</div>
|
||||
@ -56,7 +60,7 @@
|
||||
</dialog>
|
||||
|
||||
<div class="text-sm my-10 text-center">
|
||||
{{disclaimer}}
|
||||
{{translate_disclaimer}}
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
|
||||
@ -2,11 +2,11 @@
|
||||
<html data-theme="cmyk">
|
||||
|
||||
<head>
|
||||
<title>Paris 2024 - {{title}}</title>
|
||||
<title>Paris 2024 - {{translate_todaysEvents}}</title>
|
||||
<link href="https://fabrice404.github.io/olympics-calendar/style.css?refresh=20240730" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="description" content="Paris 2024 - {{title}}">
|
||||
<meta name="keywords" content="Paris 2024 - {{title}}">
|
||||
<meta name="description" content="Paris 2024 - {{translate_todaysEvents}}">
|
||||
<meta name="keywords" content="Paris 2024 - {{translate_todaysEvents}}">
|
||||
<meta name="author" content="Fabrice LAMANT">
|
||||
|
||||
<meta http-equiv="refresh" content="300">
|
||||
@ -26,6 +26,10 @@
|
||||
</svg>
|
||||
</div>
|
||||
<ul tabindex="0" class="menu menu-sm dropdown-content bg-base-100 rounded-box z-50 mt-3 w-52 p-2 shadow">
|
||||
<li><a href="./index.html">{{translate_calendars}}</a></li>
|
||||
<li><a href="./today.html">{{translate_todaysEvents}}</a></li>
|
||||
<li><a href="./medals.html">{{translate_medalsTable}}</a></li>
|
||||
<hr />
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/today.html">English</a></li>
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/ja/today.html">日本語</a></li>
|
||||
<li><a href="https://fabrice404.github.io/olympics-calendar/ko/today.html">한국어</a></li>
|
||||
@ -37,7 +41,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="navbar-center">
|
||||
<a class="btn btn-ghost text-xl" href="./">Paris 2024 - {{title}}</a>
|
||||
<a class="btn btn-ghost text-xl" href="./">Paris 2024 - {{translate_todaysEvents}}</a>
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
</div>
|
||||
@ -48,11 +52,11 @@
|
||||
</div>
|
||||
|
||||
<div class="no-event my-10 text-center text-2xl hidden">
|
||||
{{noEventToday}}
|
||||
{{translate_noEventToday}}
|
||||
</div>
|
||||
|
||||
<div class="text-sm my-10 text-center">
|
||||
{{disclaimer}}
|
||||
{{translate_disclaimer}}
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
|
||||
157
src/translate.ts
157
src/translate.ts
@ -1,69 +1,12 @@
|
||||
export const allSports = new Map<string, string>([
|
||||
const allSports = new Map<string, string>([
|
||||
["en", "All sports"],
|
||||
["ja", "すべてのスポーツ"],
|
||||
["ko", "모든 스포츠"],
|
||||
["ru", "Все виды спорта"],
|
||||
["zh", "所有运动"],
|
||||
|
||||
]);
|
||||
|
||||
export const fullSchedule = new Map<string, string>([
|
||||
["en", "Full schedule"],
|
||||
["ja", "フルスケジュール"],
|
||||
["ko", "전체 일정"],
|
||||
["ru", "Полное расписание"],
|
||||
["zh", "完整时间表"],
|
||||
]);
|
||||
|
||||
export const medalEvents = new Map<string, string>([
|
||||
["en", "Medal events"],
|
||||
["ja", "メダルイベント"],
|
||||
["ko", "메달 이벤트"],
|
||||
["ru", "Медальные события"],
|
||||
["zh", "奖牌赛事"],
|
||||
]);
|
||||
|
||||
export const genderMen = new Map<string, string>([
|
||||
["en", "M"],
|
||||
["ja", "男性"],
|
||||
["ko", "남성"],
|
||||
["ru", "М"],
|
||||
["zh", "男"],
|
||||
]);
|
||||
|
||||
export const genderWomen = new Map<string, string>([
|
||||
["en", "W"],
|
||||
["ja", "女性"],
|
||||
["ko", "여성"],
|
||||
["ru", "Ж"],
|
||||
["zh", "女"],
|
||||
]);
|
||||
|
||||
export const openingCeremony = new Map<string, string>([
|
||||
["en", "Opening Ceremony"],
|
||||
["ja", "開会式"],
|
||||
["ko", "개막식"],
|
||||
["ru", "Церемония открытия"],
|
||||
["zh", "开幕式"],
|
||||
]);
|
||||
|
||||
export const closingCeremony = new Map<string, string>([
|
||||
["en", "Closing Ceremony"],
|
||||
["ja", "閉会式"],
|
||||
["ko", "폐막식"],
|
||||
["ru", "Церемония закрытия"],
|
||||
["zh", "闭幕式"],
|
||||
]);
|
||||
|
||||
export const disclaimer = new Map<string, string>([
|
||||
["en", "This webiste is not affiliated with the International Olympic Committee. All trademarks, logos and brand names are the property of their respective owners."],
|
||||
["ja", "このウェブサイトは国際オリンピック委員会とは関係ありません。すべての商標、ロゴ、およびブランド名はそれぞれの所有者の財産です。"],
|
||||
["ko", "이 웹 사이트는 국제 올림픽 위원회와 관련이 없습니다. 모든 상표, 로고 및 상표는 각 소유자의 소유입니다."],
|
||||
["ru", "Этот сайт не связан с Международным олимпийским комитетом. Все товарные знаки, логотипы и бренды являются собственностью их соответствующих владельцев."],
|
||||
["zh", "本网站与国际奥林匹克委员会无关。所有商标、标志和品牌名称均为其各自所有者的财产。"],
|
||||
]);
|
||||
|
||||
export const calendars = new Map<string, string>([
|
||||
const calendars = new Map<string, string>([
|
||||
["en", "Calendars"],
|
||||
["ja", "カレンダー"],
|
||||
["ko", "달력"],
|
||||
@ -71,7 +14,79 @@ export const calendars = new Map<string, string>([
|
||||
["zh", "日历"],
|
||||
]);
|
||||
|
||||
export const todaysEvents = new Map<string, string>([
|
||||
const closingCeremony = new Map<string, string>([
|
||||
["en", "Closing Ceremony"],
|
||||
["ja", "閉会式"],
|
||||
["ko", "폐막식"],
|
||||
["ru", "Церемония закрытия"],
|
||||
["zh", "闭幕式"],
|
||||
]);
|
||||
|
||||
const disclaimer = new Map<string, string>([
|
||||
["en", "This webiste is not affiliated with the International Olympic Committee. All trademarks, logos and brand names are the property of their respective owners."],
|
||||
["ja", "このウェブサイトは国際オリンピック委員会とは関係ありません。すべての商標、ロゴ、およびブランド名はそれぞれの所有者の財産です。"],
|
||||
["ko", "이 웹 사이트는 국제 올림픽 위원회와 관련이 없습니다. 모든 상표, 로고 및 상표는 각 소유자의 소유입니다."],
|
||||
["ru", "Этот сайт не связан с Международным олимпийским комитетом. Все товарные знаки, логотипы и бренды являются собственностью их соответствующих владельцев."],
|
||||
["zh", "本网站与国际奥林匹克委员会无关。所有商标、标志和品牌名称均为其各自所有者的财产。"],
|
||||
]);
|
||||
|
||||
const fullSchedule = new Map<string, string>([
|
||||
["en", "Full schedule"],
|
||||
["ja", "フルスケジュール"],
|
||||
["ko", "전체 일정"],
|
||||
["ru", "Полное расписание"],
|
||||
["zh", "完整时间表"],
|
||||
]);
|
||||
|
||||
const genderMen = new Map<string, string>([
|
||||
["en", "M"],
|
||||
["ja", "男性"],
|
||||
["ko", "남성"],
|
||||
["ru", "М"],
|
||||
["zh", "男"],
|
||||
]);
|
||||
|
||||
const genderWomen = new Map<string, string>([
|
||||
["en", "W"],
|
||||
["ja", "女性"],
|
||||
["ko", "여성"],
|
||||
["ru", "Ж"],
|
||||
["zh", "女"],
|
||||
]);
|
||||
|
||||
const medalEvents = new Map<string, string>([
|
||||
["en", "Medal events"],
|
||||
["ja", "メダルイベント"],
|
||||
["ko", "메달 이벤트"],
|
||||
["ru", "Медальные события"],
|
||||
["zh", "奖牌赛事"],
|
||||
]);
|
||||
|
||||
const medalsTable = new Map<string, string>([
|
||||
["en", "Medals table"],
|
||||
["ja", "メダル表"],
|
||||
["ko", "메달 테이블"],
|
||||
["ru", "Таблица медалей"],
|
||||
["zh", "奖牌榜"],
|
||||
]);
|
||||
|
||||
const noEventToday = new Map<string, string>([
|
||||
["en", "No event today, come back tomorrow! :)"],
|
||||
["ja", "今日のイベントはありません。明日また来てください! :)"],
|
||||
["ko", "오늘 이벤트가 없습니다. 내일 다시 오세요! :)"],
|
||||
["ru", "Сегодня нет событий, вернитесь завтра! :)"],
|
||||
["zh", "今天没有活动,请明天再来! :)"],
|
||||
]);
|
||||
|
||||
const openingCeremony = new Map<string, string>([
|
||||
["en", "Opening Ceremony"],
|
||||
["ja", "開会式"],
|
||||
["ko", "개막식"],
|
||||
["ru", "Церемония открытия"],
|
||||
["zh", "开幕式"],
|
||||
]);
|
||||
|
||||
const todaysEvents = new Map<string, string>([
|
||||
["en", "Today's events"],
|
||||
["ja", "今日のイベント"],
|
||||
["ko", "오늘의 이벤트"],
|
||||
@ -79,10 +94,18 @@ export const todaysEvents = new Map<string, string>([
|
||||
["zh", "今天的活动"],
|
||||
]);
|
||||
|
||||
export const noEventToday = new Map<string, string>([
|
||||
["en", "No event today, come back tomorrow! :)"],
|
||||
["ja", "今日のイベントはありません。明日また来てください! :)"],
|
||||
["ko", "오늘 이벤트가 없습니다. 내일 다시 오세요! :)"],
|
||||
["ru", "Сегодня нет событий, вернитесь завтра! :)"],
|
||||
["zh", "今天没有活动,请明天再来! :)"],
|
||||
]);
|
||||
|
||||
export const translate = (text: string, language: string) => text
|
||||
.replace(/\{\{translate_allSports}}/gi, allSports.get(language)!)
|
||||
.replace(/\{\{translate_calendars}}/gi, calendars.get(language)!)
|
||||
.replace(/\{\{translate_closingCeremony}}/gi, closingCeremony.get(language)!)
|
||||
.replace(/\{\{translate_disclaimer}}/gi, disclaimer.get(language)!)
|
||||
.replace(/\{\{translate_fullSchedule}}/gi, fullSchedule.get(language)!)
|
||||
.replace(/\{\{translate_genderMen}}/gi, genderMen.get(language)!)
|
||||
.replace(/\{\{translate_genderWomen}}/gi, genderWomen.get(language)!)
|
||||
.replace(/\{\{translate_medalEvents}}/gi, medalEvents.get(language)!)
|
||||
.replace(/\{\{translate_medalsTable}}/gi, medalsTable.get(language)!)
|
||||
.replace(/\{\{translate_noEventToday}}/gi, noEventToday.get(language)!)
|
||||
.replace(/\{\{translate_openingCeremony}}/gi, openingCeremony.get(language)!)
|
||||
.replace(/\{\{translate_todaysEvents}}/gi, todaysEvents.get(language)!)
|
||||
;
|
||||
|
||||
6
src/types.d.ts
vendored
6
src/types.d.ts
vendored
@ -30,3 +30,9 @@ export interface NOC {
|
||||
icon: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface Medal {
|
||||
color: "gold" | "silver" | "bronze";
|
||||
name: string;
|
||||
noc: string;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user