Compare commits

..

5 Commits

Author SHA1 Message Date
Ajay Ramachandran
21f54eef67 Add svgjs and testing with fake dom 2021-09-26 00:23:49 -04:00
Ajay Ramachandran
51d9edbbb4 Add start of visual segment editing 2021-09-25 23:33:13 -04:00
Ajay Ramachandran
76d9a9afa9 Merge pull request #957 from mchangrh/update-workflow
Update workflow
2021-09-21 19:04:20 -04:00
Michael C
514ebe8660 update wiki links in README 2021-09-20 02:14:54 -04:00
Michael C
2f4722162b update workflows to newest versions 2021-09-20 02:13:41 -04:00
12 changed files with 3263 additions and 289 deletions

View File

@@ -10,8 +10,8 @@ jobs:
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm install
- name: Copy configuration
run: cp config.json.example config.json
@@ -23,44 +23,44 @@ jobs:
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtension
path: dist
- run: mkdir ./builds
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/ChromeExtension.zip ./dist
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtension
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/FirefoxExtension.zip ./dist
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/ChromeExtensionBeta.zip ./dist
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionBeta
path: dist
- uses: montudor/action-zip@v0.1.0
- uses: montudor/action-zip@v1
with:
args: zip -qq -r ./builds/FirefoxExtensionBeta.zip ./dist

View File

@@ -12,8 +12,8 @@ jobs:
steps:
# Initialization
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
- uses: actions/checkout@v2
- uses: actions/setup-node@v2
- run: npm install
- name: Copy configuration
run: cp config.json.example config.json
@@ -21,7 +21,7 @@ jobs:
# Create Chrome artifacts
- name: Create Chrome artifacts
run: npm run build:chrome
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtension
path: dist
@@ -32,7 +32,7 @@ jobs:
# Create Firefox artifacts
- name: Create Firefox artifacts
run: npm run build:firefox
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtension
path: dist
@@ -42,7 +42,7 @@ jobs:
# Create Beta artifacts (Builds with the name changed to beta)
- name: Create Chrome Beta artifacts
run: npm run build:chrome -- --env.stream=beta
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: ChromeExtensionBeta
path: dist
@@ -75,7 +75,7 @@ jobs:
# Firefox Beta
- name: Create Firefox Beta artifacts
run: npm run build:firefox -- --env.stream=beta
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionBeta
path: dist
@@ -92,7 +92,7 @@ jobs:
run: sudo apt-get install rename
- name: Rename signed file
run: cd ./web-ext-artifacts ; rename 's/.*/FirefoxSignedInstaller.xpi/' *
- uses: actions/upload-artifact@v1
- uses: actions/upload-artifact@v2
with:
name: FirefoxExtensionSigned.xpi
path: ./web-ext-artifacts/FirefoxSignedInstaller.xpi

View File

