Compare commits

...

14 Commits

Author SHA1 Message Date
zhom 0047c80967 style: make the row chart shorter 2025-11-30 21:28:19 +04:00
zhom 3d7bd2b14c chore: version bump 2025-11-30 21:25:25 +04:00
zhom 8899e58987 chore: simplify tsconfig 2025-11-30 21:18:56 +04:00
zhom acf8651bd1 refactor: fix types after dependency upgrade 2025-11-30 21:16:26 +04:00
zhom ef534ee779 chore: update major dependencies 2025-11-30 21:06:09 +04:00
zhom 75bb10cf61 chore: remove ipecho from domain checkers 2025-11-30 21:03:31 +04:00
zhom 6f9e0de633 chore: update dependencies 2025-11-30 20:59:19 +04:00
zhom 39c2a9f6f0 refactor: disable quit confirmations in browser 2025-11-30 20:59:04 +04:00
zhom 4b6f08fca3 refactor: disable more update-related settings 2025-11-30 20:44:59 +04:00
zhom 24eff75d4e chore: cleanup logs 2025-11-30 20:42:06 +04:00
zhom 11869855e9 build: make permissions more explicit 2025-11-30 20:40:34 +04:00
zhom 0d1f1f1497 refactor: suppress first-run warnings 2025-11-30 20:40:10 +04:00
zhom e8026d817f refactor: clean up old binary after installation 2025-11-30 20:39:34 +04:00
zhom d1ca4273de chore: check tag name instead of ref 2025-11-30 20:08:25 +04:00
18 changed files with 1091 additions and 1004 deletions
@@ -11,7 +11,7 @@ permissions:
jobs:
generate-release-notes:
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v') && !github.event.release.prerelease
if: startsWith(github.event.release.tag_name, 'v') && !github.event.release.prerelease
steps:
- name: Checkout repository
@@ -23,7 +23,7 @@ jobs:
id: get-previous-tag
run: |
# Get the previous release tag (excluding the current one)
CURRENT_TAG="${{ github.ref_name }}"
CURRENT_TAG="${{ github.event.release.tag_name }}"
PREVIOUS_TAG=$(git tag --sort=-version:refname | grep -E '^v[0-9]+\.[0-9]+\.[0-9]+$' | grep -v "$CURRENT_TAG" | head -n 1)
if [ -z "$PREVIOUS_TAG" ]; then
+6
View File
@@ -54,6 +54,7 @@
"esac",
"esbuild",
"etree",
"firstrun",
"flate",
"frontmost",
"geoip",
@@ -70,6 +71,7 @@
"idlelib",
"idletime",
"idna",
"infobars",
"Inno",
"kdeglobals",
"keras",
@@ -77,6 +79,7 @@
"killall",
"Kolkata",
"kreadconfig",
"langpack",
"launchservices",
"letterboxing",
"libatk",
@@ -139,6 +142,7 @@
"pyoxidizer",
"pytest",
"pyyaml",
"reportingpolicy",
"reqwest",
"ridedott",
"rlib",
@@ -149,6 +153,7 @@
"screeninfo",
"selectables",
"serde",
"sessionstore",
"setpriority",
"setsid",
"SETTINGCHANGE",
@@ -184,6 +189,7 @@
"Torbrowser",
"tqdm",
"trackingprotection",
"trailhead",
"turbopack",
"turtledemo",
"udeps",
+4 -4
View File
@@ -21,15 +21,15 @@
"author": "",
"license": "AGPL-3.0",
"dependencies": {
"@types/node": "^24.10.0",
"@types/node": "^24.10.1",
"commander": "^14.0.2",
"donutbrowser-camoufox-js": "^0.7.0",
"dotenv": "^17.2.3",
"fingerprint-generator": "^2.1.76",
"fingerprint-generator": "^2.1.77",
"get-port": "^7.1.0",
"nodemon": "^3.1.11",
"playwright-core": "^1.56.1",
"proxy-chain": "^2.5.9",
"playwright-core": "^1.57.0",
"proxy-chain": "^2.6.0",
"tmp": "^0.2.5",
"ts-node": "^10.9.2",
"typescript": "^5.9.3"
+11 -11
View File
@@ -2,7 +2,7 @@
"name": "donutbrowser",
"private": true,
"license": "AGPL-3.0",
"version": "0.13.0",
"version": "0.13.1",
"type": "module",
"scripts": {
"dev": "next dev --turbopack",
@@ -41,7 +41,7 @@
"@radix-ui/react-tabs": "^1.1.13",
"@radix-ui/react-tooltip": "^1.2.8",
"@tanstack/react-table": "^8.21.3",
"@tauri-apps/api": "^2.9.0",
"@tauri-apps/api": "^2.9.1",
"@tauri-apps/plugin-deep-link": "^2.4.5",
"@tauri-apps/plugin-dialog": "^2.4.2",
"@tauri-apps/plugin-fs": "~2.4.4",
@@ -51,17 +51,17 @@
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"color": "^5.0.2",
"color": "^5.0.3",
"flag-icons": "^7.5.0",
"lucide-react": "^0.555.0",
"motion": "^12.23.24",
"next": "^15.5.6",
"next": "^16.0.6",
"next-themes": "^0.4.6",
"radix-ui": "^1.4.3",
"react": "^19.2.0",
"react-dom": "^19.2.0",
"react-icons": "^5.5.0",
"recharts": "2.15.4",
"recharts": "3.5.1",
"sonner": "^2.0.7",
"tailwind-merge": "^3.4.0",
"tauri-plugin-macos-permissions-api": "^2.3.0"
@@ -69,14 +69,14 @@
"devDependencies": {
"@biomejs/biome": "2.2.3",
"@tailwindcss/postcss": "^4.1.17",
"@tauri-apps/cli": "^2.9.4",
"@tauri-apps/cli": "^2.9.5",
"@types/color": "^4.2.0",
"@types/node": "^24.10.0",
"@types/react": "^19.2.3",
"@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0",
"@types/node": "^24.10.1",
"@types/react": "^19.2.7",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^5.1.1",
"husky": "^9.1.7",
"lint-staged": "^16.2.6",
"lint-staged": "^16.2.7",
"tailwindcss": "^4.1.17",
"ts-unused-exports": "^11.0.1",
"tw-animate-css": "^1.4.0",
+971 -953
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1293,7 +1293,7 @@ dependencies = [
[[package]]
name = "donutbrowser"
version = "0.13.0"
version = "0.13.1"
dependencies = [
"aes-gcm",
"argon2",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "donutbrowser"
version = "0.13.0"
version = "0.13.1"
description = "Simple Yet Powerful Anti-Detect Browser"
authors = ["zhom@github"]
edition = "2021"
+9 -1
View File
@@ -5,7 +5,15 @@
"windows": ["main"],
"permissions": [
"core:default",
"core:event:default",
"core:event:allow-listen",
"core:event:allow-emit",
"core:event:allow-emit-to",
"core:event:allow-unlisten",
"core:image:default",
"core:menu:default",
"core:path:default",
"core:tray:default",
"core:webview:default",
"core:window:default",
"core:window:allow-start-dragging",
"core:window:allow-close",
-1
View File
@@ -564,7 +564,6 @@ impl ApiClient {
let cached_data: CachedGithubData = serde_json::from_str(&content).ok()?;
// Always use cached GitHub releases - cache never expires, only gets updated with new versions
log::info!("Using cached GitHub releases for {browser}");
Some(cached_data.releases)
}
+16
View File
@@ -999,6 +999,22 @@ impl AppAutoUpdater {
// Clean up backup after successful installation
let _ = fs::remove_dir_all(&backup_path);
// Clean up old "Donut Browser.app" if it exists (from before the project rename)
if let Some(parent_dir) = current_app_path.parent() {
let old_app_path = parent_dir.join("Donut Browser.app");
if old_app_path.exists() && old_app_path != current_app_path {
log::info!(
"Removing old 'Donut Browser.app' from: {}",
old_app_path.display()
);
if let Err(e) = fs::remove_dir_all(&old_app_path) {
log::warn!("Warning: Failed to remove old 'Donut Browser.app': {e}");
} else {
log::info!("Successfully removed old 'Donut Browser.app'");
}
}
}
Ok(())
}
+4
View File
@@ -737,6 +737,10 @@ impl Browser for ChromiumBrowser {
"--disable-background-timer-throttling".to_string(),
"--crash-server-url=".to_string(),
"--disable-updater".to_string(),
// Disable quit confirmation and session restore prompts
"--disable-session-crashed-bubble".to_string(),
"--hide-crash-restore-bubble".to_string(),
"--disable-infobars".to_string(),
];
// Add remote debugging if requested
+42 -11
View File
@@ -1071,7 +1071,7 @@ impl ProfileManager {
fn get_common_firefox_preferences(&self) -> Vec<String> {
vec![
// Disable default browser updates
// Disable default browser check
"user_pref(\"browser.shell.checkDefaultBrowser\", false);".to_string(),
"user_pref(\"browser.shell.skipDefaultBrowserCheckOnFirstRun\", true);".to_string(),
"user_pref(\"browser.preferences.moreFromMozilla\", false);".to_string(),
@@ -1086,27 +1086,58 @@ impl ProfileManager {
// Keep extension updates enabled
"user_pref(\"extensions.update.enabled\", true);".to_string(),
"user_pref(\"extensions.update.autoUpdateDefault\", true);".to_string(),
// Completely disable browser update checking
"user_pref(\"app.update.enabled\", false);".to_string(),
"user_pref(\"app.update.staging.enabled\", false);".to_string(),
"user_pref(\"app.update.timerFirstInterval\", -1);".to_string(),
"user_pref(\"app.update.download.maxAttempts\", 0);".to_string(),
"user_pref(\"app.update.elevate.maxAttempts\", 0);".to_string(),
"user_pref(\"app.update.disabledForTesting\", true);".to_string(),
"user_pref(\"app.update.auto\", false);".to_string(),
"user_pref(\"app.update.mode\", 0);".to_string(),
"user_pref(\"app.update.promptWaitTime\", -1);".to_string(),
"user_pref(\"app.update.service.enabled\", false);".to_string(),
"user_pref(\"app.update.staging.enabled\", false);".to_string(),
"user_pref(\"app.update.silent\", true);".to_string(),
"user_pref(\"app.update.disabledForTesting\", true);".to_string(),
// Prevent update URL access entirely
"user_pref(\"app.update.url\", \"\");".to_string(),
"user_pref(\"app.update.url.manual\", \"\");".to_string(),
"user_pref(\"app.update.url.details\", \"\");".to_string(),
// Disable update timing/scheduling
"user_pref(\"app.update.timerFirstInterval\", 999999999);".to_string(),
"user_pref(\"app.update.interval\", 999999999);".to_string(),
"user_pref(\"app.update.background.interval\", 999999999);".to_string(),
"user_pref(\"app.update.idletime\", 999999999);".to_string(),
"user_pref(\"app.update.promptWaitTime\", 999999999);".to_string(),
// Disable update attempts
"user_pref(\"app.update.download.maxAttempts\", 0);".to_string(),
"user_pref(\"app.update.elevate.maxAttempts\", 0);".to_string(),
"user_pref(\"app.update.checkInstallTime\", false);".to_string(),
"user_pref(\"app.update.interval\", -1);".to_string(),
"user_pref(\"app.update.background.interval\", -1);".to_string(),
"user_pref(\"app.update.idletime\", -1);".to_string(),
// Suppress additional update UI/prompts
// Suppress update UI/prompts/notifications
"user_pref(\"app.update.doorhanger\", false);".to_string(),
"user_pref(\"app.update.badge\", false);".to_string(),
"user_pref(\"app.update.notifyDuringDownload\", false);".to_string(),
"user_pref(\"app.update.background.scheduling.enabled\", false);".to_string(),
"user_pref(\"app.update.background.enabled\", false);".to_string(),
// Disable BITS (Windows Background Intelligent Transfer Service) updates
"user_pref(\"app.update.BITS.enabled\", false);".to_string(),
// Disable language pack updates
"user_pref(\"app.update.langpack.enabled\", false);".to_string(),
// Suppress upgrade dialogs on startup
"user_pref(\"browser.startup.upgradeDialog.enabled\", false);".to_string(),
// Disable update ping telemetry
"user_pref(\"toolkit.telemetry.updatePing.enabled\", false);".to_string(),
// Zen browser specific - disable welcome screen and updates
"user_pref(\"zen.welcome-screen.seen\", true);".to_string(),
"user_pref(\"zen.updates.enabled\", false);".to_string(),
"user_pref(\"zen.updates.check-for-updates\", false);".to_string(),
// Additional first-run suppressions
"user_pref(\"app.normandy.first_run\", false);".to_string(),
"user_pref(\"trailhead.firstrun.didSeeAboutWelcome\", true);".to_string(),
"user_pref(\"datareporting.policy.dataSubmissionPolicyBypassNotification\", true);"
.to_string(),
"user_pref(\"toolkit.telemetry.reportingpolicy.firstRun\", false);".to_string(),
// Disable quit confirmation dialogs
"user_pref(\"browser.warnOnQuit\", false);".to_string(),
"user_pref(\"browser.showQuitWarning\", false);".to_string(),
"user_pref(\"browser.tabs.warnOnClose\", false);".to_string(),
"user_pref(\"browser.tabs.warnOnCloseOtherTabs\", false);".to_string(),
"user_pref(\"browser.sessionstore.warnOnQuit\", false);".to_string(),
]
}
-1
View File
@@ -491,7 +491,6 @@ impl ProxyManager {
"https://ipinfo.io/ip",
"https://icanhazip.com",
"https://ifconfig.co/ip",
"https://ipecho.net/plain",
];
// Create HTTP client with proxy
+1 -1
View File
@@ -1,7 +1,7 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Donut",
"version": "0.13.0",
"version": "0.13.1",
"identifier": "com.donutbrowser",
"build": {
"beforeDevCommand": "pnpm copy-proxy-binary && pnpm dev",
+1 -1
View File
@@ -69,7 +69,7 @@ export function BandwidthMiniChart({
type="button"
onClick={onClick}
className={cn(
"relative flex items-center gap-1.5 px-2 rounded cursor-pointer hover:bg-accent/50 transition-colors min-w-[130px] border-none bg-transparent",
"relative flex items-center gap-1.5 px-2 rounded cursor-pointer hover:bg-accent/50 transition-colors min-w-[120px] border-none bg-transparent",
className,
)}
>
+2 -6
View File
@@ -2,7 +2,6 @@
import { invoke } from "@tauri-apps/api/core";
import * as React from "react";
import type { TooltipProps } from "recharts";
import {
Area,
AreaChart,
@@ -12,10 +11,7 @@ import {
XAxis,
YAxis,
} from "recharts";
import type {
NameType,
ValueType,
} from "recharts/types/component/DefaultTooltipContent";
import type { TooltipContentProps } from "recharts/types/component/Tooltip";
import {
Dialog,
DialogContent,
@@ -140,7 +136,7 @@ export function TrafficDetailsDialog({
// Tooltip render function
const renderTooltip = React.useCallback(
(props: TooltipProps<ValueType, NameType>) => {
(props: TooltipContentProps<number, string>) => {
const { active, payload, label } = props;
if (!active || !payload?.length) return null;
+16 -8
View File
@@ -2,6 +2,12 @@
import * as React from "react";
import * as RechartsPrimitive from "recharts";
import type {
Props as DefaultLegendContentProps,
LegendPayload,
} from "recharts/types/component/DefaultLegendContent";
import type { Payload } from "recharts/types/component/DefaultTooltipContent";
import type { TooltipContentProps } from "recharts/types/component/Tooltip";
import { cn } from "@/lib/utils";
@@ -105,13 +111,15 @@ const ChartTooltip = RechartsPrimitive.Tooltip;
const ChartTooltipContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<typeof RechartsPrimitive.Tooltip> &
TooltipContentProps<number, string> &
React.ComponentProps<"div"> & {
hideLabel?: boolean;
hideIndicator?: boolean;
indicator?: "line" | "dot" | "dashed";
nameKey?: string;
labelKey?: string;
labelClassName?: string;
color?: string;
}
>(
(
@@ -187,15 +195,15 @@ const ChartTooltipContent = React.forwardRef<
{!nestLabel ? tooltipLabel : null}
<div className="grid gap-1.5">
{payload
.filter((item) => item.type !== "none")
.map((item, index) => {
.filter((item: Payload<number, string>) => item.type !== "none")
.map((item: Payload<number, string>, index: number) => {
const key = `${nameKey || item.name || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
const indicatorColor = color || item.payload.fill || item.color;
const indicatorColor = color || item.payload?.fill || item.color;
return (
<div
key={item.dataKey}
key={String(item.dataKey ?? index)}
className={cn(
"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground",
indicator === "dot" && "items-center",
@@ -264,7 +272,7 @@ const ChartLegend = RechartsPrimitive.Legend;
const ChartLegendContent = React.forwardRef<
HTMLDivElement,
React.ComponentProps<"div"> &
Pick<RechartsPrimitive.LegendProps, "payload" | "verticalAlign"> & {
Pick<DefaultLegendContentProps, "payload" | "verticalAlign"> & {
hideIcon?: boolean;
nameKey?: string;
}
@@ -289,8 +297,8 @@ const ChartLegendContent = React.forwardRef<
)}
>
{payload
.filter((item) => item.type !== "none")
.map((item) => {
.filter((item: LegendPayload) => item.type !== "none")
.map((item: LegendPayload) => {
const key = `${nameKey || item.dataKey || "value"}`;
const itemConfig = getPayloadConfigFromPayload(config, item, key);
+4 -2
View File
@@ -13,7 +13,7 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"plugins": [
{
@@ -29,7 +29,9 @@
"**/*.tsx",
".next/types/**/*.ts",
"next-env.d.ts",
"dist/types/**/*.ts"
"dist/types/**/*.ts",
".next/dev/types/**/*.ts",
"dist/dev/types/**/*.ts"
],
"exclude": ["node_modules", "nodecar", "src-tauri/target"]
}