Toast fixes/refactoring (#4289)

* Memoize Toast functions
* Rename Toast.success to Toast.toast, add new Toast.success
* Disable prefer-destructuring on AssignmentExpression
This commit is contained in:
DingDongSoLong4
2023-11-20 05:14:34 +02:00
committed by GitHub
parent 049a1b15c3
commit f9e11813f0
52 changed files with 336 additions and 387 deletions

View File

@@ -2,9 +2,6 @@
"env": { "env": {
"browser": true "browser": true
}, },
"globals": {
"Mousetrap": "readonly"
},
"parser": "@typescript-eslint/parser", "parser": "@typescript-eslint/parser",
"parserOptions": { "parserOptions": {
"project": "./tsconfig.json" "project": "./tsconfig.json"
@@ -25,7 +22,7 @@
}, },
"ignorePatterns": ["node_modules/", "src/core/generated-graphql.tsx"], "ignorePatterns": ["node_modules/", "src/core/generated-graphql.tsx"],
"rules": { "rules": {
"@typescript-eslint/no-explicit-any": 2, "@typescript-eslint/lines-between-class-members": "off",
"@typescript-eslint/naming-convention": [ "@typescript-eslint/naming-convention": [
"error", "error",
{ {
@@ -37,8 +34,11 @@
} }
} }
], ],
"lines-between-class-members": "off", "@typescript-eslint/no-explicit-any": 2,
"@typescript-eslint/lines-between-class-members": "off", "@typescript-eslint/no-use-before-define": [
"error",
{ "functions": false, "classes": false }
],
"import/extensions": [ "import/extensions": [
"error", "error",
"ignorePackages", "ignorePackages",
@@ -52,26 +52,24 @@
"import/named": "off", "import/named": "off",
"import/namespace": "off", "import/namespace": "off",
"import/no-unresolved": "off", "import/no-unresolved": "off",
"lines-between-class-members": "off",
"no-nested-ternary": "off",
"prefer-destructuring": [
"error",
{
"VariableDeclarator": {
"array": false,
"object": true
},
"AssignmentExpression": {
"array": false,
"object": false
}
}
],
"react/display-name": "off", "react/display-name": "off",
"react/prop-types": "off", "react/prop-types": "off",
"react/style-prop-object": [ "react/style-prop-object": ["error", { "allow": ["FormattedNumber"] }],
"error", "spaced-comment": ["error", "always", { "markers": ["/"] }]
{
"allow": ["FormattedNumber"]
}
],
"spaced-comment": [
"error",
"always",
{
"markers": ["/"]
}
],
"prefer-destructuring": ["error", { "object": true, "array": false }],
"@typescript-eslint/no-use-before-define": [
"error",
{ "functions": false, "classes": false }
],
"no-nested-ternary": "off"
} }
} }

View File

