161 lines
4.2 KiB
TypeScript
161 lines
4.2 KiB
TypeScript
import browser from "webextension-polyfill";
|
|
import {type JSX} from "preact";
|
|
import {
|
|
Link,
|
|
log,
|
|
isValidHexColor,
|
|
isValidTildesUsername,
|
|
} from "../../utilities/exports.js";
|
|
import {type SettingProps, Setting} from "./index.js";
|
|
|
|
async function importFileHandler(event: Event): Promise<void> {
|
|
// Grab the imported files (if any).
|
|
const fileList = (event.target as HTMLInputElement).files;
|
|
|
|
if (fileList === null) {
|
|
log("No file imported.");
|
|
return;
|
|
}
|
|
|
|
const reader = new window.FileReader();
|
|
|
|
reader.addEventListener("load", async (): Promise<void> => {
|
|
let data: unknown;
|
|
|
|
try {
|
|
// eslint-disable-next-line @typescript-eslint/no-base-to-string
|
|
data = JSON.parse(reader.result!.toString());
|
|
} catch (error: unknown) {
|
|
log(error, true);
|
|
return;
|
|
}
|
|
|
|
if (!(data instanceof Object)) {
|
|
log("Imported data is not an object", true);
|
|
return;
|
|
}
|
|
|
|
await browser.storage.sync.set(data);
|
|
log("Successfully imported your settings, reloading the page to apply.");
|
|
setTimeout(() => {
|
|
window.location.reload();
|
|
}, 1000);
|
|
});
|
|
|
|
reader.addEventListener("error", (): void => {
|
|
log(reader.error, true);
|
|
reader.abort();
|
|
});
|
|
|
|
reader.readAsText(fileList[0]);
|
|
}
|
|
|
|
async function exportSettings(event: MouseEvent): Promise<void> {
|
|
event.preventDefault();
|
|
|
|
const storage = await browser.storage.sync.get();
|
|
const settingsBlob = new window.Blob([JSON.stringify(storage, null, 2)], {
|
|
type: "text/json",
|
|
});
|
|
|
|
const objectUrl = URL.createObjectURL(settingsBlob);
|
|
|
|
try {
|
|
await browser.downloads.download({
|
|
filename: "tildes-reextended-sync-data.json",
|
|
url: objectUrl,
|
|
saveAs: true,
|
|
});
|
|
} catch (error: unknown) {
|
|
log(error);
|
|
} finally {
|
|
// According to MDN, when creating an object URL we should also revoke it
|
|
// when "it's safe to do so" to prevent excessive memory/storage use.
|
|
// 60 seconds should probably be enough time to download the settings.
|
|
setTimeout(() => {
|
|
URL.revokeObjectURL(objectUrl);
|
|
}, 60 * 1000);
|
|
}
|
|
}
|
|
|
|
export function AboutSetting(props: SettingProps): JSX.Element {
|
|
const importSettings = () => {
|
|
document.querySelector<HTMLElement>("#import-settings")!.click();
|
|
};
|
|
|
|
const communityLink = (
|
|
<Link
|
|
url="https://gitlab.com/tildes-community"
|
|
text="Tildes Community project"
|
|
/>
|
|
);
|
|
const criusLink = <Link url="https://tildes.net/user/crius" text="Crius" />;
|
|
const gitlabIssuesLink = (
|
|
<Link
|
|
url="https://gitlab.com/tildes-community/tildes-reextended/-/issues"
|
|
text="GitLab issue tracker"
|
|
/>
|
|
);
|
|
const gitlabLicenseLink = (
|
|
<Link
|
|
url="https://gitlab.com/tildes-community/tildes-reextended/blob/main/LICENSE"
|
|
text="MIT License"
|
|
/>
|
|
);
|
|
const messageCommunityLink = (
|
|
<Link
|
|
url="https://tildes.net/user/Community/new_message"
|
|
text="message Community"
|
|
/>
|
|
);
|
|
const tildesExtendedLink = (
|
|
<Link
|
|
url="https://github.com/theCrius/tildes-extended"
|
|
text="Tildes Extended"
|
|
/>
|
|
);
|
|
return (
|
|
<Setting {...props}>
|
|
<p class="info">
|
|
This feature will make debugging logs output to the console when
|
|
enabled.
|
|
</p>
|
|
|
|
<p>
|
|
Tildes ReExtended is a from-scratch recreation of the original{" "}
|
|
{tildesExtendedLink} web extension by {criusLink}. Open-sourced with the{" "}
|
|
{gitlabLicenseLink} and maintained as a {communityLink}.
|
|
</p>
|
|
|
|
<p>
|
|
To report bugs or request new features use the links at the bottom of
|
|
this page, check out the {gitlabIssuesLink} or {messageCommunityLink} on
|
|
Tildes.
|
|
</p>
|
|
|
|
<div class="divider" />
|
|
|
|
<div class="import-export">
|
|
<p>
|
|
Note that importing settings will delete and overwrite your existing
|
|
ones.
|
|
</p>
|
|
|
|
<input
|
|
id="import-settings"
|
|
onChange={importFileHandler}
|
|
class="trx-hidden"
|
|
accept="application/json"
|
|
type="file"
|
|
/>
|
|
<button onClick={importSettings} class="button">
|
|
Import Settings
|
|
</button>
|
|
<button onClick={exportSettings} class="button">
|
|
Export Settings
|
|
</button>
|
|
</div>
|
|
</Setting>
|
|
);
|
|
}
|