i dont get it

This commit is contained in:
Pas 2025-12-19 15:24:17 -07:00
parent 28527618a9
commit 28dec0bfc7
7 changed files with 561 additions and 525 deletions

View file

@ -38,7 +38,7 @@
"@ladjs/country-language": "^1.0.3",
"@marsidev/react-turnstile": "^0.7.2",
"@noble/hashes": "^1.8.0",
"@p-stream/providers": "github:p-stream/providers#production",
"@p-stream/providers": "github:p-stream/providers#skip-sources",
"@plasmohq/messaging": "^0.6.2",
"@react-spring/web": "^9.7.5",
"@scure/bip39": "^1.6.0",

File diff suppressed because it is too large Load diff

View file

@ -14,6 +14,7 @@ export interface ScrapeItemProps {
id?: string;
percentage?: number;
children?: ReactNode;
onSkip?: () => void;
}
export interface ScrapeCardProps extends ScrapeItemProps {
@ -40,17 +41,32 @@ export function ScrapeItem(props: ScrapeItemProps) {
const text = statusTextMap[props.status];
const status = statusMap[props.status];
const handleSkip = () => {
props.onSkip?.();
};
return (
<div className="grid gap-4 grid-cols-[auto,1fr]" data-source-id={props.id}>
<StatusCircle type={status} percentage={props.percentage ?? 0} />
<div>
<p
className={
status === "loading" ? "text-white" : "text-type-secondary"
}
>
{props.name}
</p>
<div className="flex items-center justify-between">
<p
className={
status === "loading" ? "text-white" : "text-type-secondary"
}
>
{props.name}
</p>
{props.status === "pending" && (
<button
type="button"
onClick={handleSkip}
className="text-[11px] px-2 py-0.5 rounded-full bg-white/10 text-white/70"
>
Skip
</button>
)}
</div>
<Transition animation="fade" show={!!text}>
<p className="text-[15px] mt-1">{text ? t(text) : ""}</p>
</Transition>

View file

@ -154,6 +154,8 @@ export function useScrape() {
startScrape,
} = useBaseScrape();
const abortControllerRef = useRef<AbortController | null>(null);
const preferredSourceOrder = usePreferencesStore((s) => s.sourceOrder);
const enableSourceOrder = usePreferencesStore((s) => s.enableSourceOrder);
const lastSuccessfulSource = usePreferencesStore(
@ -257,22 +259,63 @@ export function useScrape() {
return getResult(sseOutput === "" ? null : sseOutput);
}
// Use individual source loops for local scraping
startScrape();
const providers = getProviders();
const output = await providers.runAll({
media,
sourceOrder: filteredSourceOrder,
embedOrder: filteredEmbedOrder,
events: {
init: initEvent,
start: startEvent,
update: updateEvent,
discoverEmbeds: discoverEmbedsEvent,
},
// Initialize with all sources
initEvent({
sourceIds: filteredSourceOrder,
});
if (output && isExtensionActiveCached())
await prepareStream(output.stream);
return getResult(output);
for (const sourceId of filteredSourceOrder) {
// Create new abort controller for each source
abortControllerRef.current = new AbortController();
try {
const output = await providers.runSourceWithEmbeds({
sourceId,
media,
embedOrder: filteredEmbedOrder,
abortSignal: abortControllerRef.current.signal,
skipInit: true,
events: {
init: initEvent,
start: startEvent,
update: updateEvent,
discoverEmbeds: discoverEmbedsEvent,
abort: (abortedId: string) => {
// Mark as cancelled/failed when aborted
updateEvent({
id: abortedId,
percentage: 100,
status: "notfound",
reason: "Skipped by user",
});
},
},
});
// Clear abort controller after completion
abortControllerRef.current = null;
if (output) {
if (isExtensionActiveCached()) {
await prepareStream(output.stream);
}
return getResult(output);
}
} catch (error) {
// Clear abort controller on error
abortControllerRef.current = null;
// Continue to next source on error
continue;
}
}
// No sources found streams
return getResult(null);
},
[
initEvent,
@ -292,6 +335,13 @@ export function useScrape() {
],
);
const skipCurrentSource = useCallback(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
abortControllerRef.current = null;
}
}, []);
const resumeScraping = useCallback(
async (media: ScrapeMedia, startFromSourceId: string) => {
return startScraping(media, startFromSourceId);
@ -302,6 +352,7 @@ export function useScrape() {
return {
startScraping,
resumeScraping,
skipCurrentSource,
sourceOrder,
sources,
currentSource,

View file

@ -36,8 +36,14 @@ export interface ScrapingProps {
export function ScrapingPart(props: ScrapingProps) {
const { report } = useReportProviders();
const { startScraping, resumeScraping, sourceOrder, sources, currentSource } =
useScrape();
const {
startScraping,
resumeScraping,
skipCurrentSource,
sourceOrder,
sources,
currentSource,
} = useScrape();
const isMounted = useMountedState();
const { t } = useTranslation();
@ -134,6 +140,9 @@ export function ScrapingPart(props: ScrapingProps) {
status={source.status}
hasChildren={order.children.length > 0}
percentage={source.percentage}
onSkip={
source.status === "pending" ? skipCurrentSource : undefined
}
>
<div
className={classNames({

View file

@ -323,9 +323,8 @@ export const createSourceSlice: MakeSlice<SourceSlice> = (set, get) => ({
});
try {
const { scrapeExternalSubtitles } = await import(
"@/utils/externalSubtitles"
);
const { scrapeExternalSubtitles } =
await import("@/utils/externalSubtitles");
const externalCaptions = await scrapeExternalSubtitles(store.meta);
if (externalCaptions.length > 0) {

View file

@ -5,7 +5,7 @@ import { useAuthStore } from "@/stores/auth";
export function isAutoplayAllowed() {
return Boolean(
conf().ALLOW_AUTOPLAY ||
isExtensionActiveCached() ||
useAuthStore.getState().proxySet,
isExtensionActiveCached() ||
useAuthStore.getState().proxySet,
);
}