Redesign #3
97
icons/logo-black-square.svg
Normal file
97
icons/logo-black-square.svg
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="2048"
|
||||||
|
height="2048"
|
||||||
|
viewBox="0 0 541.86667 541.86667"
|
||||||
|
version="1.1"
|
||||||
|
id="svg2399"
|
||||||
|
inkscape:version="1.1.1 (3bf5ae0d25, 2021-09-20, custom)"
|
||||||
|
sodipodi:docname="logo-black-square.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview2401"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
showgrid="false"
|
||||||
|
fit-margin-top="0"
|
||||||
|
fit-margin-left="0"
|
||||||
|
fit-margin-right="0"
|
||||||
|
fit-margin-bottom="0"
|
||||||
|
units="px"
|
||||||
|
lock-margins="true"
|
||||||
|
inkscape:zoom="0.083628825"
|
||||||
|
inkscape:cx="-131.53359"
|
||||||
|
inkscape:cy="2845.9087"
|
||||||
|
inkscape:window-width="1920"
|
||||||
|
inkscape:window-height="1024"
|
||||||
|
inkscape:window-x="0"
|
||||||
|
inkscape:window-y="0"
|
||||||
|
inkscape:window-maximized="1"
|
||||||
|
inkscape:current-layer="g5214-0-20-3-1-92" />
|
||||||
|
<defs
|
||||||
|
id="defs2396" />
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(195.39804,196.97992)">
|
||||||
|
<g
|
||||||
|
id="g2559">
|
||||||
|
<rect
|
||||||
|
y="-196.9799"
|
||||||
|
x="-195.39803"
|
||||||
|
height="541.86664"
|
||||||
|
width="541.86664"
|
||||||
|
id="rect5174-5-2-1-8-9"
|
||||||
|
style="fill:#000000;fill-opacity:1;stroke:none;stroke-width:89.9968;stroke-opacity:1"
|
||||||
|
inkscape:export-xdpi="562.5"
|
||||||
|
inkscape:export-ydpi="562.5" />
|
||||||
|
<g
|
||||||
|
id="g5216-6-9-9-2-87"
|
||||||
|
transform="matrix(25.209725,0,0,25.209725,-5013.7768,-42754.638)"
|
||||||
|
style="fill:#ffffff;fill-opacity:1">
|
||||||
|
<g
|
||||||
|
id="g5214-0-20-3-1-92"
|
||||||
|
transform="translate(-146.29537,198.647)"
|
||||||
|
style="fill:#ffffff;fill-opacity:1">
|
||||||
|
<g
|
||||||
|
id="g17009"
|
||||||
|
transform="matrix(1.0494588,0,0,1.0494588,-16.219745,-80.475607)">
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:13.4678px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;word-spacing:0px;stroke-width:0.0935269"
|
||||||
|
x="338.93002"
|
||||||
|
y="1510.9918"
|
||||||
|
id="text3426"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3424"
|
||||||
|
style="font-style:italic;font-variant:normal;font-weight:900;font-stretch:normal;font-size:13.4678px;font-family:Poppins;-inkscape-font-specification:'Poppins Heavy Italic';stroke-width:0.0935269"
|
||||||
|
x="338.93002"
|
||||||
|
y="1510.9918">Pr</tspan></text>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-size:13.4678px;line-height:1.25;font-family:Poppins;-inkscape-font-specification:Poppins;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke-width:0.0935269"
|
||||||
|
x="352.05331"
|
||||||
|
y="1510.884"
|
||||||
|
id="text3426-3"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan3424-6"
|
||||||
|
style="font-style:italic;font-variant:normal;font-weight:900;font-stretch:normal;font-size:13.4678px;font-family:Poppins;-inkscape-font-specification:'Poppins Heavy Italic';stroke-width:0.0935269"
|
||||||
|
x="352.05331"
|
||||||
|
y="1510.884">.</tspan></text>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
@ -1,33 +1,35 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"name": "Problematyczne requesty",
|
"name": "Problematyczne requesty",
|
||||||
"version": "1.0",
|
"version": "1.0",
|
||||||
|
|
||||||
"description": "",
|
"description": "",
|
||||||
|
|
||||||
"sidebar_action": {
|
"sidebar_action": {
|
||||||
"default_title": "ICD",
|
"default_title": "Problematic requests",
|
||||||
"default_panel": "sidebar/sidebar.html",
|
"default_panel": "sidebar/sidebar.html",
|
||||||
"default_icon": "sidebar_icon.png"
|
"default_icon": "icons/logo-black-square.svg",
|
||||||
},
|
"browser_style": true,
|
||||||
"background": {
|
"open_at_install": true
|
||||||
"scripts": ["lib/background.js"]
|
},
|
||||||
},
|
"background": {
|
||||||
"icons": {
|
"scripts": ["lib/background.js"]
|
||||||
"48": "icons/border-48.png"
|
},
|
||||||
},
|
"icons": {
|
||||||
"permissions": [
|
"48": "icons/border-48.png"
|
||||||
"proxy",
|
},
|
||||||
"storage",
|
"permissions": [
|
||||||
"<all_urls>",
|
"proxy",
|
||||||
"webRequest",
|
"storage",
|
||||||
"webRequestBlocking",
|
"<all_urls>",
|
||||||
"cookies",
|
"webRequest",
|
||||||
"privacy"
|
"webRequestBlocking",
|
||||||
],
|
"cookies",
|
||||||
"browser_specific_settings": {
|
"privacy"
|
||||||
"gecko": {
|
],
|
||||||
"id": "problematic-requests@internet-czas-dzialac.pl"
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "problematic-requests@internet-czas-dzialac.pl"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
23
options.tsx
23
options.tsx
@ -10,6 +10,8 @@ export default function Options({
|
|||||||
setCookiesOrOriginOnly,
|
setCookiesOrOriginOnly,
|
||||||
readWarningDataDialog,
|
readWarningDataDialog,
|
||||||
setReadWarningDataDialog,
|
setReadWarningDataDialog,
|
||||||
|
logoVisibility,
|
||||||
|
setLogoVisibility,
|
||||||
}: {
|
}: {
|
||||||
minValueLength: number;
|
minValueLength: number;
|
||||||
setMinValueLength: (n: number) => void;
|
setMinValueLength: (n: number) => void;
|
||||||
@ -19,6 +21,8 @@ export default function Options({
|
|||||||
setCookiesOrOriginOnly: (b: boolean) => void;
|
setCookiesOrOriginOnly: (b: boolean) => void;
|
||||||
readWarningDataDialog: string;
|
readWarningDataDialog: string;
|
||||||
setReadWarningDataDialog: (s: string) => void;
|
setReadWarningDataDialog: (s: string) => void;
|
||||||
|
logoVisibility: string;
|
||||||
|
setLogoVisibility: (s: string) => void;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div className="options-container">
|
<div className="options-container">
|
||||||
@ -43,7 +47,24 @@ export default function Options({
|
|||||||
className="label-checkbox"
|
className="label-checkbox"
|
||||||
htmlFor="readWarningDataDialog"
|
htmlFor="readWarningDataDialog"
|
||||||
>
|
>
|
||||||
Wyświetlaj informację o pozyskiwanych danych
|
Wyświetlaj komunikat o pozyskiwanych danych
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="input-container">
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
id="logoVisibility"
|
||||||
|
checked={logoVisibility != '0'}
|
||||||
|
onChange={(e) => {
|
||||||
|
setLogoVisibility(e.target.checked ? '1' : '0');
|
||||||
|
localStorage.setItem(
|
||||||
|
'logoVisibility',
|
||||||
|
e.target.checked ? '1' : '0'
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<label className="label-checkbox" htmlFor="logoVisibility">
|
||||||
|
Wyświetlaj logo <i>Internet. Czas działać!</i>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from 'react';
|
||||||
import { RequestCluster } from "../request-cluster";
|
import { RequestCluster } from '../request-cluster';
|
||||||
import { StolenDataEntry } from "../stolen-data-entry";
|
import { StolenDataEntry } from '../stolen-data-entry';
|
||||||
import EmailTemplate1 from "./email-template-1";
|
import EmailTemplate1 from './email-template-1';
|
||||||
import EmailTemplate2 from "./email-template-2";
|
import EmailTemplate2 from './email-template-2';
|
||||||
|
|
||||||
export default function EmailTemplate({
|
export default function EmailTemplate({
|
||||||
entries,
|
entries,
|
||||||
clusters,
|
clusters,
|
||||||
version,
|
version,
|
||||||
}: {
|
}: {
|
||||||
entries: StolenDataEntry[];
|
entries: StolenDataEntry[];
|
||||||
clusters: Record<string, RequestCluster>;
|
clusters: Record<string, RequestCluster>;
|
||||||
version: number;
|
version: number;
|
||||||
}) {
|
}) {
|
||||||
const [templateVersion, setTemplateVersion] = useState("2");
|
const [templateVersion, setTemplateVersion] = useState('2');
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<select
|
<select
|
||||||
value={templateVersion}
|
value={templateVersion}
|
||||||
onChange={(e) => setTemplateVersion(e.target.value)}
|
onChange={(e) => setTemplateVersion(e.target.value)}
|
||||||
>
|
>
|
||||||
<option value="1">wersja 1</option>
|
<option value="1">wersja 1</option>
|
||||||
<option value="2">wersja 2</option>
|
<option value="2">wersja 2</option>
|
||||||
</select>
|
</select>
|
||||||
{templateVersion === "1" ? (
|
{templateVersion === '1' ? (
|
||||||
<EmailTemplate1 {...{ entries, clusters, version }} />
|
<EmailTemplate1 {...{ entries, clusters, version }} />
|
||||||
) : (
|
) : (
|
||||||
<EmailTemplate2 {...{ entries, clusters, version }} />
|
<EmailTemplate2 {...{ entries, clusters, version }} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,117 +1,124 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from 'react';
|
||||||
import { HAREntry } from "../extended-request";
|
import { HAREntry } from '../extended-request';
|
||||||
import { StolenDataEntry } from "../stolen-data-entry";
|
import { StolenDataEntry } from '../stolen-data-entry';
|
||||||
import { getshorthost, unique } from "../util";
|
import { getshorthost, unique } from '../util';
|
||||||
|
|
||||||
function handleNewFile(
|
function handleNewFile(
|
||||||
element: HTMLInputElement,
|
element: HTMLInputElement,
|
||||||
entries: StolenDataEntry[],
|
entries: StolenDataEntry[],
|
||||||
setFiltered: (Blob) => void
|
setFiltered: (Blob) => void
|
||||||
): void {
|
): void {
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.addEventListener("load", () => {
|
reader.addEventListener('load', () => {
|
||||||
const content = JSON.parse(reader.result as string);
|
const content = JSON.parse(reader.result as string);
|
||||||
content.log.entries = content.log.entries.filter((har_entry: HAREntry) =>
|
content.log.entries = content.log.entries.filter(
|
||||||
entries.some((entry) => entry.matchesHAREntry(har_entry))
|
(har_entry: HAREntry) =>
|
||||||
);
|
entries.some((entry) => entry.matchesHAREntry(har_entry))
|
||||||
setFiltered(
|
);
|
||||||
new Blob([JSON.stringify(content)], { type: "application/json" })
|
setFiltered(
|
||||||
);
|
new Blob([JSON.stringify(content)], { type: 'application/json' })
|
||||||
});
|
);
|
||||||
reader.readAsText(element.files[0]);
|
});
|
||||||
|
reader.readAsText(element.files[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateFakeHAR(entries: StolenDataEntry[]) {
|
function generateFakeHAR(entries: StolenDataEntry[]) {
|
||||||
const requests = unique(entries.map((entry) => entry.request))
|
const requests = unique(entries.map((entry) => entry.request))
|
||||||
.sort((request1, request2) => {
|
.sort((request1, request2) => {
|
||||||
if (request1.shorthost < request2.shorthost) {
|
if (request1.shorthost < request2.shorthost) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (request1.shorthost > request2.shorthost) {
|
} else if (request1.shorthost > request2.shorthost) {
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
return request2.getBalancedPriority() - request1.getBalancedPriority();
|
return (
|
||||||
}
|
request2.getBalancedPriority() -
|
||||||
})
|
request1.getBalancedPriority()
|
||||||
.filter((_, index, array) => {
|
);
|
||||||
if (index == 0) return true;
|
}
|
||||||
if (array[index].shorthost == array[index - 1].shorthost) {
|
})
|
||||||
return false;
|
.filter((_, index, array) => {
|
||||||
}
|
if (index == 0) return true;
|
||||||
return true;
|
if (array[index].shorthost == array[index - 1].shorthost) {
|
||||||
})
|
return false;
|
||||||
.sort(
|
}
|
||||||
(entry1, entry2) =>
|
return true;
|
||||||
entry2.getBalancedPriority() - entry1.getBalancedPriority()
|
})
|
||||||
);
|
.sort(
|
||||||
|
(entry1, entry2) =>
|
||||||
|
entry2.getBalancedPriority() - entry1.getBalancedPriority()
|
||||||
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
log: {
|
log: {
|
||||||
version: "1.2",
|
version: '1.2',
|
||||||
creator: {
|
creator: {
|
||||||
name: "Firefox",
|
name: 'Firefox',
|
||||||
version: "94.0",
|
version: '94.0',
|
||||||
},
|
},
|
||||||
browser: {
|
browser: {
|
||||||
name: "Firefox",
|
name: 'Firefox',
|
||||||
version: "94.0",
|
version: '94.0',
|
||||||
},
|
},
|
||||||
pages: [
|
pages: [
|
||||||
{
|
{
|
||||||
startedDateTime: "2021-11-08T20:27:23.195+01:00",
|
startedDateTime: '2021-11-08T20:27:23.195+01:00',
|
||||||
id: "page_1",
|
id: 'page_1',
|
||||||
title: "HAR DUmp",
|
title: 'HAR DUmp',
|
||||||
pageTimings: {
|
pageTimings: {
|
||||||
onContentLoad: 467,
|
onContentLoad: 467,
|
||||||
onLoad: 4226,
|
onLoad: 4226,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
entries: requests.map((r) => r.toHAR()),
|
||||||
},
|
},
|
||||||
],
|
};
|
||||||
entries: requests.map((r) => r.toHAR()),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function HARConverter({
|
export default function HARConverter({
|
||||||
entries,
|
entries,
|
||||||
}: {
|
}: {
|
||||||
entries: StolenDataEntry[];
|
entries: StolenDataEntry[];
|
||||||
}) {
|
}) {
|
||||||
const [filtered, setFiltered] = useState<Blob | null>(null);
|
const [filtered, setFiltered] = useState<Blob | null>(null);
|
||||||
const [filename, setFilename] = useState("");
|
const [filename, setFilename] = useState('');
|
||||||
const [fakeHAR, setFakeHAR] = useState<ReturnType<typeof generateFakeHAR>>();
|
const [fakeHAR, setFakeHAR] =
|
||||||
useEffect(() => {
|
useState<ReturnType<typeof generateFakeHAR>>();
|
||||||
setFakeHAR(generateFakeHAR(entries));
|
useEffect(() => {
|
||||||
}, []);
|
setFakeHAR(generateFakeHAR(entries));
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
accept=".har"
|
accept=".har"
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
setFilename(e.target.files[0].name);
|
setFilename(e.target.files[0].name);
|
||||||
handleNewFile(e.target, entries, setFiltered);
|
handleNewFile(e.target, entries, setFiltered);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{(filtered && (
|
{(filtered && (
|
||||||
<a
|
<a
|
||||||
href={URL.createObjectURL(filtered)}
|
href={URL.createObjectURL(filtered)}
|
||||||
download={filename.replace(".har", "-filtered.har")}
|
download={filename.replace('.har', '-filtered.har')}
|
||||||
>
|
>
|
||||||
Pobierz wyfiltrowany HAR
|
Pobierz wyfiltrowany HAR
|
||||||
</a>
|
</a>
|
||||||
)) ||
|
)) ||
|
||||||
null}
|
null}
|
||||||
<a
|
<a
|
||||||
href={URL.createObjectURL(
|
href={URL.createObjectURL(
|
||||||
new Blob([JSON.stringify(fakeHAR)], { type: "application/json" })
|
new Blob([JSON.stringify(fakeHAR)], {
|
||||||
)}
|
type: 'application/json',
|
||||||
download={`${getshorthost(
|
})
|
||||||
entries[0].request.originalURL
|
)}
|
||||||
)}-${new Date().toJSON()}-trimmed.har`}
|
download={`${getshorthost(
|
||||||
>
|
entries[0].request.originalURL
|
||||||
Pobierz "zfałszowany" HAR
|
)}-${new Date().toJSON()}-trimmed.har`}
|
||||||
</a>
|
>
|
||||||
</div>
|
Pobierz "zredukowany" HAR
|
||||||
);
|
</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ select {
|
|||||||
|
|
||||||
#app {
|
#app {
|
||||||
user-select: text;
|
user-select: text;
|
||||||
padding: 0rem 1rem;
|
padding: 0rem 0.75rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
|
@ -3,8 +3,9 @@
|
|||||||
.sidebar {
|
.sidebar {
|
||||||
.header {
|
.header {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 8rem 1fr 1rem;
|
grid-template-columns: 6.67rem 1fr 1rem;
|
||||||
max-height: 4rem;
|
align-items: flex-start;
|
||||||
|
max-height: 3.5rem;
|
||||||
padding-top: 0.5rem;
|
padding-top: 0.5rem;
|
||||||
padding-bottom: 0.5rem;
|
padding-bottom: 0.5rem;
|
||||||
border-bottom: 1px solid $light-grey;
|
border-bottom: 1px solid $light-grey;
|
||||||
|
@ -34,6 +34,9 @@ const Sidebar = () => {
|
|||||||
const [readWarningDataDialog, setReadWarningDataDialog] = useState<
|
const [readWarningDataDialog, setReadWarningDataDialog] = useState<
|
||||||
string | null
|
string | null
|
||||||
>(localStorage.getItem('readWarningDataDialog'));
|
>(localStorage.getItem('readWarningDataDialog'));
|
||||||
|
const [logoVisibility, setLogoVisibility] = useState<string | null>(
|
||||||
|
localStorage.getItem('setLogoVisibility')
|
||||||
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const listener = async (data: any) => {
|
const listener = async (data: any) => {
|
||||||
@ -76,13 +79,19 @@ const Sidebar = () => {
|
|||||||
<header className="header">
|
<header className="header">
|
||||||
<img
|
<img
|
||||||
src="../assets/logo-internet-czas-dzialac.svg"
|
src="../assets/logo-internet-czas-dzialac.svg"
|
||||||
height={48}
|
height={40}
|
||||||
></img>
|
></img>
|
||||||
<div className="webpage-metadata">
|
<div className="webpage-metadata">
|
||||||
<span>Analiza strony</span>
|
{origin ? (
|
||||||
<span className="webpage-metadata--hyperlink">
|
<Fragment>
|
||||||
{origin}
|
<span>Analiza strony</span>
|
||||||
</span>
|
<span className="webpage-metadata--hyperlink">
|
||||||
|
{origin}
|
||||||
|
</span>
|
||||||
|
</Fragment>
|
||||||
|
) : (
|
||||||
|
<span>Przejdź do wybranej strony internetowej</span>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
{stolenDataView ? (
|
{stolenDataView ? (
|
||||||
<a href="https://internet-czas-dzialac.pl">
|
<a href="https://internet-czas-dzialac.pl">
|
||||||
@ -199,6 +208,8 @@ const Sidebar = () => {
|
|||||||
setCookiesOrOriginOnly={setCookiesOrOriginOnly}
|
setCookiesOrOriginOnly={setCookiesOrOriginOnly}
|
||||||
readWarningDataDialog={readWarningDataDialog}
|
readWarningDataDialog={readWarningDataDialog}
|
||||||
setReadWarningDataDialog={setReadWarningDataDialog}
|
setReadWarningDataDialog={setReadWarningDataDialog}
|
||||||
|
logoVisibility={logoVisibility}
|
||||||
|
setLogoVisibility={setLogoVisibility}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
|
@ -1,30 +1,30 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function TabDropdown({
|
export default function TabDropdown({
|
||||||
setPickedTab,
|
setPickedTab,
|
||||||
pickedTab,
|
pickedTab,
|
||||||
}: {
|
}: {
|
||||||
setPickedTab: (tab_id: number) => void;
|
setPickedTab: (tab_id: number) => void;
|
||||||
pickedTab: number;
|
pickedTab: number;
|
||||||
}) {
|
}) {
|
||||||
const [tabs, setTabs] = useState([]);
|
const [tabs, setTabs] = useState([]);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
browser.tabs.query({ currentWindow: true }).then(setTabs);
|
browser.tabs.query({ currentWindow: true }).then(setTabs);
|
||||||
}, []);
|
}, []);
|
||||||
return (
|
return (
|
||||||
<select
|
<select
|
||||||
id="tab_dropdown"
|
id="tab_dropdown"
|
||||||
value={pickedTab}
|
value={pickedTab}
|
||||||
onChange={async (e) => {
|
onChange={async (e) => {
|
||||||
setPickedTab(parseInt(e.target.value));
|
setPickedTab(parseInt(e.target.value));
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{tabs.map((tab) => (
|
{tabs.map((tab) => (
|
||||||
<option value={tab.id} key={tab.id}>
|
<option value={tab.id} key={tab.id}>
|
||||||
{tab.title}
|
{tab.title}
|
||||||
</option>
|
</option>
|
||||||
))}
|
))}
|
||||||
</select>
|
</select>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user