diff --git a/client/src/javascript/app.tsx b/client/src/javascript/app.tsx index d7f295c1..4bd8be80 100644 --- a/client/src/javascript/app.tsx +++ b/client/src/javascript/app.tsx @@ -1,5 +1,6 @@ -import {FC, lazy, Suspense, useEffect} from 'react'; import {observer} from 'mobx-react'; +import {QueryParamProvider} from 'use-query-params'; +import {FC, lazy, Suspense, useEffect} from 'react'; import {Router} from 'react-router-dom'; import {Route, Switch} from 'react-router'; import ReactDOM from 'react-dom'; @@ -77,13 +78,15 @@ const FloodApp: FC = observer(() => { }> - - - - - - - + + + + + + + + + diff --git a/client/src/javascript/components/AppWrapper.tsx b/client/src/javascript/components/AppWrapper.tsx index d353a85e..4b2bf037 100644 --- a/client/src/javascript/components/AppWrapper.tsx +++ b/client/src/javascript/components/AppWrapper.tsx @@ -2,6 +2,7 @@ import classnames from 'classnames'; import {CSSTransition, TransitionGroup} from 'react-transition-group'; import {FC, ReactNode} from 'react'; import {observer} from 'mobx-react'; +import {useQueryParams, StringParam} from 'use-query-params'; import AuthStore from '../stores/AuthStore'; import ConfigStore from '../stores/ConfigStore'; @@ -19,6 +20,19 @@ interface AppWrapperProps { const AppWrapper: FC = observer((props: AppWrapperProps) => { const {children, className} = props; + const [query] = useQueryParams({action: StringParam, url: StringParam}); + + if (query.action) { + if (query.action === 'add-urls') { + if (query.url) { + UIStore.setActiveModal({ + id: 'add-torrents', + initialURLs: [{id: 0, value: query.url}], + }); + } + } + } + let overlay: ReactNode = null; if (!AuthStore.isAuthenticating || (AuthStore.isAuthenticated && !UIStore.haveUIDependenciesResolved)) { overlay = ; diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.tsx b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.tsx index 64cf2b3e..8c70471f 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.tsx +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.tsx @@ -6,6 +6,7 @@ import AddTorrentsByFile from './AddTorrentsByFile'; import AddTorrentsByURL from './AddTorrentsByURL'; import Modal from '../Modal'; import SettingStore from '../../../stores/SettingStore'; +import UIStore from '../../../stores/UIStore'; const AddTorrentsModal: FC = () => { const intl = useIntl(); @@ -31,13 +32,22 @@ const AddTorrentsModal: FC = () => { }, }; + if (UIStore.activeModal?.id !== 'add-torrents') { + return null; + } + + let initialTabId: keyof typeof tabs = 'by-url'; + if (!UIStore.activeModal.initialURLs?.length) { + initialTabId = SettingStore.floodSettings.UITorrentsAddTab ?? initialTabId; + } + return ( ); }; diff --git a/package-lock.json b/package-lock.json index b8102408..55d431ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -125,6 +125,7 @@ "postcss-loader": "^4.1.0", "prettier": "^2.2.1", "promise": "^8.1.0", + "query-string": "^6.13.7", "react": "^17.0.1", "react-dev-utils": "^11.0.1", "react-dnd": "^11.1.3", @@ -156,6 +157,7 @@ "typed-emitter": "^1.3.1", "typescript": "^4.1.3", "url-loader": "^4.1.1", + "use-query-params": "^1.1.9", "webpack": "^5.10.1", "webpack-dev-server": "^4.0.0-beta.0", "webpackbar": "^5.0.0-3", @@ -18999,6 +19001,23 @@ "node": ">=0.6" } }, + "node_modules/query-string": { + "version": "6.13.7", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.7.tgz", + "integrity": "sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA==", + "dev": true, + "dependencies": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -21121,6 +21140,15 @@ "randombytes": "^2.1.0" } }, + "node_modules/serialize-query-params": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-1.2.4.tgz", + "integrity": "sha512-m4hGkOY5y+ksPDSEkw12cNxt3HRUJv5G6oF9/4yq+GCw4LznudxC73qnz++VTHqXa0j1x1/iaBIpoiMBxr6w2w==", + "dev": true, + "peerDependencies": { + "query-string": "^5.1.1 || ^6" + } + }, "node_modules/serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -21850,6 +21878,15 @@ "wbuf": "^1.7.3" } }, + "node_modules/split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -22224,6 +22261,15 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -23959,6 +24005,19 @@ "node": ">=0.10.0" } }, + "node_modules/use-query-params": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-1.1.9.tgz", + "integrity": "sha512-WAJ1GrKbFWv1TBn1RQpHqAwC7yyJsLaJjBhIfefrbY/h6mFSngzBQKirJndYwCS1ry77EwhpR/tQi5iovXWvuw==", + "dev": true, + "dependencies": { + "serialize-query-params": "^1.2.3" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, "node_modules/utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", @@ -40104,6 +40163,17 @@ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, + "query-string": { + "version": "6.13.7", + "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.13.7.tgz", + "integrity": "sha512-CsGs8ZYb39zu0WLkeOhe0NMePqgYdAuCqxOYKDR5LVCytDZYMGx3Bb+xypvQvPHVPijRXB0HZNFllCzHRe4gEA==", + "dev": true, + "requires": { + "decode-uri-component": "^0.2.0", + "split-on-first": "^1.0.0", + "strict-uri-encode": "^2.0.0" + } + }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", @@ -41774,6 +41844,13 @@ "randombytes": "^2.1.0" } }, + "serialize-query-params": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/serialize-query-params/-/serialize-query-params-1.2.4.tgz", + "integrity": "sha512-m4hGkOY5y+ksPDSEkw12cNxt3HRUJv5G6oF9/4yq+GCw4LznudxC73qnz++VTHqXa0j1x1/iaBIpoiMBxr6w2w==", + "dev": true, + "requires": {} + }, "serve-index": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", @@ -42404,6 +42481,12 @@ "wbuf": "^1.7.3" } }, + "split-on-first": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", + "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", + "dev": true + }, "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", @@ -42746,6 +42829,12 @@ } } }, + "strict-uri-encode": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", + "integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=", + "dev": true + }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -44092,6 +44181,15 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", "dev": true }, + "use-query-params": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/use-query-params/-/use-query-params-1.1.9.tgz", + "integrity": "sha512-WAJ1GrKbFWv1TBn1RQpHqAwC7yyJsLaJjBhIfefrbY/h6mFSngzBQKirJndYwCS1ry77EwhpR/tQi5iovXWvuw==", + "dev": true, + "requires": { + "serialize-query-params": "^1.2.3" + } + }, "utf8-byte-length": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", diff --git a/package.json b/package.json index b251c69c..f52822fb 100644 --- a/package.json +++ b/package.json @@ -174,6 +174,7 @@ "postcss-loader": "^4.1.0", "prettier": "^2.2.1", "promise": "^8.1.0", + "query-string": "^6.13.7", "react": "^17.0.1", "react-dev-utils": "^11.0.1", "react-dnd": "^11.1.3", @@ -205,6 +206,7 @@ "typed-emitter": "^1.3.1", "typescript": "^4.1.3", "url-loader": "^4.1.1", + "use-query-params": "^1.1.9", "webpack": "^5.10.1", "webpack-dev-server": "^4.0.0-beta.0", "webpackbar": "^5.0.0-3",