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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -31,12 +31,12 @@ const MovieCreate: React.FC = () => {
});
if (result.data?.movieCreate?.id) {
history.push(`/movies/${result.data.movieCreate.id}`);
Toast.success({
content: intl.formatMessage(
Toast.success(
intl.formatMessage(
{ id: "toast.created_entity" },
{ 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));
setNewStudio(undefined);
Toast.success({
content: (
Toast.success(
<span>
Created studio: <b>{toCreate.name}</b>
</span>
),
});
);
} catch (e) {
Toast.error(e);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -103,20 +103,6 @@ export const SettingsContext: React.FC = ({ children }) => {
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(() => {
if (!data?.configuration || error) return;
@@ -144,6 +130,14 @@ export const SettingsContext: React.FC = ({ children }) => {
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
const saveGeneralConfig = useDebounce(
async (input: GQL.ConfigGeneralInput) => {
@@ -158,7 +152,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingGeneral(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
},
500
@@ -207,7 +201,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingInterface(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
},
500
@@ -256,7 +250,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingDefaults(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
},
500
@@ -305,7 +299,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingScraping(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
},
500
@@ -353,7 +347,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingDLNA(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
}, 500);
@@ -399,7 +393,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingUI(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
}, 500);
@@ -453,7 +447,7 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingPlugins(undefined);
onSuccess();
} catch (e) {
setSaveError(e);
onError(e);
}
}, 500);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -128,9 +128,7 @@ export const TagList: React.FC<ITagList> = ({ filterHook, alterQuery }) => {
if (!tag) return;
try {
await mutateMetadataAutoTag({ tags: [tag.id] });
Toast.success({
content: intl.formatMessage({ id: "toast.started_auto_tagging" }),
});
Toast.success(intl.formatMessage({ id: "toast.started_auto_tagging" }));
} catch (e) {
Toast.error(e);
}
@@ -147,16 +145,16 @@ export const TagList: React.FC<ITagList> = ({ filterHook, alterQuery }) => {
parents: [],
children: [],
});
Toast.success({
content: intl.formatMessage(
Toast.success(
intl.formatMessage(
{ id: "toast.delete_past_tense" },
{
count: 1,
singularEntity: intl.formatMessage({ id: "tag" }),
pluralEntity: intl.formatMessage({ id: "tags" }),
}
),
});
)
);
setDeletingTag(null);
} catch (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";
interface IToast {
@@ -7,18 +13,20 @@ interface IToast {
delay?: number;
variant?: "success" | "danger" | "warning";
}
interface IActiveToast extends IToast {
id: number;
}
let toastID = 0;
const ToastContext = createContext<(item: IToast) => void>(() => {});
export const ToastProvider: React.FC = ({ children }) => {
const [toasts, setToasts] = useState<IActiveToast[]>([]);
const removeToast = (id: number) =>
setToasts(toasts.filter((item) => item.id !== id));
setToasts((prev) => prev.filter((item) => item.id !== id));
const toastItems = toasts.map((toast) => (
<Toast
@@ -35,8 +43,9 @@ export const ToastProvider: React.FC = ({ children }) => {
</Toast>
));
const addToast = (toast: IToast) =>
setToasts([...toasts, { ...toast, id: toastID++ }]);
const addToast = useCallback((toast: IToast) => {
setToasts((prev) => [...prev, { ...toast, id: toastID++ }]);
}, []);
return (
<ToastContext.Provider value={addToast}>
@@ -46,41 +55,37 @@ export const ToastProvider: React.FC = ({ children }) => {
);
};
function createHookObject(toastFunc: (toast: IToast) => void) {
return {
success: toastFunc,
error: (error: unknown) => {
/* eslint-disable no-console */
let message: string;
if (error instanceof Error) {
message = error.message ?? error.toString();
} else if (error instanceof String) {
message = error.toString();
} else {
console.error(error);
toastFunc({
variant: "danger",
header: "Error",
content: "Unknown error",
export const useToast = () => {
const addToast = useContext(ToastContext);
return useMemo(
() => ({
toast: addToast,
success(message: React.ReactNode | string) {
addToast({
content: message,
});
return;
},
error(error: unknown) {
let message;
if (error instanceof Error) {
message = error.message;
}
if (!message) {
message = String(error);
}
if (!message) {
message = "Unknown error";
}
console.error(message);
toastFunc({
console.error(error);
addToast({
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;
}),
[addToast]
);
};