Skip to content

Commit

Permalink
move settings applying and setting plr elements out of onPageChange
Browse files Browse the repository at this point in the history
  • Loading branch information
GooseOb committed Dec 1, 2024
1 parent bc15bc0 commit e8eb9fa
Showing 1 changed file with 105 additions and 94 deletions.
199 changes: 105 additions & 94 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,6 @@ const untilAppear = <T>(getItem: () => T, msToWait?: number) =>
until<T>(getItem, Boolean, msToWait);

let channelConfig = null as Partial<Cfg>;
let video: HTMLVideoElement,
subtitlesBtn: HTMLButtonElement,
muteBtn: HTMLButtonElement,
speedNormal: string,
isSpeedApplied = false;

type Focusable = { focus(): void };

Expand Down Expand Up @@ -290,50 +285,82 @@ const findInNodeList = <T extends HTMLElement>(
return null;
};

const ytMenu = {
async setPlayer(plr: Readonly<HTMLElement>) {
this.element = plr.querySelector('.ytp-settings-menu');
this._btn = plr.querySelector('.ytp-settings-button');
const clickBtn = this._btn.click.bind(this._btn);
const plr = {
async set(el: HTMLElement) {
this.isSpeedApplied = false;
await delay(1_000);
const getAd = () => el.querySelector('.ytp-ad-player-overlay');
await until(getAd, (ad) => !ad, 200_000);
this.video ||= el.querySelector('.html5-main-video');
this.subtitlesBtn ||= el.querySelector('.ytp-subtitles-button');
this.muteBtn ||= el.querySelector('.ytp-mute-button');

this.menu.element ||= el.querySelector('.ytp-settings-menu');
this.menu._btn ||= el.querySelector('.ytp-settings-button');
const clickBtn = () => {
this.menu._btn.click();
};

restoreFocusAfter(clickBtn);
await delay(50);
restoreFocusAfter(clickBtn);

const getMenuItems = () =>
plr.menu.element.querySelectorAll<YtSettingItem>(
'.ytp-menuitem[role="menuitem"]'
);
plr.menu.setSettingItems(await until(getMenuItems, (arr) => !!arr.length));
if (!this.speedNormal)
restoreFocusAfter(() => {
this.speedNormal = plr.menu.findInItem(
SPEED,
(btn) => !+btn.textContent
).textContent;
});
},
isSpeedApplied: false,
speedNormal: '',
element: null as HTMLElement,
_btn: null as HTMLElement,
isOpen() {
return this.element.style.display !== 'none';
},
setOpen(bool: boolean) {
if (bool !== this.isOpen()) this._btn.click();
},
openItem(item: Readonly<YtSettingItem>) {
this.setOpen(true);
item.click();
return this.element.querySelectorAll(
'.ytp-panel-animate-forward .ytp-menuitem-label'
);
},
settingItems: {
[SPEED]: null,
[QUALITY]: null,
} as Record<YtSettingName, YtSettingItem | null>,
setSettingItems(items: DeepReadonly<NodeListOf<YtSettingItem>>) {
const findIcon = (d: string) =>
findInNodeList(items, (el) => !!el.querySelector(`path[d="${d}"]`));

this.settingItems[SPEED] = findIcon(
'M10,8v8l6-4L10,8L10,8z M6.3,5L5.7,4.2C7.2,3,9,2.2,11,2l0.1,1C9.3,3.2,7.7,3.9,6.3,5z M5,6.3L4.2,5.7C3,7.2,2.2,9,2,11 l1,.1C3.2,9.3,3.9,7.7,5,6.3z M5,17.7c-1.1-1.4-1.8-3.1-2-4.8L2,13c0.2,2,1,3.8,2.2,5.4L5,17.7z M11.1,21c-1.8-0.2-3.4-0.9-4.8-2 l-0.6,.8C7.2,21,9,21.8,11,22L11.1,21z M22,12c0-5.2-3.9-9.4-9-10l-0.1,1c4.6,.5,8.1,4.3,8.1,9s-3.5,8.5-8.1,9l0.1,1 C18.2,21.5,22,17.2,22,12z'
);
this.settingItems[QUALITY] = findIcon(
'M15,17h6v1h-6V17z M11,17H3v1h8v2h1v-2v-1v-2h-1V17z M14,8h1V6V5V3h-1v2H3v1h11V8z M18,5v1h3V5H18z M6,14h1v-2v-1V9H6v2H3v1 h3V14z M10,12h11v-1H10V12z'
);
},
findInItem(
name: YtSettingName,
finder: (item: Readonly<HTMLElement>) => boolean
) {
return findInNodeList(this.openItem(this.settingItems[name]), finder);
video: null as HTMLVideoElement,
subtitlesBtn: null as HTMLButtonElement,
muteBtn: null as HTMLButtonElement,
menu: {
element: null as HTMLElement,
_btn: null as HTMLElement,
isOpen() {
return this.element.style.display !== 'none';
},
setOpen(bool: boolean) {
if (bool !== this.isOpen()) this._btn.click();
},
openItem(item: Readonly<YtSettingItem>) {
this.setOpen(true);
item.click();
return this.element.querySelectorAll(
'.ytp-panel-animate-forward .ytp-menuitem-label'
);
},
settingItems: {
[SPEED]: null,
[QUALITY]: null,
} as Record<YtSettingName, YtSettingItem | null>,
setSettingItems(items: DeepReadonly<NodeListOf<YtSettingItem>>) {
const findIcon = (d: string) =>
findInNodeList(items, (el) => !!el.querySelector(`path[d="${d}"]`));

this.settingItems[SPEED] = findIcon(
'M10,8v8l6-4L10,8L10,8z M6.3,5L5.7,4.2C7.2,3,9,2.2,11,2l0.1,1C9.3,3.2,7.7,3.9,6.3,5z M5,6.3L4.2,5.7C3,7.2,2.2,9,2,11 l1,.1C3.2,9.3,3.9,7.7,5,6.3z M5,17.7c-1.1-1.4-1.8-3.1-2-4.8L2,13c0.2,2,1,3.8,2.2,5.4L5,17.7z M11.1,21c-1.8-0.2-3.4-0.9-4.8-2 l-0.6,.8C7.2,21,9,21.8,11,22L11.1,21z M22,12c0-5.2-3.9-9.4-9-10l-0.1,1c4.6,.5,8.1,4.3,8.1,9s-3.5,8.5-8.1,9l0.1,1 C18.2,21.5,22,17.2,22,12z'
);
this.settingItems[QUALITY] = findIcon(
'M15,17h6v1h-6V17z M11,17H3v1h8v2h1v-2v-1v-2h-1V17z M14,8h1V6V5V3h-1v2H3v1h11V8z M18,5v1h3V5H18z M6,14h1v-2v-1V9H6v2H3v1 h3V14z M10,12h11v-1H10V12z'
);
},
findInItem(
name: YtSettingName,
finder: (item: Readonly<HTMLElement>) => boolean
) {
return findInNodeList(this.openItem(this.settingItems[name]), finder);
},
},
};

Expand Down Expand Up @@ -381,42 +408,42 @@ type ValueSetters = { [P in Setting]: (value: Cfg[P]) => void };

const valueSetters: ValueSetters & ValueSetterHelpers = {
_ytSettingItem(settingName, value) {
const isOpen = ytMenu.isOpen();
const isOpen = plr.menu.isOpen();
const compare = comparators[settingName];
const btn = ytMenu.findInItem(settingName, (btn) =>
const btn = plr.menu.findInItem(settingName, (btn) =>
compare(value, btn.textContent)
);
if (btn) {
btn.click();
ytMenu.setOpen(isOpen);
plr.menu.setOpen(isOpen);
}
},
speed(value) {
this._ytSettingItem(SPEED, isSpeedApplied ? speedNormal : value);
isSpeedApplied = !isSpeedApplied;
this._ytSettingItem(SPEED, plr.isSpeedApplied ? plr.speedNormal : value);
plr.isSpeedApplied = !plr.isSpeedApplied;
},
customSpeed(value) {
try {
video.playbackRate = isSpeedApplied ? 1 : +value;
plr.video.playbackRate = plr.isSpeedApplied ? 1 : +value;
} catch {
logger.outOfRange('Custom speed');
return;
}
isSpeedApplied = !isSpeedApplied;
plr.isSpeedApplied = !plr.isSpeedApplied;
},
subtitles(value) {
if (subtitlesBtn.ariaPressed !== value.toString()) subtitlesBtn.click();
if (plr.subtitlesBtn.ariaPressed !== value.toString())
plr.subtitlesBtn.click();
},
volume(value) {
const num = +value;
muteBtn ||= document.querySelector<HTMLButtonElement>('.ytp-mute-button');
const isMuted = muteBtn.dataset.titleNoTooltip !== 'Mute';
const isMuted = plr.muteBtn.dataset.titleNoTooltip !== 'Mute';
if (num === 0) {
if (!isMuted) muteBtn.click();
if (!isMuted) plr.muteBtn.click();
} else {
if (isMuted) muteBtn.click();
if (isMuted) plr.muteBtn.click();
try {
video.volume = num / 100;
plr.video.volume = num / 100;
} catch {
logger.outOfRange('Volume');
}
Expand Down Expand Up @@ -486,7 +513,7 @@ const computeSettings = (doNotChangeSpeed: boolean) => {
const isChannelSpeed = 'speed' in channelConfig;
const isChannelCustomSpeed = 'customSpeed' in channelConfig;
if (doNotChangeSpeed) {
settings.speed = speedNormal;
settings.speed = plr.speedNormal;
delete settings.customSpeed;
} else if (isChannelCustomSpeed) {
delete settings.speed;
Expand All @@ -496,6 +523,20 @@ const computeSettings = (doNotChangeSpeed: boolean) => {
return settings;
};

const applySettings = (settings: Cfg) => {
restoreFocusAfter(() => {
if (!isNaN(+settings.customSpeed)) {
valueSetters.customSpeed(settings.customSpeed);
}

delete settings.customSpeed;

for (const setting in settings)
valueSetters[setting as Setting](settings[setting as never]);
plr.menu.setOpen(false);
});
};

const delay = (ms: number) => new Promise((res) => setTimeout(res, ms));
const onPageChange = async () => {
if (location.pathname !== '/watch') return;
Expand All @@ -507,43 +548,13 @@ const onPageChange = async () => {

channelConfig = cfg.channels[channelUsername] ||= {};

const plr = await untilAppear(getPlr);
await delay(1_000);
const getAd = () => plr.querySelector('.ytp-ad-player-overlay');
await until(getAd, (ad) => !ad, 200_000);
await ytMenu.setPlayer(plr);
const getMenuItems = () =>
ytMenu.element.querySelectorAll<YtSettingItem>(
'.ytp-menuitem[role="menuitem"]'
);
ytMenu.setSettingItems(await until(getMenuItems, (arr) => !!arr.length));
if (!speedNormal)
restoreFocusAfter(() => {
speedNormal = ytMenu.findInItem(
SPEED,
(btn) => !+btn.textContent
).textContent;
});
await plr.set(await untilAppear(getPlr));

isSpeedApplied = false;
video ||= plr.querySelector('.html5-main-video');
subtitlesBtn ||= plr.querySelector('.ytp-subtitles-button');
restoreFocusAfter(() => {
const settings = computeSettings(
applySettings(
computeSettings(
cfg.flags.standardMusicSpeed && isMusicChannel(aboveTheFold)
);

if (!isNaN(+settings.customSpeed)) {
isSpeedApplied = false;
valueSetters.customSpeed(settings.customSpeed);
}

delete settings.customSpeed;

for (const setting in settings)
valueSetters[setting as Setting](settings[setting as never]);
ytMenu.setOpen(false);
});
)
);

/* ---------------------- settings menu ---------------------- */

Expand Down Expand Up @@ -586,7 +597,7 @@ const onPageChange = async () => {
'1.75',
'1.5',
'1.25',
speedNormal,
plr.speedNormal,
'0.75',
'0.5',
'0.25',
Expand Down

0 comments on commit e8eb9fa

Please sign in to comment.