139 lines
4.1 KiB
TypeScript
139 lines
4.1 KiB
TypeScript
import {
|
|
LoaderFunctionArgs,
|
|
useLoaderData,
|
|
} from "react-router";
|
|
import { createAccountDMsReviewPageURL } from "#lib/urls";
|
|
import { fetchHasPendingDMs } from "#api/dms";
|
|
import { fetchImportLogs } from "#api/imports";
|
|
import { getLocalStorageItem, setLocalStorageItem } from "#storage/local";
|
|
import { PageSkeleton } from "#components/pages";
|
|
import { LoadingIcon } from "#components/loading";
|
|
|
|
import * as styles from "./importer_status.module.scss";
|
|
import { KemonoLink } from "#components/links";
|
|
import { useEffect, useState } from "react";
|
|
|
|
interface IProps {
|
|
importId: string;
|
|
isDMS?: boolean;
|
|
}
|
|
|
|
export function ImporterStatusPage() {
|
|
const { importId, isDMS } = useLoaderData() as IProps;
|
|
const title = `Import "${importId}" logs`;
|
|
const heading = `Importer Logs for ${importId}`;
|
|
const cooldown = 15_000;
|
|
const [reverse, setReverse] = useState(false);
|
|
const [logs, setLogs] = useState<Array<string> | null>(null);
|
|
const [finished, setFinished] = useState(false);
|
|
|
|
useEffect(() => {
|
|
if (finished) return;
|
|
async function fetchLogs() {
|
|
try {
|
|
let resp = await fetchImportLogs(importId);
|
|
setLogs(reverse ? [...resp].reverse() : [...resp]);
|
|
if (resp?.[resp?.length - 1]?.match(/Finished/i)) {
|
|
setFinished(true);
|
|
} else {
|
|
setFinished(false);
|
|
}
|
|
} catch (error) {
|
|
console.log(error)
|
|
}
|
|
}
|
|
|
|
fetchLogs();
|
|
|
|
const id = setInterval(fetchLogs, cooldown);
|
|
|
|
return () => clearInterval(id);
|
|
}, [reverse, finished]);
|
|
|
|
function toggleReverse() {
|
|
setReverse(!reverse);
|
|
setLogs(logs?.reverse() ?? []);
|
|
}
|
|
|
|
return (
|
|
<PageSkeleton name="importer-status" title={title} heading={heading}>
|
|
{!logs ? (
|
|
<p>
|
|
<LoadingIcon /> <span>Wait until logs load...</span>
|
|
</p>
|
|
) : logs.length ? (
|
|
<>
|
|
{isDMS && (
|
|
<div className="jumbo no-posts">
|
|
<strong>Hey!</strong>
|
|
<p>
|
|
You gave the importer permission to access your messages. To protect your anonymity, you must manually approve each one. Wait until <em>after</em> the importer says <code>Done importing DMs</code>, then go go{" "}
|
|
<KemonoLink url={String(createAccountDMsReviewPageURL())}>
|
|
here
|
|
</KemonoLink>{" "}
|
|
to choose which ones you wish to import. to choose which ones you wish to import.
|
|
</p>
|
|
</div>
|
|
)}
|
|
<div className="import__info">
|
|
<div className="import__stats">
|
|
<span>Status: {finished ? "Completed" : "In Progress"}</span>
|
|
<span>Total: {logs?.length}</span>
|
|
</div>
|
|
<button className="button" onClick={toggleReverse}>Reverse order</button>
|
|
</div>
|
|
<ol className={styles.importList}>
|
|
{logs?.map((message, index) => (
|
|
<li key={index}>{message}</li>
|
|
))}
|
|
</ol>
|
|
</>
|
|
) : (
|
|
<p>No logs found!</p>
|
|
)}
|
|
</PageSkeleton>
|
|
);
|
|
}
|
|
|
|
async function initPendingReviewDms(
|
|
forceReload = false,
|
|
minutesForRecheck = 30
|
|
) {
|
|
let hasPendingReviewDms = getLocalStorageItem("has_pending_review_dms") === "true";
|
|
const lastCheckedHasPendingReviewDms = parseInt(
|
|
getLocalStorageItem("last_checked_has_pending_review_dms") ?? "0",
|
|
10
|
|
);
|
|
|
|
if (
|
|
forceReload ||
|
|
!lastCheckedHasPendingReviewDms ||
|
|
lastCheckedHasPendingReviewDms < Date.now() - minutesForRecheck * 60 * 1000
|
|
) {
|
|
hasPendingReviewDms = await fetchHasPendingDMs();
|
|
setLocalStorageItem("has_pending_review_dms", String(hasPendingReviewDms));
|
|
localStorage.setItem(
|
|
"last_checked_has_pending_review_dms",
|
|
Date.now().toString()
|
|
);
|
|
}
|
|
}
|
|
|
|
export async function loader({
|
|
params,
|
|
request,
|
|
}: LoaderFunctionArgs): Promise<IProps> {
|
|
const importId = params.import_id?.trim();
|
|
if (!importId) {
|
|
throw new Error("Import ID is required.");
|
|
}
|
|
|
|
const searchparams = new URL(request.url).searchParams;
|
|
let isDMS = Boolean(searchparams.get("dms")?.trim());
|
|
|
|
return {
|
|
importId,
|
|
isDMS,
|
|
};
|
|
}
|