mirror of
https://github.com/idanoo/autobrr
synced 2025-07-22 16:29:12 +00:00
feat(web): replace react-portal with own implementation (#1862)
* feat(web): replace react-portal with own implementation * chore: add missing license headers
This commit is contained in:
parent
ab718b8232
commit
172fa651af
6 changed files with 113 additions and 99 deletions
|
@ -5,54 +5,55 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#18181B">
|
||||
<meta name="description" content="autobrr" />
|
||||
<link rel="preload" href="/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin="use-credentials">
|
||||
<link rel="apple-touch-icon" href="/logo192.png" />
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon-iphone-60x60.png" />
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-ipad-76x76.png" />
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-iphone-retina-120x120.png" />
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-ipad-retina-152x152.png" />
|
||||
<title>autobrr</title>
|
||||
<base href="{{.BaseUrl}}">
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter Var";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
font-feature-settings: "calt" 0;
|
||||
src:
|
||||
local("Inter Var"), local("Inter Variable"),
|
||||
local("Inter var"), local("Inter variable"),
|
||||
local("InterVar"), local("InterVariable"),
|
||||
local("Inter"),
|
||||
url("/Inter-Variable.woff2") format("woff2");
|
||||
}
|
||||
:root {
|
||||
font-family: "Inter Var", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel="icon" href="/favicon.ico"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||||
<meta name="theme-color" content="#18181B">
|
||||
<meta name="description" content="autobrr"/>
|
||||
<link rel="preload" href="/Inter-Variable.woff2" as="font" type="font/woff2" crossorigin="use-credentials">
|
||||
<link rel="apple-touch-icon" href="/logo192.png"/>
|
||||
<link rel="apple-touch-icon" href="/apple-touch-icon-iphone-60x60.png"/>
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/apple-touch-icon-ipad-76x76.png"/>
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-iphone-retina-120x120.png"/>
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-ipad-retina-152x152.png"/>
|
||||
<title>autobrr</title>
|
||||
<base href="{{.BaseUrl}}">
|
||||
<style>
|
||||
@font-face {
|
||||
font-family: "Inter Var";
|
||||
font-style: normal;
|
||||
font-weight: 100 900;
|
||||
font-display: block;
|
||||
font-feature-settings: "calt" 0;
|
||||
src: local("Inter Var"), local("Inter Variable"),
|
||||
local("Inter var"), local("Inter variable"),
|
||||
local("InterVar"), local("InterVariable"),
|
||||
local("Inter"),
|
||||
url("/Inter-Variable.woff2") format("woff2");
|
||||
}
|
||||
|
||||
:root {
|
||||
font-family: "Inter Var", -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
|
||||
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.APP = {};
|
||||
window.APP.baseUrl = "{{.BaseUrl}}";
|
||||
|
||||
const browserPrefers = !(window.matchMedia !== undefined && window.matchMedia("(prefers-color-scheme: light)").matches);
|
||||
const { darkTheme = browserPrefers } = JSON.parse(localStorage.getItem("settings")) || {};
|
||||
const {darkTheme = browserPrefers} = JSON.parse(localStorage.getItem("settings")) || {};
|
||||
document.documentElement.classList.toggle("dark", darkTheme);
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-color">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="pattern h-screen"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</script>
|
||||
</head>
|
||||
<body class="bg-color">
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root" class="pattern h-screen"></div>
|
||||
<div id="portal-root"></div>
|
||||
<script type="module" src="./src/index.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -44,7 +44,6 @@
|
|||
"@types/node": "^22.10.0",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@types/react-portal": "^4.0.7",
|
||||
"@types/react-table": "^7.7.20",
|
||||
"@typescript-eslint/eslint-plugin": "^8.16.0",
|
||||
"@typescript-eslint/parser": "^8.16.0",
|
||||
|
@ -62,7 +61,6 @@
|
|||
"react-hot-toast": "^2.4.1",
|
||||
"react-multi-select-component": "^4.3.4",
|
||||
"react-popper-tooltip": "^4.4.2",
|
||||
"react-portal": "^4.2.2",
|
||||
"react-ridge-state": "4.2.9",
|
||||
"react-select": "^5.8.3",
|
||||
"react-table": "^7.8.0",
|
||||
|
@ -81,7 +79,6 @@
|
|||
"@types/node": "^22.10.0",
|
||||
"@types/react": "^18.3.12",
|
||||
"@types/react-dom": "^18.3.1",
|
||||
"@types/react-portal": "^4.0.7",
|
||||
"@types/react-table": "^7.7.20",
|
||||
"@typescript-eslint/eslint-plugin": "^8.16.0",
|
||||
"@typescript-eslint/parser": "^8.16.0",
|
||||
|
|
85
web/pnpm-lock.yaml
generated
85
web/pnpm-lock.yaml
generated
|
@ -46,9 +46,6 @@ importers:
|
|||
'@types/react-dom':
|
||||
specifier: ^18.3.1
|
||||
version: 18.3.1
|
||||
'@types/react-portal':
|
||||
specifier: ^4.0.7
|
||||
version: 4.0.7
|
||||
'@types/react-table':
|
||||
specifier: ^7.7.20
|
||||
version: 7.7.20
|
||||
|
@ -100,9 +97,6 @@ importers:
|
|||
react-popper-tooltip:
|
||||
specifier: ^4.4.2
|
||||
version: 4.4.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-portal:
|
||||
specifier: ^4.2.2
|
||||
version: 4.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
react-ridge-state:
|
||||
specifier: 4.2.9
|
||||
version: 4.2.9(react@18.3.1)
|
||||
|
@ -175,7 +169,7 @@ importers:
|
|||
version: 0.21.0(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))(workbox-build@7.0.0)(workbox-window@7.3.0)
|
||||
vite-plugin-svgr:
|
||||
specifier: ^4.3.0
|
||||
version: 4.3.0(@rollup/wasm-node@4.27.4)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))
|
||||
version: 4.3.0(@rollup/wasm-node@4.28.1)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1))
|
||||
|
||||
packages:
|
||||
|
||||
|
@ -1091,6 +1085,11 @@ packages:
|
|||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@rollup/wasm-node@4.28.1':
|
||||
resolution: {integrity: sha512-t4ckEC09V3wbe0r6T4fGjq85lEbvGcGxn7QYYgjHyKNzZaQU5kFqr4FsavXYHRiVNYq8m+dRhdGjpfcC9UzzPg==}
|
||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||
hasBin: true
|
||||
|
||||
'@rtsao/scc@1.1.0':
|
||||
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
|
||||
|
||||
|
@ -1345,9 +1344,6 @@ packages:
|
|||
'@types/react-dom@18.3.1':
|
||||
resolution: {integrity: sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ==}
|
||||
|
||||
'@types/react-portal@4.0.7':
|
||||
resolution: {integrity: sha512-3zQJL6Pqcq7d73+cakVkZDqAYGFBo37XXPfahjhdScr9EdYPlf9evYilL38Fpzs1YGWz7F2SkPtN6+ygTO7ymg==}
|
||||
|
||||
'@types/react-table@7.7.20':
|
||||
resolution: {integrity: sha512-ahMp4pmjVlnExxNwxyaDrFgmKxSbPwU23sGQw2gJK4EhCvnvmib2s/O/+y1dfV57dXOwpr2plfyBol+vEHbi2w==}
|
||||
|
||||
|
@ -2827,12 +2823,6 @@ packages:
|
|||
react: ^18.3.1
|
||||
react-dom: ^16.8.0 || ^17 || ^18
|
||||
|
||||
react-portal@4.2.2:
|
||||
resolution: {integrity: sha512-vS18idTmevQxyQpnde0Td6ZcUlv+pD8GTyR42n3CHUQq9OHi1C4jDE4ZWEbEsrbrLRhSECYiao58cvocwMtP7Q==}
|
||||
peerDependencies:
|
||||
react: ^18.3.1
|
||||
react-dom: ^16.0.0-0 || ^17.0.0-0 || ^18.0.0-0
|
||||
|
||||
react-ridge-state@4.2.9:
|
||||
resolution: {integrity: sha512-1u2a5l5wl0H//hR1R69ZFbvD9mnvOXK3rit859vy15THQv/M+t7U5VF27Ufzcxb8kbKMwZ1Ni/J5f2chrrTHCQ==}
|
||||
peerDependencies:
|
||||
|
@ -3412,7 +3402,6 @@ packages:
|
|||
|
||||
workbox-google-analytics@7.0.0:
|
||||
resolution: {integrity: sha512-MEYM1JTn/qiC3DbpvP2BVhyIH+dV/5BjHk756u9VbwuAhu0QHyKscTnisQuz21lfRpOwiS9z4XdqeVAKol0bzg==}
|
||||
deprecated: It is not compatible with newer versions of GA starting with v4, as long as you are using GAv3 it should be ok, but the package is not longer being maintained
|
||||
|
||||
workbox-navigation-preload@7.0.0:
|
||||
resolution: {integrity: sha512-juWCSrxo/fiMz3RsvDspeSLGmbgC0U9tKqcUPZBCf35s64wlaLXyn2KdHHXVQrb2cqF7I0Hc9siQalainmnXJA==}
|
||||
|
@ -4493,45 +4482,45 @@ snapshots:
|
|||
dependencies:
|
||||
react: 18.3.1
|
||||
|
||||
'@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.27.4)':
|
||||
'@rollup/plugin-babel@5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.28.1)':
|
||||
dependencies:
|
||||
'@babel/core': 7.26.0
|
||||
'@babel/helper-module-imports': 7.25.9
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.27.4)':
|
||||
'@rollup/plugin-node-resolve@11.2.1(@rollup/wasm-node@4.28.1)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
|
||||
'@types/resolve': 1.17.1
|
||||
builtin-modules: 3.3.0
|
||||
deepmerge: 4.3.1
|
||||
is-module: 1.0.0
|
||||
resolve: 1.22.8
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
|
||||
'@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.27.4)':
|
||||
'@rollup/plugin-replace@2.4.2(@rollup/wasm-node@4.28.1)':
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/pluginutils': 3.1.0(@rollup/wasm-node@4.28.1)
|
||||
magic-string: 0.25.9
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
|
||||
'@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.27.4)':
|
||||
'@rollup/pluginutils@3.1.0(@rollup/wasm-node@4.28.1)':
|
||||
dependencies:
|
||||
'@types/estree': 0.0.39
|
||||
estree-walker: 1.0.1
|
||||
picomatch: 2.3.1
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
|
||||
'@rollup/pluginutils@5.1.3(@rollup/wasm-node@4.27.4)':
|
||||
'@rollup/pluginutils@5.1.3(@rollup/wasm-node@4.28.1)':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
estree-walker: 2.0.2
|
||||
picomatch: 4.0.2
|
||||
optionalDependencies:
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
|
||||
'@rollup/wasm-node@4.27.4':
|
||||
dependencies:
|
||||
|
@ -4539,6 +4528,12 @@ snapshots:
|
|||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
'@rollup/wasm-node@4.28.1':
|
||||
dependencies:
|
||||
'@types/estree': 1.0.6
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
|
||||
'@rtsao/scc@1.1.0': {}
|
||||
|
||||
'@surma/rollup-plugin-off-main-thread@2.2.3':
|
||||
|
@ -4769,10 +4764,6 @@ snapshots:
|
|||
dependencies:
|
||||
'@types/react': 18.3.12
|
||||
|
||||
'@types/react-portal@4.0.7':
|
||||
dependencies:
|
||||
'@types/react': 18.3.12
|
||||
|
||||
'@types/react-table@7.7.20':
|
||||
dependencies:
|
||||
'@types/react': 18.3.12
|
||||
|
@ -6394,12 +6385,6 @@ snapshots:
|
|||
react-fast-compare: 3.2.2
|
||||
warning: 4.0.3
|
||||
|
||||
react-portal@4.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1):
|
||||
dependencies:
|
||||
prop-types: 15.8.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
react-ridge-state@4.2.9(react@18.3.1):
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
|
@ -6523,11 +6508,11 @@ snapshots:
|
|||
dependencies:
|
||||
glob: 7.2.3
|
||||
|
||||
rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.27.4):
|
||||
rollup-plugin-terser@7.0.2(@rollup/wasm-node@4.28.1):
|
||||
dependencies:
|
||||
'@babel/code-frame': 7.26.2
|
||||
jest-worker: 26.6.2
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
serialize-javascript: 4.0.0
|
||||
terser: 5.36.0
|
||||
|
||||
|
@ -6956,9 +6941,9 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
vite-plugin-svgr@4.3.0(@rollup/wasm-node@4.27.4)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)):
|
||||
vite-plugin-svgr@4.3.0(@rollup/wasm-node@4.28.1)(typescript@5.7.2)(vite@6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)):
|
||||
dependencies:
|
||||
'@rollup/pluginutils': 5.1.3(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/pluginutils': 5.1.3(@rollup/wasm-node@4.28.1)
|
||||
'@svgr/core': 8.1.0(typescript@5.7.2)
|
||||
'@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.7.2))
|
||||
vite: 6.0.0(@types/node@22.10.0)(jiti@1.21.6)(terser@5.36.0)(yaml@2.6.1)
|
||||
|
@ -6971,7 +6956,7 @@ snapshots:
|
|||
dependencies:
|
||||
esbuild: 0.24.0
|
||||
postcss: 8.4.49
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
optionalDependencies:
|
||||
'@types/node': 22.10.0
|
||||
fsevents: 2.3.3
|
||||
|
@ -7051,9 +7036,9 @@ snapshots:
|
|||
'@babel/core': 7.26.0
|
||||
'@babel/preset-env': 7.26.0(@babel/core@7.26.0)
|
||||
'@babel/runtime': 7.26.0
|
||||
'@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.27.4)
|
||||
'@rollup/plugin-babel': 5.3.1(@babel/core@7.26.0)(@rollup/wasm-node@4.28.1)
|
||||
'@rollup/plugin-node-resolve': 11.2.1(@rollup/wasm-node@4.28.1)
|
||||
'@rollup/plugin-replace': 2.4.2(@rollup/wasm-node@4.28.1)
|
||||
'@surma/rollup-plugin-off-main-thread': 2.2.3
|
||||
ajv: 8.17.1
|
||||
common-tags: 1.8.2
|
||||
|
@ -7062,8 +7047,8 @@ snapshots:
|
|||
glob: 7.2.3
|
||||
lodash: 4.17.21
|
||||
pretty-bytes: 5.6.0
|
||||
rollup: '@rollup/wasm-node@4.27.4'
|
||||
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.27.4)
|
||||
rollup: '@rollup/wasm-node@4.28.1'
|
||||
rollup-plugin-terser: 7.0.2(@rollup/wasm-node@4.28.1)
|
||||
source-map: 0.8.0-beta.0
|
||||
stringify-object: 3.3.0
|
||||
strip-comments: 2.0.1
|
||||
|
|
|
@ -7,11 +7,11 @@ import { useEffect } from "react";
|
|||
import { RouterProvider } from "@tanstack/react-router"
|
||||
import { QueryClientProvider } from "@tanstack/react-query";
|
||||
import { Toaster } from "react-hot-toast";
|
||||
import { Portal } from "react-portal";
|
||||
import { Router } from "@app/routes";
|
||||
import { routerBasePath } from "@utils";
|
||||
import { queryClient } from "@api/QueryClient";
|
||||
import { SettingsContext } from "@utils/Context";
|
||||
import { Portal } from "@components/portal";
|
||||
|
||||
declare module '@tanstack/react-router' {
|
||||
interface Register {
|
||||
|
|
25
web/src/components/portal/Portal.tsx
Normal file
25
web/src/components/portal/Portal.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
import { useEffect, ReactNode } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
|
||||
interface PortalProps {
|
||||
children?: ReactNode;
|
||||
}
|
||||
|
||||
export const Portal = ({children }: PortalProps) => {
|
||||
const mount = document.getElementById("portal-root");
|
||||
const el = document.createElement("div");
|
||||
|
||||
useEffect(() => {
|
||||
mount?.appendChild(el);
|
||||
return () => {
|
||||
mount?.removeChild(el);
|
||||
}
|
||||
}, [el, mount]);
|
||||
|
||||
return createPortal(children, el)
|
||||
};
|
6
web/src/components/portal/index.ts
Normal file
6
web/src/components/portal/index.ts
Normal file
|
@ -0,0 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2021 - 2024, Ludvig Lundgren and the autobrr contributors.
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
export { Portal } from "./Portal"
|
Loading…
Add table
Add a link
Reference in a new issue