diff --git a/src/frontend/src/components/displayError.ts b/src/frontend/src/components/displayError.ts index 87a64fa9e3..70e5177893 100644 --- a/src/frontend/src/components/displayError.ts +++ b/src/frontend/src/components/displayError.ts @@ -1,3 +1,4 @@ +import { ERROR_SUPPORT_URL } from "$src/config"; import { TemplateElement } from "$src/utils/lit-html"; import { nonNullish } from "@dfinity/utils"; import { html, render } from "lit-html"; @@ -40,6 +41,13 @@ ${options.detail} ${options.primaryButton} + + Go to support + `, }); diff --git a/src/frontend/src/components/loader.ts b/src/frontend/src/components/loader.ts index 3c781ce2aa..31c77ff87d 100644 --- a/src/frontend/src/components/loader.ts +++ b/src/frontend/src/components/loader.ts @@ -1,22 +1,40 @@ +import { ERROR_SUPPORT_URL } from "$src/config"; import { html, render } from "lit-html"; import loaderUrl from "./loader.svg"; -const loader = () => html`
- loading -
`; +// Duration in milliseconds a user considers as taking forever +const TAKING_FOREVER = 10000; + +const loader = (takingForever = false) => + html`
+ loading + ${takingForever && + html`Check ongoing issues`} +
`; const startLoader = () => { const container = document.getElementById("loaderContainer") as HTMLElement; render(loader(), container); -}; -const endLoader = () => { - const container = document.getElementById("loaderContainer") as HTMLElement; - render(html``, container); + const takingForeverTimeout = setTimeout( + () => render(loader(true), container), + TAKING_FOREVER + ); + + return () => { + clearTimeout(takingForeverTimeout); + render(html``, container); + }; }; export const withLoader = async (action: () => Promise): Promise => { - startLoader(); + const endLoader = startLoader(); try { return await action(); } finally { diff --git a/src/frontend/src/config.ts b/src/frontend/src/config.ts index 911f982dcf..6004b2f10e 100644 --- a/src/frontend/src/config.ts +++ b/src/frontend/src/config.ts @@ -10,3 +10,7 @@ export const OFFICIAL_II_URL = "https://" + OFFICIAL_II_URL_NO_PROTOCOL; export const LEGACY_II_URL = "https://identity.ic0.app"; export const PORTAL_II_URL = "https://internetcomputer.org/internet-identity"; + +// Default support page URL for when error is shown to user +export const ERROR_SUPPORT_URL = + "https://identitysupport.dfinity.org/hc/en-us/articles/32301362727188"; diff --git a/src/frontend/src/styles/main.css b/src/frontend/src/styles/main.css index 7023bfa81d..b7fc34867d 100644 --- a/src/frontend/src/styles/main.css +++ b/src/frontend/src/styles/main.css @@ -1718,12 +1718,6 @@ by all browsers (FF is missing) */ fill: currentColor; } -.c-button--secondary { - background: var(--rc-button-secondary); - color: var(--rc-onButton-secondary); - border: var(--rs-line) solid var(--rc-line-interaction); -} - .c-button--textOnly { background: transparent; color: var(--rc-interaction-text); @@ -1737,10 +1731,23 @@ by all browsers (FF is missing) */ .c-button:not([disabled]):focus, .c-button:not([disabled]):hover { + color: var(--rc-onButton); opacity: 0.9; box-shadow: 0 0 0 2px #ffffff, 0 0 3px 5px var(--rc-interaction); outline: 2px dotted transparent; outline-offset: 2px; + text-decoration: none; +} + +.c-button--secondary { + background: var(--rc-button-secondary); + color: var(--rc-onButton-secondary); + border: var(--rs-line) solid var(--rc-line-interaction); +} + +.c-button--secondary:not([disabled]):hover, +.c-button--secondary:not([disabled]):focus { + color: var(--rc-onButton-secondary); } /* Copy pasted from the focus and hover, but with different opacity to show action */ @@ -3144,6 +3151,20 @@ input[type="checkbox"] { animation-timing-function: ease-in-out; } +.c-loader__link { + color: var(--rc-surface); + display: block; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, 72px); +} + +.c-loader__link:hover, +.c-loader__link:focus { + color: var(--rc-surface); +} + /* Wrap QR codes in a white square (for legibility) and prettify a bit */ .c-qrcode canvas { display: block;