summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-08-15 10:20:29 +0200
committerTobias Järvelöv <tobias.jarvelov@mullvad.net>2025-08-15 10:20:29 +0200
commit5eb54c409647ff43b807617df0486d5a70603f51 (patch)
tree8519858a9685221618b877e24af52780f1b43867
parent04cf484cf9d0f4f5449393a2483c974ef5c1508a (diff)
parent0a8fcda430f58d09d5455a70a7b023ed54eefcdb (diff)
downloadmullvadvpn-5eb54c409647ff43b807617df0486d5a70603f51.tar.xz
mullvadvpn-5eb54c409647ff43b807617df0486d5a70603f51.zip
Merge branch 'upgrade-to-react-19-des-1287'
-rw-r--r--desktop/package-lock.json344
-rw-r--r--desktop/packages/mullvad-vpn/package.json14
-rw-r--r--desktop/packages/mullvad-vpn/src/main/windows-pe-parser.ts4
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/app.tsx42
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Account.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/AriaGroup.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ErrorBoundary.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Focus.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/KeyboardNavigation.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/List.tsx10
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/MacOsScrollbarDetection.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Map.tsx32
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx11
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/NavigationScrollbars.tsx12
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx9
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/ProxyForm.tsx15
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx10
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/cell/Input.tsx10
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsForm.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsSelect.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsTextInput.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx5
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/ScrollPositionContext.tsx6
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/components/select-location/SpacePreAllocationView.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/api-access-methods.ts2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/history.tsx2
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/transition-hooks.ts7
-rw-r--r--desktop/packages/mullvad-vpn/src/renderer/lib/utility-hooks.ts6
31 files changed, 379 insertions, 215 deletions
diff --git a/desktop/package-lock.json b/desktop/package-lock.json
index 5e463aaded..728fb2c2ca 100644
--- a/desktop/package-lock.json
+++ b/desktop/package-lock.json
@@ -2904,15 +2904,6 @@
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
"dev": true
},
- "node_modules/@types/hoist-non-react-statics": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
- "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
- "dependencies": {
- "@types/react": "*",
- "hoist-non-react-statics": "^3.3.0"
- }
- },
"node_modules/@types/http-cache-semantics": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@@ -2986,38 +2977,24 @@
"xmlbuilder": ">=11.0.1"
}
},
- "node_modules/@types/prop-types": {
- "version": "15.7.3",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
- "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
- },
"node_modules/@types/react": {
- "version": "18.3.3",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
- "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
+ "version": "19.1.9",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz",
+ "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==",
+ "devOptional": true,
+ "license": "MIT",
"dependencies": {
- "@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"node_modules/@types/react-dom": {
- "version": "18.3.0",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
- "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
+ "version": "19.1.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz",
+ "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
"dev": true,
- "dependencies": {
- "@types/react": "*"
- }
- },
- "node_modules/@types/react-redux": {
- "version": "7.1.24",
- "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
- "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
- "dependencies": {
- "@types/hoist-non-react-statics": "^3.3.0",
- "@types/react": "*",
- "hoist-non-react-statics": "^3.3.0",
- "redux": "^4.0.0"
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "^19.0.0"
}
},
"node_modules/@types/react-router": {
@@ -3074,6 +3051,12 @@
"@types/geojson": "*"
}
},
+ "node_modules/@types/use-sync-external-store": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
+ "license": "MIT"
+ },
"node_modules/@types/verror": {
"version": "1.10.11",
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
@@ -5402,15 +5385,16 @@
}
},
"node_modules/eslint-plugin-react-compiler": {
- "version": "0.0.0-experimental-42acc6a-20241001",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-0.0.0-experimental-42acc6a-20241001.tgz",
- "integrity": "sha512-pzkTsWowlHK4yKHsK1d9tTKOUtApZzL7wI6jT5iN31d00DhI9JGDD0pkLohQ6Wfkll+2aiqTPGj9esJoGYmRaw==",
+ "version": "19.1.0-rc.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.1.0-rc.2.tgz",
+ "integrity": "sha512-oKalwDGcD+RX9mf3NEO4zOoUMeLvjSvcbbEOpquzmzqEEM2MQdp7/FY/Hx9NzmUwFzH1W9SKTz5fihfMldpEYw==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@babel/core": "^7.24.4",
"@babel/parser": "^7.24.4",
"@babel/plugin-proposal-private-methods": "^7.18.6",
- "hermes-parser": "^0.20.1",
+ "hermes-parser": "^0.25.1",
"zod": "^3.22.4",
"zod-validation-error": "^3.0.3"
},
@@ -5422,10 +5406,11 @@
}
},
"node_modules/eslint-plugin-react-hooks": {
- "version": "0.0.0-experimental-2d16326d-20240930",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-0.0.0-experimental-2d16326d-20240930.tgz",
- "integrity": "sha512-6SrTdUGjhhQ51U6a695UlDFzR46pFlhz0yYyLrO5f4pXGHA0aE9X0TrqcB1gPyqB7LhSKjDSaoHC5/J48GG2UQ==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=10"
},
@@ -6513,18 +6498,20 @@
}
},
"node_modules/hermes-estree": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz",
- "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==",
- "dev": true
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
+ "dev": true,
+ "license": "MIT"
},
"node_modules/hermes-parser": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz",
- "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
"dev": true,
+ "license": "MIT",
"dependencies": {
- "hermes-estree": "0.20.1"
+ "hermes-estree": "0.25.1"
}
},
"node_modules/hoist-non-react-statics": {
@@ -8998,6 +8985,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
},
@@ -9009,6 +8997,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -9023,34 +9012,28 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"node_modules/react-redux": {
- "version": "7.2.9",
- "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
- "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
+ "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
+ "license": "MIT",
"dependencies": {
- "@babel/runtime": "^7.15.4",
- "@types/react-redux": "^7.1.20",
- "hoist-non-react-statics": "^3.3.2",
- "loose-envify": "^1.4.0",
- "prop-types": "^15.7.2",
- "react-is": "^17.0.2"
+ "@types/use-sync-external-store": "^0.0.6",
+ "use-sync-external-store": "^1.4.0"
},
"peerDependencies": {
- "react": "^16.8.3 || ^17 || ^18"
+ "@types/react": "^18.2.25 || ^19",
+ "react": "^18.0 || ^19",
+ "redux": "^5.0.0"
},
"peerDependenciesMeta": {
- "react-dom": {
+ "@types/react": {
"optional": true
},
- "react-native": {
+ "redux": {
"optional": true
}
}
},
- "node_modules/react-redux/node_modules/react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
- },
"node_modules/react-refresh": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.17.0.tgz",
@@ -9163,12 +9146,12 @@
"dev": true
},
"node_modules/redux": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz",
- "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==",
- "dependencies": {
- "@babel/runtime": "^7.9.2"
- }
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
+ "license": "MIT",
+ "optional": true,
+ "peer": true
},
"node_modules/reflect.getprototypeof": {
"version": "1.0.6",
@@ -9556,6 +9539,7 @@
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -10720,6 +10704,15 @@
"punycode": "^2.1.0"
}
},
+ "node_modules/use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/utf8-byte-length": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
@@ -11327,9 +11320,9 @@
"management-interface": "0.0.0",
"node-gettext": "^3.0.0",
"nseventforwarder": "0.0.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
- "react-redux": "^7.2.9",
+ "react": "^19.1.1",
+ "react-dom": "^19.1.1",
+ "react-redux": "^9.2.0",
"react-router": "^5.3.4",
"redux": "^4.2.0",
"simple-plist": "^1.3.1",
@@ -11347,8 +11340,8 @@
"@types/history": "^4.7.11",
"@types/mocha": "^10.0.0",
"@types/node-gettext": "^3.0.3",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
+ "@types/react": "^19.1.9",
+ "@types/react-dom": "^19.1.7",
"@types/react-router": "^5.1.19",
"@types/sinon": "^10.0.13",
"@types/sprintf-js": "^1.1.2",
@@ -11362,8 +11355,8 @@
"electron-builder": "26.0.18",
"electron-devtools-installer": "^3.2.0",
"eslint-plugin-react": "^7.36.1",
- "eslint-plugin-react-compiler": "^0.0.0-experimental-42acc6a-20241001",
- "eslint-plugin-react-hooks": "^0.0.0-experimental-2d16326d-20240930",
+ "eslint-plugin-react-compiler": "^19.1.0-rc.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"gettext-extractor": "^3.5.4",
"globals": "^15.9.0",
"mocha": "^10.8.2",
@@ -11621,6 +11614,42 @@
"dev": true,
"license": "MIT"
},
+ "packages/mullvad-vpn/node_modules/react": {
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
+ "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "packages/mullvad-vpn/node_modules/react-dom": {
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
+ "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
+ "license": "MIT",
+ "dependencies": {
+ "scheduler": "^0.26.0"
+ },
+ "peerDependencies": {
+ "react": "^19.1.1"
+ }
+ },
+ "packages/mullvad-vpn/node_modules/redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "packages/mullvad-vpn/node_modules/scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
+ "license": "MIT"
+ },
"packages/mullvad-vpn/node_modules/which": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
@@ -13576,15 +13605,6 @@
"integrity": "sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==",
"dev": true
},
- "@types/hoist-non-react-statics": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz",
- "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==",
- "requires": {
- "@types/react": "*",
- "hoist-non-react-statics": "^3.3.0"
- }
- },
"@types/http-cache-semantics": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz",
@@ -13655,39 +13675,21 @@
"xmlbuilder": ">=11.0.1"
}
},
- "@types/prop-types": {
- "version": "15.7.3",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
- "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
- },
"@types/react": {
- "version": "18.3.3",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz",
- "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==",
+ "version": "19.1.9",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.9.tgz",
+ "integrity": "sha512-WmdoynAX8Stew/36uTSVMcLJJ1KRh6L3IZRx1PZ7qJtBqT3dYTgyDTx8H1qoRghErydW7xw9mSJ3wS//tCRpFA==",
+ "devOptional": true,
"requires": {
- "@types/prop-types": "*",
"csstype": "^3.0.2"
}
},
"@types/react-dom": {
- "version": "18.3.0",
- "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
- "integrity": "sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==",
+ "version": "19.1.7",
+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz",
+ "integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
"dev": true,
- "requires": {
- "@types/react": "*"
- }
- },
- "@types/react-redux": {
- "version": "7.1.24",
- "resolved": "https://registry.npmjs.org/@types/react-redux/-/react-redux-7.1.24.tgz",
- "integrity": "sha512-7FkurKcS1k0FHZEtdbbgN8Oc6b+stGSfZYjQGicofJ0j4U0qIn/jaSvnP2pLwZKiai3/17xqqxkkrxTgN8UNbQ==",
- "requires": {
- "@types/hoist-non-react-statics": "^3.3.0",
- "@types/react": "*",
- "hoist-non-react-statics": "^3.3.0",
- "redux": "^4.0.0"
- }
+ "requires": {}
},
"@types/react-router": {
"version": "5.1.19",
@@ -13743,6 +13745,11 @@
"@types/geojson": "*"
}
},
+ "@types/use-sync-external-store": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg=="
+ },
"@types/verror": {
"version": "1.10.11",
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
@@ -15437,23 +15444,23 @@
}
},
"eslint-plugin-react-compiler": {
- "version": "0.0.0-experimental-42acc6a-20241001",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-0.0.0-experimental-42acc6a-20241001.tgz",
- "integrity": "sha512-pzkTsWowlHK4yKHsK1d9tTKOUtApZzL7wI6jT5iN31d00DhI9JGDD0pkLohQ6Wfkll+2aiqTPGj9esJoGYmRaw==",
+ "version": "19.1.0-rc.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-compiler/-/eslint-plugin-react-compiler-19.1.0-rc.2.tgz",
+ "integrity": "sha512-oKalwDGcD+RX9mf3NEO4zOoUMeLvjSvcbbEOpquzmzqEEM2MQdp7/FY/Hx9NzmUwFzH1W9SKTz5fihfMldpEYw==",
"dev": true,
"requires": {
"@babel/core": "^7.24.4",
"@babel/parser": "^7.24.4",
"@babel/plugin-proposal-private-methods": "^7.18.6",
- "hermes-parser": "^0.20.1",
+ "hermes-parser": "^0.25.1",
"zod": "^3.22.4",
"zod-validation-error": "^3.0.3"
}
},
"eslint-plugin-react-hooks": {
- "version": "0.0.0-experimental-2d16326d-20240930",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-0.0.0-experimental-2d16326d-20240930.tgz",
- "integrity": "sha512-6SrTdUGjhhQ51U6a695UlDFzR46pFlhz0yYyLrO5f4pXGHA0aE9X0TrqcB1gPyqB7LhSKjDSaoHC5/J48GG2UQ==",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz",
+ "integrity": "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==",
"dev": true,
"requires": {}
},
@@ -16159,18 +16166,18 @@
"dev": true
},
"hermes-estree": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.20.1.tgz",
- "integrity": "sha512-SQpZK4BzR48kuOg0v4pb3EAGNclzIlqMj3Opu/mu7bbAoFw6oig6cEt/RAi0zTFW/iW6Iz9X9ggGuZTAZ/yZHg==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz",
+ "integrity": "sha512-0wUoCcLp+5Ev5pDW2OriHC2MJCbwLwuRx+gAqMTOkGKJJiBCLjtrvy4PWUGn6MIVefecRpzoOZ/UV6iGdOr+Cw==",
"dev": true
},
"hermes-parser": {
- "version": "0.20.1",
- "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.20.1.tgz",
- "integrity": "sha512-BL5P83cwCogI8D7rrDCgsFY0tdYUtmFP9XaXtl2IQjC+2Xo+4okjfXintlTxcIwl4qeGddEl28Z11kbVIw0aNA==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/hermes-parser/-/hermes-parser-0.25.1.tgz",
+ "integrity": "sha512-6pEjquH3rqaI6cYAXYPcz9MS4rY6R4ngRgrgfDshRptUZIc3lw0MCIJIGDj9++mfySOuPTHB4nrSW99BCvOPIA==",
"dev": true,
"requires": {
- "hermes-estree": "0.20.1"
+ "hermes-estree": "0.25.1"
}
},
"hoist-non-react-statics": {
@@ -17393,8 +17400,8 @@
"@types/history": "^4.7.11",
"@types/mocha": "^10.0.0",
"@types/node-gettext": "^3.0.3",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
+ "@types/react": "^19.1.9",
+ "@types/react-dom": "^19.1.7",
"@types/react-router": "^5.1.19",
"@types/sinon": "^10.0.13",
"@types/sprintf-js": "^1.1.2",
@@ -17409,8 +17416,8 @@
"electron-builder": "26.0.18",
"electron-devtools-installer": "^3.2.0",
"eslint-plugin-react": "^7.36.1",
- "eslint-plugin-react-compiler": "^0.0.0-experimental-42acc6a-20241001",
- "eslint-plugin-react-hooks": "^0.0.0-experimental-2d16326d-20240930",
+ "eslint-plugin-react-compiler": "^19.1.0-rc.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"gettext-extractor": "^3.5.4",
"gettext-parser": "^6.0.0",
"gl-matrix": "^3.4.3",
@@ -17422,9 +17429,9 @@
"nseventforwarder": "0.0.0",
"playwright": "^1.41.1",
"postject": "^1.0.0-alpha.6",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
- "react-redux": "^7.2.9",
+ "react": "^19.1.1",
+ "react-dom": "^19.1.1",
+ "react-redux": "^9.2.0",
"react-router": "^5.3.4",
"redux": "^4.2.0",
"simple-plist": "^1.3.1",
@@ -17620,6 +17627,32 @@
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"dev": true
},
+ "react": {
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
+ "integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ=="
+ },
+ "react-dom": {
+ "version": "19.1.1",
+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.1.tgz",
+ "integrity": "sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==",
+ "requires": {
+ "scheduler": "^0.26.0"
+ }
+ },
+ "redux": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz",
+ "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==",
+ "requires": {
+ "@babel/runtime": "^7.9.2"
+ }
+ },
+ "scheduler": {
+ "version": "0.26.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="
+ },
"which": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz",
@@ -18179,6 +18212,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz",
"integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
+ "peer": true,
"requires": {
"loose-envify": "^1.1.0"
}
@@ -18187,6 +18221,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "peer": true,
"requires": {
"loose-envify": "^1.1.0",
"scheduler": "^0.23.2"
@@ -18198,23 +18233,12 @@
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
},
"react-redux": {
- "version": "7.2.9",
- "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz",
- "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==",
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
+ "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
"requires": {
- "@babel/runtime": "^7.15.4",
- "@types/react-redux": "^7.1.20",
- "hoist-non-react-statics": "^3.3.2",
- "loose-envify": "^1.4.0",
- "prop-types": "^15.7.2",
- "react-is": "^17.0.2"
- },
- "dependencies": {
- "react-is": {
- "version": "17.0.2",
- "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
- "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
- }
+ "@types/use-sync-external-store": "^0.0.6",
+ "use-sync-external-store": "^1.4.0"
}
},
"react-refresh": {
@@ -18314,12 +18338,11 @@
}
},
"redux": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz",
- "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==",
- "requires": {
- "@babel/runtime": "^7.9.2"
- }
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
+ "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
+ "optional": true,
+ "peer": true
},
"reflect.getprototypeof": {
"version": "1.0.6",
@@ -18578,6 +18601,7 @@
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "peer": true,
"requires": {
"loose-envify": "^1.1.0"
}
@@ -19397,6 +19421,12 @@
"punycode": "^2.1.0"
}
},
+ "use-sync-external-store": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
+ "requires": {}
+ },
"utf8-byte-length": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
diff --git a/desktop/packages/mullvad-vpn/package.json b/desktop/packages/mullvad-vpn/package.json
index 1ba5754669..10d115feda 100644
--- a/desktop/packages/mullvad-vpn/package.json
+++ b/desktop/packages/mullvad-vpn/package.json
@@ -20,9 +20,9 @@
"management-interface": "0.0.0",
"node-gettext": "^3.0.0",
"nseventforwarder": "0.0.0",
- "react": "^18.3.1",
- "react-dom": "^18.3.1",
- "react-redux": "^7.2.9",
+ "react": "^19.1.1",
+ "react-dom": "^19.1.1",
+ "react-redux": "^9.2.0",
"react-router": "^5.3.4",
"redux": "^4.2.0",
"simple-plist": "^1.3.1",
@@ -40,8 +40,8 @@
"@types/history": "^4.7.11",
"@types/mocha": "^10.0.0",
"@types/node-gettext": "^3.0.3",
- "@types/react": "^18.3.3",
- "@types/react-dom": "^18.3.0",
+ "@types/react": "^19.1.9",
+ "@types/react-dom": "^19.1.7",
"@types/react-router": "^5.1.19",
"@types/sinon": "^10.0.13",
"@types/sprintf-js": "^1.1.2",
@@ -55,8 +55,8 @@
"electron-builder": "26.0.18",
"electron-devtools-installer": "^3.2.0",
"eslint-plugin-react": "^7.36.1",
- "eslint-plugin-react-compiler": "^0.0.0-experimental-42acc6a-20241001",
- "eslint-plugin-react-hooks": "^0.0.0-experimental-2d16326d-20240930",
+ "eslint-plugin-react-compiler": "^19.1.0-rc.2",
+ "eslint-plugin-react-hooks": "^5.2.0",
"gettext-extractor": "^3.5.4",
"globals": "^15.9.0",
"mocha": "^10.8.2",
diff --git a/desktop/packages/mullvad-vpn/src/main/windows-pe-parser.ts b/desktop/packages/mullvad-vpn/src/main/windows-pe-parser.ts
index f4d6ebc852..fbc670e128 100644
--- a/desktop/packages/mullvad-vpn/src/main/windows-pe-parser.ts
+++ b/desktop/packages/mullvad-vpn/src/main/windows-pe-parser.ts
@@ -150,7 +150,7 @@ export class ArrayValue<T extends ArrayWrapper = ArrayWrapper> extends Value<T>
const datatype = this.datatype.array[0];
const itemSize = Value.sizeOf(datatype);
const offset = index * itemSize;
- const buffer = this.buffer.slice(offset, offset + itemSize);
+ const buffer = this.buffer.subarray(offset, offset + itemSize);
return this.createNew(buffer, datatype, offset) as U;
}
@@ -172,7 +172,7 @@ export class StructValue<T extends StructWrapper = StructWrapper> extends Value<
const slicedType = { struct: this.datatype.struct.slice(0, index) };
const offset = Value.sizeOf(slicedType);
const size = Value.sizeOf(datatype);
- const buffer = this.buffer.slice(offset, offset + size);
+ const buffer = this.buffer.subarray(offset, offset + size);
return this.createNew(buffer, datatype, offset) as U;
}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/app.tsx b/desktop/packages/mullvad-vpn/src/renderer/app.tsx
index 368654e475..44ee6d8084 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/app.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/app.tsx
@@ -1,5 +1,5 @@
import { StrictMode } from 'react';
-import { batch, Provider } from 'react-redux';
+import { Provider } from 'react-redux';
import { Router } from 'react-router';
import { bindActionCreators } from 'redux';
import { StyleSheetManager } from 'styled-components';
@@ -920,32 +920,30 @@ export default class AppRenderer {
this.tunnelState = tunnelState;
- batch(() => {
- switch (tunnelState.state) {
- case 'connecting':
- actions.connection.connecting(tunnelState.details, tunnelState.featureIndicators);
- break;
+ switch (tunnelState.state) {
+ case 'connecting':
+ actions.connection.connecting(tunnelState.details, tunnelState.featureIndicators);
+ break;
- case 'connected':
- actions.connection.connected(tunnelState.details, tunnelState.featureIndicators);
- break;
+ case 'connected':
+ actions.connection.connected(tunnelState.details, tunnelState.featureIndicators);
+ break;
- case 'disconnecting':
- actions.connection.disconnecting(tunnelState.details);
- break;
+ case 'disconnecting':
+ actions.connection.disconnecting(tunnelState.details);
+ break;
- case 'disconnected':
- actions.connection.disconnected(tunnelState.lockedDown);
- break;
+ case 'disconnected':
+ actions.connection.disconnected(tunnelState.lockedDown);
+ break;
- case 'error':
- actions.connection.blocked(tunnelState.details);
- break;
- }
+ case 'error':
+ actions.connection.blocked(tunnelState.details);
+ break;
+ }
- // Update the location when entering a new tunnel state since it's likely changed.
- this.updateLocation();
- });
+ // Update the location when entering a new tunnel state since it's likely changed.
+ this.updateLocation();
}
private setSettings(newSettings: ISettings) {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Account.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Account.tsx
index f932139a2b..b7c1f2354a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Account.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Account.tsx
@@ -37,6 +37,11 @@ export default function Account() {
});
const onMount = useEffectEvent(() => updateAccountData());
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => onMount(), []);
// Hack needed because if we just call `logout` directly in `onClick`
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/AriaGroup.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/AriaGroup.tsx
index 184971b562..59536e6109 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/AriaGroup.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/AriaGroup.tsx
@@ -78,7 +78,7 @@ export function AriaInputGroup(props: IAriaGroupProps) {
}
interface IAriaElementProps {
- children: React.ReactElement;
+ children: React.ReactElement<React.LabelHTMLAttributes<HTMLLabelElement>>;
}
export function AriaInput(props: IAriaElementProps) {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ErrorBoundary.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ErrorBoundary.tsx
index 84425471cf..b289f2cd75 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ErrorBoundary.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ErrorBoundary.tsx
@@ -40,7 +40,7 @@ export default class ErrorBoundary extends React.Component<IProps, IState> {
messages
.pgettext('error-boundary-view', 'Something went wrong. Please contact us at %(email)s')
.split('%(email)s', 2);
- reachBackMessage.splice(1, 0, <Email>{strings.supportEmail}</Email>);
+ void reachBackMessage.splice(1, 0, <Email>{strings.supportEmail}</Email>);
return <ErrorView settingsUnavailable>{reachBackMessage}</ErrorView>;
} else {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Focus.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Focus.tsx
index c29cbe653e..116c2ccb11 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Focus.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Focus.tsx
@@ -66,7 +66,7 @@ function Focus(props: IFocusProps, ref: React.Ref<IFocusHandle>) {
export default React.memo(React.forwardRef(Focus));
interface IFocusFallbackProps {
- children: React.ReactElement;
+ children: React.ReactElement<React.HTMLAttributes<HTMLElement>>;
}
export function FocusFallback(props: IFocusFallbackProps) {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/KeyboardNavigation.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/KeyboardNavigation.tsx
index 2dff95ec5d..79fde5e536 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/KeyboardNavigation.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/KeyboardNavigation.tsx
@@ -129,6 +129,11 @@ function BackActionTracker(props: IBackActionTracker) {
props.registerBackAction(backActions.at(0));
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => registerBackActionEvent(backActions), [backActions]);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/List.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/List.tsx
index 4961855fba..3773b563e2 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/List.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/List.tsx
@@ -53,6 +53,11 @@ export default function List<T>(props: ListProps<T>) {
});
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => itemChangeEvent(props.items), [props.items]);
useEffect(() => {
@@ -79,6 +84,11 @@ export default function List<T>(props: ListProps<T>) {
});
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => handleDisplayItemsChange(displayItems), [displayItems]);
useEffect(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/MacOsScrollbarDetection.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/MacOsScrollbarDetection.tsx
index 520b6f3f3b..0e862b7be5 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/MacOsScrollbarDetection.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/MacOsScrollbarDetection.tsx
@@ -35,6 +35,11 @@ export default function MacOsScrollbarDetection() {
}
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => detectVisibility(visibility), [visibility]);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Map.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Map.tsx
index c4df7ebbbe..a8e41e8078 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Map.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Map.tsx
@@ -34,9 +34,12 @@ export default function Map() {
const hasLocationValue = hasLocation(connection);
const location = useMemo<Coordinate | undefined>(() => {
- return hasLocationValue ? connection : defaultLocation;
- // eslint-disable-next-line react-compiler/react-compiler
- // eslint-disable-next-line react-hooks/exhaustive-deps
+ return hasLocationValue
+ ? {
+ latitude: connection.latitude,
+ longitude: connection.longitude,
+ }
+ : defaultLocation;
}, [hasLocationValue, connection.longitude, connection.latitude]);
if (window.env.e2e) {
@@ -84,19 +87,17 @@ function MapInner(props: MapInnerProps) {
const { getMapData } = useAppContext();
// When location or connection state changes it's stored here until passed to 3dmap
- const newParams = useRef<MapParams>();
+ const newParams = useRef<MapParams>(undefined);
// This is set to true when rendering should be paused
const pause = useRef<boolean>(false);
- const mapRef = useRef<GlMap>();
- const canvasRef = useRef<HTMLCanvasElement>();
+ const mapRef = useRef<GlMap>(undefined);
+ const canvasRef = useRef<HTMLCanvasElement>(undefined);
- // eslint-disable-next-line react-compiler/react-compiler
const width = applyPixelRatio(canvasRef.current?.clientWidth ?? window.innerWidth);
// This constant is used for the height the first frame that is rendered only.
- // eslint-disable-next-line react-compiler/react-compiler
const height = applyPixelRatio(canvasRef.current?.clientHeight ?? 493);
// Hack to rerender when window size changes or when ref is set.
@@ -125,6 +126,11 @@ function MapInner(props: MapInnerProps) {
}
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
const render = useCallback(() => requestAnimationFrame(animationFrameCallback), []);
// This is called when the canvas has been rendered the first time and initializes the gl context
@@ -171,11 +177,21 @@ function MapInner(props: MapInnerProps) {
useEffect(() => {
addEventListener('resize', onSizeChange);
return () => removeEventListener('resize', onSizeChange);
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
const unsubscribe = window.ipc.window.listenScaleFactorChange(onSizeChange);
return () => unsubscribe();
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const devicePixelRatio = window.devicePixelRatio;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
index ba2077ec03..85b73fa82a 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/Modal.tsx
@@ -55,7 +55,7 @@ interface IModalContainerProps {
interface IModalContext {
activeModal: boolean;
setActiveModal: (value: boolean) => void;
- previousActiveElement: React.MutableRefObject<HTMLElement | undefined>;
+ previousActiveElement: React.RefObject<HTMLElement | undefined>;
}
const noActiveModalContextError = new Error('ActiveModalContext.Provider missing');
@@ -66,14 +66,14 @@ const ActiveModalContext = React.createContext<IModalContext>({
setActiveModal(_value) {
throw noActiveModalContextError;
},
- get previousActiveElement(): React.MutableRefObject<HTMLElement | undefined> {
+ get previousActiveElement(): React.RefObject<HTMLElement | undefined> {
throw noActiveModalContextError;
},
});
export function ModalContainer(props: IModalContainerProps) {
const [activeModal, setActiveModal] = useState(false);
- const previousActiveElement = useRef<HTMLElement>();
+ const previousActiveElement = useRef<HTMLElement>(undefined);
const contextValue = useMemo(
() => ({
@@ -193,6 +193,11 @@ export function ModalAlert(props: IModalAlertProps & { isOpen: boolean }) {
}));
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => onOpenStateChange(isOpen), [isOpen]);
if (!openState.wasOpen && !isOpen && !openState.isClosing) {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/NavigationScrollbars.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/NavigationScrollbars.tsx
index 0c088674aa..8aadf5b1c6 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/NavigationScrollbars.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/NavigationScrollbars.tsx
@@ -21,7 +21,7 @@ export const NavigationScrollbars = React.forwardRef(function NavigationScrollba
const { setNavigationHistory } = useAppContext();
const { onScroll } = useContext(NavigationScrollContext);
- const ref = useRef<CustomScrollbarsRef>();
+ const ref = useRef<CustomScrollbarsRef>(undefined);
const combinedRefs = useCombinedRefs(forwardedRef, ref);
const beforeunload = useEffectEvent(() => {
@@ -34,6 +34,11 @@ export const NavigationScrollbars = React.forwardRef(function NavigationScrollba
useEffect(() => {
window.addEventListener('beforeunload', beforeunload);
return () => window.removeEventListener('beforeunload', beforeunload);
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const onMount = useEffectEvent(() => {
@@ -53,6 +58,11 @@ export const NavigationScrollbars = React.forwardRef(function NavigationScrollba
useLayoutEffect(() => {
onMount();
return () => onUnmount();
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const handleScroll = useCallback(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
index e2adf4d10f..83e6efb322 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ProblemReport.tsx
@@ -231,7 +231,7 @@ function Sent() {
messages
.pgettext('support-view', 'If needed we will contact you at %(email)s')
.split('%(email)s', 2);
- reachBackMessage.splice(1, 0, <StyledEmail key="email">{email}</StyledEmail>);
+ void reachBackMessage.splice(1, 0, <StyledEmail key="email">{email}</StyledEmail>);
return (
<StyledContent>
@@ -422,7 +422,7 @@ const useCollectLog = () => {
const { collectProblemReport } = useAppContext();
const accountHistory = useSelector((state) => state.account.accountHistory);
- const collectLogPromise = useRef<Promise<string>>();
+ const collectLogPromise = useRef<Promise<string>>(undefined);
const collectLog = useCallback(async (): Promise<string> => {
if (collectLogPromise.current) {
@@ -504,6 +504,11 @@ const ProblemReportContextProvider = ({ children }: { children: ReactNode }) =>
/**
* Save the form whenever email or message gets updated
*/
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => onMount(email, message), [email, message]);
const value: ProblemReportContextType = useMemo(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/ProxyForm.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/ProxyForm.tsx
index e8e47bf15d..0eda7027ca 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/ProxyForm.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/ProxyForm.tsx
@@ -292,6 +292,11 @@ function EditShadowsocks(props: EditProxyProps<ShadowsocksCustomProxy>) {
);
// Report back to form component with the proxy values when all required values are set.
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => onUpdate(ip, port, password, cipher), [ip, port, password, cipher]);
return (
@@ -371,6 +376,11 @@ function EditSocks5Remote(props: EditProxyProps<Socks5RemoteCustomProxy>) {
);
// Report back to form component with the proxy values when all required values are set.
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => onUpdate(ip, port, username, password), [ip, port, username, password]);
return (
@@ -467,6 +477,11 @@ function EditSocks5Local(props: EditProxyProps<Socks5LocalCustomProxy>) {
useEffect(
() => onUpdate(remoteIp, remotePort, localPort, remoteTransportProtocol),
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
[remoteIp, remotePort, localPort, remoteTransportProtocol],
);
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
index edbcb6df97..fb896b95e0 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/SearchBar.tsx
@@ -86,6 +86,11 @@ export default function SearchBar(props: ISearchBarProps) {
}
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => focusInput(), []);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx
index 541e5cab44..f25e411cc3 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/SettingsImport.tsx
@@ -100,6 +100,11 @@ export default function SettingsImport() {
}
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => void onMount(), []);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx
index 26fe69ab7c..d18f671b5f 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/SplitTunnelingSettings.tsx
@@ -126,6 +126,11 @@ function LinuxSplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsProps
});
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => void updateApplications(), []);
const launchApplication = useCallback(
@@ -367,6 +372,11 @@ export function SplitTunnelingSettings(props: IPlatformSplitTunnelingSettingsPro
});
});
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => void onMount(), []);
const filteredSplitApplications = useMemo(
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Input.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Input.tsx
index e7f129ca73..c1d9405b4b 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Input.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Input.tsx
@@ -147,6 +147,11 @@ function InputWithRef(props: IInputProps, forwardedRef: React.Ref<HTMLInputEleme
// then we want to update the value.
useEffect(() => {
handleInitialValueChange(props.initialValue);
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.initialValue]);
const valid = validateValue?.(value);
@@ -373,6 +378,11 @@ export function RowInput(props: IRowInputProps) {
useEffect(() => {
focusOnMount();
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
useEffect(() => {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx
index a21a70c034..38cdbb6820 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/Section.tsx
@@ -79,6 +79,11 @@ export function ExpandableSection(props: ExpandableSectionProps) {
useEffect(() => {
updateHistory(expanded);
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [expanded]);
const title = (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsForm.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsForm.tsx
index 9a901d88d8..f986101e04 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsForm.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsForm.tsx
@@ -43,6 +43,11 @@ export function useSettingsFormSubmittableReporter() {
useEffect(() => {
// Remove from required fields if unmounted.
return () => clearRequiredFields();
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return reportInputSubmittable;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsSelect.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsSelect.tsx
index 3f6ccf3297..9acecc0222 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsSelect.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsSelect.tsx
@@ -145,6 +145,11 @@ export function SettingsSelect<T extends string>(props: SettingsSelectProps<T>)
// Update the parent when the value changes.
useEffect(() => {
updateEvent(value);
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [value]);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsTextInput.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsTextInput.tsx
index 73b7a55e4e..45ced44d66 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsTextInput.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/cell/SettingsTextInput.tsx
@@ -119,6 +119,11 @@ function Input<T extends ValueTypes>(props: InputProps<T>) {
// Report submittability to form context on load.
useEffect(() => {
updateReportSubmittable();
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return (
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
index 0c093af313..89f9edaee5 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/RelayListContext.tsx
@@ -320,6 +320,11 @@ function useExpandedLocations(filteredLocations: Array<IRelayLocationCountryRedu
);
// Expand locations when filters are changed
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
useEffect(() => expandLocationsForSearch(filteredLocations), [filteredLocations]);
return {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/ScrollPositionContext.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/ScrollPositionContext.tsx
index 55ee8dae97..73d402393b 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/ScrollPositionContext.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/ScrollPositionContext.tsx
@@ -13,11 +13,11 @@ import { SpacePreAllocationView } from './SpacePreAllocationView';
interface ScrollPositionContext {
scrollPositions: React.RefObject<Partial<Record<LocationType, ScrollPosition>>>;
// The selected location element is used to scroll to it when opening the view
- selectedLocationRef: React.RefObject<HTMLDivElement>;
+ selectedLocationRef: React.RefObject<HTMLDivElement | null>;
// The scroll view container is used to get the current scroll position and to restore an old one
- scrollViewRef: React.RefObject<CustomScrollbarsRef>;
+ scrollViewRef: React.RefObject<CustomScrollbarsRef | null>;
// The space pre allocation view is used to enable smooth scrolling when opening locations
- spacePreAllocationViewRef: React.RefObject<SpacePreAllocationView>;
+ spacePreAllocationViewRef: React.RefObject<SpacePreAllocationView | null>;
saveScrollPosition: () => void;
resetScrollPositions: () => void;
scrollIntoView: (rect: DOMRect) => void;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/SpacePreAllocationView.tsx b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/SpacePreAllocationView.tsx
index 4b493aeed1..40d1e241b8 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/components/select-location/SpacePreAllocationView.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/components/select-location/SpacePreAllocationView.tsx
@@ -5,7 +5,7 @@ interface ISpacePreAllocationView {
}
export class SpacePreAllocationView extends React.Component<ISpacePreAllocationView> {
- private ref = React.createRef<HTMLDivElement>();
+ private ref = React.createRef<HTMLDivElement | null>();
public allocate(height: number) {
if (this.ref.current) {
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/api-access-methods.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/api-access-methods.ts
index 90d406cc3d..d52d9ab0e2 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/api-access-methods.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/api-access-methods.ts
@@ -22,7 +22,7 @@ export function useApiAccessMethodTest(
const [testResult, setTestResult] = useState<boolean>();
// We keep the promise for the most recent test to compare it when we receive the results to know
// if it's canceled or not.
- const lastTestPromise = useRef<Promise<boolean>>();
+ const lastTestPromise = useRef<Promise<boolean>>(undefined);
// A few seconds after the test has finished the result should not be displayed anymore. This
// scheduler is used to clear it.
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/history.tsx b/desktop/packages/mullvad-vpn/src/renderer/lib/history.tsx
index f209dc8acf..bd2cd15883 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/history.tsx
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/history.tsx
@@ -221,7 +221,7 @@ export default class History {
}
private getRandomKey() {
- return Math.random().toString(36).substr(8);
+ return Math.random().toString(36).substring(8);
}
}
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/transition-hooks.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/transition-hooks.ts
index ee4a8f7eae..e48048c058 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/transition-hooks.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/transition-hooks.ts
@@ -30,7 +30,7 @@ export function useAfterTransition() {
export function useViewTransitions(onTransition?: () => void): Location<LocationState> {
const history = useHistory();
const [currentLocation, setCurrentLocation] = useState(history.location);
- const queuedLocationRef = useRef<QueueItem | undefined>();
+ const queuedLocationRef = useRef<QueueItem>(undefined);
const { setNavigationHistory } = useAppContext();
const reduceMotion = getReduceMotion();
@@ -83,6 +83,11 @@ export function useViewTransitions(onTransition?: () => void): Location<Location
return () => {
unobserveHistory?.();
};
+ // These lint rules are disabled for now because the react plugin for eslint does
+ // not understand that useEffectEvent should not be added to the dependency array.
+ // Enable these rules again when eslint can lint useEffectEvent properly.
+ // eslint-disable-next-line react-compiler/react-compiler
+ // eslint-disable-next-line react-hooks/exhaustive-deps
}, [history]);
return currentLocation;
diff --git a/desktop/packages/mullvad-vpn/src/renderer/lib/utility-hooks.ts b/desktop/packages/mullvad-vpn/src/renderer/lib/utility-hooks.ts
index 1efc49c804..0fe9a9314e 100644
--- a/desktop/packages/mullvad-vpn/src/renderer/lib/utility-hooks.ts
+++ b/desktop/packages/mullvad-vpn/src/renderer/lib/utility-hooks.ts
@@ -14,8 +14,8 @@ export function useMounted() {
return isMounted;
}
-export function useStyledRef<T>(): React.MutableRefObject<T> {
- return useRef() as React.MutableRefObject<T>;
+export function useStyledRef<T>(): React.RefObject<T | null> {
+ return useRef<T>(null);
}
export function useCombinedRefs<T>(...refs: (React.Ref<T> | undefined)[]): React.RefCallback<T> {
@@ -26,7 +26,7 @@ export function assignToRef<T>(element: T | null, ref?: React.Ref<T>) {
if (typeof ref === 'function') {
ref(element);
} else if (ref && element) {
- (ref as React.MutableRefObject<T>).current = element;
+ (ref as React.RefObject<T>).current = element;
}
}