mirror of
https://github.com/zhom/donutbrowser.git
synced 2026-07-15 08:57:24 +02:00
feat: add onboarding
This commit is contained in:
@@ -28,6 +28,10 @@ export type BackendErrorCode =
|
||||
| "CANNOT_MODIFY_CLOUD_MANAGED_PROXY"
|
||||
| "SYNC_LOCKED_BY_PROFILE"
|
||||
| "SYNC_NOT_CONFIGURED"
|
||||
| "FINGERPRINT_REQUIRES_PRO"
|
||||
| "PROXY_NOT_WORKING"
|
||||
| "PROXY_PAYMENT_REQUIRED"
|
||||
| "VPN_NOT_WORKING"
|
||||
| "INTERNAL_ERROR";
|
||||
|
||||
export interface BackendError {
|
||||
@@ -120,6 +124,14 @@ export function translateBackendError(t: TFunction, err: unknown): string {
|
||||
return t("backendErrors.syncLockedByProfile");
|
||||
case "SYNC_NOT_CONFIGURED":
|
||||
return t("backendErrors.syncNotConfigured");
|
||||
case "FINGERPRINT_REQUIRES_PRO":
|
||||
return t("backendErrors.fingerprintRequiresPro");
|
||||
case "PROXY_NOT_WORKING":
|
||||
return t("backendErrors.proxyNotWorking");
|
||||
case "PROXY_PAYMENT_REQUIRED":
|
||||
return t("backendErrors.proxyPaymentRequired");
|
||||
case "VPN_NOT_WORKING":
|
||||
return t("backendErrors.vpnNotWorking");
|
||||
case "INTERNAL_ERROR":
|
||||
return t("backendErrors.internal", {
|
||||
detail: parsed.params?.detail ?? "",
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Lightweight module-level flag for whether the first-run onboarding is in
|
||||
// progress. The welcome dialog shows its own browser-setup progress, so the
|
||||
// global browser-download toasts (from use-browser-download) are suppressed
|
||||
// while this is true to avoid a competing toast during onboarding.
|
||||
let active = false;
|
||||
|
||||
export function setOnboardingActive(value: boolean): void {
|
||||
active = value;
|
||||
}
|
||||
|
||||
export function isOnboardingActive(): boolean {
|
||||
return active;
|
||||
}
|
||||
|
||||
// Dispatched on `window` when the product tour reaches its end and the user
|
||||
// clicks "Finish" (not when they skip early). The page listens for it to show
|
||||
// the celebratory thank-you dialog.
|
||||
export const ONBOARDING_TOUR_FINISHED_EVENT = "donut:onboarding-tour-finished";
|
||||
@@ -10,6 +10,9 @@ interface BaseToastProps {
|
||||
duration?: number;
|
||||
action?: ExternalToast["action"];
|
||||
onCancel?: () => void;
|
||||
// When false, the toast cannot be dismissed by the user (no swipe; combine
|
||||
// with duration: Infinity and no onCancel to make it fully non-closable).
|
||||
dismissible?: boolean;
|
||||
}
|
||||
|
||||
interface LoadingToastProps extends BaseToastProps {
|
||||
@@ -110,12 +113,13 @@ export function showToast(props: ToastProps & { id?: string }) {
|
||||
sonnerToast.custom(() => React.createElement(UnifiedToast, props), {
|
||||
id: toastId,
|
||||
duration,
|
||||
dismissible: props.dismissible,
|
||||
style: {
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
boxShadow: "none",
|
||||
padding: 0,
|
||||
zIndex: 99999,
|
||||
zIndex: 10001,
|
||||
pointerEvents: "auto",
|
||||
},
|
||||
});
|
||||
@@ -123,12 +127,13 @@ export function showToast(props: ToastProps & { id?: string }) {
|
||||
sonnerToast.custom(() => React.createElement(UnifiedToast, props), {
|
||||
id: toastId,
|
||||
duration,
|
||||
dismissible: props.dismissible,
|
||||
style: {
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
boxShadow: "none",
|
||||
padding: 0,
|
||||
zIndex: 99999,
|
||||
zIndex: 10001,
|
||||
pointerEvents: "auto",
|
||||
},
|
||||
});
|
||||
@@ -136,12 +141,13 @@ export function showToast(props: ToastProps & { id?: string }) {
|
||||
sonnerToast.custom(() => React.createElement(UnifiedToast, props), {
|
||||
id: toastId,
|
||||
duration,
|
||||
dismissible: props.dismissible,
|
||||
style: {
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
boxShadow: "none",
|
||||
padding: 0,
|
||||
zIndex: 99999,
|
||||
zIndex: 10001,
|
||||
pointerEvents: "auto",
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user