Localise timeline and movement chart captions in English and Russian.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Danila Khodjaef
2026-08-13 12:45:44 +03:00
co-authored by Cursor
parent 44092d102b
commit 1c9fa20191
7 changed files with 25 additions and 6 deletions
+3 -1
View File
@@ -1,4 +1,5 @@
import { useMemo, useRef, useCallback, useEffect, useLayoutEffect, useState, memo } from 'react';
import { useTranslation } from 'react-i18next';
import type { ArtMovement, Artist } from '../types';
import { portraitThumbUrl } from '../api/client';
import { useQueuedImageSrc } from '../hooks/useQueuedImageSrc';
@@ -1695,6 +1696,7 @@ export default function MovementBands({
onArtistHover,
onPortraitsLoadingChange,
}: Props) {
const { t } = useTranslation('home');
const canvasRef = useRef<HTMLDivElement>(null);
const pendingPortraitsRef = useRef(0);
const [portraitsLoading, setPortraitsLoading] = useState(false);
@@ -2193,7 +2195,7 @@ export default function MovementBands({
return (
<div className="movements-flow">
<p className="movements-flow-caption">
Scroll to zoom · drag to pan · each movement stream is a solid colour band through history
{t('captionClassicFlow')}
</p>
<div
+3 -2
View File
@@ -1,4 +1,5 @@
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next';
import type { ArtMovement } from '../types';
import {
branchOriginYear,
@@ -179,6 +180,7 @@ export default function MovementTree({
onViewChange,
onMovementClick,
}: Props) {
const { t } = useTranslation('home');
const canvasRef = useRef<HTMLDivElement>(null);
const [canvas, setCanvas] = useState({ w: 900, h: 600 });
const [panning, setPanning] = useState(false);
@@ -534,8 +536,7 @@ export default function MovementTree({
return (
<div className="mtree">
<p className="mtree-caption">
Roots at the bottom, living movements at the crown · scroll to zoom · drag to
pan · click a branch to enter its gallery
{t('captionTreeFlow')}
</p>
<div
ref={canvasRef}
+3 -1
View File
@@ -1,4 +1,5 @@
import { useRef, useState, useCallback, useEffect, useMemo, useLayoutEffect } from 'react';
import { useTranslation } from 'react-i18next';
import type { HistoricalEra } from '../types';
import {
HISTORICAL_EVENTS,
@@ -38,6 +39,7 @@ function formatYear(year: number): string {
}
export default function Timeline({ eras, viewStart, viewEnd, onViewChange, absoluteMin, absoluteMax, lifespanHighlight }: Props) {
const { t } = useTranslation('home');
const containerRef = useRef<HTMLDivElement>(null);
const [dragging, setDragging] = useState<'left' | 'right' | 'pan' | null>(null);
const [containerWidth, setContainerWidth] = useState(800);
@@ -365,7 +367,7 @@ export default function Timeline({ eras, viewStart, viewEnd, onViewChange, absol
</div>
<p className="timeline-hint">
Click an era or event to zoom · Scroll to zoom · Drag to pan
{t('captionClassicTimeline')}
</p>
</div>
);
@@ -1,4 +1,5 @@
import { useMemo, useRef, useCallback, useEffect, useLayoutEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import type { ArtMovement } from '../types';
import { MOVEMENT_LINEAGE } from '../data/movement-lineage';
import { panTimelineView, zoomTimelineView } from '../utils/timelineView';
@@ -364,6 +365,7 @@ export default function VerticalMovementBands({
onViewChange,
onMovementClick,
}: Props) {
const { t } = useTranslation('home');
const canvasRef = useRef<HTMLDivElement>(null);
const [canvasSize, setCanvasSize] = useState({ w: 800, h: 600 });
const [panning, setPanning] = useState(false);
@@ -631,7 +633,7 @@ export default function VerticalMovementBands({
return (
<div className="vflow">
<p className="vflow-caption">
Bottom top through history · scroll to zoom · drag to pan · click a stream
{t('captionVerticalFlow')}
</p>
<div
ref={canvasRef}
+3 -1
View File
@@ -1,4 +1,5 @@
import { useRef, useState, useCallback, useEffect, useMemo, useLayoutEffect } from 'react';
import { useTranslation } from 'react-i18next';
import type { HistoricalEra } from '../types';
import {
HISTORICAL_EVENTS,
@@ -60,6 +61,7 @@ export default function VerticalTimeline({
absoluteMax,
lifespanHighlight,
}: Props) {
const { t } = useTranslation('home');
const containerRef = useRef<HTMLDivElement>(null);
const [dragging, setDragging] = useState<'start' | 'end' | 'pan' | null>(null);
const [containerHeight, setContainerHeight] = useState(600);
@@ -409,7 +411,7 @@ export default function VerticalTimeline({
/>
</div>
<p className="vtimeline-hint">Bottom top · Scroll to zoom · Drag to pan</p>
<p className="vtimeline-hint">{t('captionVerticalTimeline')}</p>
</aside>
);
}
+5
View File
@@ -22,6 +22,11 @@
"layoutHorizontal": "Classic timeline →",
"layoutVertical": "↑ Vertical timeline",
"layoutTree": "🌳 Tree of art",
"captionClassicTimeline": "Click an era or event to zoom · Scroll to zoom · Drag to pan",
"captionClassicFlow": "Scroll to zoom · drag to pan · each movement stream is a solid colour band through history",
"captionVerticalTimeline": "Bottom → top · Scroll to zoom · Drag to pan",
"captionVerticalFlow": "Bottom → top through history · scroll to zoom · drag to pan · click a stream",
"captionTreeFlow": "Roots at the bottom, living movements at the crown · scroll to zoom · drag to pan · click a branch to enter its gallery",
"openingTourGallery": "Opening guided tour…",
"tourEmpty": "This tour has no paintings yet.",
"tourLoadFailed": "Failed to load the tour.",
+5
View File
@@ -22,6 +22,11 @@
"layoutHorizontal": "Классическая шкала →",
"layoutVertical": "↑ Вертикальная шкала",
"layoutTree": "🌳 Древо искусства",
"captionClassicTimeline": "Щёлкните эпоху или событие для приближения · Колесо — масштаб · Перетащите для панорамы",
"captionClassicFlow": "Колесо — масштаб · перетащите для панорамы · каждое направление — цветная полоса сквозь историю",
"captionVerticalTimeline": "Снизу вверх · Колесо — масштаб · Перетащите для панорамы",
"captionVerticalFlow": "Снизу вверх по истории · колесо — масштаб · перетащите для панорамы · щёлкните поток",
"captionTreeFlow": "Корни внизу, живые направления в кроне · колесо — масштаб · перетащите для панорамы · щёлкните ветвь, чтобы войти в зал",
"openingTourGallery": "Открытие экскурсии…",
"tourEmpty": "В этой экскурсии пока нет картин.",
"tourLoadFailed": "Не удалось загрузить экскурсию.",