mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
Incorporate i18n into UI elements (#1471)
* Update zh-tw string table (till 975343d2)
* Prepare localization table
* Implement i18n for Performers & Tags
* Add "add" action strings
* Use Lodash merge for deep merging language JSONs
The original implementation does not properly merge language files, causing unexpected localization string fallback behavior.
* Localize pagination strings
* Use Field name value as null id fallback
...otherwise FormattedMessage is gonna throw when the ID is null
* Use localized "Path" string for all instances
* Localize the "Interface" tab under settings
* Localize scene & performer cards
* Rename locale folder for better compatibility with i18n-ally
* Localize majority of the categories and features
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
import React, { useEffect, useState, useCallback, useRef } from "react";
|
||||
import { Button, Card, Form, Table } from "react-bootstrap";
|
||||
import { FormattedMessage, useIntl } from "react-intl";
|
||||
import _ from "lodash";
|
||||
import {
|
||||
queryParseSceneFilenames,
|
||||
@@ -35,6 +36,7 @@ const initialShowFieldsState = new Map<string, boolean>([
|
||||
]);
|
||||
|
||||
export const SceneFilenameParser: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const Toast = useToast();
|
||||
const [parserResult, setParserResult] = useState<SceneParserResult[]>([]);
|
||||
const [parserInput, setParserInput] = useState<IParserInput>(
|
||||
@@ -184,7 +186,12 @@ export const SceneFilenameParser: React.FC = () => {
|
||||
|
||||
try {
|
||||
await updateScenes();
|
||||
Toast.success({ content: "Updated scenes" });
|
||||
Toast.success({
|
||||
content: intl.formatMessage(
|
||||
{ id: "toast.updated_entity" },
|
||||
{ entity: intl.formatMessage({ id: "scenes" }).toLocaleLowerCase() }
|
||||
),
|
||||
});
|
||||
} catch (e) {
|
||||
Toast.error(e);
|
||||
}
|
||||
@@ -333,17 +340,41 @@ export const SceneFilenameParser: React.FC = () => {
|
||||
<Table>
|
||||
<thead>
|
||||
<tr className="scene-parser-row">
|
||||
<th className="parser-field-filename">Filename</th>
|
||||
{renderHeader("Title", allTitleSet, onSelectAllTitleSet)}
|
||||
{renderHeader("Date", allDateSet, onSelectAllDateSet)}
|
||||
{renderHeader("Rating", allRatingSet, onSelectAllRatingSet)}
|
||||
<th className="parser-field-filename">
|
||||
{intl.formatMessage({
|
||||
id: "config.tools.scene_filename_parser.filename",
|
||||
})}
|
||||
</th>
|
||||
{renderHeader(
|
||||
"Performers",
|
||||
intl.formatMessage({ id: "title" }),
|
||||
allTitleSet,
|
||||
onSelectAllTitleSet
|
||||
)}
|
||||
{renderHeader(
|
||||
intl.formatMessage({ id: "date" }),
|
||||
allDateSet,
|
||||
onSelectAllDateSet
|
||||
)}
|
||||
{renderHeader(
|
||||
intl.formatMessage({ id: "rating" }),
|
||||
allRatingSet,
|
||||
onSelectAllRatingSet
|
||||
)}
|
||||
{renderHeader(
|
||||
intl.formatMessage({ id: "performers" }),
|
||||
allPerformerSet,
|
||||
onSelectAllPerformerSet
|
||||
)}
|
||||
{renderHeader("Tags", allTagSet, onSelectAllTagSet)}
|
||||
{renderHeader("Studio", allStudioSet, onSelectAllStudioSet)}
|
||||
{renderHeader(
|
||||
intl.formatMessage({ id: "tags" }),
|
||||
allTagSet,
|
||||
onSelectAllTagSet
|
||||
)}
|
||||
{renderHeader(
|
||||
intl.formatMessage({ id: "studio" }),
|
||||
allStudioSet,
|
||||
onSelectAllStudioSet
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -365,7 +396,7 @@ export const SceneFilenameParser: React.FC = () => {
|
||||
onChangePage={(page) => onPageChanged(page)}
|
||||
/>
|
||||
<Button variant="primary" onClick={onApply}>
|
||||
Apply
|
||||
<FormattedMessage id="actions.apply" />
|
||||
</Button>
|
||||
</>
|
||||
);
|
||||
@@ -373,7 +404,9 @@ export const SceneFilenameParser: React.FC = () => {
|
||||
|
||||
return (
|
||||
<Card id="parser-container" className="col col-sm-9 mx-auto">
|
||||
<h4>Scene Filename Parser</h4>
|
||||
<h4>
|
||||
{intl.formatMessage({ id: "config.tools.scene_filename_parser.title" })}
|
||||
</h4>
|
||||
<ParserInput
|
||||
input={parserInput}
|
||||
onFind={(input) => onFindClicked(input)}
|
||||
|
||||
Reference in New Issue
Block a user