Add i18n foundation and translations (#1027)
* feat: add i18n foundation * feat: localize sessions sidebar * Localize multirun/scheduled tasks and fix dialog dropdown interactions * localize git sidebar surface and add zh-CN keys * feat(ui): localize context panel, diff/plan views, and context sidebar content * fix(config): resolve user config home via fs/home before embedded home * localize header/chat UI and complete model/worktree panel strings * localize worktree + github issue/pr dialog flows * localize settings sections and split settings i18n dictionaries * localize additional settings sections and sidebars * localize more settings pages and dialogs * fix settings select trigger localization * localize tunnel settings ui surface * localize additional settings sections * localize keyboard shortcuts labels in settings * localize terminal and utility dialogs surfaces * feat(i18n): localize remaining UI strings * Add Ukrainian locale * Add Spanish locale * Add Brazilian Portuguese locale * Polish locale translations
This commit is contained in:
committed by
GitHub
parent
87db2ea210
commit
7d7285655d
@@ -11,6 +11,7 @@ import {
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '@/components/ui/collapsible';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
|
||||
interface InlineCommentCardProps {
|
||||
draft: InlineCommentDraft;
|
||||
@@ -27,6 +28,7 @@ export function InlineCommentCard({
|
||||
className,
|
||||
maxWidth,
|
||||
}: InlineCommentCardProps) {
|
||||
const { t } = useI18n();
|
||||
const themeContext = useOptionalThemeSystem();
|
||||
const currentTheme = themeContext?.currentTheme;
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
@@ -56,7 +58,7 @@ export function InlineCommentCard({
|
||||
{draft.fileLabel}
|
||||
</span>
|
||||
<span>•</span>
|
||||
<span>Lines {draft.startLine}-{draft.endLine}</span>
|
||||
<span>{t('inlineComment.range.lines', { start: draft.startLine, end: draft.endLine })}</span>
|
||||
{draft.side && <span>({draft.side})</span>}
|
||||
</div>
|
||||
|
||||
@@ -75,12 +77,12 @@ export function InlineCommentCard({
|
||||
{isOpen ? (
|
||||
<>
|
||||
<RiArrowUpSLine className="size-3 mr-1" />
|
||||
Show less
|
||||
{t('inlineComment.actions.showLess')}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<RiArrowDownSLine className="size-3 mr-1" />
|
||||
Show more
|
||||
{t('inlineComment.actions.showMore')}
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
@@ -106,11 +108,11 @@ export function InlineCommentCard({
|
||||
<DropdownMenuContent align="end">
|
||||
<DropdownMenuItem onClick={onEdit}>
|
||||
<RiEditLine className="size-4 mr-2" />
|
||||
Edit comment
|
||||
{t('inlineComment.actions.editComment')}
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem onClick={onDelete} className="text-destructive">
|
||||
<RiDeleteBinLine className="size-4 mr-2" />
|
||||
Delete comment
|
||||
{t('inlineComment.actions.deleteComment')}
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Button } from '@/components/ui/button';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { useDeviceInfo } from '@/lib/device';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
|
||||
export interface InlineCommentInputProps {
|
||||
initialText?: string;
|
||||
@@ -26,6 +27,7 @@ export function InlineCommentInput({
|
||||
className,
|
||||
maxWidth,
|
||||
}: InlineCommentInputProps) {
|
||||
const { t } = useI18n();
|
||||
const themeContext = useOptionalThemeSystem();
|
||||
const currentTheme = themeContext?.currentTheme;
|
||||
const { isMobile } = useDeviceInfo();
|
||||
@@ -131,7 +133,11 @@ export function InlineCommentInput({
|
||||
<div className="flex items-center gap-2 text-xs font-medium text-muted-foreground mb-2">
|
||||
{fileLabel && <span className="truncate max-w-[200px]">{fileLabel}</span>}
|
||||
{fileLabel && lineRange && <span>•</span>}
|
||||
{displayRange && <span>Lines {displayRange.start}-{displayRange.end}</span>}
|
||||
{displayRange && (
|
||||
<span>
|
||||
{t('inlineComment.range.lines', { start: displayRange.start, end: displayRange.end })}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -141,7 +147,7 @@ export function InlineCommentInput({
|
||||
value={text}
|
||||
onChange={(e) => setText(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder="Add a comment... (Cmd+Enter to save)"
|
||||
placeholder={t('inlineComment.input.placeholder')}
|
||||
outerClassName="rounded-[var(--radius-xl)] bg-[var(--surface-subtle)] ring-1 ring-inset ring-border/60 focus-within:ring-2 focus-within:ring-[var(--interactive-focus-ring)]"
|
||||
className="min-h-[80px] px-3 py-2.5 text-sm resize-y"
|
||||
/>
|
||||
@@ -155,7 +161,7 @@ export function InlineCommentInput({
|
||||
onTouchStart={(e) => e.stopPropagation()}
|
||||
className="h-8 text-muted-foreground hover:text-foreground"
|
||||
>
|
||||
Cancel
|
||||
{t('inlineComment.actions.cancel')}
|
||||
</Button>
|
||||
<Button
|
||||
size="sm"
|
||||
@@ -169,7 +175,7 @@ export function InlineCommentInput({
|
||||
color: currentTheme?.colors?.status?.successForeground,
|
||||
}}
|
||||
>
|
||||
{isEditing ? 'Save' : 'Comment'}
|
||||
{isEditing ? t('inlineComment.actions.save') : t('inlineComment.actions.comment')}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { toast } from '@/components/ui';
|
||||
import { useInlineCommentDraftStore, type InlineCommentDraft, type InlineCommentSource } from '@/stores/useInlineCommentDraftStore';
|
||||
import { useSessionUIStore } from '@/sync/session-ui-store';
|
||||
import { useI18n } from '@/lib/i18n';
|
||||
|
||||
type LineRangeBase = {
|
||||
start: number;
|
||||
@@ -46,6 +47,7 @@ export const normalizeLineRange = <TRange extends LineRangeBase>(range: TRange):
|
||||
export function useInlineCommentController<TRange extends LineRangeBase>(
|
||||
options: UseInlineCommentControllerOptions<TRange>
|
||||
) {
|
||||
const { t } = useI18n();
|
||||
const { source, fileLabel, language, getCodeForRange, toStoreRange, fromDraftRange } = options;
|
||||
|
||||
const currentSessionId = useSessionUIStore((state) => state.currentSessionId);
|
||||
@@ -100,7 +102,7 @@ export function useInlineCommentController<TRange extends LineRangeBase>(
|
||||
if (!targetRange || !trimmedText || !fileLabel) return;
|
||||
|
||||
if (!sessionKey) {
|
||||
toast.error('Select a session to save comment');
|
||||
toast.error(t('inlineComment.toast.selectSessionToSave'));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,7 +135,7 @@ export function useInlineCommentController<TRange extends LineRangeBase>(
|
||||
}
|
||||
|
||||
reset();
|
||||
}, [addDraft, editingDraftId, fileLabel, getCodeForRange, language, reset, selection, sessionKey, source, toStoreRange, updateDraft]);
|
||||
}, [addDraft, editingDraftId, fileLabel, getCodeForRange, language, reset, selection, sessionKey, source, t, toStoreRange, updateDraft]);
|
||||
|
||||
return {
|
||||
sessionKey,
|
||||
|
||||
Reference in New Issue
Block a user