@@ -140,12 +140,12 @@ export const GenerateDialog: React.FC<ISceneGenerateDialog> = ({
...options, ...options,
sceneIDs: selectedIds, sceneIDs: selectedIds,
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.generate" }) } { operation_name: intl.formatMessage({ id: "actions.generate" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {

View File

@@ -285,12 +285,12 @@ export const IdentifyDialog: React.FC<IIdentifyDialogProps> = ({
try { try {
await mutateMetadataIdentify(makeIdentifyInput()); await mutateMetadataIdentify(makeIdentifyInput());
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.identify" }) } { operation_name: intl.formatMessage({ id: "actions.identify" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {
@@ -358,12 +358,12 @@ export const IdentifyDialog: React.FC<IIdentifyDialogProps> = ({
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.defaults_set" }, { id: "config.tasks.defaults_set" },
{ action: intl.formatMessage({ id: "actions.identify" }) } { action: intl.formatMessage({ id: "actions.identify" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {

View File

@@ -60,7 +60,7 @@ export const DeleteGalleriesDialog: React.FC<IDeleteGalleryDialogProps> = (
setIsDeleting(true); setIsDeleting(true);
try { try {
await deleteGallery(); await deleteGallery();
Toast.success({ content: toastMessage }); Toast.success(toastMessage);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -95,14 +95,14 @@ export const EditGalleriesDialog: React.FC<IListOperationProps> = (
input: getGalleryInput(), input: getGalleryInput(),
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ {
entity: intl.formatMessage({ id: "galleries" }).toLocaleLowerCase(), entity: intl.formatMessage({ id: "galleries" }).toLocaleLowerCase(),
} }
), )
}); );
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -81,12 +81,12 @@ export const GalleryPage: React.FC<IProps> = ({ gallery, add }) => {
}, },
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() }
), )
}); );
} }
const onOrganizedClick = async () => { const onOrganizedClick = async () => {
@@ -120,15 +120,15 @@ export const GalleryPage: React.FC<IProps> = ({ gallery, add }) => {
paths: [path], paths: [path],
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.rescanning_entity" }, { id: "toast.rescanning_entity" },
{ {
count: 1, count: 1,
singularEntity: intl.formatMessage({ id: "gallery" }), singularEntity: intl.formatMessage({ id: "gallery" }),
} }
), )
}); );
} }
async function onClickChapter(imageindex: number) { async function onClickChapter(imageindex: number) {

View File

@@ -68,16 +68,16 @@ export const GalleryAddPanel: React.FC<IGalleryAddProps> = ({
image_ids: Array.from(selectedIds.values()), image_ids: Array.from(selectedIds.values()),
}); });
const imageCount = selectedIds.size; const imageCount = selectedIds.size;
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.added_entity" }, { id: "toast.added_entity" },
{ {
count: imageCount, count: imageCount,
singularEntity: intl.formatMessage({ id: "image" }), singularEntity: intl.formatMessage({ id: "image" }),
pluralEntity: intl.formatMessage({ id: "images" }), pluralEntity: intl.formatMessage({ id: "images" }),
} }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -25,12 +25,12 @@ const GalleryCreate: React.FC = () => {
}); });
if (result.data?.galleryCreate) { if (result.data?.galleryCreate) {
history.push(`/galleries/${result.data.galleryCreate.id}`); history.push(`/galleries/${result.data.galleryCreate.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() }
), )
}); );
} }
} }

View File

@@ -196,9 +196,7 @@ export const GalleryEditPanel: React.FC<IProps> = ({
try { try {
const result = await queryScrapeGallery(scraper.id, gallery.id); const result = await queryScrapeGallery(scraper.id, gallery.id);
if (!result.data || !result.data.scrapeSingleGallery?.length) { if (!result.data || !result.data.scrapeSingleGallery?.length) {
Toast.success({ Toast.success("No galleries found");
content: "No galleries found",
});
return; return;
} }
setScrapedGallery(result.data.scrapeSingleGallery[0]); setScrapedGallery(result.data.scrapeSingleGallery[0]);

View File

@@ -71,16 +71,16 @@ export const GalleryImagesPanel: React.FC<IGalleryDetailsProps> = ({
image_ids: Array.from(selectedIds.values()), image_ids: Array.from(selectedIds.values()),
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.removed_entity" }, { id: "toast.removed_entity" },
{ {
count: selectedIds.size, count: selectedIds.size,
singularEntity: intl.formatMessage({ id: "image" }), singularEntity: intl.formatMessage({ id: "image" }),
pluralEntity: intl.formatMessage({ id: "images" }), pluralEntity: intl.formatMessage({ id: "images" }),
} }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -60,7 +60,7 @@ export const DeleteImagesDialog: React.FC<IDeleteImageDialogProps> = (
setIsDeleting(true); setIsDeleting(true);
try { try {
await deleteImage(); await deleteImage();
Toast.success({ content: toastMessage }); Toast.success(toastMessage);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -88,12 +88,12 @@ export const EditImagesDialog: React.FC<IListOperationProps> = (
input: getImageInput(), input: getImageInput(),
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "images" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "images" }).toLocaleLowerCase() }
), )
}); );
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -58,12 +58,12 @@ const ImagePage: React.FC<IProps> = ({ image }) => {
await updateImage({ await updateImage({
variables: { input }, variables: { input },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "image" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "image" }).toLocaleLowerCase() }
), )
}); );
} }
async function onRescan() { async function onRescan() {
@@ -75,15 +75,15 @@ const ImagePage: React.FC<IProps> = ({ image }) => {
paths: [objectPath(image)], paths: [objectPath(image)],
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.rescanning_entity" }, { id: "toast.rescanning_entity" },
{ {
count: 1, count: 1,
singularEntity: intl.formatMessage({ id: "image" }), singularEntity: intl.formatMessage({ id: "image" }),
} }
), )
}); );
} }
const onOrganizedClick = async () => { const onOrganizedClick = async () => {

View File

@@ -82,16 +82,16 @@ export const SavedFilterList: React.FC<ISavedFilterListProps> = ({
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ {
id: "toast.saved_entity", id: "toast.saved_entity",
}, },
{ {
entity: intl.formatMessage({ id: "filter" }).toLocaleLowerCase(), entity: intl.formatMessage({ id: "filter" }).toLocaleLowerCase(),
} }
), )
}); );
setFilterName(""); setFilterName("");
setOverwritingFilter(undefined); setOverwritingFilter(undefined);
refetch(); refetch();
@@ -114,8 +114,8 @@ export const SavedFilterList: React.FC<ISavedFilterListProps> = ({
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ {
id: "toast.delete_past_tense", id: "toast.delete_past_tense",
}, },
@@ -124,8 +124,8 @@ export const SavedFilterList: React.FC<ISavedFilterListProps> = ({
singularEntity: intl.formatMessage({ id: "filter" }), singularEntity: intl.formatMessage({ id: "filter" }),
pluralEntity: intl.formatMessage({ id: "filters" }), pluralEntity: intl.formatMessage({ id: "filters" }),
} }
), )
}); );
refetch(); refetch();
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
@@ -152,11 +152,11 @@ export const SavedFilterList: React.FC<ISavedFilterListProps> = ({
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage({ intl.formatMessage({
id: "toast.default_filter_set", id: "toast.default_filter_set",
}), })
}); );
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
} finally { } finally {

View File

@@ -53,14 +53,14 @@ export const EditMoviesDialog: React.FC<IListOperationProps> = (
setIsUpdating(true); setIsUpdating(true);
try { try {
await updateMovies(); await updateMovies();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ {
entity: intl.formatMessage({ id: "movies" }).toLocaleLowerCase(), entity: intl.formatMessage({ id: "movies" }).toLocaleLowerCase(),
} }
), )
}); );
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -143,12 +143,12 @@ const MoviePage: React.FC<IProps> = ({ movie }) => {
}, },
}); });
toggleEditing(false); toggleEditing(false);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "movie" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "movie" }).toLocaleLowerCase() }
), )
}); );
} }
async function onDelete() { async function onDelete() {

View File

@@ -31,12 +31,12 @@ const MovieCreate: React.FC = () => {
}); });
if (result.data?.movieCreate?.id) { if (result.data?.movieCreate?.id) {
history.push(`/movies/${result.data.movieCreate.id}`); history.push(`/movies/${result.data.movieCreate.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "gallery" }).toLocaleLowerCase() }
), )
}); );
} }
} }

