convert plugins

This commit is contained in:
JellyBrick
2023-11-27 18:41:50 +09:00
parent 4fad456619
commit 3ffbfbe0e3
70 changed files with 1617 additions and 1836 deletions

View File

@ -1,4 +1,11 @@
import { createPluginBuilder } from '../utils/builder';
import is from 'electron-is';
import { createPlugin } from '@/utils';
import { sortSegments } from './segments';
import type { GetPlayerResponse } from '@/types/get-player-response';
import type { Segment, SkipSegment } from './types';
export type SponsorBlockPluginConfig = {
enabled: boolean;
@ -6,7 +13,9 @@ export type SponsorBlockPluginConfig = {
categories: ('sponsor' | 'intro' | 'outro' | 'interaction' | 'selfpromo' | 'music_offtopic')[];
};
const builder = createPluginBuilder('sponsorblock', {
let currentSegments: Segment[] = [];
export default createPlugin({
name: 'SponsorBlock',
restartNeeded: true,
config: {
@ -21,12 +30,83 @@ const builder = createPluginBuilder('sponsorblock', {
'music_offtopic',
],
} as SponsorBlockPluginConfig,
});
async backend({ getConfig, ipc }) {
const fetchSegments = async (apiURL: string, categories: string[], videoId: string) => {
const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoId}&categories=${JSON.stringify(
categories,
)}`;
try {
const resp = await fetch(sponsorBlockURL, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
});
if (resp.status !== 200) {
return [];
}
export default builder;
const segments = await resp.json() as SkipSegment[];
return sortSegments(
segments.map((submission) => submission.segment),
);
} catch (error) {
if (is.dev()) {
console.log('error on sponsorblock request:', error);
}
declare global {
interface PluginBuilderList {
[builder.id]: typeof builder;
return [];
}
};
const config = await getConfig();
const { apiURL, categories } = config;
ipc.on('video-src-changed', async (data: GetPlayerResponse) => {
const segments = await fetchSegments(apiURL, categories, data?.videoDetails?.videoId);
ipc.send('sponsorblock-skip', segments);
});
},
renderer: {
timeUpdateListener: (e: Event) => {
if (e.target instanceof HTMLVideoElement) {
const target = e.target;
for (const segment of currentSegments) {
if (
target.currentTime >= segment[0]
&& target.currentTime < segment[1]
) {
target.currentTime = segment[1];
if (window.electronIs.dev()) {
console.log('SponsorBlock: skipping segment', segment);
}
}
}
}
},
resetSegments: () => currentSegments = [],
start({ ipc }) {
ipc.on('sponsorblock-skip', (segments: Segment[]) => {
currentSegments = segments;
});
},
onPlayerApiReady() {
const video = document.querySelector<HTMLVideoElement>('video');
if (!video) return;
video.addEventListener('timeupdate', this.timeUpdateListener);
// Reset segments on song end
video.addEventListener('emptied', this.resetSegments);
},
stop() {
const video = document.querySelector<HTMLVideoElement>('video');
if (!video) return;
video.removeEventListener('timeupdate', this.timeUpdateListener);
video.removeEventListener('emptied', this.resetSegments);
}
}
}
});

View File

@ -1,51 +0,0 @@
import is from 'electron-is';
import { sortSegments } from './segments';
import { SkipSegment } from './types';
import builder from './index';
import type { GetPlayerResponse } from '../../types/get-player-response';
const fetchSegments = async (apiURL: string, categories: string[], videoId: string) => {
const sponsorBlockURL = `${apiURL}/api/skipSegments?videoID=${videoId}&categories=${JSON.stringify(
categories,
)}`;
try {
const resp = await fetch(sponsorBlockURL, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
},
redirect: 'follow',
});
if (resp.status !== 200) {
return [];
}
const segments = await resp.json() as SkipSegment[];
return sortSegments(
segments.map((submission) => submission.segment),
);
} catch (error) {
if (is.dev()) {
console.log('error on sponsorblock request:', error);
}
return [];
}
};
export default builder.createMain(({ getConfig, on, send }) => ({
async onLoad() {
const config = await getConfig();
const { apiURL, categories } = config;
on('video-src-changed', async (_, data: GetPlayerResponse) => {
const segments = await fetchSegments(apiURL, categories, data?.videoDetails?.videoId);
send('sponsorblock-skip', segments);
});
}
}));

View File

@ -1,49 +0,0 @@
import { Segment } from './types';
import builder from './index';
export default builder.createRenderer(({ on }) => {
let currentSegments: Segment[] = [];
const timeUpdateListener = (e: Event) => {
if (e.target instanceof HTMLVideoElement) {
const target = e.target;
for (const segment of currentSegments) {
if (
target.currentTime >= segment[0]
&& target.currentTime < segment[1]
) {
target.currentTime = segment[1];
if (window.electronIs.dev()) {
console.log('SponsorBlock: skipping segment', segment);
}
}
}
}
};
const resetSegments = () => currentSegments = [];
return ({
onLoad() {
on('sponsorblock-skip', (_, segments: Segment[]) => {
currentSegments = segments;
});
},
onPlayerApiReady() {
const video = document.querySelector<HTMLVideoElement>('video');
if (!video) return;
video.addEventListener('timeupdate', timeUpdateListener);
// Reset segments on song end
video.addEventListener('emptied', resetSegments);
},
onUnload() {
const video = document.querySelector<HTMLVideoElement>('video');
if (!video) return;
video.removeEventListener('timeupdate', timeUpdateListener);
video.removeEventListener('emptied', resetSegments);
}
});
});