@@ -50,13 +50,13 @@ See the [Wiki](https://github.com/ajayyy/SponsorBlock/wiki) for important links.
The backend server code is available here: https://github.com/ajayyy/SponsorBlockServer
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database ([License](https://github.com/ajayyy/SponsorBlock/wiki/Database-and-API-License)). If you are planning on using the database in another project, please read the [API Docs](https://github.com/ajayyy/SponsorBlock/wiki/API-Docs) page for more information.
To make sure that this project doesn't die, I have made the database publicly downloadable at https://sponsor.ajay.app/database ([License](https://github.com/ajayyy/SponsorBlock/wiki/Database-and-API-License)). If you are planning on using the database in another project, please read the [API Docs](https://wiki.sponsor.ajay.app/index.php/API_Docs) page for more information.
The dataset and API are now being used in some [ports](https://github.com/ajayyy/SponsorBlock/wiki/3rd-Party-Ports) as well as a [neural network](https://github.com/andrewzlee/NeuralBlock).
# API
You can read the API docs [here](https://github.com/ajayyy/SponsorBlockServer#api-docs).
You can read the API docs [here](https://wiki.sponsor.ajay.app/index.php/API_Docs).
# Building
@@ -90,7 +90,7 @@ mv ./oss-attribution/attribution.txt ./public/oss-attribution/attribution.txt
# Credit
The awesome [Invidious API](https://github.com/omarroth/invidious/wiki/API) was previously used, and the server is now using [NewLeaf](https://git.sr.ht/~cadence/NewLeaf) as a to get video info from YouTube.
The awesome [Invidious API](https://docs.invidious.io/API.md) was previously used, and the server is now using [NewLeaf](https://git.sr.ht/~cadence/NewLeaf) as a to get video info from YouTube.
Originally forked from [YTSponsorSkip](https://github.com/NDevTK/YTSponsorSkip), but very little code remains.

3319
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@
"description": "",
"main": "background.js",
"dependencies": {
"@svgdotjs/svg.js": "^3.1.1",
"@types/react": "^16.9.22",
"@types/react-dom": "^16.9.5",
"@types/selenium-webdriver": "^4.0.15",
@@ -13,7 +14,8 @@
"babel-preset-env": "^1.7.0",
"concurrently": "^5.1.0",
"react": "^17.0.2",
"react-dom": "^17.0.2"
"react-dom": "^17.0.2",
"svgdom": "^0.1.8"
},
"devDependencies": {
"@types/chrome": "0.0.91",

View File

@@ -305,6 +305,10 @@
"mute": {
"message": "Mute"
},
"visual": {
"message": "Visual",
"description": "This is the name of the option to create visual obstructions on top of the video to hide logos when a skip doesn't work."
},
"skip_category": {
"message": "Skip {0}?"
},

View File

@@ -1,7 +1,7 @@
import * as React from "react";
import * as CompileConfig from "../../config.json";
import Config from "../config";
import { ActionType, ActionTypes, Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
import { ActionType, Category, CategoryActionType, ContentContainer, SponsorTime } from "../types";
import Utils from "../utils";
import { getCategoryActionType } from "../utils/categoryUtils";
import SubmissionNoticeComponent from "./SubmissionNoticeComponent";

View File

@@ -0,0 +1,116 @@
import * as React from "react";
import Config from "../config";
import { ContentContainer, VisualSegmentInfo } from "../types";
import Utils from "../utils";
const utils = new Utils();
export interface VisualSegmentEditProps {
index: number,
visual: VisualSegmentInfo,
idSuffix: string,
// Contains functions and variables from the content script needed by the skip notice
contentContainer: ContentContainer,
}
export interface VisualSegmentEditState {
}
class VisualSegmentEditComponent extends React.Component<VisualSegmentEditProps, VisualSegmentEditState> {
idSuffix: string;
configUpdateListener: () => void;
constructor(props: VisualSegmentEditProps) {
super(props);
this.idSuffix = this.props.idSuffix;
this.state = {
};
}
componentDidMount(): void {
// Add as a config listener
if (!this.configUpdateListener) {
this.configUpdateListener = () => this.configUpdate();
Config.configListeners.push(this.configUpdate.bind(this));
}
}
componentWillUnmount(): void {
if (this.configUpdateListener) {
Config.configListeners.splice(Config.configListeners.indexOf(this.configUpdate.bind(this)), 1);
}
}
render(): React.ReactElement {
return <>
<span id={`time${this.props.idSuffix}`}>
{utils.getFormattedTime(this.props.visual.time, true)}
</span>
<span>
-
</span>
{this.getBoundsElement()}
<span>
-
</span>
<input
type="checkBox"
onChange={(event) => this.colorUpdated(event)}
value={this.props.visual.color}
/>
<span>
Smooth
</span>
<span>
-
</span>
<input
className="categoryColorTextBox"
type="color"
onChange={(event) => this.colorUpdated(event)}
value={this.props.visual.color}
/>
</>
}
getBoundsElement(): React.ReactElement[] {
const elements: React.ReactElement[] = [];
for (const bound of this.props.visual.bounds) {
elements.push(
<span>
{`${bound[0] * 100}% x ${bound[0] * 100}%, `}
</span>
);
}
return elements;
}
colorUpdated(event: React.ChangeEvent<HTMLInputElement>): void {
this.props.visual.color = event.target.value;
}
configUpdate(): void {
this.forceUpdate();
}
}
export default VisualSegmentEditComponent;

View File

@@ -40,7 +40,9 @@ export class SkipButtonControlBar {
this.container.appendChild(this.textContainer);
this.container.addEventListener("click", () => this.toggleSkip());
this.container.addEventListener("mouseenter", () => this.stopTimer());
this.container.addEventListener("mouseenter", () => console.log("mouseenter"));
this.container.addEventListener("mouseleave", () => this.startTimer());
this.container.addEventListener("mouseleave", () => console.log("mouseleave"));
}
getElement(): HTMLElement {

View File

@@ -58,11 +58,10 @@ export enum CategoryActionType {
export enum ActionType {
Skip = "skip",
Mute = "mute"
Mute = "mute",
Visual = "visual",
}
export const ActionTypes = [ActionType.Skip, ActionType.Mute];
export type SegmentUUID = string & { __segmentUUIDBrand: unknown };
export type Category = string & { __categoryBrand: unknown };
@@ -80,6 +79,16 @@ export interface SponsorTime {
hidden?: SponsorHideType;
source?: SponsorSourceType;
visual: string;
}
export interface VisualSegmentInfo {
time: number;
bounds: [number, number][];
smooth: boolean;
curve: string;
color: string;
}
export interface ScheduledTime extends SponsorTime {

29
src/utils/visualUtils.ts Normal file
View File

@@ -0,0 +1,29 @@
import { VisualSegmentInfo } from "../types";
import { Svg, SVG } from "@svgdotjs/svg.js";
export function toSVG(visuals: VisualSegmentInfo[]): Svg {
const svg = SVG().size(100, 100);
for (const visual of visuals) {
const path = svg.polygon();
path.fill(visual.color);
// path.stroke({
// width: 1,
// color: visual.color
// });
path.plot(visual.bounds);
}
console.log(svg.svg());
return svg;
}
export function toVisualSegmentInfo(svgInput: string | Svg): VisualSegmentInfo {
let svg = svgInput as Svg;
if (typeof svgInput === "string") {
svg = SVG().svg(svgInput);
}
throw new Error("Method not implemented.");
}

View File

@@ -0,0 +1,21 @@
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
import { createSVGWindow } from "svgdom";
import { registerWindow } from "@svgdotjs/svg.js";
import { toSVG } from "../src/utils/visualUtils";
beforeAll(() => {
const window = createSVGWindow();
registerWindow(window, window.document)
})
test("Visual Segment SVG converter", async () => {
toSVG([{
time: 0,
bounds: [[0, 0], [25, 0], [25, 40], [0, 30]],
smooth: false,
curve: "linear",
color: "#000000",
}]);
});