View File

@@ -140,13 +140,11 @@ export const MovieScrapeDialog: React.FC<IMovieScrapeDialogProps> = (
setStudio(studio.cloneWithValue(result.data!.studioCreate!.id)); setStudio(studio.cloneWithValue(result.data!.studioCreate!.id));
setNewStudio(undefined); setNewStudio(undefined);
Toast.success({ Toast.success(
content: ( <span>
<span> Created studio: <b>{toCreate.name}</b>
Created studio: <b>{toCreate.name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -133,16 +133,16 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
setIsUpdating(true); setIsUpdating(true);
try { try {
await updatePerformers(); await updatePerformers();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ {
entity: intl entity: intl
.formatMessage({ id: "performers" }) .formatMessage({ id: "performers" })
.toLocaleLowerCase(), .toLocaleLowerCase(),
} }
), )
}); );
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -151,9 +151,7 @@ const PerformerPage: React.FC<IProps> = ({ performer, tabKey }) => {
async function onAutoTag() { async function onAutoTag() {
try { try {
await mutateMetadataAutoTag({ performers: [performer.id] }); await mutateMetadataAutoTag({ performers: [performer.id] });
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.started_auto_tagging" }));
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -194,12 +192,12 @@ const PerformerPage: React.FC<IProps> = ({ performer, tabKey }) => {
}, },
}); });
toggleEditing(false); toggleEditing(false);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "performer" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "performer" }).toLocaleLowerCase() }
), )
}); );
} }
async function onDelete() { async function onDelete() {

View File

@@ -29,14 +29,14 @@ const PerformerCreate: React.FC = () => {
}); });
if (result.data?.performerCreate) { if (result.data?.performerCreate) {
history.push(`/performers/${result.data.performerCreate.id}`); history.push(`/performers/${result.data.performerCreate.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ {
entity: intl.formatMessage({ id: "performer" }).toLocaleLowerCase(), entity: intl.formatMessage({ id: "performer" }).toLocaleLowerCase(),
} }
), )
}); );
} }
} }

View File

@@ -220,13 +220,11 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
setNewTags(newTagsClone); setNewTags(newTagsClone);
Toast.success({ Toast.success(
content: ( <span>
<span> Created tag: <b>{toCreate.name}</b>
Created tag: <b>{toCreate.name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -477,13 +477,11 @@ export const PerformerScrapeDialog: React.FC<IPerformerScrapeDialogProps> = (
setNewTags(newTagsClone); setNewTags(newTagsClone);
Toast.success({ Toast.success(
content: ( <span>
<span> Created tag: <b>{toCreate.name}</b>
Created tag: <b>{toCreate.name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -187,12 +187,12 @@ export const SceneFilenameParser: React.FC = () => {
try { try {
await updateScenes(); await updateScenes();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "scenes" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "scenes" }).toLocaleLowerCase() }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -61,7 +61,7 @@ export const DeleteScenesDialog: React.FC<IDeleteSceneDialogProps> = (
setIsDeleting(true); setIsDeleting(true);
try { try {
await deleteScene(); await deleteScene();
Toast.success({ content: toastMessage }); Toast.success(toastMessage);
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -96,12 +96,12 @@ export const EditScenesDialog: React.FC<IListOperationProps> = (
setIsUpdating(true); setIsUpdating(true);
try { try {
await updateScenes(); await updateScenes();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "scenes" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "scenes" }).toLocaleLowerCase() }
), )
}); );
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -189,12 +189,12 @@ const ScenePage: React.FC<IProps> = ({
}, },
}, },
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase() }
), )
}); );
} }
const onOrganizedClick = async () => { const onOrganizedClick = async () => {
@@ -232,8 +232,8 @@ const ScenePage: React.FC<IProps> = ({
paths: [objectPath(scene)], paths: [objectPath(scene)],
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.rescanning_entity" }, { id: "toast.rescanning_entity" },
{ {
count: 1, count: 1,
@@ -241,8 +241,8 @@ const ScenePage: React.FC<IProps> = ({
.formatMessage({ id: "scene" }) .formatMessage({ id: "scene" })
.toLocaleLowerCase(), .toLocaleLowerCase(),
} }
), )
}); );
} }
async function onGenerateScreenshot(at?: number) { async function onGenerateScreenshot(at?: number) {
@@ -252,9 +252,7 @@ const ScenePage: React.FC<IProps> = ({
at, at,
}, },
}); });
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.generating_screenshot" }));
content: intl.formatMessage({ id: "toast.generating_screenshot" }),
});
} }
function onDeleteDialogClosed(deleted: boolean) { function onDeleteDialogClosed(deleted: boolean) {

View File

@@ -65,12 +65,12 @@ const SceneCreate: React.FC = () => {
}); });
if (result.data?.sceneCreate?.id) { if (result.data?.sceneCreate?.id) {
history.push(`/scenes/${result.data.sceneCreate.id}`); history.push(`/scenes/${result.data.sceneCreate.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "scene" }).toLocaleLowerCase() }
), )
}); );
} }
} }

