From 260128e165268acf6867aae1a85c1b14b75af1bb Mon Sep 17 00:00:00 2001 From: Mikael Finstad Date: Wed, 28 Jan 2026 18:02:03 +0800 Subject: [PATCH] fix some i18n closes #2726 --- docs/troubleshooting.md | 4 ++++ src/renderer/src/components/CloseButton.tsx | 6 ++++-- src/renderer/src/components/ConcatDialog.tsx | 2 +- .../src/components/CopyClipboardButton.tsx | 8 +++++--- .../src/components/FileNameTemplateEditor.tsx | 7 +++---- .../src/components/OutputFormatSelect.tsx | 18 ++++++++++-------- 6 files changed, 27 insertions(+), 18 deletions(-) diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index c173ef37..43cf48bd 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -134,6 +134,10 @@ A video’s rotation is just metadata stored in its file. A file can only have a When you use the Tracks panel to extract a single track as a file, e.g. a subtitle, a default format will be automatically chosen. For example for subtitle, it will output an `.mks`. If you want a different output format, you can instead disable all tracks except the single track you want to extract, then close the Tracks panel, the choose the output format, (e.g. `srt`) and then perform an export. +## Translation is missing + +If some text in the UI is in English even though you've selected a different language, please first check that it has actually been translated in [Weblate](translation.md). If not, you can help contribute. If it is not, you may create an issue. + # Still cannot find an answer? If any other problem please search for [existing issues](https://github.com/mifi/lossless-cut/issues) before you [ask a question](https://github.com/mifi/lossless-cut/discussions) here on GitHub. You can check the developer tools for any errors or clues. Menu: `Tools` -> `Toggle Developer Tools`. diff --git a/src/renderer/src/components/CloseButton.tsx b/src/renderer/src/components/CloseButton.tsx index 37d07e7f..6439d321 100644 --- a/src/renderer/src/components/CloseButton.tsx +++ b/src/renderer/src/components/CloseButton.tsx @@ -1,14 +1,16 @@ import { FaTimes } from 'react-icons/fa'; import type { DetailedHTMLProps, ButtonHTMLAttributes } from 'react'; +import { useTranslation } from 'react-i18next'; import styles from './CloseButton.module.css'; -import i18n from '../i18n'; export default function CloseButton({ type = 'button', ...props }: DetailedHTMLProps, HTMLButtonElement>) { + const { t } = useTranslation(); + return ( // eslint-disable-next-line react/jsx-props-no-spreading, react/button-has-type - ); diff --git a/src/renderer/src/components/ConcatDialog.tsx b/src/renderer/src/components/ConcatDialog.tsx index 487a1421..c4b28954 100644 --- a/src/renderer/src/components/ConcatDialog.tsx +++ b/src/renderer/src/components/ConcatDialog.tsx @@ -228,7 +228,7 @@ function ConcatDialog({ isShown, onHide, paths, mergedFileTemplate, generateMerg problemsByFile[path] ? ( - + diff --git a/src/renderer/src/components/CopyClipboardButton.tsx b/src/renderer/src/components/CopyClipboardButton.tsx index f1198245..7f380991 100644 --- a/src/renderer/src/components/CopyClipboardButton.tsx +++ b/src/renderer/src/components/CopyClipboardButton.tsx @@ -3,16 +3,18 @@ import { memo, useCallback } from 'react'; import { FaClipboard } from 'react-icons/fa'; import type { MotionStyle } from 'motion/react'; import { motion, useAnimation } from 'motion/react'; -import i18n from '../i18n'; +import { useTranslation } from 'react-i18next'; const electron = window.require('electron'); const { clipboard } = electron; -function CopyClipboardButton({ text, style, children = ({ onClick }) => }: { +function CopyClipboardButton({ text, style, children }: { text: string, style?: MotionStyle, children?: (p: { onClick: () => void }) => ReactNode, }) { + const { t } = useTranslation(); + const animation = useAnimation(); const onClick = useCallback(() => { @@ -25,7 +27,7 @@ function CopyClipboardButton({ text, style, children = ({ onClick }) => - {children({ onClick })} + {children != null ? children({ onClick }) : } ); } diff --git a/src/renderer/src/components/FileNameTemplateEditor.tsx b/src/renderer/src/components/FileNameTemplateEditor.tsx index fae9954b..3b55bf47 100644 --- a/src/renderer/src/components/FileNameTemplateEditor.tsx +++ b/src/renderer/src/components/FileNameTemplateEditor.tsx @@ -1,7 +1,6 @@ import type { ChangeEventHandler } from 'react'; import { memo, useState, useEffect, useCallback, useRef, useMemo } from 'react'; import { useDebounce } from 'use-debounce'; -import i18n from 'i18next'; import { useTranslation } from 'react-i18next'; import { IoIosHelpCircle } from 'react-icons/io'; import { motion, AnimatePresence } from 'motion/react'; @@ -228,7 +227,7 @@ function FileNameTemplateEditor(opts: {
- {`${i18n.t('Variables')}:`} + {`${t('Variables')}:`} electron.shell.openExternal(exportedFileNameTemplateHelpUrl)} /> {availableVariables.map((variable) => ( @@ -265,14 +264,14 @@ function FileNameTemplateEditor(opts: { {generated.problems.sameAsInputFileNameWarning && (
- {i18n.t('Output file name is the same as the source file name. This increases the risk of accidentally overwriting or deleting source files!')} + {t('Output file name is the same as the source file name. This increases the risk of accidentally overwriting or deleting source files!')}
)} {!shouldIgnoreMissingExtension && isMissingExtension && (
- {i18n.t('The file name template is missing {{ext}} and will result in a file without the suggested extension. This may result in an unplayable output file.', { ext: extVariableFormatted })} + {t('The file name template is missing {{ext}} and will result in a file without the suggested extension. This may result in an unplayable output file.', { ext: extVariableFormatted })}
)} diff --git a/src/renderer/src/components/OutputFormatSelect.tsx b/src/renderer/src/components/OutputFormatSelect.tsx index 8bdfa5ba..ed337e75 100644 --- a/src/renderer/src/components/OutputFormatSelect.tsx +++ b/src/renderer/src/components/OutputFormatSelect.tsx @@ -1,6 +1,6 @@ import type { CSSProperties } from 'react'; import { memo, useMemo } from 'react'; -import i18n from 'i18next'; +import { useTranslation } from 'react-i18next'; import type { FfmpegFormat } from '../outFormats'; import allOutFormats from '../outFormats'; @@ -24,6 +24,8 @@ function OutputFormatSelect({ style, disabled, detectedFileFormat, fileFormat, o fileFormat?: string | undefined, onOutputFormatUserChange: (a: string) => void, }) { + const { t } = useTranslation(); + const commonVideoAudioFormatsExceptDetectedFormat = useMemo(() => commonVideoAudioFormats.filter((f) => f !== detectedFileFormat), [detectedFileFormat]); const commonAudioFormatsExceptDetectedFormat = useMemo(() => commonAudioFormats.filter((f) => f !== detectedFileFormat), [detectedFileFormat]); const commonSubtitleFormatsExceptDetectedFormat = useMemo(() => commonSubtitleFormats.filter((f) => f !== detectedFileFormat), [detectedFileFormat]); @@ -33,25 +35,25 @@ function OutputFormatSelect({ style, disabled, detectedFileFormat, fileFormat, o return ( // eslint-disable-next-line react/jsx-props-no-spreading - onOutputFormatUserChange(e.target.value))}> + {detectedFileFormat && ( )} - + {renderFormatOptions(commonVideoAudioFormatsExceptDetectedFormat)} - + {renderFormatOptions(commonAudioFormatsExceptDetectedFormat)} - + {renderFormatOptions(commonSubtitleFormatsExceptDetectedFormat)} - + {renderFormatOptions(otherFormats)} );