From a48d4977c1815f5f9643a21c3fc877dfb175cea7 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Wed, 24 Jun 2026 21:02:45 +0300 Subject: [PATCH 1/5] feat: bind torrent client to a network adapter Adds a setting to bind the torrent client to a specific network adapter, so torrent traffic only flows through it (e.g. a VPN). The binding acts as a kill switch: if the selected adapter goes down, torrents stop instead of leaking through the default connection. The chosen adapter is applied to the libtorrent session via listen_interfaces and outgoing_interfaces, persisted as a user preference, and re-applied on RPC startup. A new IPC handler enumerates the available adapters for the settings dropdown. Closes #2023 --- python_rpc/main.py | 40 ++++++++++++ src/locales/en/translation.json | 4 ++ src/locales/es/translation.json | 4 ++ src/locales/pt-BR/translation.json | 4 ++ src/locales/pt-PT/translation.json | 4 ++ src/locales/ru/translation.json | 4 ++ .../events/hardware/get-network-interfaces.ts | 33 ++++++++++ src/main/events/hardware/index.ts | 1 + .../update-user-preferences.ts | 6 ++ .../services/download/download-manager.ts | 30 +++++++++ src/preload/index.ts | 1 + src/renderer/src/declaration.d.ts | 2 + .../settings/settings-context-downloads.tsx | 62 ++++++++++++++++++- .../src/pages/settings/settings-general.scss | 11 ++++ src/types/level.types.ts | 6 ++ 15 files changed, 210 insertions(+), 2 deletions(-) create mode 100644 src/main/events/hardware/get-network-interfaces.ts diff --git a/python_rpc/main.py b/python_rpc/main.py index a7f0b2ab3..cec0c6819 100644 --- a/python_rpc/main.py +++ b/python_rpc/main.py @@ -86,6 +86,7 @@ def parse_cli_args(argv): # This can be streamed down from Node downloading_game_id = -1 current_download_limit = None +current_network_interface = None torrent_session = lt.session( {"listen_interfaces": "0.0.0.0:{port}".format(port=torrent_port)} @@ -247,6 +248,39 @@ def apply_download_limit(downloader): if callable(set_download_limit): set_download_limit(current_download_limit) + +def normalize_network_interface(value): + if not isinstance(value, str): + return None + + trimmed = value.strip() + return trimmed or None + + +def apply_network_interface(interface): + if interface: + listen_interfaces = "{iface}:{port}".format( + iface=interface, port=torrent_port + ) + outgoing_interfaces = interface + else: + listen_interfaces = "0.0.0.0:{port}".format(port=torrent_port) + outgoing_interfaces = "" + + try: + torrent_session.apply_settings( + { + "listen_interfaces": listen_interfaces, + "outgoing_interfaces": outgoing_interfaces, + } + ) + logger.info( + "Bound torrent client to network interface: %s", + interface or "default (all adapters)", + ) + except Exception as error: + logger.error("Failed to bind torrent client to interface: %s", error) + def validate_rpc_password_value(password: Optional[str]): if rpc_password == "": return True @@ -429,6 +463,7 @@ def torrent_files(data: Optional[dict] = None): def action(data: Optional[dict] = None): global downloading_game_id global current_download_limit + global current_network_interface data = data or {} action_name = data.get("action") @@ -511,6 +546,11 @@ def action(data: Optional[dict] = None): for downloader in active_downloaders: apply_download_limit(downloader) + elif action_name == "set_network_interface": + current_network_interface = normalize_network_interface( + data.get("interface") + ) + apply_network_interface(current_network_interface) else: raise RpcError("invalid_action") except RpcError: diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index 7f6cc3e00..a9e7e6184 100755 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -769,6 +769,10 @@ "app_basics": "App basics", "startup_behavior": "Startup behavior", "download_behavior": "Download behavior", + "network_interface": "Network adapter for torrents", + "network_interface_default": "Default (all adapters)", + "network_interface_hint": "Bind the torrent client to a specific adapter, such as a VPN. While bound, torrents only connect through that adapter, and downloads stop if it goes down (no traffic leaks through your regular connection).", + "network_interface_unavailable": "unavailable", "library_notifications": "Library notifications", "achievement_notifications": "Achievement notifications", "content_gameplay": "Content & gameplay", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 069c5f49f..030a77e46 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -731,6 +731,10 @@ "app_basics": "Básicos de la aplicación", "startup_behavior": "Comportamiento al iniciar", "download_behavior": "Comportamiento de descarga", + "network_interface": "Adaptador de red para torrents", + "network_interface_default": "Predeterminado (todos los adaptadores)", + "network_interface_hint": "Vincula el cliente de torrents a un adaptador específico, como una VPN. Mientras está vinculado, los torrents solo se conectan a través de ese adaptador y las descargas se detienen si deja de funcionar (sin fugas de tráfico por tu conexión habitual).", + "network_interface_unavailable": "no disponible", "library_notifications": "Notificaciones de la librería", "achievement_notifications": "Notificaciones de logros", "content_preferences": "Preferencias de contenido", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index e5f30a9c6..8a06ede1b 100755 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -679,6 +679,10 @@ "app_basics": "Noções básicas do aplicativo", "startup_behavior": "Comportamento na inicialização", "download_behavior": "Comportamento de download", + "network_interface": "Adaptador de rede para torrents", + "network_interface_default": "Padrão (todos os adaptadores)", + "network_interface_hint": "Vincula o cliente de torrent a um adaptador específico, como uma VPN. Enquanto vinculado, os torrents só se conectam por esse adaptador e os downloads param se ele cair (sem vazamento de tráfego pela sua conexão normal).", + "network_interface_unavailable": "indisponível", "library_notifications": "Notificações da biblioteca", "achievement_notifications": "Notificações de conquistas", "content_preferences": "Preferências de conteúdo", diff --git a/src/locales/pt-PT/translation.json b/src/locales/pt-PT/translation.json index cfd4e66e4..615f8f99c 100644 --- a/src/locales/pt-PT/translation.json +++ b/src/locales/pt-PT/translation.json @@ -626,6 +626,10 @@ "app_basics": "Noções básicas da aplicação", "startup_behavior": "Comportamento no arranque", "download_behavior": "Comportamento de transferência", + "network_interface": "Adaptador de rede para torrents", + "network_interface_default": "Predefinido (todos os adaptadores)", + "network_interface_hint": "Vincula o cliente de torrent a um adaptador específico, como uma VPN. Enquanto vinculado, os torrents só se ligam através desse adaptador e as transferências param se ele ficar indisponível (sem fugas de tráfego pela sua ligação normal).", + "network_interface_unavailable": "indisponível", "library_notifications": "Notificações da biblioteca", "achievement_notifications": "Notificações de conquistas", "content_preferences": "Preferências de conteúdo", diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 3e2d4993e..33081c167 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -770,6 +770,10 @@ "app_basics": "Основные настройки приложения", "startup_behavior": "Поведение при запуске", "download_behavior": "Поведение загрузок", + "network_interface": "Сетевой адаптер для торрентов", + "network_interface_default": "По умолчанию (все адаптеры)", + "network_interface_hint": "Привязывает торрент-клиент к выбранному адаптеру, например к VPN. Пока привязка активна, торренты подключаются только через этот адаптер, а загрузки останавливаются, если он отключится (без утечки трафика через обычное соединение).", + "network_interface_unavailable": "недоступен", "library_notifications": "Уведомления библиотеки", "achievement_notifications": "Уведомления о достижениях", "content_gameplay": "Контент и игровой процесс", diff --git a/src/main/events/hardware/get-network-interfaces.ts b/src/main/events/hardware/get-network-interfaces.ts new file mode 100644 index 000000000..74e8b0c4c --- /dev/null +++ b/src/main/events/hardware/get-network-interfaces.ts @@ -0,0 +1,33 @@ +import os from "node:os"; + +import type { NetworkInterface } from "@types"; +import { registerEvent } from "../register-event"; + +const getNetworkInterfaces = async (): Promise => { + const interfaces = os.networkInterfaces(); + + return Object.entries(interfaces).reduce( + (acc, [name, addresses]) => { + const external = (addresses ?? []).filter((address) => !address.internal); + + if (external.length === 0) { + return acc; + } + + const sorted = external.sort((a, b) => { + if (a.family === b.family) return 0; + return a.family === "IPv4" ? -1 : 1; + }); + + acc.push({ + name, + addresses: sorted.map((address) => address.address), + }); + + return acc; + }, + [] + ); +}; + +registerEvent("getNetworkInterfaces", getNetworkInterfaces); diff --git a/src/main/events/hardware/index.ts b/src/main/events/hardware/index.ts index 76823f51c..d0753097e 100644 --- a/src/main/events/hardware/index.ts +++ b/src/main/events/hardware/index.ts @@ -1,2 +1,3 @@ import "./check-folder-write-permission"; import "./get-disk-free-space"; +import "./get-network-interfaces"; diff --git a/src/main/events/user-preferences/update-user-preferences.ts b/src/main/events/user-preferences/update-user-preferences.ts index eb0834db5..852d736de 100644 --- a/src/main/events/user-preferences/update-user-preferences.ts +++ b/src/main/events/user-preferences/update-user-preferences.ts @@ -94,6 +94,12 @@ const updateUserPreferences = async ( preferences.maxDownloadSpeedBytesPerSecond ?? null ); } + + if (Object.hasOwn(preferences, "torrentNetworkInterface")) { + await DownloadManager.applyNetworkInterface( + preferences.torrentNetworkInterface ?? null + ); + } }; registerEvent("updateUserPreferences", updateUserPreferences); diff --git a/src/main/services/download/download-manager.ts b/src/main/services/download/download-manager.ts index 062753b4b..041605bbf 100644 --- a/src/main/services/download/download-manager.ts +++ b/src/main/services/download/download-manager.ts @@ -266,12 +266,42 @@ export class DownloadManager { }); } + private static async getPersistedNetworkInterface() { + const userPreferences = await db.get( + levelKeys.userPreferences, + { valueEncoding: "json" } + ); + + return userPreferences?.torrentNetworkInterface ?? null; + } + + public static async applyNetworkInterface( + value?: string | null + ): Promise { + const networkInterface = + value === undefined ? await this.getPersistedNetworkInterface() : value; + + await PythonRPC.rpc + .call("action", { + action: "set_network_interface", + interface: networkInterface ?? "", + }) + .catch((error) => { + logger.error( + "[DownloadManager] Failed to update RPC network interface:", + error + ); + }); + } + public static async startRPC( download?: Download, downloadsToSeed?: Download[] ) { await PythonRPC.spawn(); + await this.applyNetworkInterface(); + if (downloadsToSeed?.length) { for (const seedDownload of downloadsToSeed) { await this.resumeSeeding(seedDownload).catch((error) => { diff --git a/src/preload/index.ts b/src/preload/index.ts index 38bca0be6..3f855f370 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -778,6 +778,7 @@ contextBridge.exposeInMainWorld("electron", { ipcRenderer.invoke("getDiskFreeSpace", path), checkFolderWritePermission: (path: string) => ipcRenderer.invoke("checkFolderWritePermission", path), + getNetworkInterfaces: () => ipcRenderer.invoke("getNetworkInterfaces"), /* Cloud save */ uploadSaveGame: ( diff --git a/src/renderer/src/declaration.d.ts b/src/renderer/src/declaration.d.ts index 8ae4adabb..d45a714e5 100644 --- a/src/renderer/src/declaration.d.ts +++ b/src/renderer/src/declaration.d.ts @@ -37,6 +37,7 @@ import type { AchievementNotificationInfo, Game, DiskUsage, + NetworkInterface, DownloadSource, LocalNotification, ProtonVersion, @@ -605,6 +606,7 @@ declare global { /* Hardware */ getDiskFreeSpace: (path: string) => Promise; checkFolderWritePermission: (path: string) => Promise; + getNetworkInterfaces: () => Promise; /* Cloud save */ uploadSaveGame: ( diff --git a/src/renderer/src/pages/settings/settings-context-downloads.tsx b/src/renderer/src/pages/settings/settings-context-downloads.tsx index a46757ba1..e0387914a 100644 --- a/src/renderer/src/pages/settings/settings-context-downloads.tsx +++ b/src/renderer/src/pages/settings/settings-context-downloads.tsx @@ -1,9 +1,10 @@ -import { useContext, useEffect, useState } from "react"; +import { useContext, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; -import { CheckboxField, TextField } from "@renderer/components"; +import { CheckboxField, SelectField, TextField } from "@renderer/components"; import { settingsContext } from "@renderer/context"; import { useAppSelector } from "@renderer/hooks"; +import type { NetworkInterface } from "@types"; import { SettingsDownloadSources } from "./settings-download-sources"; import "./settings-general.scss"; @@ -50,8 +51,20 @@ export function SettingsContextDownloads() { createStartMenuShortcut: true, maxDownloadSpeedMegabytes: "", deleteArchiveFilesAfterExtractionByDefault: false, + torrentNetworkInterface: "", }); + const [networkInterfaces, setNetworkInterfaces] = useState< + NetworkInterface[] + >([]); + + useEffect(() => { + window.electron + .getNetworkInterfaces() + .then(setNetworkInterfaces) + .catch(() => setNetworkInterfaces([])); + }, []); + useEffect(() => { if (!userPreferences) return; @@ -72,9 +85,40 @@ export function SettingsContextDownloads() { : "", deleteArchiveFilesAfterExtractionByDefault: userPreferences.deleteArchiveFilesAfterExtractionByDefault ?? false, + torrentNetworkInterface: userPreferences.torrentNetworkInterface ?? "", }); }, [userPreferences]); + const networkInterfaceOptions = useMemo(() => { + const options = [ + { key: "default", value: "", label: t("network_interface_default") }, + ...networkInterfaces.map((networkInterface) => { + const ipv4 = networkInterface.addresses.find( + (address) => !address.includes(":") + ); + + return { + key: networkInterface.name, + value: networkInterface.name, + label: ipv4 + ? `${networkInterface.name} (${ipv4})` + : networkInterface.name, + }; + }), + ]; + + const selected = form.torrentNetworkInterface; + if (selected && !options.some((option) => option.value === selected)) { + options.push({ + key: selected, + value: selected, + label: `${selected} (${t("network_interface_unavailable")})`, + }); + } + + return options; + }, [networkInterfaces, form.torrentNetworkInterface, t]); + const handleChange = (values: Partial) => { setForm((prev) => ({ ...prev, ...values })); updateUserPreferences(values); @@ -159,6 +203,20 @@ export function SettingsContextDownloads() { placeholder={t("max_download_speed_unlimited")} /> +
+ + handleChange({ torrentNetworkInterface: event.target.value }) + } + options={networkInterfaceOptions} + /> + + {t("network_interface_hint")} + +
+ Date: Wed, 24 Jun 2026 21:12:23 +0300 Subject: [PATCH 2/5] feat: shorten network adapter setting hint --- src/locales/en/translation.json | 2 +- src/locales/es/translation.json | 2 +- src/locales/pt-BR/translation.json | 2 +- src/locales/pt-PT/translation.json | 2 +- src/locales/ru/translation.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/locales/en/translation.json b/src/locales/en/translation.json index a9e7e6184..7923e4b4f 100755 --- a/src/locales/en/translation.json +++ b/src/locales/en/translation.json @@ -771,7 +771,7 @@ "download_behavior": "Download behavior", "network_interface": "Network adapter for torrents", "network_interface_default": "Default (all adapters)", - "network_interface_hint": "Bind the torrent client to a specific adapter, such as a VPN. While bound, torrents only connect through that adapter, and downloads stop if it goes down (no traffic leaks through your regular connection).", + "network_interface_hint": "Force torrents through a specific adapter, like a VPN. If it disconnects, downloads stop instead of leaking.", "network_interface_unavailable": "unavailable", "library_notifications": "Library notifications", "achievement_notifications": "Achievement notifications", diff --git a/src/locales/es/translation.json b/src/locales/es/translation.json index 030a77e46..0a79b6695 100644 --- a/src/locales/es/translation.json +++ b/src/locales/es/translation.json @@ -733,7 +733,7 @@ "download_behavior": "Comportamiento de descarga", "network_interface": "Adaptador de red para torrents", "network_interface_default": "Predeterminado (todos los adaptadores)", - "network_interface_hint": "Vincula el cliente de torrents a un adaptador específico, como una VPN. Mientras está vinculado, los torrents solo se conectan a través de ese adaptador y las descargas se detienen si deja de funcionar (sin fugas de tráfico por tu conexión habitual).", + "network_interface_hint": "Fuerza los torrents a través de un adaptador específico, como una VPN. Si se desconecta, las descargas se detienen en lugar de filtrarse.", "network_interface_unavailable": "no disponible", "library_notifications": "Notificaciones de la librería", "achievement_notifications": "Notificaciones de logros", diff --git a/src/locales/pt-BR/translation.json b/src/locales/pt-BR/translation.json index 8a06ede1b..fb7759b5d 100755 --- a/src/locales/pt-BR/translation.json +++ b/src/locales/pt-BR/translation.json @@ -681,7 +681,7 @@ "download_behavior": "Comportamento de download", "network_interface": "Adaptador de rede para torrents", "network_interface_default": "Padrão (todos os adaptadores)", - "network_interface_hint": "Vincula o cliente de torrent a um adaptador específico, como uma VPN. Enquanto vinculado, os torrents só se conectam por esse adaptador e os downloads param se ele cair (sem vazamento de tráfego pela sua conexão normal).", + "network_interface_hint": "Força os torrents por um adaptador específico, como uma VPN. Se ele cair, os downloads param em vez de vazar.", "network_interface_unavailable": "indisponível", "library_notifications": "Notificações da biblioteca", "achievement_notifications": "Notificações de conquistas", diff --git a/src/locales/pt-PT/translation.json b/src/locales/pt-PT/translation.json index 615f8f99c..cd0cbfcd0 100644 --- a/src/locales/pt-PT/translation.json +++ b/src/locales/pt-PT/translation.json @@ -628,7 +628,7 @@ "download_behavior": "Comportamento de transferência", "network_interface": "Adaptador de rede para torrents", "network_interface_default": "Predefinido (todos os adaptadores)", - "network_interface_hint": "Vincula o cliente de torrent a um adaptador específico, como uma VPN. Enquanto vinculado, os torrents só se ligam através desse adaptador e as transferências param se ele ficar indisponível (sem fugas de tráfego pela sua ligação normal).", + "network_interface_hint": "Força os torrents por um adaptador específico, como uma VPN. Se ficar indisponível, as transferências param em vez de vazar.", "network_interface_unavailable": "indisponível", "library_notifications": "Notificações da biblioteca", "achievement_notifications": "Notificações de conquistas", diff --git a/src/locales/ru/translation.json b/src/locales/ru/translation.json index 33081c167..5e8c6e1bb 100644 --- a/src/locales/ru/translation.json +++ b/src/locales/ru/translation.json @@ -772,7 +772,7 @@ "download_behavior": "Поведение загрузок", "network_interface": "Сетевой адаптер для торрентов", "network_interface_default": "По умолчанию (все адаптеры)", - "network_interface_hint": "Привязывает торрент-клиент к выбранному адаптеру, например к VPN. Пока привязка активна, торренты подключаются только через этот адаптер, а загрузки останавливаются, если он отключится (без утечки трафика через обычное соединение).", + "network_interface_hint": "Направляет торренты через выбранный адаптер, например VPN. Если он отключится, загрузки остановятся, а не пойдут в обход.", "network_interface_unavailable": "недоступен", "library_notifications": "Уведомления библиотеки", "achievement_notifications": "Уведомления о достижениях", From e337b511704094587a188cf8059919f0c8d98c73 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Wed, 24 Jun 2026 21:13:30 +0300 Subject: [PATCH 3/5] feat: add spacing below network adapter setting --- src/renderer/src/pages/settings/settings-general.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/src/renderer/src/pages/settings/settings-general.scss b/src/renderer/src/pages/settings/settings-general.scss index ffd43ee7f..7920bdf2b 100644 --- a/src/renderer/src/pages/settings/settings-general.scss +++ b/src/renderer/src/pages/settings/settings-general.scss @@ -29,6 +29,7 @@ display: flex; flex-direction: column; gap: globals.$spacing-unit; + margin-bottom: calc(globals.$spacing-unit * 2); } &__network-interface-hint { From c2e3b66d85fe567e24b86228ef435ef8a0649e52 Mon Sep 17 00:00:00 2001 From: Moyasee Date: Wed, 24 Jun 2026 21:14:24 +0300 Subject: [PATCH 4/5] feat: balance spacing around network adapter setting --- src/renderer/src/pages/settings/settings-general.scss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/renderer/src/pages/settings/settings-general.scss b/src/renderer/src/pages/settings/settings-general.scss index 7920bdf2b..80506dcf2 100644 --- a/src/renderer/src/pages/settings/settings-general.scss +++ b/src/renderer/src/pages/settings/settings-general.scss @@ -29,7 +29,7 @@ display: flex; flex-direction: column; gap: globals.$spacing-unit; - margin-bottom: calc(globals.$spacing-unit * 2); + margin-block: calc(globals.$spacing-unit * 2); } &__network-interface-hint { From bdb94b125aa857306c606ea0496805f77c5b318b Mon Sep 17 00:00:00 2001 From: Moyasee Date: Wed, 24 Jun 2026 21:19:50 +0300 Subject: [PATCH 5/5] refactor: address review feedback on network adapter binding --- python_rpc/main.py | 12 +++++------- src/main/services/download/download-manager.ts | 2 +- .../pages/settings/settings-context-downloads.tsx | 2 +- .../src/pages/settings/settings-general.scss | 4 ++-- src/renderer/src/scss/globals.scss | 1 + 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/python_rpc/main.py b/python_rpc/main.py index cec0c6819..59fda0e65 100644 --- a/python_rpc/main.py +++ b/python_rpc/main.py @@ -86,7 +86,6 @@ def parse_cli_args(argv): # This can be streamed down from Node downloading_game_id = -1 current_download_limit = None -current_network_interface = None torrent_session = lt.session( {"listen_interfaces": "0.0.0.0:{port}".format(port=torrent_port)} @@ -278,8 +277,9 @@ def apply_network_interface(interface): "Bound torrent client to network interface: %s", interface or "default (all adapters)", ) - except Exception as error: - logger.error("Failed to bind torrent client to interface: %s", error) + except Exception: + logger.exception("Failed to bind torrent client to interface") + def validate_rpc_password_value(password: Optional[str]): if rpc_password == "": @@ -463,7 +463,6 @@ def torrent_files(data: Optional[dict] = None): def action(data: Optional[dict] = None): global downloading_game_id global current_download_limit - global current_network_interface data = data or {} action_name = data.get("action") @@ -547,10 +546,9 @@ def action(data: Optional[dict] = None): for downloader in active_downloaders: apply_download_limit(downloader) elif action_name == "set_network_interface": - current_network_interface = normalize_network_interface( - data.get("interface") + apply_network_interface( + normalize_network_interface(data.get("interface")) ) - apply_network_interface(current_network_interface) else: raise RpcError("invalid_action") except RpcError: diff --git a/src/main/services/download/download-manager.ts b/src/main/services/download/download-manager.ts index 041605bbf..e0f59abe3 100644 --- a/src/main/services/download/download-manager.ts +++ b/src/main/services/download/download-manager.ts @@ -279,7 +279,7 @@ export class DownloadManager { value?: string | null ): Promise { const networkInterface = - value === undefined ? await this.getPersistedNetworkInterface() : value; + value ?? (await this.getPersistedNetworkInterface()); await PythonRPC.rpc .call("action", { diff --git a/src/renderer/src/pages/settings/settings-context-downloads.tsx b/src/renderer/src/pages/settings/settings-context-downloads.tsx index e0387914a..4d6acceea 100644 --- a/src/renderer/src/pages/settings/settings-context-downloads.tsx +++ b/src/renderer/src/pages/settings/settings-context-downloads.tsx @@ -59,7 +59,7 @@ export function SettingsContextDownloads() { >([]); useEffect(() => { - window.electron + globalThis.electron .getNetworkInterfaces() .then(setNetworkInterfaces) .catch(() => setNetworkInterfaces([])); diff --git a/src/renderer/src/pages/settings/settings-general.scss b/src/renderer/src/pages/settings/settings-general.scss index 80506dcf2..ab78f0260 100644 --- a/src/renderer/src/pages/settings/settings-general.scss +++ b/src/renderer/src/pages/settings/settings-general.scss @@ -19,7 +19,7 @@ } &__disabled-hint { - font-size: 13px; + font-size: globals.$hint-font-size; color: globals.$muted-color; margin-top: calc(globals.$spacing-unit * -1); font-style: italic; @@ -33,7 +33,7 @@ } &__network-interface-hint { - font-size: 13px; + font-size: globals.$hint-font-size; color: globals.$muted-color; } diff --git a/src/renderer/src/scss/globals.scss b/src/renderer/src/scss/globals.scss index 9a5b6f604..96776a7e8 100644 --- a/src/renderer/src/scss/globals.scss +++ b/src/renderer/src/scss/globals.scss @@ -63,6 +63,7 @@ $backdrop-z-index: 4; $modal-z-index: 5; $body-font-size: 14px; +$hint-font-size: 13px; $small-font-size: 12px; $app-container: app-container;