View File

@@ -297,9 +297,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
try { try {
const result = await queryScrapeScene(s, scene.id!); const result = await queryScrapeScene(s, scene.id!);
if (!result.data || !result.data.scrapeSingleScene?.length) { if (!result.data || !result.data.scrapeSingleScene?.length) {
Toast.success({ Toast.success("No scenes found");
content: "No scenes found",
});
return; return;
} }
// assume one returned scene // assume one returned scene
@@ -330,9 +328,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
const result = await queryScrapeSceneQueryFragment(s, input); const result = await queryScrapeSceneQueryFragment(s, input);
if (!result.data || !result.data.scrapeSingleScene?.length) { if (!result.data || !result.data.scrapeSingleScene?.length) {
Toast.success({ Toast.success("No scenes found");
content: "No scenes found",
});
return; return;
} }
// assume one returned scene // assume one returned scene

View File

@@ -77,7 +77,6 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
onClick={( onClick={(
event: React.MouseEvent<HTMLInputElement, MouseEvent> event: React.MouseEvent<HTMLInputElement, MouseEvent>
) => { ) => {
// eslint-disable-next-line prefer-destructuring
shiftKey = event.shiftKey; shiftKey = event.shiftKey;
event.stopPropagation(); event.stopPropagation();
}} }}

View File

@@ -692,9 +692,7 @@ export const SceneMergeModal: React.FC<ISceneMergeModalProps> = ({
values values
); );
if (result.data?.sceneMerge) { if (result.data?.sceneMerge) {
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.merged_scenes" }));
content: intl.formatMessage({ id: "toast.merged_scenes" }),
});
// refetch the scene // refetch the scene
await queryFindScenesByID([parseInt(destScene[0].id)]); await queryFindScenesByID([parseInt(destScene[0].id)]);
onClose(destScene[0].id); onClose(destScene[0].id);

View File

@@ -68,18 +68,18 @@ export const SettingsServicesPanel: React.FC = () => {
try { try {
if (enableDisable) { if (enableDisable) {
await enableDLNA(input); await enableDLNA(input);
Toast.success({ Toast.success(
content: intl.formatMessage({ intl.formatMessage({
id: "config.dlna.enabled_dlna_temporarily", id: "config.dlna.enabled_dlna_temporarily",
}), })
}); );
} else { } else {
await disableDLNA(input); await disableDLNA(input);
Toast.success({ Toast.success(
content: intl.formatMessage({ intl.formatMessage({
id: "config.dlna.disabled_dlna_temporarily", id: "config.dlna.disabled_dlna_temporarily",
}), })
}); );
} }
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
@@ -105,11 +105,11 @@ export const SettingsServicesPanel: React.FC = () => {
try { try {
await addTempDLANIP(input); await addTempDLANIP(input);
Toast.success({ Toast.success(
content: intl.formatMessage({ intl.formatMessage({
id: "config.dlna.allowed_ip_temporarily", id: "config.dlna.allowed_ip_temporarily",
}), })
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {
@@ -129,9 +129,7 @@ export const SettingsServicesPanel: React.FC = () => {
try { try {
await removeTempDLNAIP(input); await removeTempDLNAIP(input);
Toast.success({ Toast.success(intl.formatMessage({ id: "config.dlna.disallowed_ip" }));
content: intl.formatMessage({ id: "config.dlna.disallowed_ip" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {
@@ -209,11 +207,11 @@ export const SettingsServicesPanel: React.FC = () => {
} else { } else {
await disableDLNA(input); await disableDLNA(input);
} }
Toast.success({ Toast.success(
content: intl.formatMessage({ intl.formatMessage({
id: "config.dlna.successfully_cancelled_temporary_behaviour", id: "config.dlna.successfully_cancelled_temporary_behaviour",
}), })
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {

View File

@@ -196,12 +196,12 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
setDialogOpen({ importAlert: false }); setDialogOpen({ importAlert: false });
try { try {
await mutateMetadataImport(); await mutateMetadataImport();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.import" }) } { operation_name: intl.formatMessage({ id: "actions.import" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -239,12 +239,12 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
paths, paths,
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.clean" }) } { operation_name: intl.formatMessage({ id: "actions.clean" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {
@@ -255,16 +255,16 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
async function onMigrateHashNaming() { async function onMigrateHashNaming() {
try { try {
await mutateMigrateHashNaming(); await mutateMigrateHashNaming();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ {
operation_name: intl.formatMessage({ operation_name: intl.formatMessage({
id: "actions.hash_migration", id: "actions.hash_migration",
}), }),
} }
), )
}); );
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
} }
@@ -273,16 +273,16 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
async function onMigrateSceneScreenshots() { async function onMigrateSceneScreenshots() {
try { try {
await mutateMigrateSceneScreenshots(migrateSceneScreenshotsOptions); await mutateMigrateSceneScreenshots(migrateSceneScreenshotsOptions);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ {
operation_name: intl.formatMessage({ operation_name: intl.formatMessage({
id: "actions.migrate_scene_screenshots", id: "actions.migrate_scene_screenshots",
}), }),
} }
), )
}); );
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
} }
@@ -291,16 +291,16 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
async function onMigrateBlobs() { async function onMigrateBlobs() {
try { try {
await mutateMigrateBlobs(migrateBlobsOptions); await mutateMigrateBlobs(migrateBlobsOptions);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ {
operation_name: intl.formatMessage({ operation_name: intl.formatMessage({
id: "actions.migrate_blobs", id: "actions.migrate_blobs",
}), }),
} }
), )
}); );
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
} }
@@ -309,12 +309,12 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
async function onExport() { async function onExport() {
try { try {
await mutateMetadataExport(); await mutateMetadataExport();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.export" }) } { operation_name: intl.formatMessage({ id: "actions.export" }) }
), )
}); );
} catch (err) { } catch (err) {
Toast.error(err); Toast.error(err);
} }
@@ -342,16 +342,16 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
async function onOptimiseDatabase() { async function onOptimiseDatabase() {
try { try {
await mutateOptimiseDatabase(); await mutateOptimiseDatabase();
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ {
operation_name: intl.formatMessage({ operation_name: intl.formatMessage({
id: "actions.optimise_database", id: "actions.optimise_database",
}), }),
} }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -103,9 +103,7 @@ export const ImportDialog: React.FC<IImportDialogProps> = (
file, file,
}); });
setIsRunning(false); setIsRunning(false);
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.started_importing" }));
content: intl.formatMessage({ id: "toast.started_importing" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} finally { } finally {

View File

@@ -198,12 +198,12 @@ export const LibraryTasks: React.FC = () => {
paths, paths,
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.scan" }) } { operation_name: intl.formatMessage({ id: "actions.scan" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -240,12 +240,12 @@ export const LibraryTasks: React.FC = () => {
paths, paths,
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.auto_tag" }) } { operation_name: intl.formatMessage({ id: "actions.auto_tag" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -270,12 +270,12 @@ export const LibraryTasks: React.FC = () => {
}); });
await mutateMetadataGenerate(generateOptions); await mutateMetadataGenerate(generateOptions);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: intl.formatMessage({ id: "actions.generate" }) } { operation_name: intl.formatMessage({ id: "actions.generate" }) }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -70,12 +70,12 @@ export const PluginTasks: React.FC = () => {
async function onPluginTaskClicked(plugin: Plugin, operation: PluginTask) { async function onPluginTaskClicked(plugin: Plugin, operation: PluginTask) {
await mutateRunPluginTask(plugin.id, operation.name); await mutateRunPluginTask(plugin.id, operation.name);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "config.tasks.added_job_to_queue" }, { id: "config.tasks.added_job_to_queue" },
{ operation_name: operation.name } { operation_name: operation.name }
), )
}); );
} }
return <Form.Group>{renderPlugins()}</Form.Group>; return <Form.Group>{renderPlugins()}</Form.Group>;

View File

@@ -103,20 +103,6 @@ export const SettingsContext: React.FC = ({ children }) => {
const [apiKey, setApiKey] = useState(""); const [apiKey, setApiKey] = useState("");
// cannot use Toast.error directly with the debounce functions
// since they are refreshed every time the Toast context is updated.
const [saveError, setSaveError] = useState<unknown>();
useEffect(() => {
if (!saveError) {
return;
}
Toast.error(saveError);
setSaveError(undefined);
setUpdateSuccess(false);
}, [saveError, Toast]);
useEffect(() => { useEffect(() => {
if (!data?.configuration || error) return; if (!data?.configuration || error) return;
@@ -144,6 +130,14 @@ export const SettingsContext: React.FC = ({ children }) => {
resetSuccess(); resetSuccess();
}, [resetSuccess]); }, [resetSuccess]);
const onError = useCallback(
(err) => {
Toast.error(err);
setUpdateSuccess(false);
},
[Toast]
);
// saves the configuration if no further changes are made after a half second // saves the configuration if no further changes are made after a half second
const saveGeneralConfig = useDebounce( const saveGeneralConfig = useDebounce(
async (input: GQL.ConfigGeneralInput) => { async (input: GQL.ConfigGeneralInput) => {
@@ -158,7 +152,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingGeneral(undefined); setPendingGeneral(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, },
500 500
@@ -207,7 +201,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingInterface(undefined); setPendingInterface(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, },
500 500
@@ -256,7 +250,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingDefaults(undefined); setPendingDefaults(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, },
500 500
@@ -305,7 +299,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingScraping(undefined); setPendingScraping(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, },
500 500
@@ -353,7 +347,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingDLNA(undefined); setPendingDLNA(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, 500); }, 500);
@@ -399,7 +393,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingUI(undefined); setPendingUI(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, 500); }, 500);
@@ -453,7 +447,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingPlugins(undefined); setPendingPlugins(undefined);
onSuccess(); onSuccess();
} catch (e) { } catch (e) {
setSaveError(e); onError(e);
} }
}, 500); }, 500);

