diff --git a/public/locales/en-US.json b/public/locales/en-US.json index d21d1655..55227485 100644 --- a/public/locales/en-US.json +++ b/public/locales/en-US.json @@ -223,6 +223,10 @@ "label": "Hide shorts", "title": "Hides all shorts" }, + "hideTranslateComment": { + "label": "Hide translate comment button", + "title": "Hides 'Translate to Language' button under comments" + }, "loopButton": { "label": "Loop button", "title": "Adds a button to the feature menu to loop the video you're watching" diff --git a/public/locales/en-US.json.d.ts b/public/locales/en-US.json.d.ts index e0cf3f99..f64c6b70 100644 --- a/public/locales/en-US.json.d.ts +++ b/public/locales/en-US.json.d.ts @@ -148,6 +148,10 @@ interface EnUS { hideLiveStreamChat: { label: "Hide live stream chat"; title: "Hides the live stream chat" }; hideScrollbar: { label: "Hide scrollbar"; title: "Hides the pages scrollbar" }; hideShorts: { label: "Hide shorts"; title: "Hides all shorts" }; + hideTranslateComment: { + label: "Hide translate comment button"; + title: "Hides 'Translate to Language' button under comments"; + }; loopButton: { label: "Loop button"; title: "Adds a button to the feature menu to loop the video you're watching"; diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index c4cd04e7..7cdf2f12 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -664,6 +664,14 @@ export default function Settings() { title={t("settings.sections.miscellaneous.features.hideLiveStreamChat.title")} type="checkbox" /> + diff --git a/src/features/hideTranslateComment/index.css b/src/features/hideTranslateComment/index.css new file mode 100644 index 00000000..76fbc43f --- /dev/null +++ b/src/features/hideTranslateComment/index.css @@ -0,0 +1,3 @@ +.yte-hide-translate-comment { + display: none !important; +} \ No newline at end of file diff --git a/src/features/hideTranslateComment/index.ts b/src/features/hideTranslateComment/index.ts new file mode 100644 index 00000000..01b78174 --- /dev/null +++ b/src/features/hideTranslateComment/index.ts @@ -0,0 +1,27 @@ +import type { Nullable } from "@/src/types"; + +import { observeTranslateComment, translateButtonSelector } from "@/src/features/hideTranslateComment/utils"; +import { modifyElementClassList, waitForAllElements, waitForSpecificMessage } from "@/src/utils/utilities"; + +import "./index.css"; +let translateCommentObserver: Nullable = null; +export async function enableHideTranslateComment() { + const { + data: { + options: { enable_hide_translate_comment } + } + } = await waitForSpecificMessage("options", "request_data", "content"); + if (!enable_hide_translate_comment) return; + await waitForAllElements(["ytd-item-section-renderer.ytd-comments div#header div#leading-section"]); + const translateCommentButtons = document.querySelectorAll(translateButtonSelector); + translateCommentButtons.forEach((button) => modifyElementClassList("add", { className: "yte-hide-translate-comment", element: button })); + translateCommentObserver = observeTranslateComment(); +} + +export async function disableHideTranslateComment() { + await waitForAllElements(["ytd-item-section-renderer.ytd-comments div#header div#leading-section"]); + translateCommentObserver?.disconnect(); + translateCommentObserver = null; + const translateCommentButtons = document.querySelectorAll(translateButtonSelector); + translateCommentButtons.forEach((button) => modifyElementClassList("remove", { className: "yte-hide-translate-comment", element: button })); +} diff --git a/src/features/hideTranslateComment/utils.ts b/src/features/hideTranslateComment/utils.ts new file mode 100644 index 00000000..4ae1afb3 --- /dev/null +++ b/src/features/hideTranslateComment/utils.ts @@ -0,0 +1,26 @@ +import { modifyElementClassList } from "@/src/utils/utilities"; +export const translateButtonSelector = "ytd-tri-state-button-view-model.translate-button"; + +export function observeTranslateComment() { + const observer = new MutationObserver((mutationList) => { + mutationList.forEach((mutation) => { + const translateButtons = Array.from(mutation.addedNodes).some( + (addedNode) => + addedNode instanceof Element && + addedNode.matches("ytd-comment-thread-renderer") && + addedNode.querySelector(translateButtonSelector) !== null + ); + if (mutation.type !== "childList" || !mutation.addedNodes.length || !translateButtons) return; + mutation.addedNodes.forEach((addedNode) => { + modifyElementClassList("add", { + className: "yte-hide-translate-comment", + element: (addedNode as Element).querySelector(translateButtonSelector) + }); + }); + }); + }); + const commentsSection = document.querySelector("ytd-item-section-renderer.ytd-comments div#contents"); + if (!commentsSection) return null; + observer.observe(commentsSection, { childList: true, subtree: true }); + return observer; +} diff --git a/src/pages/content/index.ts b/src/pages/content/index.ts index 91d7a9fa..d3e5bcfa 100644 --- a/src/pages/content/index.ts +++ b/src/pages/content/index.ts @@ -290,6 +290,11 @@ const storageChangeHandler = async (changes: StorageChanges, areaName: string) = hideShortsEnabled: newValue }); }, + enable_hide_translate_comment: (__oldValue, newValue) => { + sendExtensionOnlyMessage("hideTranslateCommentChange", { + hideTranslateCommentEnabled: newValue + }); + }, enable_loop_button: (__oldValue, newValue) => { sendExtensionOnlyMessage("loopButtonChange", { loopButtonEnabled: newValue diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index 2d280886..f5c7db8c 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -14,6 +14,7 @@ import { disableHideLiveStreamChat, enableHideLiveStreamChat } from "@/src/featu import { enableHideScrollBar } from "@/src/features/hideScrollBar"; import { hideScrollBar, showScrollBar } from "@/src/features/hideScrollBar/utils"; import { disableHideShorts, enableHideShorts } from "@/src/features/hideShorts"; +import { disableHideTranslateComment, enableHideTranslateComment } from "@/src/features/hideTranslateComment"; import { addLoopButton, removeLoopButton } from "@/src/features/loopButton"; import { addMaximizePlayerButton, removeMaximizePlayerButton } from "@/src/features/maximizePlayerButton"; import { maximizePlayer } from "@/src/features/maximizePlayerButton/utils"; @@ -153,7 +154,8 @@ const enableFeatures = () => { setPlayerQuality(), setPlayerSpeed(), adjustVolumeOnScrollWheel(), - adjustSpeedOnScrollWheel() + adjustSpeedOnScrollWheel(), + enableHideTranslateComment() ]); // Enable feature menu before calling button functions await enableFeatureMenu(); @@ -364,6 +366,14 @@ window.addEventListener("DOMContentLoaded", function () { } break; } + case "hideTranslateCommentChange": { + const { + data: { hideTranslateCommentEnabled } + } = message; + if (hideTranslateCommentEnabled) await enableHideTranslateComment(); + else await disableHideTranslateComment(); + break; + } case "hideScrollBarChange": { const scrollBarHidden = document.getElementById("yte-hide-scroll-bar") !== null; const { diff --git a/src/types/index.ts b/src/types/index.ts index 25496245..083018b1 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -276,6 +276,7 @@ export type ExtensionSendOnlyMessageMappings = { hideLiveStreamChatChange: DataResponseMessage<"hideLiveStreamChatChange", { hideLiveStreamChatEnabled: boolean }>; hideScrollBarChange: DataResponseMessage<"hideScrollBarChange", { hideScrollBarEnabled: boolean }>; hideShortsChange: DataResponseMessage<"hideShortsChange", { hideShortsEnabled: boolean }>; + hideTranslateCommentChange: DataResponseMessage<"hideTranslateCommentChange", { hideTranslateCommentEnabled: boolean }>; languageChange: DataResponseMessage<"languageChange", { language: AvailableLocales }>; loopButtonChange: DataResponseMessage<"loopButtonChange", { loopButtonEnabled: boolean }>; maximizeButtonChange: DataResponseMessage<"maximizeButtonChange", { maximizePlayerButtonEnabled: boolean }>; @@ -356,6 +357,7 @@ export type configuration = { enable_hide_live_stream_chat: boolean; enable_hide_scrollbar: boolean; enable_hide_shorts: boolean; + enable_hide_translate_comment: boolean; enable_loop_button: boolean; enable_maximize_player_button: boolean; enable_open_transcript_button: boolean; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index c3f9d82e..fc13f2e3 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -49,6 +49,7 @@ export const defaultConfiguration = { enable_hide_live_stream_chat: false, enable_hide_scrollbar: false, enable_hide_shorts: false, + enable_hide_translate_comment: false, enable_loop_button: false, enable_maximize_player_button: false, enable_open_transcript_button: false, @@ -130,6 +131,7 @@ export const configurationImportSchema: TypeToPartialZodSchema< enable_hide_live_stream_chat: z.boolean().optional(), enable_hide_scrollbar: z.boolean().optional(), enable_hide_shorts: z.boolean().optional(), + enable_hide_translate_comment: z.boolean().optional(), enable_loop_button: z.boolean().optional(), enable_maximize_player_button: z.boolean().optional(), enable_open_transcript_button: z.boolean().optional(),