mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
* 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
96 lines
2.6 KiB
TypeScript
96 lines
2.6 KiB
TypeScript
import React from "react";
|
|
import * as GQL from "src/core/generated-graphql";
|
|
import { GalleriesCriterion } from "src/models/list-filter/criteria/galleries";
|
|
import { ListFilterModel } from "src/models/list-filter/filter";
|
|
import { ImageList } from "src/components/Images/ImageList";
|
|
import { mutateRemoveGalleryImages } from "src/core/StashService";
|
|
import { showWhenSelected, PersistanceLevel } from "src/hooks/ListHook";
|
|
import { useToast } from "src/hooks";
|
|
import { TextUtils } from "src/utils";
|
|
import { useIntl } from "react-intl";
|
|
|
|
interface IGalleryDetailsProps {
|
|
gallery: GQL.GalleryDataFragment;
|
|
}
|
|
|
|
export const GalleryImagesPanel: React.FC<IGalleryDetailsProps> = ({
|
|
gallery,
|
|
}) => {
|
|
const intl = useIntl();
|
|
const Toast = useToast();
|
|
|
|
function filterHook(filter: ListFilterModel) {
|
|
const galleryValue = {
|
|
id: gallery.id!,
|
|
label: gallery.title ?? TextUtils.fileNameFromPath(gallery.path ?? ""),
|
|
};
|
|
// if galleries is already present, then we modify it, otherwise add
|
|
let galleryCriterion = filter.criteria.find((c) => {
|
|
return c.criterionOption.value === "galleries";
|
|
}) as GalleriesCriterion;
|
|
|
|
if (
|
|
galleryCriterion &&
|
|
(galleryCriterion.modifier === GQL.CriterionModifier.IncludesAll ||
|
|
galleryCriterion.modifier === GQL.CriterionModifier.Includes)
|
|
) {
|
|
// add the gallery if not present
|
|
if (
|
|
!galleryCriterion.value.find((p) => {
|
|
return p.id === gallery.id;
|
|
})
|
|
) {
|
|
galleryCriterion.value.push(galleryValue);
|
|
}
|
|
|
|
galleryCriterion.modifier = GQL.CriterionModifier.IncludesAll;
|
|
} else {
|
|
// overwrite
|
|
galleryCriterion = new GalleriesCriterion();
|
|
galleryCriterion.value = [galleryValue];
|
|
filter.criteria.push(galleryCriterion);
|
|
}
|
|
|
|
return filter;
|
|
}
|
|
|
|
async function removeImages(
|
|
result: GQL.FindImagesQueryResult,
|
|
filter: ListFilterModel,
|
|
selectedIds: Set<string>
|
|
) {
|
|
try {
|
|
await mutateRemoveGalleryImages({
|
|
gallery_id: gallery.id!,
|
|
image_ids: Array.from(selectedIds.values()),
|
|
});
|
|
Toast.success({
|
|
content: intl.formatMessage(
|
|
{ id: "toast.added_entity" },
|
|
{ entity: intl.formatMessage({ id: "images" }) }
|
|
),
|
|
});
|
|
} catch (e) {
|
|
Toast.error(e);
|
|
}
|
|
}
|
|
|
|
const otherOperations = [
|
|
{
|
|
text: "Remove from Gallery",
|
|
onClick: removeImages,
|
|
isDisplayed: showWhenSelected,
|
|
postRefetch: true,
|
|
},
|
|
];
|
|
|
|
return (
|
|
<ImageList
|
|
filterHook={filterHook}
|
|
extraOperations={otherOperations}
|
|
persistState={PersistanceLevel.VIEW}
|
|
persistanceKey="galleryimages"
|
|
/>
|
|
);
|
|
};
|