View File

@@ -62,13 +62,13 @@ export const DeleteEntityDialog: React.FC<IDeleteEntityDialogProps> = ({
if (onDeleted) { if (onDeleted) {
onDeleted(); onDeleted();
} }
Toast.success({ Toast.success(
content: intl.formatMessage(messages.deleteToast, { intl.formatMessage(messages.deleteToast, {
count, count,
singularEntity, singularEntity,
pluralEntity, pluralEntity,
}), })
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -44,7 +44,7 @@ export const DeleteFilesDialog: React.FC<IDeleteSceneDialogProps> = (
setIsDeleting(true); setIsDeleting(true);
try { try {
await mutateDeleteFiles(props.selected.map((f) => f.id)); await mutateDeleteFiles(props.selected.map((f) => f.id));
Toast.success({ content: toastMessage }); Toast.success(toastMessage);
props.onClose(true); props.onClose(true);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -197,13 +197,11 @@ export const FilterSelectComponent = <
} }
setLoading(false); setLoading(false);
Toast.success({ Toast.success(
content: ( <span>
<span> {message}: <b>{name}</b>
{message}: <b>{name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -72,7 +72,6 @@ export const GridCard: React.FC<ICardProps> = (props: ICardProps) => {
checked={props.selected} checked={props.selected}
onChange={() => props.onSelectedChanged!(!props.selected, shiftKey)} onChange={() => props.onSelectedChanged!(!props.selected, shiftKey)}
onClick={(event: React.MouseEvent<HTMLInputElement, MouseEvent>) => { onClick={(event: React.MouseEvent<HTMLInputElement, MouseEvent>) => {
// eslint-disable-next-line prefer-destructuring
shiftKey = event.shiftKey; shiftKey = event.shiftKey;
event.stopPropagation(); event.stopPropagation();
}} }}

View File

@@ -50,7 +50,7 @@ export const ReassignFilesDialog: React.FC<IReassignFilesDialogProps> = (
setReassigning(true); setReassigning(true);
try { try {
await mutateSceneAssignFile(scenes[0].id, props.selected.id); await mutateSceneAssignFile(scenes[0].id, props.selected.id);
Toast.success({ content: toastMessage }); Toast.success(toastMessage);
props.onClose(); props.onClose();
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -22,16 +22,16 @@ function useCreateObject<T>(
try { try {
await createFunc(o); await createFunc(o);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ {
entity: intl entity: intl
.formatMessage({ id: entityTypeID }) .formatMessage({ id: entityTypeID })
.toLocaleLowerCase(), .toLocaleLowerCase(),
} }
), )
}); );
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -311,13 +311,11 @@ const FilterSelectComponent = <T extends boolean>(
newItem, newItem,
]); ]);
setLoading(false); setLoading(false);
Toast.success({ Toast.success(
content: ( <span>
<span> {message}: <b>{name}</b>
{message}: <b>{name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -174,21 +174,19 @@ const StudioPage: React.FC<IProps> = ({ studio, tabKey }) => {
}, },
}); });
toggleEditing(false); toggleEditing(false);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "studio" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "studio" }).toLocaleLowerCase() }
), )
}); );
} }
async function onAutoTag() { async function onAutoTag() {
if (!studio.id) return; if (!studio.id) return;
try { try {
await mutateMetadataAutoTag({ studios: [studio.id] }); await mutateMetadataAutoTag({ studios: [studio.id] });
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.started_auto_tagging" }));
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -32,12 +32,12 @@ const StudioCreate: React.FC = () => {
}); });
if (result.data?.studioCreate?.id) { if (result.data?.studioCreate?.id) {
history.push(`/studios/${result.data.studioCreate.id}`); history.push(`/studios/${result.data.studioCreate.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ entity: intl.formatMessage({ id: "studio" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "studio" }).toLocaleLowerCase() }
), )
}); );
} }
} }

View File

@@ -531,13 +531,11 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
Toast.success({ Toast.success(
content: ( <span>
<span> Created tag: <b>{toCreate.name}</b>
Created tag: <b>{toCreate.name}</b> </span>
</span> );
),
});
return tagID; return tagID;
} catch (e) { } catch (e) {
@@ -581,13 +579,11 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
Toast.success({ Toast.success(
content: ( <span>
<span> Created performer: <b>{toCreate.name}</b>
Created performer: <b>{toCreate.name}</b> </span>
</span> );
),
});
return performerID; return performerID;
} catch (e) { } catch (e) {
@@ -649,9 +645,7 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
Toast.success({ Toast.success(<span>Added stash-id to performer</span>);
content: <span>Added stash-id to performer</span>,
});
} }
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
@@ -691,13 +685,11 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
Toast.success({ Toast.success(
content: ( <span>
<span> Created studio: <b>{toCreate.name}</b>
Created studio: <b>{toCreate.name}</b> </span>
</span> );
),
});
return studioID; return studioID;
} catch (e) { } catch (e) {
@@ -740,13 +732,11 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
} }
Toast.success({ Toast.success(
content: ( <span>
<span> Created studio: <b>{input.name}</b>
Created studio: <b>{input.name}</b> </span>
</span> );
),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -800,9 +790,7 @@ export const TaggerContext: React.FC = ({ children }) => {
setSearchResults(newSearchResults); setSearchResults(newSearchResults);
Toast.success({ Toast.success(<span>Added stash-id to studio</span>);
content: <span>Added stash-id to studio</span>,
});
} }
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -179,12 +179,12 @@ const TagPage: React.FC<IProps> = ({ tag, tabKey }) => {
parents: updated.parents, parents: updated.parents,
children: updated.children, children: updated.children,
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.updated_entity" }, { id: "toast.updated_entity" },
{ entity: intl.formatMessage({ id: "tag" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "tag" }).toLocaleLowerCase() }
), )
}); );
} }
} }
@@ -192,9 +192,7 @@ const TagPage: React.FC<IProps> = ({ tag, tabKey }) => {
if (!tag.id) return; if (!tag.id) return;
try { try {
await mutateMetadataAutoTag({ tags: [tag.id] }); await mutateMetadataAutoTag({ tags: [tag.id] });
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.started_auto_tagging" }));
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -40,12 +40,12 @@ const TagCreate: React.FC = () => {
children: created.children, children: created.children,
}); });
history.push(`/tags/${created.id}`); history.push(`/tags/${created.id}`);
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.created_entity" }, { id: "toast.created_entity" },
{ entity: intl.formatMessage({ id: "tag" }).toLocaleLowerCase() } { entity: intl.formatMessage({ id: "tag" }).toLocaleLowerCase() }
), )
}); );
} }
} }

View File

@@ -52,9 +52,7 @@ export const TagMergeModal: React.FC<ITagMergeModalProps> = ({
}, },
}); });
if (result.data?.tagsMerge) { if (result.data?.tagsMerge) {
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.merged_tags" }));
content: intl.formatMessage({ id: "toast.merged_tags" }),
});
onClose(); onClose();
history.push(`/tags/${destination}`); history.push(`/tags/${destination}`);
} }

View File

@@ -128,9 +128,7 @@ export const TagList: React.FC<ITagList> = ({ filterHook, alterQuery }) => {
if (!tag) return; if (!tag) return;
try { try {
await mutateMetadataAutoTag({ tags: [tag.id] }); await mutateMetadataAutoTag({ tags: [tag.id] });
Toast.success({ Toast.success(intl.formatMessage({ id: "toast.started_auto_tagging" }));
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
});
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -147,16 +145,16 @@ export const TagList: React.FC<ITagList> = ({ filterHook, alterQuery }) => {
parents: [], parents: [],
children: [], children: [],
}); });
Toast.success({ Toast.success(
content: intl.formatMessage( intl.formatMessage(
{ id: "toast.delete_past_tense" }, { id: "toast.delete_past_tense" },
{ {
count: 1, count: 1,
singularEntity: intl.formatMessage({ id: "tag" }), singularEntity: intl.formatMessage({ id: "tag" }),
pluralEntity: intl.formatMessage({ id: "tags" }), pluralEntity: intl.formatMessage({ id: "tags" }),
} }
), )
}); );
setDeletingTag(null); setDeletingTag(null);
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);

View File

@@ -1,4 +1,10 @@
import React, { useEffect, useState, useContext, createContext } from "react"; import React, {
useState,
useContext,
createContext,
useCallback,
useMemo,
} from "react";
import { Toast } from "react-bootstrap"; import { Toast } from "react-bootstrap";
interface IToast { interface IToast {
@@ -7,18 +13,20 @@ interface IToast {
delay?: number; delay?: number;
variant?: "success" | "danger" | "warning"; variant?: "success" | "danger" | "warning";
} }
interface IActiveToast extends IToast { interface IActiveToast extends IToast {
id: number; id: number;
} }
let toastID = 0; let toastID = 0;
const ToastContext = createContext<(item: IToast) => void>(() => {}); const ToastContext = createContext<(item: IToast) => void>(() => {});
export const ToastProvider: React.FC = ({ children }) => { export const ToastProvider: React.FC = ({ children }) => {
const [toasts, setToasts] = useState<IActiveToast[]>([]); const [toasts, setToasts] = useState<IActiveToast[]>([]);
const removeToast = (id: number) => const removeToast = (id: number) =>
setToasts(toasts.filter((item) => item.id !== id)); setToasts((prev) => prev.filter((item) => item.id !== id));
const toastItems = toasts.map((toast) => ( const toastItems = toasts.map((toast) => (
<Toast <Toast
@@ -35,8 +43,9 @@ export const ToastProvider: React.FC = ({ children }) => {
</Toast> </Toast>
)); ));
const addToast = (toast: IToast) => const addToast = useCallback((toast: IToast) => {
setToasts([...toasts, { ...toast, id: toastID++ }]); setToasts((prev) => [...prev, { ...toast, id: toastID++ }]);
}, []);
return ( return (
<ToastContext.Provider value={addToast}> <ToastContext.Provider value={addToast}>
@@ -46,41 +55,37 @@ export const ToastProvider: React.FC = ({ children }) => {
); );
}; };
function createHookObject(toastFunc: (toast: IToast) => void) { export const useToast = () => {
return { const addToast = useContext(ToastContext);
success: toastFunc,
error: (error: unknown) => { return useMemo(
/* eslint-disable no-console */ () => ({
let message: string; toast: addToast,
if (error instanceof Error) { success(message: React.ReactNode | string) {
message = error.message ?? error.toString(); addToast({
} else if (error instanceof String) { content: message,
message = error.toString(); });
} else { },
error(error: unknown) {
let message;
if (error instanceof Error) {
message = error.message;
}
if (!message) {
message = String(error);
}
if (!message) {
message = "Unknown error";
}
console.error(error); console.error(error);
toastFunc({ addToast({
variant: "danger", variant: "danger",
header: "Error", header: "Error",
content: "Unknown error", content: message,
}); });
return; },
} }),
[addToast]
console.error(message); );
toastFunc({
variant: "danger",
header: "Error",
content: message,
});
/* eslint-enable no-console */
},
};
}
export const useToast = () => {
const setToast = useContext(ToastContext);
const [hookObject, setHookObject] = useState(createHookObject(setToast));
useEffect(() => setHookObject(createHookObject(setToast)), [setToast]);
return hookObject;
}; };