refactor: show deprecated profile names

This commit is contained in:
zhom
2025-08-12 12:18:38 +04:00
parent 69b7963dd4
commit 341a461abf
3 changed files with 35 additions and 7 deletions
+15 -5
View File
@@ -704,25 +704,35 @@ export default function Home() {
loadGroups,
]);
// Show deprecation warning for unsupported profiles
// Show deprecation warning for unsupported profiles (with names)
useEffect(() => {
if (profiles.length === 0) return;
const hasDeprecated = profiles.some(
const deprecatedProfiles = profiles.filter(
(p) =>
["tor-browser", "mullvad-browser"].includes(p.browser) ||
(p.release_type === "nightly" && p.browser !== "firefox-developer"),
);
if (hasDeprecated) {
if (deprecatedProfiles.length > 0) {
const deprecatedNames = deprecatedProfiles.map((p) => p.name).join(", ");
// Use a stable id to avoid duplicate toasts on re-renders
showToast({
id: "deprecated-profiles-warning",
type: "error",
title: "Some profiles will be deprecated soon",
description:
"Tor, Mullvad Browser and nightly profiles (except Firefox Developers Edition) will be removed in upcoming versions. Please check GitHub for migration instructions which will be available soon.",
description: `The following profiles will be deprecated soon: ${deprecatedNames}. Tor Browser, Mullvad Browser, and nightly profiles (except Firefox Developers Edition) will be removed in upcoming versions. Please check GitHub for migration instructions.`,
duration: 15000,
action: {
label: "Learn more",
onClick: () => {
const event = new CustomEvent("url-open-request", {
detail: "https://github.com/zhom/donutbrowser/discussions/66",
});
window.dispatchEvent(event);
},
},
});
}
}, [profiles]);
+18 -1
View File
@@ -55,12 +55,16 @@ import {
LuRocket,
LuTriangleAlert,
} from "react-icons/lu";
import type { ExternalToast } from "sonner";
import { Button } from "./ui/button";
import { RippleButton } from "./ui/ripple";
interface BaseToastProps {
id?: string;
title: string;
description?: string;
duration?: number;
action?: ExternalToast["action"];
}
interface LoadingToastProps extends BaseToastProps {
@@ -158,7 +162,7 @@ function getToastIcon(type: ToastProps["type"], stage?: string) {
}
export function UnifiedToast(props: ToastProps) {
const { title, description, type } = props;
const { title, description, type, action } = props;
const stage = "stage" in props ? props.stage : undefined;
const progress = "progress" in props ? props.progress : undefined;
@@ -289,6 +293,19 @@ export function UnifiedToast(props: ToastProps) {
)}
</>
)}
{action &&
"onClick" in (action as any) &&
"label" in (action as any) && (
<div className="mt-2 w-full">
<RippleButton
size="sm"
className="ml-auto"
onClick={(action as any).onClick}
>
{(action as any).label}
</RippleButton>
</div>
)}
</div>
</div>
);
+2 -1
View File
@@ -1,5 +1,5 @@
import React from "react";
import { toast as sonnerToast } from "sonner";
import { type ExternalToast, toast as sonnerToast } from "sonner";
import { UnifiedToast } from "@/components/custom-toast";
interface BaseToastProps {
@@ -7,6 +7,7 @@ interface BaseToastProps {
title: string;
description?: string;
duration?: number;
action?: ExternalToast["action"];
}
interface LoadingToastProps extends BaseToastProps {