Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't let toast elapse in background in some browsers #7741

Merged
merged 14 commits into from
Apr 15, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export async function tryToFetchDatasetsByName(
);
return datasets;
} catch (exception) {
console.warn(exception);
Toast.warning(userErrorMessage);
console.warn(exception);
return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ export default function WorkflowListView() {
const _workflows = (await getVoxelyticsWorkflows()).map(parseWorkflowInfo);
setWorkflows(_workflows);
} catch (err) {
console.error(err);
Toast.error("Could not load workflow list.");
console.error(err);
} finally {
setIsLoading(false);
}
Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/admin/voxelytics/workflow_view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -372,8 +372,8 @@ export default function WorkflowView() {
error: err as Error,
});
} catch (accessibleBySwitchingError) {
console.log(accessibleBySwitchingError);
Toast.error("Could not load workflow report.");
console.error(accessibleBySwitchingError);
setLoadingState({ status: "FAILED", error: accessibleBySwitchingError as Error });
}
}
Expand Down
8 changes: 4 additions & 4 deletions frontend/javascripts/libs/browser_feature_check.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,6 @@ export default function checkBrowserFeatures() {
new BigUint64Array(1);
"hello".replaceAll("l", "k");
} catch (exception) {
console.error(
"This browser lacks support for some modern features. Exception caught during test of features:",
exception,
);
Toast.warning(
<div>
Your browser seems to be outdated.{" "}
Expand All @@ -23,5 +19,9 @@ export default function checkBrowserFeatures() {
to avoid errors. See console for details.
</div>,
);
console.error(
"This browser lacks support for some modern features. Exception caught during test of features:",
exception,
);
}
}
1 change: 0 additions & 1 deletion frontend/javascripts/libs/error_handling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,6 @@ class ErrorHandling {
error = new Error(message);
}

console.error(error);
this.notify(error);

