QOL: Move source code under the src directory. (#1318)

This commit is contained in:
Angelos Bouklis
2023-10-15 15:52:48 +03:00
committed by GitHub
parent 30c8dcf730
commit 7625a3aa52
159 changed files with 102 additions and 71 deletions

View File

@ -0,0 +1,52 @@
import { BrowserWindow, ipcMain } from 'electron';
import is from 'electron-is';
import { sortSegments } from './segments';
import { SkipSegment } from './types';
import defaultConfig from '../../config/defaults';
import type { GetPlayerResponse } from '../../types/get-player-response';
import type { ConfigType } from '../../config/dynamic';
export default (win: BrowserWindow, options: ConfigType<'sponsorblock'>) => {
const { apiURL, categories } = {
...defaultConfig.plugins.sponsorblock,
...options,
};
ipcMain.on('video-src-changed', async (_, data: GetPlayerResponse) => {
const segments = await fetchSegments(apiURL, categories, data?.videoDetails?.videoId);
win.webContents.send('sponsorblock-skip', segments);
});
};
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 [];
}
};

View File

@ -0,0 +1,37 @@
import { ipcRenderer } from 'electron';
import is from 'electron-is';
import { Segment } from './types';
let currentSegments: Segment[] = [];
export default () => {
ipcRenderer.on('sponsorblock-skip', (_, segments: Segment[]) => {
currentSegments = segments;
});
document.addEventListener('apiLoaded', () => {
const video = document.querySelector<HTMLVideoElement>('video');
if (!video) return;
video.addEventListener('timeupdate', (e) => {
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 (is.dev()) {
console.log('SponsorBlock: skipping segment', segment);
}
}
}
}
});
// Reset segments on song end
video.addEventListener('emptied', () => currentSegments = []);
}, { once: true, passive: true });
};

View File

@ -0,0 +1,34 @@
// Segments are an array [ [start, end], … ]
import { Segment } from './types';
export const sortSegments = (segments: Segment[]) => {
segments.sort((segment1, segment2) =>
segment1[0] === segment2[0]
? segment1[1] - segment2[1]
: segment1[0] - segment2[0],
);
const compiledSegments: Segment[] = [];
let currentSegment: Segment | undefined;
for (const segment of segments) {
if (!currentSegment) {
currentSegment = segment;
continue;
}
if (currentSegment[1] < segment[0]) {
compiledSegments.push(currentSegment);
currentSegment = segment;
continue;
}
currentSegment[1] = Math.max(currentSegment[1], segment[1]);
}
if (currentSegment) {
compiledSegments.push(currentSegment);
}
return compiledSegments;
};

View File

@ -0,0 +1,36 @@
const { test, expect } = require('@playwright/test');
const { sortSegments } = require('../segments');
test('Segment sorting', () => {
expect(
sortSegments([
[0, 3],
[7, 8],
[5, 6],
]),
).toEqual([
[0, 3],
[5, 6],
[7, 8],
]);
expect(
sortSegments([
[0, 5],
[6, 8],
[4, 6],
]),
).toEqual([[0, 8]]);
expect(
sortSegments([
[0, 6],
[7, 8],
[4, 6],
]),
).toEqual([
[0, 6],
[7, 8],
]);
});

View File

@ -0,0 +1,12 @@
export type Segment = [number, number];
export interface SkipSegment { // Array of this object
segment: Segment; //[0, 15.23] start and end time in seconds
UUID: string,
category: string, // [1]
videoDuration: number // Duration of video when submission occurred (to be used to determine when a submission is out of date). 0 when unknown. +- 1 second
actionType: string, // [3]
locked: number, // if submission is locked
votes: number, // Votes on segment
description: string, // title for chapters, empty string for other segments
}