Skip to content

Commit 33ff22c

Browse files
feat: automatically disable ambient mode #708
1 parent d0fac1a commit 33ff22c

File tree

9 files changed

+118
-1
lines changed

9 files changed

+118
-1
lines changed
Loading

Diff for: public/locales/en-US.json

+4
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@
264264
"label": "Automatic theater mode",
265265
"title": "Automatically enables theater mode when you load a video"
266266
},
267+
"automaticallyDisableAmbientMode": {
268+
"label": "Automatically disable ambient mode",
269+
"title": "Automatically disables ambient mode when you load a video"
270+
},
267271
"automaticallyDisableClosedCaptions": {
268272
"label": "Automatically disable closed captions",
269273
"title": "Automatically disables closed captions when you load a video"

Diff for: public/locales/en-US.json.d.ts

+4
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,10 @@ interface EnUS {
179179
};
180180
miscellaneous: {
181181
features: {
182+
automaticallyDisableAmbientMode: {
183+
label: "Automatically disable ambient mode";
184+
title: "Automatically disables ambient mode when you load a video";
185+
};
182186
automaticallyDisableClosedCaptions: {
183187
label: "Automatically disable closed captions";
184188
title: "Automatically disables closed captions when you load a video";

Diff for: src/components/Settings/Settings.tsx

+8
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,14 @@ export default function Settings() {
765765
title={t("settings.sections.miscellaneous.features.automaticallyDisableClosedCaptions.title")}
766766
type="checkbox"
767767
/>
768+
<Setting
769+
checked={settings.enable_automatically_disable_ambient_mode?.toString() === "true"}
770+
id="enable_automatically_disable_ambient_mode"
771+
label={t("settings.sections.miscellaneous.features.automaticallyDisableAmbientMode.label")}
772+
onChange={setCheckboxOption("enable_automatically_disable_ambient_mode")}
773+
title={t("settings.sections.miscellaneous.features.automaticallyDisableAmbientMode.title")}
774+
type="checkbox"
775+
/>
768776
</SettingSection>
769777
<SettingSection title={t("settings.sections.videoHistory.title")}>
770778
<SettingTitle />
+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import { isWatchPage, waitForAllElements, waitForSpecificMessage } from "@/src/utils/utilities";
2+
let ambientModeWasEnabled = false;
3+
4+
export async function enableAutomaticallyDisableAmbientMode() {
5+
const {
6+
data: {
7+
options: { enable_automatically_disable_ambient_mode }
8+
}
9+
} = await waitForSpecificMessage("options", "request_data", "content");
10+
if (!enable_automatically_disable_ambient_mode) return;
11+
if (!isWatchPage()) return;
12+
await waitForAllElements([
13+
"div#player",
14+
"div#player-wide-container",
15+
"div#video-container",
16+
"div#player-container",
17+
"div.ytp-settings-menu:not(#yte-feature-menu)"
18+
]);
19+
const settingsButton = document.querySelector<HTMLButtonElement>("button.ytp-settings-button");
20+
const settingsMenu = document.querySelector<HTMLDivElement>("div.ytp-settings-menu:not(#yte-feature-menu)");
21+
const settingsPanelMenu = settingsMenu?.querySelector<HTMLDivElement>("div.ytp-panel-menu");
22+
if (!settingsButton || !settingsMenu || !settingsPanelMenu) return;
23+
// If the settings panel menu is empty, emulate a click on the settings button to hydrate the settings menu with the necessary elements
24+
if (!settingsPanelMenu.hasChildNodes()) {
25+
// Hide the settings menu temporarily
26+
settingsMenu.classList.add("hidden");
27+
// Click on the settings button to open the settings menu
28+
settingsButton.click();
29+
// Click on the settings button again to close the settings menu
30+
settingsButton.click();
31+
}
32+
// Get the ambient mode menu item element
33+
const ambientModeMenuItem = settingsPanelMenu.querySelector<HTMLDivElement>(
34+
".ytp-menuitem:has(.ytp-menuitem-icon svg path[d='M21 7v10H3V7h18m1-1H2v12h20V6zM11.5 2v3h1V2h-1zm1 17h-1v3h1v-3zM3.79 3 6 5.21l.71-.71L4.5 2.29 3.79 3zm2.92 16.5L6 18.79 3.79 21l.71.71 2.21-2.21zM19.5 2.29 17.29 4.5l.71.71L20.21 3l-.71-.71zm0 19.42.71-.71L18 18.79l-.71.71 2.21 2.21z'])"
35+
);
36+
// If ambient mode menu item is not available, return
37+
if (!ambientModeMenuItem) return settingsMenu.classList.remove("hidden");
38+
const ambientModeEnabled = ambientModeMenuItem.getAttribute("aria-checked") === "true";
39+
// If ambient mode was not enabled, return
40+
if (!ambientModeEnabled) return settingsMenu.classList.remove("hidden");
41+
ambientModeWasEnabled = ambientModeEnabled;
42+
// Disable ambient mode
43+
ambientModeMenuItem.click();
44+
settingsMenu.classList.remove("hidden");
45+
}
46+
47+
export async function disableAutomaticallyDisableAmbientMode() {
48+
// If ambient mode wasn't enabled, return
49+
if (!ambientModeWasEnabled) return;
50+
await waitForAllElements([
51+
"div#player",
52+
"div#player-wide-container",
53+
"div#video-container",
54+
"div#player-container",
55+
"div.ytp-settings-menu:not(#yte-feature-menu)"
56+
]);
57+
const settingsButton = document.querySelector<HTMLButtonElement>("button.ytp-settings-button");
58+
const settingsMenu = document.querySelector<HTMLDivElement>("div.ytp-settings-menu:not(#yte-feature-menu)");
59+
const settingsPanelMenu = settingsMenu?.querySelector<HTMLDivElement>("div.ytp-panel-menu");
60+
if (!settingsButton || !settingsMenu || !settingsPanelMenu) return;
61+
// If the settings panel menu is empty, emulate a click on the settings button to hydrate the settings menu with the necessary elements
62+
if (!settingsPanelMenu.hasChildNodes()) {
63+
settingsMenu.classList.add("hidden");
64+
// Click on the settings button to open the settings menu in a hidden state
65+
settingsButton.click();
66+
// Click on the settings button again to close the settings menu
67+
settingsButton.click();
68+
}
69+
const ambientModeMenuItem = settingsPanelMenu.querySelector<HTMLDivElement>(
70+
".ytp-menuitem:has(.ytp-menuitem-icon svg path[d='M21 7v10H3V7h18m1-1H2v12h20V6zM11.5 2v3h1V2h-1zm1 17h-1v3h1v-3zM3.79 3 6 5.21l.71-.71L4.5 2.29 3.79 3zm2.92 16.5L6 18.79 3.79 21l.71.71 2.21-2.21zM19.5 2.29 17.29 4.5l.71.71L20.21 3l-.71-.71zm0 19.42.71-.71L18 18.79l-.71.71 2.21 2.21z'])"
71+
);
72+
// If ambient mode menu item is not available, return
73+
if (!ambientModeMenuItem) return settingsMenu.classList.remove("hidden");
74+
// Enable ambient mode
75+
ambientModeMenuItem.click();
76+
}

Diff for: src/pages/content/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,11 @@ const storageChangeHandler = async (changes: StorageChanges, areaName: string) =
271271
automaticTheaterModeEnabled: newValue
272272
});
273273
},
274+
enable_automatically_disable_ambient_mode: (__oldValue, newValue) => {
275+
sendExtensionOnlyMessage("automaticallyDisableAmbientModeChange", {
276+
automaticallyDisableAmbientModeEnabled: newValue
277+
});
278+
},
274279
enable_automatically_disable_closed_captions: (__oldValue, newValue) => {
275280
sendExtensionOnlyMessage("automaticallyDisableClosedCaptionsChange", {
276281
automaticallyDisableClosedCaptionsEnabled: newValue

Diff for: src/pages/embedded/index.ts

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { deepDarkPresets } from "@/src/deepDarkPresets";
22
import { featureButtonFunctions, type FeatureFuncRecord } from "@/src/features";
3+
import { disableAutomaticallyDisableAmbientMode, enableAutomaticallyDisableAmbientMode } from "@/src/features/automaticallyDisableAmbientMode";
34
import {
45
disableAutomaticallyDisableClosedCaptions,
56
enableAutomaticallyDisableClosedCaptions
@@ -191,7 +192,8 @@ const enableFeatures = () => {
191192
enableHideTranslateComment(),
192193
enableHideEndScreenCards(),
193194
enablePlaylistLength(),
194-
enableAutomaticallyDisableClosedCaptions()
195+
enableAutomaticallyDisableClosedCaptions(),
196+
enableAutomaticallyDisableAmbientMode()
195197
]);
196198
// Enable feature menu before calling button functions
197199
await enableFeatureMenu();
@@ -299,6 +301,17 @@ window.addEventListener("DOMContentLoaded", function () {
299301
}
300302
if (!message) return;
301303
switch (message.type) {
304+
case "automaticallyDisableAmbientModeChange": {
305+
const {
306+
data: { automaticallyDisableAmbientModeEnabled }
307+
} = message;
308+
if (automaticallyDisableAmbientModeEnabled) {
309+
await enableAutomaticallyDisableAmbientMode();
310+
} else {
311+
await disableAutomaticallyDisableAmbientMode();
312+
}
313+
break;
314+
}
302315
case "automaticallyDisableClosedCaptionsChange": {
303316
const {
304317
data: { automaticallyDisableClosedCaptionsEnabled }

Diff for: src/types/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ export type ContentToBackgroundSendOnlyMessageMappings = {
353353
pauseBackgroundPlayers: ActionMessage<"pauseBackgroundPlayers">;
354354
};
355355
export type ExtensionSendOnlyMessageMappings = {
356+
automaticallyDisableAmbientModeChange: DataResponseMessage<
357+
"automaticallyDisableAmbientModeChange",
358+
{ automaticallyDisableAmbientModeEnabled: boolean }
359+
>;
356360
automaticallyDisableClosedCaptionsChange: DataResponseMessage<
357361
"automaticallyDisableClosedCaptionsChange",
358362
{ automaticallyDisableClosedCaptionsEnabled: boolean }
@@ -458,6 +462,7 @@ export type configuration = {
458462
deep_dark_custom_theme_colors: DeepDarkCustomThemeColors;
459463
deep_dark_preset: DeepDarkPreset;
460464
enable_automatic_theater_mode: boolean;
465+
enable_automatically_disable_ambient_mode: boolean;
461466
enable_automatically_disable_closed_captions: boolean;
462467
enable_automatically_set_quality: boolean;
463468
enable_copy_timestamp_url_button: boolean;

Diff for: src/utils/constants.ts

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export const defaultConfiguration = {
5151
},
5252
deep_dark_preset: "Deep-Dark",
5353
enable_automatic_theater_mode: false,
54+
enable_automatically_disable_ambient_mode: false,
5455
enable_automatically_disable_closed_captions: false,
5556
enable_automatically_set_quality: false,
5657
enable_copy_timestamp_url_button: false,
@@ -147,6 +148,7 @@ export const configurationImportSchema: TypeToPartialZodSchema<
147148
.optional(),
148149
deep_dark_preset: z.enum(deepDarkPreset).optional(),
149150
enable_automatic_theater_mode: z.boolean().optional(),
151+
enable_automatically_disable_ambient_mode: z.boolean().optional(),
150152
enable_automatically_disable_closed_captions: z.boolean().optional(),
151153
enable_automatically_set_quality: z.boolean().optional(),
152154
enable_copy_timestamp_url_button: z.boolean().optional(),

0 commit comments

Comments
 (0)