Skip to content

Commit

Permalink
Fix capture downloads (#294, #295)
Browse files Browse the repository at this point in the history
  • Loading branch information
baptistecdr committed Oct 21, 2023
1 parent 0ebf773 commit 89af575
Show file tree
Hide file tree
Showing 10 changed files with 119 additions and 199 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "aria2-integration",
"private": true,
"type": "module",
"version": "4.5.1-SNAPSHOT.0",
"version": "4.5.1",
"scripts": {
"lint": "eslint 'src/**/*.{js,ts,jsx,tsx}'",
"lint:fix": "eslint 'src/**/*.{js,ts,jsx,tsx}' --fix",
Expand Down
2 changes: 1 addition & 1 deletion public/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"author": "baptistecdr",
"homepage_url": "https://github.com/baptistecdr/aria2-extensions",
"description": "__MSG_extDescription__",
"version": "4.5.1-SNAPSHOT.0",
"version": "4.5.1",
"default_locale": "en",
"permissions": [
"contextMenus",
Expand Down
20 changes: 13 additions & 7 deletions src/background/background.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,15 @@ function downloadItemMustBeCaptured(extensionOptions: ExtensionOptions, item: Do
const url = new URL(item.finalUrl ?? item.url); // finalUrl exists only on Chromium
const refererURL = referrer !== "" ? new URL(referrer) : null;

if (excludedProtocols.indexOf(url.protocol) !== -1) {
if (excludedProtocols.includes(url.protocol)) {
return false;
}

if (
!!extensionOptions.excludedSites.map((site) => url.hostname.includes(site)).filter((isFound) => isFound).length ||
(refererURL && !!extensionOptions.excludedSites.map((site) => refererURL.hostname.includes(site)).filter((include) => include).length)
) {
if (extensionOptions.excludedSites.map((site) => url.hostname.includes(site)).includes(true)) {
return false;
}

if (refererURL && extensionOptions.excludedSites.map((site) => refererURL.hostname.includes(site)).includes(true)) {
return false;
}

Expand Down Expand Up @@ -166,8 +167,13 @@ browser.downloads.onCreated.addListener(async (downloadItem) => {
}
const cookies = await getCookies(referrer, currentTab?.cookieStoreId);
if (downloadItemMustBeCaptured(extensionOptions, downloadItem, referrer)) {
await browser.downloads.cancel(downloadItem.id).catch();
await browser.downloads.erase({ id: downloadItem.id }).catch();
try {
await browser.downloads.cancel(downloadItem.id);
} catch {
await browser.downloads.removeFile(downloadItem.id);
} finally {
await browser.downloads.erase({ id: downloadItem.id });
}
try {
await captureDownloadItem(connection, server, downloadItem, referrer, cookies);
await showNotification(browser.i18n.getMessage("addFileSuccess", server.name));
Expand Down
86 changes: 26 additions & 60 deletions src/options/components/extension-options-tab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeEvent, useCallback, useEffect, useState } from "react";
import { ChangeEvent, useState } from "react";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap/dist/js/bootstrap";
import { Alert, Button, Col, Form, FormText } from "react-bootstrap";
Expand All @@ -21,15 +21,6 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
const [theme, setTheme] = useState(extensionOptions.theme);
const [alertProps, setAlertProps] = useState(new AlertProps());

useEffect(() => {
setCaptureDownloads(extensionOptions.captureDownloads);
setCaptureServer(extensionOptions.captureServer);
setExcludedProtocols(extensionOptions.excludedProtocols);
setExcludedSites(extensionOptions.excludedSites);
setExcludedFileTypes(extensionOptions.excludedFileTypes);
setTheme(extensionOptions.theme);
}, [extensionOptions]);

function serializeExcludedOption(excludedOptions: string) {
return excludedOptions
.trim()
Expand All @@ -41,47 +32,22 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
return excludedOption.join(", ");
}

const onChangeCaptureServer = useCallback(
(event: ChangeEvent<HTMLSelectElement>) => {
if (extensionOptions.servers[event.target.value]) {
setCaptureServer(event.target.value);
}
},
[extensionOptions.servers],
);

const onChangeCaptureDownloads = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
setCaptureDownloads(e.target.checked);
if (!e.target.checked) {
setCaptureServer("");
} else {
setCaptureServer(extensionOptions.captureServer);
}
},
[extensionOptions.captureServer],
);

const onChangeExcludedProtocols = useCallback(
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setExcludedProtocols(serializeExcludedOption(e.target.value)),
[],
);

const onChangeExcludedSites = useCallback(
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setExcludedSites(serializeExcludedOption(e.target.value)),
[],
);

const onChangeExcludedFileTypes = useCallback(
(e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => setExcludedFileTypes(serializeExcludedOption(e.target.value)),
[],
);

const onChangeTheme = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setTheme(e.target.value as Theme);
}, []);
const onChangeCaptureServer = (event: ChangeEvent<HTMLSelectElement>) => {
if (extensionOptions.servers[event.target.value]) {
setCaptureServer(event.target.value);
}
};

const onChangeCaptureDownloads = (e: ChangeEvent<HTMLInputElement>) => {
setCaptureDownloads(e.target.checked);
if (!e.target.checked) {
setCaptureServer("");
} else {
setCaptureServer(extensionOptions.captureServer);
}
};

const onClickSaveExtensionOptions = useCallback(async () => {
const onClickSaveExtensionOptions = async () => {
try {
const newExtensionOptions = await new ExtensionOptions(
extensionOptions.servers,
Expand All @@ -97,7 +63,7 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
} catch {
setAlertProps(AlertProps.error(i18n("serverOptionsError")));
}
}, [captureDownloads, captureServer, excludedFileTypes, excludedProtocols, excludedSites, extensionOptions.servers, setExtensionOptions, theme]);
};

return (
<Form className="row p-3">
Expand Down Expand Up @@ -140,8 +106,8 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
rows={3}
placeholder={i18n("extensionOptionsExcludeProtocolsInformation")}
disabled={!captureDownloads}
defaultValue={deserializeExcludedOption(excludedProtocols)}
onChange={onChangeExcludedProtocols}
value={deserializeExcludedOption(excludedProtocols)}
onChange={(e) => setExcludedProtocols(serializeExcludedOption(e.target.value))}
/>
<FormText id="exclude-protocols-description" muted>
{i18n("extensionOptionsExcludeProtocolsDescription")}
Expand All @@ -157,8 +123,8 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
rows={3}
placeholder={i18n("extensionOptionsExcludeSitesInformation")}
disabled={!captureDownloads}
defaultValue={deserializeExcludedOption(excludedSites)}
onChange={onChangeExcludedSites}
value={deserializeExcludedOption(excludedSites)}
onChange={(e) => setExcludedSites(serializeExcludedOption(e.target.value))}
/>
<FormText id="exclude-sites-description" muted>
{i18n("extensionOptionsExcludeSitesDescription")}
Expand All @@ -174,8 +140,8 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
rows={3}
placeholder={i18n("extensionOptionsExcludeFileTypesInformation")}
disabled={!captureDownloads}
defaultValue={deserializeExcludedOption(excludedFileTypes)}
onChange={onChangeExcludedFileTypes}
value={deserializeExcludedOption(excludedFileTypes)}
onChange={(e) => setExcludedFileTypes(serializeExcludedOption(e.target.value))}
/>
<Form.Text id="exclude-file-types-description" muted>
{i18n("extensionOptionsExcludeFileTypesDescription")}
Expand All @@ -195,7 +161,7 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
id="theme-light"
value={Theme.Light}
checked={theme === Theme.Light}
onChange={onChangeTheme}
onChange={(e) => setTheme(e.target.value as Theme)}
/>
<Form.Check
inline
Expand All @@ -205,7 +171,7 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
id="theme-dark"
value={Theme.Dark}
checked={theme === Theme.Dark}
onChange={onChangeTheme}
onChange={(e) => setTheme(e.target.value as Theme)}
/>
<Form.Check
inline
Expand All @@ -215,7 +181,7 @@ function ExtensionOptionsTab({ extensionOptions, setExtensionOptions }: Props) {
id="theme-auto"
value={Theme.Auto}
checked={theme === Theme.Auto}
onChange={onChangeTheme}
onChange={(e) => setTheme(e.target.value as Theme)}
/>
</Form.Group>
</Form.Group>
Expand Down
46 changes: 9 additions & 37 deletions src/options/components/server-options-tab.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeEvent, FormEvent, useCallback, useState } from "react";
import { FormEvent, useState } from "react";
import "bootstrap/dist/css/bootstrap.css";
import "bootstrap-icons/font/bootstrap-icons.css";
import { Alert, Button, Col, Form, InputGroup, Row } from "react-bootstrap";
Expand Down Expand Up @@ -51,34 +51,6 @@ function ServerOptionsTab({ extensionOptions, setExtensionOptions, server, delet
.trim();
}

const onChangeServerName = useCallback((e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setServerName(e.target.value);
}, []);

const onChangeServerHost = useCallback((e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setServerHost(e.target.value);
}, []);

const onChangeServerPort = useCallback((e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setServerPort(parseInt(e.target.value, 10));
}, []);

const onChangeServerSecure = useCallback((e: ChangeEvent<HTMLInputElement>) => {
setServerSecure(e.target.checked);
}, []);

const onChangeServerSecret = useCallback((e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setServerSecret(e.target.value);
}, []);

const onChangeRpcParameters = useCallback((e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setServerRpcParameters(serializeRpcParameters(e.target.value));
}, []);

const onClickDeleteServer = useCallback(async () => {
await deleteServer(server);
}, [deleteServer, server]);

async function onSubmitSaveServer(formEvent: FormEvent<HTMLFormElement>) {
formEvent.preventDefault();
formEvent.stopPropagation();
Expand Down Expand Up @@ -113,31 +85,31 @@ function ServerOptionsTab({ extensionOptions, setExtensionOptions, server, delet
<Row className="mb-3">
<Form.Group as={Col} controlId="form-server-name">
<Form.Label>{i18n("serverOptionsName")}</Form.Label>
<Form.Control type="text" value={serverName} required onChange={onChangeServerName} />
<Form.Control type="text" value={serverName} required onChange={(e) => setServerName(e.target.value)} />
</Form.Group>
<Form.Group as={Col} controlId="form-server-host">
<Form.Label>{i18n("serverOptionsHost")}</Form.Label>
<Form.Control type="text" value={serverHost} required onChange={onChangeServerHost} />
<Form.Control type="text" value={serverHost} required onChange={(e) => setServerHost(e.target.value)} />
</Form.Group>
</Row>

<Row className="mb-3">
<Form.Group as={Col} controlId="form-server-port">
<Form.Label>{i18n("serverOptionsPort")}</Form.Label>
<Form.Control type="number" min={0} max={49151} value={serverPort} required onChange={onChangeServerPort} />
<Form.Control type="number" min={0} max={49151} value={serverPort} required onChange={(e) => setServerPort(parseInt(e.target.value, 10))} />
</Form.Group>

<Form.Group as={Col} controlId="form-server-secure">
<Form.Label>{i18n("serverOptionsSecureConnection")}</Form.Label>
<Form.Check checked={serverSecure} onChange={onChangeServerSecure} />
<Form.Check checked={serverSecure} onChange={(e) => setServerSecure(e.target.checked)} />
</Form.Group>
</Row>

<Row className="mb-3">
<Form.Group as={Col} controlId="form-server-secret">
<Form.Label>{i18n("serverOptionsSecret")}</Form.Label>
<InputGroup>
<Form.Control type={showPassword ? "text" : "password"} value={serverSecret} onChange={onChangeServerSecret} />
<Form.Control type={showPassword ? "text" : "password"} value={serverSecret} onChange={(e) => setServerSecret(e.target.value)} />
<InputGroup.Text role="button" tabIndex={0} onClick={() => setShowPassword(!showPassword)}>
<i className={showPassword ? "bi-eye-slash" : "bi-eye"} />
</InputGroup.Text>
Expand All @@ -155,8 +127,8 @@ function ServerOptionsTab({ extensionOptions, setExtensionOptions, server, delet
as="textarea"
rows={3}
placeholder="split: 5"
defaultValue={deserializeRpcParameters(serverRpcParameters)}
onChange={onChangeRpcParameters}
value={deserializeRpcParameters(serverRpcParameters)}
onChange={(e) => setServerRpcParameters(serializeRpcParameters(e.target.value))}
/>
<Form.Text id="form-rpc-parameters-description">{i18n("serverOptionsRpcParametersDescription")}</Form.Text>
</Form.Group>
Expand All @@ -167,7 +139,7 @@ function ServerOptionsTab({ extensionOptions, setExtensionOptions, server, delet
<Button type="submit" variant="primary">
{i18n("serverOptionsSave")}
</Button>
<Button variant="danger" className="ms-2" onClick={onClickDeleteServer}>
<Button variant="danger" className="ms-2" onClick={() => deleteServer(server)}>
{i18n("serverOptionsDelete")}
</Button>
</Col>
Expand Down
51 changes: 24 additions & 27 deletions src/options/options.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createRoot } from "react-dom/client";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.min";
import { useCallback, useEffect, useState } from "react";
import { useEffect, useState } from "react";
import { Container, Tab, Tabs } from "react-bootstrap";
import ExtensionOptionsTab from "./components/extension-options-tab";
import ServerOptionsTab from "./components/server-options-tab";
Expand Down Expand Up @@ -42,39 +42,36 @@ function Options() {
setActiveTab(server.uuid);
}

const deleteServer = useCallback(
async (server: Server) => {
let newExtensionOptions = await extensionOptions.deleteServer(server);
const serversKeys = Object.keys(newExtensionOptions.servers);
let newActiveTab = EXTENSION_OPTIONS_TAB;
if (serversKeys.length === 0) {
newExtensionOptions = await new ExtensionOptions(
newExtensionOptions.servers,
"",
false,
newExtensionOptions.excludedProtocols,
newExtensionOptions.excludedSites,
newExtensionOptions.excludedFileTypes,
).toStorage();
} else {
[newActiveTab] = serversKeys;
}
setExtensionOptions(newExtensionOptions);
setActiveTab(newActiveTab);
},
[extensionOptions],
);
const deleteServer = async (server: Server) => {
let newExtensionOptions = await extensionOptions.deleteServer(server);
const serversKeys = Object.keys(newExtensionOptions.servers);
let newActiveTab = EXTENSION_OPTIONS_TAB;
if (serversKeys.length === 0) {
newExtensionOptions = await new ExtensionOptions(
newExtensionOptions.servers,
"",
false,
newExtensionOptions.excludedProtocols,
newExtensionOptions.excludedSites,
newExtensionOptions.excludedFileTypes,
).toStorage();
} else {
[newActiveTab] = serversKeys;
}
setExtensionOptions(newExtensionOptions);
setActiveTab(newActiveTab);
};

return (
<Tabs
id="tabs-servers-options"
defaultActiveKey={defaultActiveTab}
activeKey={activeTab}
onSelect={async (k) => {
if (k === ADD_SERVER_TAB) {
onSelect={async (selectedTab) => {
if (selectedTab === ADD_SERVER_TAB) {
await addServer();
} else {
setActiveTab(k ?? defaultActiveTab);
setActiveTab(selectedTab ?? defaultActiveTab);
}
}}
>
Expand All @@ -91,7 +88,7 @@ function Options() {
))}
<Tab eventKey={ADD_SERVER_TAB} title="+" />
<Tab eventKey={EXTENSION_OPTIONS_TAB} title={i18n("extensionOptionsTitle")}>
<ExtensionOptionsTab extensionOptions={extensionOptions} setExtensionOptions={setExtensionOptions} />
<ExtensionOptionsTab key={Object.keys(extensionOptions.servers).length} extensionOptions={extensionOptions} setExtensionOptions={setExtensionOptions} />
</Tab>
</Tabs>
);
Expand Down
Loading

0 comments on commit 89af575

Please sign in to comment.