if (error.toString() === "Error: Script error.") {
Expand Down
31 changes: 26 additions & 5 deletions frontend/javascripts/libs/toast.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { notification, Collapse } from "antd";
import { CloseCircleOutlined } from "@ant-design/icons";
import React from "react";
import { sleep } from "./utils";

export type ToastStyle = "info" | "warning" | "success" | "error";
export type Message = {
Expand Down Expand Up @@ -75,12 +76,12 @@ const Toast = {
);
},

message(
async message(
type: ToastStyle,
rawMessage: string | React.ReactNode,
config: ToastConfig,
details?: string,
): void {
): Promise<void> {
const message = this.buildContentWithDetails(rawMessage, details);
const timeout = config.timeout != null ? config.timeout : 6000;
const key = config.key || (typeof message === "string" ? message : undefined);
Expand All @@ -94,11 +95,10 @@ const Toast = {
toastMessage = message;
}

const timeOutInSeconds = timeout / 1000;
let toastConfig = {
icon: undefined,
key,
duration: sticky ? 0 : timeOutInSeconds,
duration: 0,
message: toastMessage,
style: {},
className: "",
Expand All @@ -112,13 +112,33 @@ const Toast = {
}

notification[type](toastConfig);

// Make sure that toasts don't just dissapear while user has WK in background tab (e.g. while uploading large dataset).
dieknolle3333 marked this conversation as resolved.
Show resolved Hide resolved
// Most browsers pause requestAnimationFrame() if the current tab is not active, but Firefox does not seem to do that.
if (!sticky && key != null) {
requestAnimationFrame(async () => {
dieknolle3333 marked this conversation as resolved.
Show resolved Hide resolved
// ensure tab is active
const timeoutAfterTabSwitch = timeout >= 1000 ? 1000 : 0;
await sleep(timeout - timeoutAfterTabSwitch);
dieknolle3333 marked this conversation as resolved.
Show resolved Hide resolved
requestAnimationFrame(async () => {
// If the user has switched the tab, show the toast for a short time so that the user doesn't just see the toast dissapear.
await sleep(timeoutAfterTabSwitch);
this.close(key);
});
});
}
},

info(message: React.ReactNode, config: ToastConfig = {}, details?: string | undefined): void {
this.message("info", message, config, details);
},

warning(message: React.ReactNode, config: ToastConfig = {}, details?: string | undefined): void {
warning(
message: React.ReactNode | string,
config: ToastConfig = {},
details?: string | undefined,
): void {
if (typeof message === "string") console.warn(message);
this.message("warning", message, config, details);
},

Expand All @@ -135,6 +155,7 @@ const Toast = {
config: ToastConfig = {},
details?: string | undefined,
): void {
if (typeof message === "string") console.error(message);
this.message("error", message, config, details);
},

Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/oxalis/controller.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,10 @@ class Controller extends React.PureComponent<PropsWithRouter, State> {
// eslint-disable-next-line no-eval
eval(content);
} catch (error) {
console.error(error);
Toast.error(
`Error executing the task script "${script.name}". See console for more information.`,
);
console.error(error);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ export function* pushAnnotationUpdateAsync(action: Action) {
// we will only notify the user if the name, visibility or description could not be changed.
// Otherwise, we won't notify the user and won't let the sagas crash as the actual skeleton/volume
// tracings are handled separately.
console.error(error);
ErrorHandling.notify(error as Error);
if (
["SET_ANNOTATION_NAME", "SET_ANNOTATION_VISIBILITY", "SET_ANNOTATION_DESCRIPTION"].includes(
Expand All @@ -92,6 +91,7 @@ export function* pushAnnotationUpdateAsync(action: Action) {
) {
Toast.error("Could not update annotation property. Please try again.");
}
console.error(error);
}
}

Expand Down
8 changes: 4 additions & 4 deletions frontend/javascripts/oxalis/model/sagas/mesh_saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -785,8 +785,8 @@ function* loadPrecomputedMeshForSegmentId(
scale = chunkDescriptors.scale;
loadingOrder = chunkDescriptors.loadingOrder;
} catch (exception) {
console.warn("Mesh chunk couldn't be loaded due to", exception);
Toast.warning(messages["tracing.mesh_listing_failed"]);
console.warn("Mesh chunk couldn't be loaded due to", exception);
yield* put(finishedLoadingMeshAction(layerName, id));
yield* put(removeMeshAction(layerName, id));
return;
Expand All @@ -808,8 +808,8 @@ function* loadPrecomputedMeshForSegmentId(
try {
yield* call(processTaskWithPool, loadChunksTasks, PARALLEL_PRECOMPUTED_MESH_LOADING_COUNT);
} catch (exception) {
console.error(exception);
Toast.warning(`Some mesh chunks could not be loaded for segment ${id}.`);
console.error(exception);
}

yield* put(finishedLoadingMeshAction(layerName, id));
Expand Down Expand Up @@ -1089,8 +1089,8 @@ function* downloadMeshCellById(cellName: string, segmentId: number, layerName: s
yield* call(saveAs, blob, `${cellName}-${segmentId}.stl`);
} catch (exception) {
ErrorHandling.notify(exception as Error);
console.error(exception);
Toast.error("Could not export to STL. See console for details");
console.error(exception);
}
}

Expand Down Expand Up @@ -1123,8 +1123,8 @@ function* downloadMeshCellsAsZIP(
yield* call(saveAs, result as Blob, "mesh-export.zip");
} catch (exception) {
ErrorHandling.notify(exception as Error);
console.error(exception);
Toast.error("Could not export meshes as STL files. See console for details");
console.error(exception);
}
}

Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/oxalis/model/sagas/proofread_saga.ts
Original file line number Diff line number Diff line change
Expand Up @@ -826,10 +826,10 @@ function* getAgglomerateInfos(
}> | null> {
const idInfos = yield* all(positions.map((pos) => call(getMappedAndUnmapped, pos)));
if (idInfos.find((idInfo) => idInfo.agglomerateId === 0 || idInfo.unmappedId === 0) != null) {
console.warn("At least one id was zero:", idInfos);
Toast.warning(
"One of the selected segments has the id 0 which is the background. Cannot merge/split.",
);
console.warn("At least one id was zero:", idInfos);
return null;
}
return idInfos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,6 @@ export default function* listenToQuickSelect(): Saga<void> {
} catch (ex) {
Toast.error((ex as Error).toString());
ErrorHandling.notify(ex as Error);
console.error(ex);
} finally {
yield* put(setBusyBlockingInfoAction(false));
action.quickSelectGeometry.setCoordinates([0, 0, 0], [0, 0, 0]);
Expand Down
2 changes: 1 addition & 1 deletion frontend/javascripts/oxalis/model_initialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -700,11 +700,11 @@ async function applyLayerState(stateByLayer: UrlStateByLayer) {
// The name of the layer could have changed if a volume tracing was created from a viewed annotation
effectiveLayerName = getLayerByName(dataset, layerName, true).name;
} catch (e) {
console.error(e);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In cases like this I didnt omit the separate log because Error not only has a message, but also a type, and I didnt want that to be omitted. Let me know if you think I should change that :)

Toast.error(
// @ts-ignore
`URL configuration values for the layer "${layerName}" are ignored, because: ${e.message}`,
);
console.error(e);
// @ts-ignore
ErrorHandling.notify(e, {
urlLayerState: stateByLayer,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,10 +553,10 @@ function StartJobForm(props: StartJobFormProps) {
);
handleClose();
} catch (error) {
console.error(error);
Toast.error(
`The ${jobName} job could not be started. Please contact an administrator or look in the console for more details.`,
);
console.error(error);
handleClose();
}
};
Expand Down