From 9abc101e9ef1f662a3aa5514a83851cbd299edc3 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Wed, 15 May 2024 19:24:21 -0400 Subject: [PATCH 01/77] chore: fix syntax error --- .all-contributorsrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index 56e88d57..a36ceea8 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -147,7 +147,7 @@ "contributions": [ "ideas" ] - }, + },{ "login": "charlymoon741", "name": "Carlos Ramos Luna", "avatar_url": "https://avatars.githubusercontent.com/u/62484941?v=4", From 2c66c3239fe53e626ed389740f76828d471c7ee6 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Sun, 19 May 2024 00:05:21 -0400 Subject: [PATCH 02/77] refactor: Add initialChecked parameter --- src/features/buttonPlacement/index.ts | 7 ++++--- src/features/buttonPlacement/utils.ts | 8 ++++---- src/features/featureMenu/utils.ts | 6 ++++-- 3 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/features/buttonPlacement/index.ts b/src/features/buttonPlacement/index.ts index d093cfee..97627ba4 100644 --- a/src/features/buttonPlacement/index.ts +++ b/src/features/buttonPlacement/index.ts @@ -13,11 +13,12 @@ export async function addFeatureButton, listener: ListenerType, - isToggle: boolean + isToggle: boolean, + initialChecked: boolean = false ) { switch (placement) { case "feature_menu": { - if (icon instanceof SVGSVGElement) await addFeatureItemToMenu(buttonName, label, icon, listener, isToggle); + if (icon instanceof SVGSVGElement) await addFeatureItemToMenu(buttonName, label, icon, listener, isToggle, initialChecked); break; } case "below_player": @@ -25,7 +26,7 @@ export async function addFeatureButton, listener: ListenerType, - isToggle: boolean + isToggle: boolean, + initialChecked: boolean = false ) { const featureName = findKeyByValue(buttonName as MultiButtonNames) ?? (buttonName as SingleButtonFeatureNames); if (placement === "feature_menu") throw new Error("Cannot make a feature button for the feature menu"); @@ -49,7 +50,6 @@ export function makeFeatureButton(menuItem: HTML * @param icon The icon for the feature * @param listener The listener for the feature * @param isToggle Whether the feature is a toggle + * @param initialChecked The initial checked state of the feature */ export async function addFeatureItemToMenu( buttonName: Name, label: string, icon: BasicIcon, listener: ListenerType, - isToggle: boolean + isToggle: boolean, + initialChecked: boolean = false ) { const featureName = findKeyByValue(buttonName as MultiButtonNames) ?? (buttonName as SingleButtonFeatureNames); // Add the feature name to the set of features in the menu @@ -95,7 +97,7 @@ export async function addFeatureItemToMenu Date: Sun, 19 May 2024 00:11:51 -0400 Subject: [PATCH 03/77] feat: Hide end screen cards button #484 --- .../Hide_End_Screen_Cards_Button.png | Bin 0 -> 3165 bytes public/locales/ca-ES.json | 14 ++++ public/locales/cs-CZ.json | 14 ++++ public/locales/de-DE.json | 14 ++++ public/locales/en-GB.json | 14 ++++ public/locales/en-US.json | 14 ++++ public/locales/en-US.json.d.ts | 11 +++ public/locales/es-ES.json | 14 ++++ public/locales/fa-IR.json | 14 ++++ public/locales/fr-FR.json | 14 ++++ public/locales/he-IL.json | 14 ++++ public/locales/hi-IN.json | 14 ++++ public/locales/it-IT.json | 18 ++++- public/locales/ja-JP.json | 18 ++++- public/locales/pl-PL.json | 14 ++++ public/locales/pt-BR.json | 14 ++++ public/locales/ru-RU.json | 30 +++++--- public/locales/sv-SE.json | 14 ++++ public/locales/tr-TR.json | 18 ++++- public/locales/zh-CN.json | 18 ++++- public/locales/zh-TW.json | 18 ++++- src/components/Settings/Settings.tsx | 11 ++- src/features/hideEndScreenCards/index.ts | 65 +++++++++++++++++- src/features/index.ts | 5 ++ src/i18n/index.ts | 38 +++++----- src/icons.ts | 42 ++++++++++- src/pages/content/index.ts | 6 ++ src/pages/embedded/index.ts | 56 +++++++++++++-- src/types/index.ts | 8 ++- src/utils/EventManager.ts | 1 + src/utils/constants.ts | 3 + 31 files changed, 497 insertions(+), 51 deletions(-) create mode 100644 assets/translation context screenshots/Miscellaneous Settings/Hide_End_Screen_Cards_Button.png diff --git a/assets/translation context screenshots/Miscellaneous Settings/Hide_End_Screen_Cards_Button.png b/assets/translation context screenshots/Miscellaneous Settings/Hide_End_Screen_Cards_Button.png new file mode 100644 index 0000000000000000000000000000000000000000..2cde1895eb3c4984228d8d6ff359cf26bbadfeb9 GIT binary patch literal 3165 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 EFIxKZE&u=k literal 0 HcmV?d00001 diff --git a/public/locales/ca-ES.json b/public/locales/ca-ES.json index 521fe736..108d5f6e 100644 --- a/public/locales/ca-ES.json +++ b/public/locales/ca-ES.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/cs-CZ.json b/public/locales/cs-CZ.json index ecd841e9..8ed6e9a2 100644 --- a/public/locales/cs-CZ.json +++ b/public/locales/cs-CZ.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/de-DE.json b/public/locales/de-DE.json index 3d650f50..9ad7d131 100644 --- a/public/locales/de-DE.json +++ b/public/locales/de-DE.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/en-GB.json b/public/locales/en-GB.json index 8760b6b0..75edb602 100644 --- a/public/locales/en-GB.json +++ b/public/locales/en-GB.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/en-US.json b/public/locales/en-US.json index 434c6423..8b400488 100644 --- a/public/locales/en-US.json +++ b/public/locales/en-US.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/en-US.json.d.ts b/public/locales/en-US.json.d.ts index c0ad1027..0fa281fd 100644 --- a/public/locales/en-US.json.d.ts +++ b/public/locales/en-US.json.d.ts @@ -9,6 +9,12 @@ interface EnUS { content: { features: { featureMenu: { button: { label: "Feature menu" } }; + hideEndScreenCardsButton: { + button: { + label: "Hide end screen cards"; + toggle: { off: "Hide end screen cards"; on: "Show end screen cards" }; + }; + }; loopButton: { button: { label: "Loop"; toggle: { off: "Loop off"; on: "Loop on" } } }; maximizePlayerButton: { button: { label: "Maximize"; toggle: { off: "Maximize off"; on: "Maximize on" } } }; openTranscriptButton: { button: { label: "Open transcript" } }; @@ -80,6 +86,7 @@ interface EnUS { select: { buttonNames: { decreasePlaybackSpeedButton: "Decrease Speed button"; + hideEndScreenCardsButton: "Hide end screen cards button"; increasePlaybackSpeedButton: "Increase Speed button"; loopButton: "Loop button"; maximizePlayerButton: "Maximize button"; @@ -149,6 +156,10 @@ interface EnUS { label: "Hide end screen cards"; title: "Hides the cards at the end of the video"; }; + hideEndScreenCardsButton: { + label: "Enable 'Hide end screen cards' button"; + title: "Adds a button to show/hide the cards at the end of the video"; + }; 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" }; diff --git a/public/locales/es-ES.json b/public/locales/es-ES.json index a238fcc0..79dd39ac 100644 --- a/public/locales/es-ES.json +++ b/public/locales/es-ES.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Botón de repetición", "maximizePlayerButton": "Maximizar botón", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/fa-IR.json b/public/locales/fa-IR.json index 42b0eeb4..59691929 100644 --- a/public/locales/fa-IR.json +++ b/public/locales/fa-IR.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/fr-FR.json b/public/locales/fr-FR.json index 8fc9fbc2..8dfcdd2f 100644 --- a/public/locales/fr-FR.json +++ b/public/locales/fr-FR.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/he-IL.json b/public/locales/he-IL.json index 50112462..b1aed11d 100644 --- a/public/locales/he-IL.json +++ b/public/locales/he-IL.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/hi-IN.json b/public/locales/hi-IN.json index a670ebed..ea9032d1 100644 --- a/public/locales/hi-IN.json +++ b/public/locales/hi-IN.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/it-IT.json b/public/locales/it-IT.json index 01f2add8..875737e8 100644 --- a/public/locales/it-IT.json +++ b/public/locales/it-IT.json @@ -13,6 +13,15 @@ "label": "Menu' funzioni" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Nascondi le schede finali", + "toggle": { + "off": "Mostra le schede finali", + "on": "Nascondi le schede finali" + } + } + }, "loopButton": { "button": { "label": "Ripeti", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Pulsante Riduci velocità", + "hideEndScreenCardsButton": "Pulsante Nascondi schede finali", "increasePlaybackSpeedButton": "Pulsante Aumenta velocità", "loopButton": "Pulsante Ripeti", "maximizePlayerButton": "Pulsante Massimizza", @@ -212,8 +222,12 @@ "title": "Attiva automaticamente la modalità teatro quando carichi un video" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "Nascondi le schede finali", + "title": "Nasconde le schede alla fine del video" + }, + "hideEndScreenCardsButton": { + "label": "Pulsante Nascondi schede finali", + "title": "Aggiunge un pulsante per mostrare/nascondere le schede alla fine del video" }, "hideLiveStreamChat": { "label": "Nascondi chat live stream", diff --git a/public/locales/ja-JP.json b/public/locales/ja-JP.json index 72ee7f37..ab1c5b6f 100644 --- a/public/locales/ja-JP.json +++ b/public/locales/ja-JP.json @@ -13,6 +13,15 @@ "label": "フィーチャー・メニュー" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "終了画面のカードを非表示にする", + "toggle": { + "off": "終了画面のカードを表示にする", + "on": "終了画面のカードを非表示にする" + } + } + }, "loopButton": { "button": { "label": "ループ", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "速度を下げるボタン", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "速度を上げるボタン", "loopButton": "ループボタン", "maximizePlayerButton": "最大表示ボタン", @@ -212,8 +222,12 @@ "title": "動画の読み込み時に自動的にシアターモードを有効にする" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "終了画面のカードを非表示にする", + "title": "動画の終了で画面カードを非表示にする" + }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" }, "hideLiveStreamChat": { "label": "配信チャットを隠す", diff --git a/public/locales/pl-PL.json b/public/locales/pl-PL.json index 2c4557e2..b818e9bf 100644 --- a/public/locales/pl-PL.json +++ b/public/locales/pl-PL.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Loop button", "maximizePlayerButton": "Maximize button", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/pt-BR.json b/public/locales/pt-BR.json index 42f4e1e4..dbc00084 100644 --- a/public/locales/pt-BR.json +++ b/public/locales/pt-BR.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Loop", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Botão de Repetir", "maximizePlayerButton": "Botão de Maximizar", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/ru-RU.json b/public/locales/ru-RU.json index 211e935c..d69b4195 100644 --- a/public/locales/ru-RU.json +++ b/public/locales/ru-RU.json @@ -13,6 +13,15 @@ "label": "Меню функций" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Скрыть заставки следующих видео", + "toggle": { + "off": "Показать заставки следующих видео", + "on": "Скрыть заставки следующих видео" + } + } + }, "loopButton": { "button": { "label": "Зациклить", @@ -45,8 +54,8 @@ "label": "Увеличить скорость на {{SPEED}}" } }, - "decreaseLimit": "Can't decrease further ({{SPEED}})", - "increaseLimit": "Can't increase further ({{SPEED}})" + "decreaseLimit": "Невозможно уменьшить ({{SPEED}})", + "increaseLimit": "Невозможно увеличить ({{SPEED}})" }, "screenshotButton": { "button": { @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Кнопка уменьшения скорости видео", + "hideEndScreenCardsButton": "Кнопка «Скрыть заставки следующих видео»", "increasePlaybackSpeedButton": "Кнопка увеличения скорости видео", "loopButton": "Кнопка «Зациклить»", "maximizePlayerButton": "Кнопка «Развернуть»", @@ -212,12 +222,16 @@ "title": "Автоматически включать режим кинотеатра при загрузке видео" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "Скрыть заставки следующих видео", + "title": "Скрывает заставки следующих (предлагаемых) видео в конце ролика" + }, + "hideEndScreenCardsButton": { + "label": "Кнопка «Скрыть заставки следующих видео»", + "title": "Добавляет кнопку для скрытия/отображения заставок следующих видео в конце ролика" }, "hideLiveStreamChat": { - "label": "Hide live stream chat", - "title": "Hides the live stream chat" + "label": "Спрятать чат прямого эфира", + "title": "Прячет чат прямого эфира (стрима)" }, "hideScrollbar": { "label": "Включить скрытие полосы прокрутки страницы", @@ -228,8 +242,8 @@ "title": "Скрывает все Shorts" }, "hideTranslateComment": { - "label": "Hide translate comment button", - "title": "Hides 'Translate to Language' button under comments" + "label": "Спрятать кнопку 'Перевести на...'", + "title": "Прячет кнопку 'Перевести на русский' под комментарием" }, "loopButton": { "label": "Включить кнопку «Зациклить»", diff --git a/public/locales/sv-SE.json b/public/locales/sv-SE.json index ced8740d..5be111c9 100644 --- a/public/locales/sv-SE.json +++ b/public/locales/sv-SE.json @@ -13,6 +13,15 @@ "label": "Funktionsmeny" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "Slinga", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Knapp för att mindska hastigheten", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "Knapp för att öka hastigheten", "loopButton": "Slingknapp", "maximizePlayerButton": "Maximeraknapp", @@ -215,6 +225,10 @@ "label": "Hide end screen cards", "title": "Hides the cards at the end of the video" }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" + }, "hideLiveStreamChat": { "label": "Hide live stream chat", "title": "Hides the live stream chat" diff --git a/public/locales/tr-TR.json b/public/locales/tr-TR.json index 11f1e499..521fe989 100644 --- a/public/locales/tr-TR.json +++ b/public/locales/tr-TR.json @@ -13,6 +13,15 @@ "label": "Özellik menüsü" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Bitiş ekranı kartlarını gizle", + "toggle": { + "off": "Bitiş ekranı kartlarını göster", + "on": "Bitiş ekranı kartlarını gizle" + } + } + }, "loopButton": { "button": { "label": "Tekrarla", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "Decrease Speed button", + "hideEndScreenCardsButton": "Bitiş ekranı kartlarını gizleme düğmesi", "increasePlaybackSpeedButton": "Increase Speed button", "loopButton": "Döngü düğmesi", "maximizePlayerButton": "Tam ekran düğmesi", @@ -212,8 +222,12 @@ "title": "Video yüklediğinizde tiyatro modunu otomatik olarak etkinleştirir" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "Bitiş ekranı kartlarını gizle", + "title": "Video'nun sonundaki kartları gizler" + }, + "hideEndScreenCardsButton": { + "label": "Bitiş ekranı kartlarını gizleme düğmesi", + "title": "Video'nun sonuna bitiş ekranı kartlarını gizlemek/göstermek için bir düğme ekler" }, "hideLiveStreamChat": { "label": "Canlı yayın sohbetini gizle", diff --git a/public/locales/zh-CN.json b/public/locales/zh-CN.json index 1fbbf6a2..f445757a 100644 --- a/public/locales/zh-CN.json +++ b/public/locales/zh-CN.json @@ -13,6 +13,15 @@ "label": "功能菜单" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "隐藏结束界面卡片", + "toggle": { + "off": "显示结束界面卡片", + "on": "隐藏结束界面卡片" + } + } + }, "loopButton": { "button": { "label": "循环播放", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "降低速度按钮", + "hideEndScreenCardsButton": "隐藏结束界面卡片按钮", "increasePlaybackSpeedButton": "增加速度按钮", "loopButton": "循环按钮", "maximizePlayerButton": "最大化按钮", @@ -212,8 +222,12 @@ "title": "当视频打开时,自动启用剧场模式" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "隐藏结束界面卡片", + "title": "隐藏视频末尾的卡片" + }, + "hideEndScreenCardsButton": { + "label": "隐藏结束界面卡片按钮", + "title": "添加按钮以显示/隐藏视频末尾的卡片" }, "hideLiveStreamChat": { "label": "隐藏直播聊天", diff --git a/public/locales/zh-TW.json b/public/locales/zh-TW.json index d3abd03c..7109ff32 100644 --- a/public/locales/zh-TW.json +++ b/public/locales/zh-TW.json @@ -13,6 +13,15 @@ "label": "Feature menu" } }, + "hideEndScreenCardsButton": { + "button": { + "label": "Hide end screen cards", + "toggle": { + "off": "Show end screen cards", + "on": "Hide end screen cards" + } + } + }, "loopButton": { "button": { "label": "循環播放", @@ -128,6 +137,7 @@ "select": { "buttonNames": { "decreasePlaybackSpeedButton": "減慢速度按鈕", + "hideEndScreenCardsButton": "Hide end screen cards button", "increasePlaybackSpeedButton": "加快速度按妞", "loopButton": "循環播放按鈕", "maximizePlayerButton": "最大化按鈕", @@ -212,8 +222,12 @@ "title": "載入影片時自動啟用劇院模式" }, "hideEndScreenCards": { - "label": "Hide end screen cards", - "title": "Hides the cards at the end of the video" + "label": "隱藏片尾資訊卡", + "title": "隱藏影片片尾的資訊卡" + }, + "hideEndScreenCardsButton": { + "label": "Hide end screen cards button", + "title": "Adds a button to show/hide the cards at the end of the video" }, "hideLiveStreamChat": { "label": "隱藏直播聊天室", diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index 22a2bfca..5314ba93 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -359,6 +359,7 @@ export default function Settings() { ]; const buttonPlacementOptions: SelectOption< | "button_placements.decreasePlaybackSpeedButton" + | "button_placements.hideEndScreenCardsButton" | "button_placements.increasePlaybackSpeedButton" | "button_placements.loopButton" | "button_placements.maximizePlayerButton" @@ -523,7 +524,7 @@ export default function Settings() { {buttonNames.map((feature) => { - const label = t(`settings.sections.buttonPlacement.select.buttonNames.${feature}`) as string; + const label = t(`settings.sections.buttonPlacement.select.buttonNames.${feature}`); return ( + diff --git a/src/features/hideEndScreenCards/index.ts b/src/features/hideEndScreenCards/index.ts index 3117155d..fef5eae3 100644 --- a/src/features/hideEndScreenCards/index.ts +++ b/src/features/hideEndScreenCards/index.ts @@ -1,3 +1,10 @@ +import type { AddButtonFunction, RemoveButtonFunction } from "@/src/features"; +import type { ButtonPlacement } from "@/src/types"; + +import { addFeatureButton, removeFeatureButton } from "@/src/features/buttonPlacement"; +import { updateFeatureButtonTitle } from "@/src/features/buttonPlacement/utils"; +import { getFeatureIcon } from "@/src/icons"; +import eventManager from "@/src/utils/EventManager"; import { modifyElementsClassList, waitForAllElements, waitForSpecificMessage } from "@/src/utils/utilities"; import "./index.css"; @@ -8,8 +15,58 @@ export async function enableHideEndScreenCards() { } } = await waitForSpecificMessage("options", "request_data", "content"); if (!enableHideEndScreenCards) return; + await waitForAllElements(["div#player", "div#player-wide-container", "div#video-container", "div#player-container"]); + hideEndScreenCards(); +} +export async function disableHideEndScreenCards() { + await waitForAllElements(["div#player", "div#player-wide-container", "div#video-container", "div#player-container"]); + showEndScreenCards(); +} +export const addHideEndScreenCardsButton: AddButtonFunction = async () => { + const { + data: { + options: { + button_placements: { hideEndScreenCardsButton: hideEndScreenCardsButtonPlacement }, + enable_hide_end_screen_cards_button: enableHideEndScreenCardsButton + } + } + } = await waitForSpecificMessage("options", "request_data", "content"); + if (!enableHideEndScreenCardsButton) return; await waitForAllElements(["div#player", "div#player-wide-container", "div#video-container", "div#player-container"]); + const endScreenCardsAreHidden = isEndScreenCardsHidden(); + const handleButtonClick = (placement: ButtonPlacement, checked?: boolean) => { + if (placement === "feature_menu") { + if (checked && !isEndScreenCardsHidden()) hideEndScreenCards(); + else if (!checked && isEndScreenCardsHidden()) showEndScreenCards(); + } else { + updateFeatureButtonTitle( + "hideEndScreenCardsButton", + window.i18nextInstance.t(`pages.content.features.hideEndScreenCardsButton.button.toggle.${checked ? "on" : "off"}`) + ); + if (checked && isEndScreenCardsHidden()) showEndScreenCards(); + else if (!checked && !isEndScreenCardsHidden()) hideEndScreenCards(); + } + }; + await addFeatureButton( + "hideEndScreenCardsButton", + hideEndScreenCardsButtonPlacement, + window.i18nextInstance.t( + hideEndScreenCardsButtonPlacement === "feature_menu" ? + "pages.content.features.hideEndScreenCardsButton.button.label" + : `pages.content.features.hideEndScreenCardsButton.button.toggle.${!endScreenCardsAreHidden ? "on" : "off"}` + ), + getFeatureIcon("hideEndScreenCardsButton", hideEndScreenCardsButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + (checked) => handleButtonClick(hideEndScreenCardsButtonPlacement, checked), + true, + hideEndScreenCardsButtonPlacement !== "feature_menu" ? !endScreenCardsAreHidden : endScreenCardsAreHidden + ); +}; +export const removeHideEndScreenCardsButton: RemoveButtonFunction = async (placement) => { + await removeFeatureButton("hideEndScreenCardsButton", placement); + eventManager.removeEventListeners("hideEndScreenCardsButton"); +}; +function hideEndScreenCards() { modifyElementsClassList( "add", Array.from(document.querySelectorAll(".ytp-ce-element")).map((element) => ({ @@ -18,9 +75,7 @@ export async function enableHideEndScreenCards() { })) ); } - -export async function disableHideEndScreenCards() { - await waitForAllElements(["div#player", "div#player-wide-container", "div#video-container", "div#player-container"]); +function showEndScreenCards() { modifyElementsClassList( "remove", Array.from(document.querySelectorAll(".ytp-ce-element")).map((element) => ({ @@ -29,3 +84,7 @@ export async function disableHideEndScreenCards() { })) ); } +export function isEndScreenCardsHidden(): boolean { + const endCards = document.querySelectorAll(".ytp-ce-element.yte-hide-end-screen-cards"); + return endCards.length > 0; +} diff --git a/src/features/index.ts b/src/features/index.ts index 9034da11..b2aa3316 100644 --- a/src/features/index.ts +++ b/src/features/index.ts @@ -1,5 +1,6 @@ import type { AllButtonNames, ButtonPlacement } from "@/src/types"; +import { addHideEndScreenCardsButton, removeHideEndScreenCardsButton } from "@/src/features/hideEndScreenCards"; import { addLoopButton, removeLoopButton } from "@/src/features/loopButton"; import { addMaximizePlayerButton, removeMaximizePlayerButton } from "@/src/features/maximizePlayerButton"; import { addOpenTranscriptButton, removeOpenTranscriptButton } from "@/src/features/openTranscriptButton/utils"; @@ -22,6 +23,10 @@ export const featureButtonFunctions = { add: addDecreasePlaybackSpeedButton, remove: removeDecreasePlaybackSpeedButton }, + hideEndScreenCardsButton: { + add: addHideEndScreenCardsButton, + remove: removeHideEndScreenCardsButton + }, increasePlaybackSpeedButton: { add: addIncreasePlaybackSpeedButton, remove: removeIncreasePlaybackSpeedButton diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 24805ccb..c5637d2c 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -2,25 +2,25 @@ import { type Resource, createInstance } from "i18next"; import { waitForSpecificMessage } from "../utils/utilities"; export const availableLocales = [ - "ca-ES", - "cs-CZ", - "de-DE", - "en-GB", - "en-US", - "es-ES", - "fa-IR", - "fr-FR", - "he-IL", - "hi-IN", - "it-IT", - "ja-JP", - "pl-PL", - "pt-BR", - "ru-RU", - "sv-SE", - "tr-TR", - "zh-CN", - "zh-TW" + "ca-ES", + "cs-CZ", + "de-DE", + "en-GB", + "en-US", + "es-ES", + "fa-IR", + "fr-FR", + "he-IL", + "hi-IN", + "it-IT", + "ja-JP", + "pl-PL", + "pt-BR", + "ru-RU", + "sv-SE", + "tr-TR", + "zh-CN", + "zh-TW" ] as const; export const localePercentages: Record = { "ca-ES": 0, diff --git a/src/icons.ts b/src/icons.ts index 52c4c085..420b7ec0 100644 --- a/src/icons.ts +++ b/src/icons.ts @@ -3,9 +3,12 @@ import type { AllButtonNames, ButtonPlacement } from "./types"; import { createSVGElement } from "./utils/utilities"; export type ToggleIcon = { off: SVGSVGElement; on: SVGSVGElement }; export type BasicIcon = SVGSVGElement; -export const toggleFeatures = Object.keys({ loopButton: "", maximizePlayerButton: "", volumeBoostButton: "" } satisfies Partial< - Record ->); +export const toggleFeatures = Object.keys({ + hideEndScreenCardsButton: "", + loopButton: "", + maximizePlayerButton: "", + volumeBoostButton: "" +} satisfies Partial>); export type ToggleFeatures = (typeof toggleFeatures)[number]; export type IconType = T extends ToggleFeatures ? ToggleIcon : BasicIcon; export type GetPlacementKey = Placement extends "feature_menu" ? "feature_menu" : "shared_icon_position"; @@ -231,11 +234,44 @@ const increasePlaybackSpeedButtonSVG = createSVGElement( fill: "white" }) ); +const hideEndScreenCardsButtonSVG = createSVGElement( + "svg", + { + height: "24px", + "stroke-width": "1", + viewBox: "0 0 24 24", + width: "24px" + }, + createSVGElement("path", { + d: "M 19.615385,7.7692309 V 19.615385 a 1.6923077,1.6923077 0 0 1 -1.692308,1.692307 H 2.6923077 A 1.6923077,1.6923077 0 0 1 1,19.615385 V 7.7692309 A 1.6923077,1.6923077 0 0 1 2.6923077,6.0769232 H 17.923077 a 1.6923077,1.6923077 0 0 1 1.692308,1.6923077 z m 1.692307,-5.076923 H 5.2307692 a 0.84615385,0.84615385 0 0 0 0,1.6923077 H 21.307692 V 17.076923 a 0.846154,0.846154 0 0 0 1.692308,0 V 4.3846156 A 1.6923077,1.6923077 0 0 0 21.307692,2.6923079 Z", + fill: "white" + }) +); +const showEndScreenCardsButtonSVG = createSVGElement( + "svg", + { + height: "24px", + "stroke-width": "1", + viewBox: "0 0 24 24", + width: "24px" + }, + createSVGElement("path", { + d: "M 17.894749,6.1105233 H 2.7368227 A 1.684214,1.6827074 0 0 0 1.0526086,7.793231 v 11.778954 a 1.684214,1.6827074 0 0 0 1.6842141,1.682707 H 17.894749 a 1.684214,1.6827074 0 0 0 1.684215,-1.682707 V 7.793231 A 1.684214,1.6827074 0 0 0 17.894749,6.1105233 Z m 0,13.4616617 H 2.7368227 V 7.793231 H 17.894749 Z M 22.947391,4.4278159 V 17.048122 a 0.84210706,0.84135374 0 0 1 -1.684213,0 V 4.4278159 H 5.2631439 a 0.84210707,0.84135375 0 0 1 0,-1.6827074 H 21.263178 a 1.684214,1.6827074 0 0 1 1.684213,1.6827074 z", + fill: "white" + }) +); export const featureIcons = { decreasePlaybackSpeedButton: { feature_menu: decreasePlaybackSpeedButtonSVG, shared_icon_position: decreasePlaybackSpeedButtonSVG }, + hideEndScreenCardsButton: { + feature_menu: hideEndScreenCardsButtonSVG, + shared_icon_position: { + off: showEndScreenCardsButtonSVG, + on: hideEndScreenCardsButtonSVG + } + }, increasePlaybackSpeedButton: { feature_menu: increasePlaybackSpeedButtonSVG, shared_icon_position: increasePlaybackSpeedButtonSVG diff --git a/src/pages/content/index.ts b/src/pages/content/index.ts index 9db41f4c..39454a64 100644 --- a/src/pages/content/index.ts +++ b/src/pages/content/index.ts @@ -277,9 +277,15 @@ const storageChangeHandler = async (changes: StorageChanges, areaName: string) = }, enable_hide_end_screen_cards: (__oldValue, newValue) => { sendExtensionOnlyMessage("hideEndScreenCardsChange", { + hideEndScreenCardsButtonPlacement: options.button_placements["hideEndScreenCardsButton"], hideEndScreenCardsEnabled: newValue }); }, + enable_hide_end_screen_cards_button: (__oldValue, newValue) => { + sendExtensionOnlyMessage("hideEndScreenCardsButtonChange", { + hideEndScreenCardsButtonEnabled: newValue + }); + }, enable_hide_live_stream_chat: (__oldValue, newValue) => { sendExtensionOnlyMessage("hideLiveStreamChatChange", { hideLiveStreamChatEnabled: newValue diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index 09be394e..05524368 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -3,14 +3,25 @@ import { deepDarkPresets } from "@/src/deepDarkPresets"; import { type FeatureFuncRecord, featureButtonFunctions } from "@/src/features"; import { enableAutomaticTheaterMode } from "@/src/features/automaticTheaterMode"; import { featuresInControls } from "@/src/features/buttonPlacement"; -import { checkIfFeatureButtonExists, getFeatureButton, updateFeatureButtonTitle } from "@/src/features/buttonPlacement/utils"; +import { + checkIfFeatureButtonExists, + getFeatureButton, + updateFeatureButtonIcon, + updateFeatureButtonTitle +} from "@/src/features/buttonPlacement/utils"; import { disableCustomCSS, enableCustomCSS } from "@/src/features/customCSS"; import { customCSSExists, updateCustomCSS } from "@/src/features/customCSS/utils"; import { disableDeepDarkCSS, enableDeepDarkCSS } from "@/src/features/deepDarkCSS"; import { deepDarkCSSExists, getDeepDarkCustomThemeStyle, updateDeepDarkCSS } from "@/src/features/deepDarkCSS/utils"; import { enableFeatureMenu, setupFeatureMenuEventListeners } from "@/src/features/featureMenu"; import { featuresInMenu, getFeatureMenuItem, updateFeatureMenuItemLabel, updateFeatureMenuTitle } from "@/src/features/featureMenu/utils"; -import { disableHideEndScreenCards, enableHideEndScreenCards } from "@/src/features/hideEndScreenCards"; +import { + addHideEndScreenCardsButton, + disableHideEndScreenCards, + enableHideEndScreenCards, + isEndScreenCardsHidden, + removeHideEndScreenCardsButton +} from "@/src/features/hideEndScreenCards"; import { disableHideLiveStreamChat, enableHideLiveStreamChat } from "@/src/features/hideLiveStreamChat"; import { enableHideScrollBar } from "@/src/features/hideScrollBar"; import { hideScrollBar, showScrollBar } from "@/src/features/hideScrollBar/utils"; @@ -49,7 +60,7 @@ import volumeBoost, { removeVolumeBoostButton } from "@/src/features/volumeBoost"; import { i18nService } from "@/src/i18n"; -import { type ToggleFeatures, toggleFeatures } from "@/src/icons"; +import { type ToggleFeatures, type ToggleIcon, getFeatureIcon, toggleFeatures } from "@/src/icons"; import { type ExtensionSendOnlyMessageMappings, type Messages, @@ -164,6 +175,7 @@ const enableFeatures = () => { // Features that add buttons should be put below and be ordered in the order those buttons should appear await addIncreasePlaybackSpeedButton(); await addDecreasePlaybackSpeedButton(); + await addHideEndScreenCardsButton(); await addScreenshotButton(); await openTranscriptButton(); await addMaximizePlayerButton(); @@ -267,10 +279,34 @@ window.addEventListener("DOMContentLoaded", function () { } case "hideEndScreenCardsChange": { const { - data: { hideEndScreenCardsEnabled } + data: { hideEndScreenCardsButtonPlacement: hideEndScreenCardsPlacement, hideEndScreenCardsEnabled } } = message; - if (hideEndScreenCardsEnabled) await enableHideEndScreenCards(); - else await disableHideEndScreenCards(); + const updateHideEndScreenCardsButtonState = (icon: ToggleIcon, checked: boolean) => { + if (hideEndScreenCardsPlacement === "feature_menu") { + const hideEndScreenCardsMenuItem = getFeatureMenuItem("hideEndScreenCardsButton"); + if (!hideEndScreenCardsMenuItem) return; + hideEndScreenCardsMenuItem.ariaChecked = checked ? "false" : "true"; + } else { + const hideEndScreenCardsButton = getFeatureButton("hideEndScreenCardsButton"); + if (!hideEndScreenCardsButton || !(hideEndScreenCardsButton instanceof HTMLButtonElement)) return; + updateFeatureButtonIcon(hideEndScreenCardsButton, icon[checked ? "on" : "off"]); + updateFeatureButtonTitle( + "hideEndScreenCardsButton", + i18nextInstance.t(`pages.content.features.hideEndScreenCardsButton.button.toggle.${checked ? "on" : "off"}`) + ); + hideEndScreenCardsButton.ariaChecked = checked ? "true" : "false"; + } + }; + const endScreenCardsHidden = isEndScreenCardsHidden(); + const hideEndScreenCardsIcon = getFeatureIcon("hideEndScreenCardsButton", "shared_icon_position"); + if (hideEndScreenCardsIcon instanceof SVGSVGElement) return; + if (hideEndScreenCardsEnabled && !endScreenCardsHidden) { + await enableHideEndScreenCards(); + updateHideEndScreenCardsButtonState(hideEndScreenCardsIcon, false); + } else if (!hideEndScreenCardsEnabled && endScreenCardsHidden) { + await disableHideEndScreenCards(); + updateHideEndScreenCardsButtonState(hideEndScreenCardsIcon, true); + } break; } case "maximizeButtonChange": { @@ -409,6 +445,14 @@ window.addEventListener("DOMContentLoaded", function () { } break; } + case "hideEndScreenCardsButtonChange": { + const { + data: { hideEndScreenCardsButtonEnabled } + } = message; + if (hideEndScreenCardsButtonEnabled) await addHideEndScreenCardsButton(); + else await removeHideEndScreenCardsButton(); + break; + } case "hideLiveStreamChatChange": { const { data: { hideLiveStreamChatEnabled } diff --git a/src/types/index.ts b/src/types/index.ts index 49dadc76..d10ec446 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -140,6 +140,7 @@ export type FeatureMenuItemId = `yte-feature-${AllButtonNames}-menuitem`; export type FeatureMenuItemLabelId = `yte-${AllButtonNames}-label`; export const buttonNames = Object.keys({ decreasePlaybackSpeedButton: "", + hideEndScreenCardsButton: "", increasePlaybackSpeedButton: "", loopButton: "", maximizePlayerButton: "", @@ -273,7 +274,11 @@ export type ExtensionSendOnlyMessageMappings = { { deepDarkCustomThemeColors: DeepDarkCustomThemeColors; deepDarkPreset: DeepDarkPreset; deepDarkThemeEnabled: boolean } >; featureMenuOpenTypeChange: DataResponseMessage<"featureMenuOpenTypeChange", { featureMenuOpenType: FeatureMenuOpenType }>; - hideEndScreenCardsChange: DataResponseMessage<"hideEndScreenCardsChange", { hideEndScreenCardsEnabled: boolean }>; + hideEndScreenCardsButtonChange: DataResponseMessage<"hideEndScreenCardsButtonChange", { hideEndScreenCardsButtonEnabled: boolean }>; + hideEndScreenCardsChange: DataResponseMessage< + "hideEndScreenCardsChange", + { hideEndScreenCardsButtonPlacement: ButtonPlacement; hideEndScreenCardsEnabled: boolean } + >; hideLiveStreamChatChange: DataResponseMessage<"hideLiveStreamChatChange", { hideLiveStreamChatEnabled: boolean }>; hideScrollBarChange: DataResponseMessage<"hideScrollBarChange", { hideScrollBarEnabled: boolean }>; hideShortsChange: DataResponseMessage<"hideShortsChange", { hideShortsEnabled: boolean }>; @@ -356,6 +361,7 @@ export type configuration = { enable_deep_dark_theme: boolean; enable_forced_playback_speed: boolean; enable_hide_end_screen_cards: boolean; + enable_hide_end_screen_cards_button: boolean; enable_hide_live_stream_chat: boolean; enable_hide_scrollbar: boolean; enable_hide_shorts: boolean; diff --git a/src/utils/EventManager.ts b/src/utils/EventManager.ts index 84d22d32..110a7451 100644 --- a/src/utils/EventManager.ts +++ b/src/utils/EventManager.ts @@ -1,6 +1,7 @@ export type FeatureName = | "automaticTheaterMode" | "featureMenu" + | "hideEndScreenCardsButton" | "hideScrollBar" | "hideShorts" | "loopButton" diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 35b9fff5..41d291ea 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -23,6 +23,7 @@ export const outputFolderName = "dist"; export const defaultConfiguration = { button_placements: { decreasePlaybackSpeedButton: "player_controls_left", + hideEndScreenCardsButton: "player_controls_right", increasePlaybackSpeedButton: "player_controls_left", loopButton: "feature_menu", maximizePlayerButton: "feature_menu", @@ -47,6 +48,7 @@ export const defaultConfiguration = { enable_deep_dark_theme: false, enable_forced_playback_speed: false, enable_hide_end_screen_cards: false, + enable_hide_end_screen_cards_button: false, enable_hide_live_stream_chat: false, enable_hide_scrollbar: false, enable_hide_shorts: false, @@ -130,6 +132,7 @@ export const configurationImportSchema: TypeToPartialZodSchema< enable_deep_dark_theme: z.boolean().optional(), enable_forced_playback_speed: z.boolean().optional(), enable_hide_end_screen_cards: z.boolean().optional(), + enable_hide_end_screen_cards_button: z.boolean().optional(), enable_hide_live_stream_chat: z.boolean().optional(), enable_hide_scrollbar: z.boolean().optional(), enable_hide_shorts: z.boolean().optional(), From fcfefb32cd888adf58845205142304b03c2ab020 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Sun, 19 May 2024 01:55:06 -0400 Subject: [PATCH 04/77] refactor: Improve getFeatureIcon --- src/features/hideEndScreenCards/index.ts | 2 +- src/features/loopButton/index.ts | 4 ++-- src/features/maximizePlayerButton/index.ts | 4 ++-- src/features/openTranscriptButton/utils.ts | 2 +- src/features/playbackSpeedButtons/index.ts | 4 ++-- src/features/screenshotButton/index.ts | 2 +- src/features/volumeBoost/index.ts | 2 +- src/icons.ts | 7 ++----- src/pages/embedded/index.ts | 2 +- 9 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/features/hideEndScreenCards/index.ts b/src/features/hideEndScreenCards/index.ts index fef5eae3..5cc9964f 100644 --- a/src/features/hideEndScreenCards/index.ts +++ b/src/features/hideEndScreenCards/index.ts @@ -56,7 +56,7 @@ export const addHideEndScreenCardsButton: AddButtonFunction = async () => { "pages.content.features.hideEndScreenCardsButton.button.label" : `pages.content.features.hideEndScreenCardsButton.button.toggle.${!endScreenCardsAreHidden ? "on" : "off"}` ), - getFeatureIcon("hideEndScreenCardsButton", hideEndScreenCardsButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("hideEndScreenCardsButton", hideEndScreenCardsButtonPlacement), (checked) => handleButtonClick(hideEndScreenCardsButtonPlacement, checked), true, hideEndScreenCardsButtonPlacement !== "feature_menu" ? !endScreenCardsAreHidden : endScreenCardsAreHidden diff --git a/src/features/loopButton/index.ts b/src/features/loopButton/index.ts index 3ec163e6..05377dde 100644 --- a/src/features/loopButton/index.ts +++ b/src/features/loopButton/index.ts @@ -37,12 +37,12 @@ export const addLoopButton: AddButtonFunction = async () => { loopButtonPlacement === "feature_menu" ? window.i18nextInstance.t("pages.content.features.loopButton.button.label") : window.i18nextInstance.t("pages.content.features.loopButton.button.toggle.off"), - getFeatureIcon("loopButton", loopButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("loopButton", loopButtonPlacement), loopButtonClickListener, true ); const loopChangedHandler = (mutationList: MutationRecord[]) => { - const loopSVG = getFeatureIcon("loopButton", loopButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"); + const loopSVG = getFeatureIcon("loopButton", loopButtonPlacement); for (const mutation of mutationList) { if (mutation.type === "attributes") { const { attributeName, target } = mutation; diff --git a/src/features/maximizePlayerButton/index.ts b/src/features/maximizePlayerButton/index.ts index 888ef762..e85cb33d 100644 --- a/src/features/maximizePlayerButton/index.ts +++ b/src/features/maximizePlayerButton/index.ts @@ -61,7 +61,7 @@ export const addMaximizePlayerButton: AddButtonFunction = async () => { maximizePlayer(); maximizePlayerButton.ariaChecked = "false"; const button = getFeatureButton("maximizePlayerButton"); - const icon = getFeatureIcon("maximizePlayerButton", "shared_icon_position"); + const icon = getFeatureIcon("maximizePlayerButton", "below_player"); if (button && button instanceof HTMLButtonElement) { if (typeof icon === "object" && "off" in icon && "on" in icon) updateFeatureButtonIcon(button, icon.off); updateFeatureButtonTitle("maximizePlayerButton", window.i18nextInstance.t("pages.content.features.maximizePlayerButton.button.toggle.off")); @@ -74,7 +74,7 @@ export const addMaximizePlayerButton: AddButtonFunction = async () => { maximizePlayerButtonPlacement === "feature_menu" ? window.i18nextInstance.t("pages.content.features.maximizePlayerButton.button.label") : window.i18nextInstance.t("pages.content.features.maximizePlayerButton.button.toggle.off"), - getFeatureIcon("maximizePlayerButton", maximizePlayerButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("maximizePlayerButton", maximizePlayerButtonPlacement), maximizePlayerButtonClickListener, true ); diff --git a/src/features/openTranscriptButton/utils.ts b/src/features/openTranscriptButton/utils.ts index fe688baf..f4e52577 100644 --- a/src/features/openTranscriptButton/utils.ts +++ b/src/features/openTranscriptButton/utils.ts @@ -24,7 +24,7 @@ export const addOpenTranscriptButton: AddButtonFunction = async () => { "openTranscriptButton", openTranscriptButtonPlacement, window.i18nextInstance.t("pages.content.features.openTranscriptButton.button.label"), - getFeatureIcon("openTranscriptButton", openTranscriptButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("openTranscriptButton", openTranscriptButtonPlacement), transcriptButtonClickerListener, false ); diff --git a/src/features/playbackSpeedButtons/index.ts b/src/features/playbackSpeedButtons/index.ts index 8bb48477..c45e9d42 100644 --- a/src/features/playbackSpeedButtons/index.ts +++ b/src/features/playbackSpeedButtons/index.ts @@ -119,7 +119,7 @@ export const addIncreasePlaybackSpeedButton: AddButtonFunction = async () => { window.i18nextInstance.t("pages.content.features.playbackSpeedButtons.buttons.increasePlaybackSpeedButton.label", { SPEED: currentPlaybackSpeed + playbackSpeedPerClick }), - getFeatureIcon("increasePlaybackSpeedButton", increasePlaybackSpeedButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("increasePlaybackSpeedButton", increasePlaybackSpeedButtonPlacement), playbackSpeedButtonClickListener(playbackSpeedPerClick), false ); @@ -143,7 +143,7 @@ export const addDecreasePlaybackSpeedButton: AddButtonFunction = async () => { window.i18nextInstance.t("pages.content.features.playbackSpeedButtons.buttons.decreasePlaybackSpeedButton.label", { SPEED: currentPlaybackSpeed - playbackSpeedPerClick }), - getFeatureIcon("decreasePlaybackSpeedButton", decreasePlaybackSpeedButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("decreasePlaybackSpeedButton", decreasePlaybackSpeedButtonPlacement), playbackSpeedButtonClickListener(-playbackSpeedPerClick), false ); diff --git a/src/features/screenshotButton/index.ts b/src/features/screenshotButton/index.ts index c1b4321e..edb1da6a 100644 --- a/src/features/screenshotButton/index.ts +++ b/src/features/screenshotButton/index.ts @@ -96,7 +96,7 @@ export const addScreenshotButton: AddButtonFunction = async () => { "screenshotButton", screenshotButtonPlacement, window.i18nextInstance.t("pages.content.features.screenshotButton.button.label"), - getFeatureIcon("screenshotButton", screenshotButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("screenshotButton", screenshotButtonPlacement), screenshotButtonClickListener, false ); diff --git a/src/features/volumeBoost/index.ts b/src/features/volumeBoost/index.ts index 8baeaf1c..80bd634b 100644 --- a/src/features/volumeBoost/index.ts +++ b/src/features/volumeBoost/index.ts @@ -79,7 +79,7 @@ export const addVolumeBoostButton: AddButtonFunction = async () => { volumeBoostButtonPlacement === "feature_menu" ? window.i18nextInstance.t("pages.content.features.volumeBoostButton.button.label") : window.i18nextInstance.t(`pages.content.features.volumeBoostButton.button.toggle.off`), - getFeatureIcon("volumeBoostButton", volumeBoostButtonPlacement !== "feature_menu" ? "shared_icon_position" : "feature_menu"), + getFeatureIcon("volumeBoostButton", volumeBoostButtonPlacement), (checked) => { void (async () => { if (checked !== undefined) { diff --git a/src/icons.ts b/src/icons.ts index 420b7ec0..2739ed53 100644 --- a/src/icons.ts +++ b/src/icons.ts @@ -306,9 +306,6 @@ export const featureIcons = { } } } satisfies FeatureIconMap; -export function getFeatureIcon( - featureName: Name, - placement: GetPlacementKey -) { - return featureIcons[featureName][placement]; +export function getFeatureIcon(featureName: Name, placement: ButtonPlacement): IconType { + return featureIcons[featureName][placement !== "feature_menu" ? "shared_icon_position" : "feature_menu"] as IconType; } diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index 05524368..895c1beb 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -298,7 +298,7 @@ window.addEventListener("DOMContentLoaded", function () { } }; const endScreenCardsHidden = isEndScreenCardsHidden(); - const hideEndScreenCardsIcon = getFeatureIcon("hideEndScreenCardsButton", "shared_icon_position"); + const hideEndScreenCardsIcon = getFeatureIcon("hideEndScreenCardsButton", "below_player"); if (hideEndScreenCardsIcon instanceof SVGSVGElement) return; if (hideEndScreenCardsEnabled && !endScreenCardsHidden) { await enableHideEndScreenCards(); From b34b86e4209d7b1438a8bf6d85ba91f6f00ac526 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Sun, 19 May 2024 02:18:56 -0400 Subject: [PATCH 05/77] fix: object type not being handled properly --- src/pages/content/index.ts | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/pages/content/index.ts b/src/pages/content/index.ts index 39454a64..112946a3 100644 --- a/src/pages/content/index.ts +++ b/src/pages/content/index.ts @@ -199,12 +199,34 @@ const getStoredSettings = async (): Promise => { return options; }; +const deepEqual = (a: unknown, b: unknown): boolean => { + if (a === b) return true; + + if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) { + return false; + } + + const keysA = Object.keys(a); + const keysB = Object.keys(b); + + if (keysA.length !== keysB.length) return false; + + for (const key of keysA) { + if (!keysB.includes(key)) return false; + if (!deepEqual((a as Record)[key], (b as Record)[key])) return false; + } + + return true; +}; const isValidChange = (change?: { newValue?: unknown; oldValue?: unknown }) => { - return ( - change?.newValue !== undefined && - change?.oldValue !== undefined && - parseStoredValue(change.oldValue as string) !== parseStoredValue(change.newValue as string) - ); + if (change?.newValue === undefined || change?.oldValue === undefined) { + return false; + } + + const parsedOldValue = parseStoredValue(change.oldValue as string); + const parsedNewValue = parseStoredValue(change.newValue as string); + + return !deepEqual(parsedOldValue, parsedNewValue); }; const storageChangeHandler = async (changes: StorageChanges, areaName: string) => { if (areaName !== "local") return; From 733e14c8b3037124e1d1081fa5fa18f51d01e92d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:24:37 +0000 Subject: [PATCH 06/77] build(deps): bump tailwindcss-multi from 0.4.1 to 0.4.6 Bumps [tailwindcss-multi](https://github.com/brandonmcconnell/tailwindcss-multi) from 0.4.1 to 0.4.6. - [Commits](https://github.com/brandonmcconnell/tailwindcss-multi/compare/v0.4.1...v0.4.6) --- updated-dependencies: - dependency-name: tailwindcss-multi dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b29b000c..6c7a887d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^0.8.1", @@ -12208,9 +12208,9 @@ } }, "node_modules/tailwindcss-multi": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/tailwindcss-multi/-/tailwindcss-multi-0.4.1.tgz", - "integrity": "sha512-SCHG5J24MUJFRRTJosc557tJuXg5B8eB+HdXzDdIQPWxILRzpsjF2aJL9pYamQCrOZRBXkgmArVet0oHllL81A==", + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/tailwindcss-multi/-/tailwindcss-multi-0.4.6.tgz", + "integrity": "sha512-Bn9yLrMkeYFrJjRYuuTfqT9ibm6U2qnTwlIKYchWyGX3qgL+1+NN4JgiHJG1qrR4QQeU28eCl8sMSBobdzijvQ==", "dependencies": { "@types/node": "^20.4.1" } From f02e2582110a54fe350291ea5598823f44e577d2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:25:07 +0000 Subject: [PATCH 07/77] build(deps-dev): bump @typescript-eslint/parser from 7.8.0 to 7.9.0 Bumps [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) from 7.8.0 to 7.9.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.9.0/packages/parser) --- updated-dependencies: - dependency-name: "@typescript-eslint/parser" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 142 +++++++++++++++++++++++----------------------- 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/package-lock.json b/package-lock.json index b29b000c..afdc2640 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^0.8.1", @@ -1671,15 +1671,15 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.8.0.tgz", - "integrity": "sha512-KgKQly1pv0l4ltcftP59uQZCi4HUYswCLbTqVZEJu7uLX8CTLyswqMLqLN+2QFz4jCptqWVV4SB7vdxcH2+0kQ==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.9.0.tgz", + "integrity": "sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==", "dev": true, "dependencies": { - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/scope-manager": "7.9.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/typescript-estree": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4" }, "engines": { @@ -1698,14 +1698,33 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/scope-manager": { + "node_modules/@typescript-eslint/scope-manager": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.9.0.tgz", + "integrity": "sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", + "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/typescript-estree": "7.8.0", + "@typescript-eslint/utils": "7.8.0", + "debug": "^4.3.4", + "ts-api-utils": "^1.3.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1713,9 +1732,17 @@ "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", @@ -1728,7 +1755,7 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", @@ -1756,7 +1783,7 @@ } } }, - "node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": { + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", @@ -1773,37 +1800,10 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "node_modules/@typescript-eslint/types": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.9.0.tgz", + "integrity": "sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1813,14 +1813,14 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "node_modules/@typescript-eslint/typescript-estree": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.9.0.tgz", + "integrity": "sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.9.0", + "@typescript-eslint/visitor-keys": "7.9.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1841,23 +1841,6 @@ } } }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.8.0", - "eslint-visitor-keys": "^3.4.3" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@typescript-eslint/utils": { "version": "7.8.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", @@ -1958,6 +1941,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.9.0.tgz", + "integrity": "sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "7.9.0", + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", From bc464293f83e40431b2d0ec51a10191d93c5e6bd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:25:31 +0000 Subject: [PATCH 08/77] build(deps): bump @rollup/rollup-linux-x64-gnu from 4.16.4 to 4.17.2 Bumps [@rollup/rollup-linux-x64-gnu](https://github.com/rollup/rollup) from 4.16.4 to 4.17.2. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.16.4...v4.17.2) --- updated-dependencies: - dependency-name: "@rollup/rollup-linux-x64-gnu" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 202 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 198 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index b29b000c..8d97af9a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,16 +1,17 @@ { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^0.8.1", "@monaco-editor/react": "^4.6.0", + "@rollup/rollup-linux-x64-gnu": "^4.14.3", "@tanstack/react-query": "^5.18.0", "dotenv": "^16.3.1", "i18next": "^23.7.3", @@ -776,10 +777,154 @@ "node": ">=12" } }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.16.4.tgz", + "integrity": "sha512-GkhjAaQ8oUTOKE4g4gsZ0u8K/IHU1+2WQSgS1TwTcYvL+sjbaQjNHFXbOJ6kgqGHIO1DfUhI/Sphi9GkRT9K+Q==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.16.4.tgz", + "integrity": "sha512-Bvm6D+NPbGMQOcxvS1zUl8H7DWlywSXsphAeOnVeiZLQ+0J6Is8T7SrjGTH29KtYkiY9vld8ZnpV3G2EPbom+w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.16.4.tgz", + "integrity": "sha512-i5d64MlnYBO9EkCOGe5vPR/EeDwjnKOGGdd7zKFhU5y8haKhQZTN2DgVtpODDMxUr4t2K90wTUJg7ilgND6bXw==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.16.4.tgz", + "integrity": "sha512-WZupV1+CdUYehaZqjaFTClJI72fjJEgTXdf4NbW69I9XyvdmztUExBtcI2yIIU6hJtYvtwS6pkTkHJz+k08mAQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.16.4.tgz", + "integrity": "sha512-ADm/xt86JUnmAfA9mBqFcRp//RVRt1ohGOYF6yL+IFCYqOBNwy5lbEK05xTsEoJq+/tJzg8ICUtS82WinJRuIw==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.16.4.tgz", + "integrity": "sha512-tJfJaXPiFAG+Jn3cutp7mCs1ePltuAgRqdDZrzb1aeE3TktWWJ+g7xK9SNlaSUFw6IU4QgOxAY4rA+wZUT5Wfg==", + "cpu": [ + "arm" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.16.4.tgz", + "integrity": "sha512-7dy1BzQkgYlUTapDTvK997cgi0Orh5Iu7JlZVBy1MBURk7/HSbHkzRnXZa19ozy+wwD8/SlpJnOOckuNZtJR9w==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.16.4.tgz", + "integrity": "sha512-zsFwdUw5XLD1gQe0aoU2HVceI6NEW7q7m05wA46eUAyrkeNYExObfRFQcvA6zw8lfRc5BHtan3tBpo+kqEOxmg==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.16.4.tgz", + "integrity": "sha512-p8C3NnxXooRdNrdv6dBmRTddEapfESEUflpICDNKXpHvTjRRq1J82CbU5G3XfebIZyI3B0s074JHMWD36qOW6w==", + "cpu": [ + "ppc64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.16.4.tgz", + "integrity": "sha512-Lh/8ckoar4s4Id2foY7jNgitTOUQczwMWNYi+Mjt0eQ9LKhr6sK477REqQkmy8YHY3Ca3A2JJVdXnfb3Rrwkng==", + "cpu": [ + "riscv64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.16.4.tgz", + "integrity": "sha512-1xwwn9ZCQYuqGmulGsTZoKrrn0z2fAur2ujE60QgyDpHmBbXbxLaQiEvzJWDrscRq43c8DnuHx3QorhMTZgisQ==", + "cpu": [ + "s390x" + ], + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", + "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { "version": "4.16.4", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz", - "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.16.4.tgz", + "integrity": "sha512-ch86i7KkJKkLybDP2AtySFTRi5fM3KXp0PnHocHuJMdZwu7BuyIKi35BE9guMlmTpwwBTB3ljHj9IQXnTCD0vA==", "cpu": [ "x64" ], @@ -788,6 +933,30 @@ "linux" ] }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.16.4.tgz", + "integrity": "sha512-Ma4PwyLfOWZWayfEsNQzTDBVW8PZ6TUUN1uFTBQbF2Chv/+sjenE86lpiEwj2FiviSmSZ4Ap4MaAfl1ciF4aSA==", + "cpu": [ + "arm64" + ], + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.16.4.tgz", + "integrity": "sha512-9m/ZDrQsdo/c06uOlP3W9G2ENRVzgzbSXmXHT4hwVaDQhYcRpi9bgBT0FTG9OhESxwK0WjQxYOSfv40cU+T69w==", + "cpu": [ + "ia32" + ], + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { "version": "4.16.4", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.16.4.tgz", @@ -5025,6 +5194,19 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -11021,6 +11203,18 @@ "fsevents": "~2.3.2" } }, + "node_modules/rollup/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.16.4.tgz", + "integrity": "sha512-LuOGGKAJ7dfRtxVnO1i3qWc6N9sh0Em/8aZ3CezixSTM+E9Oq3OvTsvC4sm6wWjzpsIlOCnZjdluINKESflJLA==", + "cpu": [ + "x64" + ], + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", From e1409e460d1d3d7623570eefb639f5e70c75d422 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:26:04 +0000 Subject: [PATCH 09/77] build(deps): bump react-icons from 5.1.0 to 5.2.1 Bumps [react-icons](https://github.com/react-icons/react-icons) from 5.1.0 to 5.2.1. - [Release notes](https://github.com/react-icons/react-icons/releases) - [Commits](https://github.com/react-icons/react-icons/compare/v5.1.0...v5.2.1) --- updated-dependencies: - dependency-name: react-icons dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b29b000c..795b85d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^0.8.1", @@ -10613,9 +10613,9 @@ } }, "node_modules/react-icons": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.1.0.tgz", - "integrity": "sha512-D3zug1270S4hbSlIRJ0CUS97QE1yNNKDjzQe3HqY0aefp2CBn9VgzgES27sRR2gOvFK+0CNx/BW0ggOESp6fqQ==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.2.1.tgz", + "integrity": "sha512-zdbW5GstTzXaVKvGSyTaBalt7HSfuK5ovrzlpyiWHAFXndXTdd/1hdDHI4xBM1Mn7YriT6aqESucFl9kEXzrdw==", "peerDependencies": { "react": "*" } From 7e8862e3b3a821ca284cc1798bad711782e5883d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 01:26:26 +0000 Subject: [PATCH 10/77] build(deps-dev): bump zod from 3.23.4 to 3.23.8 Bumps [zod](https://github.com/colinhacks/zod) from 3.23.4 to 3.23.8. - [Release notes](https://github.com/colinhacks/zod/releases) - [Changelog](https://github.com/colinhacks/zod/blob/main/CHANGELOG.md) - [Commits](https://github.com/colinhacks/zod/compare/v3.23.4...v3.23.8) --- updated-dependencies: - dependency-name: zod dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index b29b000c..8aaff352 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-enhancer", - "version": "1.24.2", + "version": "1.25.0", "license": "MIT", "dependencies": { "@formkit/auto-animate": "^0.8.1", @@ -13452,9 +13452,9 @@ } }, "node_modules/zod": { - "version": "3.23.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.4.tgz", - "integrity": "sha512-/AtWOKbBgjzEYYQRNfoGKHObgfAZag6qUJX1VbHo2PRBgS+wfWagEY2mizjfyAPcGesrJOcx/wcl0L9WnVrHFw==", + "version": "3.23.8", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", + "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", "dev": true, "funding": { "url": "https://github.com/sponsors/colinhacks" From c6215801845cc9569e389300246a7f7230a7b94e Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Mon, 20 May 2024 09:29:54 -0400 Subject: [PATCH 11/77] feat(automatic quality): Fallback strategy #461 --- .../Quality_Fallback_Strategy.png | Bin 0 -> 5534 bytes public/locales/en-US.json | 10 ++++++ public/locales/en-US.json.d.ts | 11 ++++-- src/components/Settings/Settings.tsx | 20 +++++++++++ src/features/playerQuality/index.ts | 4 +-- src/types/index.ts | 3 ++ src/utils/constants.ts | 3 ++ src/utils/utilities.ts | 33 +++++++++++++++--- 8 files changed, 75 insertions(+), 9 deletions(-) create mode 100644 assets/translation context screenshots/Automatic Quality Settings/Quality_Fallback_Strategy.png diff --git a/assets/translation context screenshots/Automatic Quality Settings/Quality_Fallback_Strategy.png b/assets/translation context screenshots/Automatic Quality Settings/Quality_Fallback_Strategy.png new file mode 100644 index 0000000000000000000000000000000000000000..78e34c5be1783a6388dc6809d7340af6ae8117f7 GIT binary patch literal 5534 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 literal 0 HcmV?d00001 diff --git a/public/locales/en-US.json b/public/locales/en-US.json index 8b400488..a8556f75 100644 --- a/public/locales/en-US.json +++ b/public/locales/en-US.json @@ -110,6 +110,16 @@ "label": "Automatic quality adjustment", "title": "Automatically adjusts the video quality to the selected level." }, + "fallbackQualityStrategy": { + "select": { + "label": "Quality fallback strategy", + "options": { + "higher": "Higher", + "lower": "Lower" + }, + "title": "The strategy to use when the selected quality is not available" + } + }, "select": { "label": "Player quality", "title": "The quality to set the video to" diff --git a/public/locales/en-US.json.d.ts b/public/locales/en-US.json.d.ts index 0fa281fd..fd67e8b4 100644 --- a/public/locales/en-US.json.d.ts +++ b/public/locales/en-US.json.d.ts @@ -12,7 +12,7 @@ interface EnUS { hideEndScreenCardsButton: { button: { label: "Hide end screen cards"; - toggle: { off: "Hide end screen cards"; on: "Show end screen cards" }; + toggle: { off: "Show end screen cards"; on: "Hide end screen cards" }; }; }; loopButton: { button: { label: "Loop"; toggle: { off: "Loop off"; on: "Loop on" } } }; @@ -67,6 +67,13 @@ interface EnUS { label: "Automatic quality adjustment"; title: "Automatically adjusts the video quality to the selected level."; }; + fallbackQualityStrategy: { + select: { + label: "Fallback quality strategy"; + options: { higher: "Higher"; lower: "Lower" }; + title: "The strategy to use when the selected quality is not available"; + }; + }; select: { label: "Player quality"; title: "The quality to set the video to" }; title: "Automatic quality settings"; }; @@ -157,7 +164,7 @@ interface EnUS { title: "Hides the cards at the end of the video"; }; hideEndScreenCardsButton: { - label: "Enable 'Hide end screen cards' button"; + label: "Hide end screen cards button"; title: "Adds a button to show/hide the cards at the end of the video"; }; hideLiveStreamChat: { label: "Hide live stream chat"; title: "Hides the live stream chat" }; diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index 5314ba93..8abf294c 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -328,6 +328,16 @@ export default function Settings() { { label: "auto", value: "auto" } // This cast is here because otherwise it would require marking all the options 'as const' ].reverse() as SelectOption<"player_quality">[]; + const PlayerQualityFallbackStrategyOptions = [ + { + label: t("settings.sections.automaticQuality.fallbackQualityStrategy.select.options.higher"), + value: "higher" + }, + { + label: t("settings.sections.automaticQuality.fallbackQualityStrategy.select.options.lower"), + value: "lower" + } + ] as SelectOption<"player_quality_fallback_strategy">[]; const YouTubePlayerSpeedOptions = youtubePlayerSpeedRates.map((rate) => ({ label: rate?.toString(), value: rate?.toString() @@ -900,6 +910,16 @@ export default function Settings() { title={t("settings.sections.automaticQuality.select.title")} type="select" /> + diff --git a/src/features/playerQuality/index.ts b/src/features/playerQuality/index.ts index 7cf8553d..f6559dc9 100644 --- a/src/features/playerQuality/index.ts +++ b/src/features/playerQuality/index.ts @@ -13,7 +13,7 @@ export default async function setPlayerQuality(): Promise { const optionsData = await waitForSpecificMessage("options", "request_data", "content"); const { data: { - options: { enable_automatically_set_quality, player_quality } + options: { enable_automatically_set_quality, player_quality, player_quality_fallback_strategy } } } = optionsData; @@ -40,7 +40,7 @@ export default async function setPlayerQuality(): Promise { // Check if the specified player quality is available if (player_quality && player_quality !== "auto") { - const closestQuality = chooseClosestQuality(player_quality, availableQualityLevels); + const closestQuality = chooseClosestQuality(player_quality, availableQualityLevels, player_quality_fallback_strategy); if (!closestQuality) return; // Log the message indicating the player quality being set browserColorLog(`Setting player quality to ${closestQuality}`, "FgMagenta"); diff --git a/src/types/index.ts b/src/types/index.ts index d10ec446..6e300c44 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -100,6 +100,8 @@ export const youtubePlayerQualityLevels = [ "auto" ] as const; export type YoutubePlayerQualityLevel = (typeof youtubePlayerQualityLevels)[number]; +export const PlayerQualityFallbackStrategy = ["higher", "lower"] as const; +export type PlayerQualityFallbackStrategy = (typeof PlayerQualityFallbackStrategy)[number]; export const youtubePlayerSpeedRatesExtended = [2.25, 2.5, 2.75, 3, 3.25, 3.75, 4] as const; export const youtubePlayerSpeedRates = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2, ...youtubePlayerSpeedRatesExtended] as const; export const youtubePlaybackSpeedButtonsRates = [0.25, 0.5, 0.75, 1] as const; @@ -395,6 +397,7 @@ export type configuration = { osd_display_type: OnScreenDisplayType; playback_buttons_speed: number; player_quality: YoutubePlayerQualityLevel; + player_quality_fallback_strategy: PlayerQualityFallbackStrategy; player_speed: number; remembered_volumes: RememberedVolumes; screenshot_format: ScreenshotFormat; diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 41d291ea..a660c90b 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -5,6 +5,7 @@ import type { AllButtonNames, ButtonPlacement, TypeToPartialZodSchema, configura import { deepDarkPreset } from "../deepDarkPresets"; import { availableLocales } from "../i18n/index"; import { + PlayerQualityFallbackStrategy, buttonNames, buttonPlacements, featureMenuOpenTypes, @@ -82,6 +83,7 @@ export const defaultConfiguration = { osd_display_type: "text", playback_buttons_speed: 0.25, player_quality: "auto", + player_quality_fallback_strategy: "lower", player_speed: 1, remembered_volumes: { shortsPageVolume: 100, @@ -166,6 +168,7 @@ export const configurationImportSchema: TypeToPartialZodSchema< osd_display_type: z.enum(onScreenDisplayTypes).optional(), playback_buttons_speed: z.number().min(0.25).max(4.0).step(0.25).optional(), player_quality: z.enum(youtubePlayerQualityLevels).optional(), + player_quality_fallback_strategy: z.enum(PlayerQualityFallbackStrategy).optional(), player_speed: z.number().min(0.25).max(4.0).step(0.25).optional(), remembered_volumes: z .object({ diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index fdb7f1e2..d484af70 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -15,6 +15,7 @@ import type { OnScreenDisplayPosition, Path, PathValue, + PlayerQualityFallbackStrategy, Selector, SendDataMessage, SingleButtonFeatureNames, @@ -47,16 +48,19 @@ export const toDivisible = (value: number, divider: number): number => Math.ceil export function chooseClosestQuality( selectedQuality: YoutubePlayerQualityLevel, - availableQualities: YoutubePlayerQualityLevel[] + availableQualities: YoutubePlayerQualityLevel[], + fallbackStrategy: PlayerQualityFallbackStrategy ): Nullable { // If there are no available qualities, return null if (availableQualities.length === 0) { return null; } + // If the selected quality is available, return it if (availableQualities.includes(selectedQuality)) { return selectedQuality; } + // Find the index of the selected quality in the array const selectedIndex = youtubePlayerQualityLevels.indexOf(selectedQuality); @@ -65,15 +69,34 @@ export function chooseClosestQuality( (acc, quality) => { const qualityIndex = youtubePlayerQualityLevels.indexOf(quality); if (qualityIndex !== -1) { - acc.push({ difference: Math.abs(selectedIndex - qualityIndex), quality }); + acc.push({ difference: Math.abs(selectedIndex - qualityIndex), quality, qualityIndex }); } return acc; }, - [] as { difference: number; quality: YoutubePlayerQualityLevel }[] + [] as { difference: number; quality: YoutubePlayerQualityLevel; qualityIndex: number }[] ); - // Return the quality level with the minimum difference - return closestQualities[0].quality; + // Sort the closest qualities by difference in ascending order + closestQualities.sort((a, b) => a.difference - b.difference); + + // If fallback strategy is "higher", prefer higher quality levels + if (fallbackStrategy === "higher") { + for (const { quality, qualityIndex } of closestQualities) { + if (qualityIndex > selectedIndex) { + return quality; + } + } + } + + // If fallback strategy is "lower", prefer lower quality levels + if (fallbackStrategy === "lower") { + for (const { quality, qualityIndex } of closestQualities) { + if (qualityIndex < selectedIndex) { + return quality; + } + } + } + return null; } const BrowserColors = { BgBlack: "background-color: black; color: white;", From ef5229a1a73e811bac3958512d2b711f91d4c2b3 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 13:41:45 +0000 Subject: [PATCH 12/77] docs: update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 92640b84..7bd02804 100755 --- a/README.md +++ b/README.md @@ -306,8 +306,9 @@ Contributions to the YouTube Enhancer Extension are welcome! If you'd like to co Secret-Peter
Secret-Peter

🌍 - Carlos Ramos Luna
Carlos Ramos Luna

🤔 Marcos C.R.
Marcos C.R.

🤔 + Carlos Ramos Luna
Carlos Ramos Luna

🤔 + Mabra51
Mabra51

🤔 From caefacd85517e28c29bb13d2098b528a58d48daa Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 13:41:46 +0000 Subject: [PATCH 13/77] docs: update .all-contributorsrc --- .all-contributorsrc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a4747296..f2f9ef1b 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -148,7 +148,7 @@ "ideas" ] }, - { + { "login": "charlymoon741", "name": "Carlos Ramos Luna", "avatar_url": "https://avatars.githubusercontent.com/u/62484941?v=4", @@ -156,6 +156,15 @@ "contributions": [ "ideas" ] + }, + { + "login": "Mabra51", + "name": "Mabra51", + "avatar_url": "https://avatars.githubusercontent.com/u/12016338?v=4", + "profile": "https://github.com/Mabra51", + "contributions": [ + "ideas" + ] } ] } From 37e05c0005ba0de4db51509782caf70004433d19 Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 20:19:53 +0000 Subject: [PATCH 14/77] docs: update README.md --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 92640b84..6449b11b 100755 --- a/README.md +++ b/README.md @@ -306,8 +306,9 @@ Contributions to the YouTube Enhancer Extension are welcome! If you'd like to co Secret-Peter
Secret-Peter

🌍 - Carlos Ramos Luna
Carlos Ramos Luna

🤔 Marcos C.R.
Marcos C.R.

🤔 + Carlos Ramos Luna
Carlos Ramos Luna

🤔 + 앙시모사우루스
앙시모사우루스

🌍 From 2d064f987f6a50e5b95ed72b22e2ca0cc0b4253e Mon Sep 17 00:00:00 2001 From: "allcontributors[bot]" <46447321+allcontributors[bot]@users.noreply.github.com> Date: Mon, 20 May 2024 20:19:54 +0000 Subject: [PATCH 15/77] docs: update .all-contributorsrc --- .all-contributorsrc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.all-contributorsrc b/.all-contributorsrc index a4747296..7358e1c6 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -148,7 +148,7 @@ "ideas" ] }, - { + { "login": "charlymoon741", "name": "Carlos Ramos Luna", "avatar_url": "https://avatars.githubusercontent.com/u/62484941?v=4", @@ -156,6 +156,15 @@ "contributions": [ "ideas" ] + }, + { + "login": "Angsimosaurus", + "name": "앙시모사우루스", + "avatar_url": "https://avatars.githubusercontent.com/u/79510039?v=4", + "profile": "https://github.com/Angsimosaurus", + "contributions": [ + "translation" + ] } ] } From caed5987c09349bff7a7d906fe5053aa75096d4b Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Wed, 22 May 2024 22:29:15 -0400 Subject: [PATCH 16/77] fix: Button placement change causing multi buttons to stop working. --- src/pages/embedded/index.ts | 69 +++++++++++++++++++++++++++---------- src/types/index.ts | 42 +++++++++++++--------- src/utils/utilities.ts | 38 ++++++++++++++++++++ 3 files changed, 114 insertions(+), 35 deletions(-) diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index 895c1beb..a39a470d 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -3,12 +3,7 @@ import { deepDarkPresets } from "@/src/deepDarkPresets"; import { type FeatureFuncRecord, featureButtonFunctions } from "@/src/features"; import { enableAutomaticTheaterMode } from "@/src/features/automaticTheaterMode"; import { featuresInControls } from "@/src/features/buttonPlacement"; -import { - checkIfFeatureButtonExists, - getFeatureButton, - updateFeatureButtonIcon, - updateFeatureButtonTitle -} from "@/src/features/buttonPlacement/utils"; +import { getFeatureButton, updateFeatureButtonIcon, updateFeatureButtonTitle } from "@/src/features/buttonPlacement/utils"; import { disableCustomCSS, enableCustomCSS } from "@/src/features/customCSS"; import { customCSSExists, updateCustomCSS } from "@/src/features/customCSS/utils"; import { disableDeepDarkCSS, enableDeepDarkCSS } from "@/src/features/deepDarkCSS"; @@ -62,6 +57,8 @@ import volumeBoost, { import { i18nService } from "@/src/i18n"; import { type ToggleFeatures, type ToggleIcon, getFeatureIcon, toggleFeatures } from "@/src/icons"; import { + type AllButtonNames, + type ButtonPlacement, type ExtensionSendOnlyMessageMappings, type Messages, type MultiButtonFeatureNames, @@ -76,6 +73,7 @@ import { browserColorLog, findKeyByValue, formatError, + groupButtonChanges, isShortsPage, isWatchPage, sendContentOnlyMessage, @@ -182,7 +180,21 @@ const enableFeatures = () => { await addLoopButton(); })(); }; +const getFeatureFunctions = (featureName: AllButtonNames, oldPlacement: ButtonPlacement) => { + const { [featureName]: featureFunctions } = featureButtonFunctions; + // Ensure featureFunctions exist before proceeding + if (!featureFunctions) { + throw new Error(`Feature '${featureName}' not found in featureButtonFunctions`); + } + + // Cast featureFunctions to FeatureFuncRecord + const castFeatureFunctions = featureFunctions as unknown as FeatureFuncRecord; + return { + add: () => castFeatureFunctions.add(), + remove: () => castFeatureFunctions.remove(oldPlacement) + }; +}; window.addEventListener("DOMContentLoaded", function () { void (async () => { const response = await waitForSpecificMessage("language", "request_data", "content"); @@ -637,19 +649,38 @@ window.addEventListener("DOMContentLoaded", function () { break; } case "buttonPlacementChange": { - const { - data: { buttonPlacement: buttonPlacements } - } = message; - for (const [featureName, { new: newPlacement, old: oldPlacement }] of Object.entries(buttonPlacements)) { - const buttonExists = checkIfFeatureButtonExists(featureName, newPlacement); - if (buttonExists) continue; - const { [featureName]: featureFunctions } = featureButtonFunctions; - // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment - const castFeatureFunctions = featureFunctions as unknown as FeatureFuncRecord; - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access - await castFeatureFunctions.remove(oldPlacement); - // eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access - await castFeatureFunctions.add(); + const { data } = message; + const { multiButtonChanges, singleButtonChanges } = groupButtonChanges(data); + for (const [featureName, changes] of Object.entries(multiButtonChanges)) { + switch (featureName) { + case "playbackSpeedButtons": { + for (const [buttonName, { old: oldPlacement }] of Object.entries(changes)) { + const increasePlaybackSpeedButtonFuncs = getFeatureFunctions( + "increasePlaybackSpeedButton", + buttonName === "decreasePlaybackSpeedButton" ? multiButtonChanges[featureName]["increasePlaybackSpeedButton"].old : oldPlacement + ); + const decreasePlaybackSpeedButtonFuncs = getFeatureFunctions( + "decreasePlaybackSpeedButton", + buttonName === "increasePlaybackSpeedButton" ? multiButtonChanges[featureName]["decreasePlaybackSpeedButton"].old : oldPlacement + ); + switch (buttonName) { + case "increasePlaybackSpeedButton": + case "decreasePlaybackSpeedButton": { + await decreasePlaybackSpeedButtonFuncs.remove(); + await increasePlaybackSpeedButtonFuncs.remove(); + await decreasePlaybackSpeedButtonFuncs.add(); + await increasePlaybackSpeedButtonFuncs.add(); + } + } + } + break; + } + } + } + for (const [featureName, { old: oldPlacement }] of Object.entries(singleButtonChanges)) { + const featureFuncs = getFeatureFunctions(featureName, oldPlacement); + await featureFuncs.remove(); + await featureFuncs.add(); } break; } diff --git a/src/types/index.ts b/src/types/index.ts index 6e300c44..55337710 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,4 +1,5 @@ import type { ParseKeys, TOptions } from "i18next"; +import type EnUS from "public/locales/en-US.json"; import type { YouTubePlayer } from "youtube-player/dist/types"; import z, { ZodType } from "zod"; @@ -118,6 +119,18 @@ export type VideoHistoryResumeType = (typeof videoHistoryResumeTypes)[number]; export const buttonPlacements = ["below_player", "feature_menu", "player_controls_left", "player_controls_right"] as const; export type ButtonPlacement = (typeof buttonPlacements)[number]; export const featureMenuOpenTypes = ["click", "hover"] as const; +export type MultiButtonChange = { + [K in MultiButtonFeatureNames]: Record; +}; +export type SingleButtonChange = { [K in SingleButtonFeatureNames]: { new: ButtonPlacement; old: ButtonPlacement } }; +export type ButtonPlacementChange = { + buttonPlacement: { + [Key in AllButtonNames]: { + new: ButtonPlacement; + old: ButtonPlacement; + }; + }; +}; export type FeatureMenuOpenType = (typeof featureMenuOpenTypes)[number]; export type DeepDarkCustomThemeColors = { colorShadow: string; @@ -131,12 +144,19 @@ export type DeepDarkCustomThemeColors = { type TOptionsKeys = ParseKeys<"en-US", TOptions, undefined>; export type AllButtonNames = Exclude, "featureMenu">; export type SingleButtonNames = Exclude; -export type SingleButtonFeatureNames = Exclude, "featureMenu">; +export type SingleButtonFeatureNames = Exclude< + ExtractButtonFeatureNames<`pages.content.features.${string}.button.label` & TOptionsKeys>, + "featureMenu" +>; export type MultiButtonNames = Exclude; -export type MultiButtonFeatureNames = Exclude; -export const featureToMultiButtonsMap: Map = new Map([ - ["playbackSpeedButtons", ["increasePlaybackSpeedButton", "decreasePlaybackSpeedButton"]] -]); +export type MultiButtonFeatureNames = ExtractButtonFeatureNames<`pages.content.features.${string}.buttons.${string}.label` & TOptionsKeys>; +export type FeatureToMultiButtonMap = { + [K in MultiButtonFeatureNames]: (keyof EnUS["pages"]["content"]["features"][K]["buttons"])[]; +}; +const featureToMultiButtonMapEntries: FeatureToMultiButtonMap = { + playbackSpeedButtons: ["increasePlaybackSpeedButton" as const, "decreasePlaybackSpeedButton" as const] +}; +export const featureToMultiButtonsMap = new Map(Object.entries(featureToMultiButtonMapEntries)); export type FeatureMenuItemIconId = `yte-${AllButtonNames}-icon`; export type FeatureMenuItemId = `yte-feature-${AllButtonNames}-menuitem`; export type FeatureMenuItemLabelId = `yte-${AllButtonNames}-label`; @@ -259,17 +279,7 @@ export type ContentToBackgroundSendOnlyMessageMappings = { }; export type ExtensionSendOnlyMessageMappings = { automaticTheaterModeChange: DataResponseMessage<"automaticTheaterModeChange", { automaticTheaterModeEnabled: boolean }>; - buttonPlacementChange: DataResponseMessage< - "buttonPlacementChange", - { - buttonPlacement: { - [Key in AllButtonNames]: { - new: ButtonPlacement; - old: ButtonPlacement; - }; - }; - } - >; + buttonPlacementChange: DataResponseMessage<"buttonPlacementChange", ButtonPlacementChange>; customCSSChange: DataResponseMessage<"customCSSChange", { customCSSCode: string; customCSSEnabled: boolean }>; deepDarkThemeChange: DataResponseMessage< "deepDarkThemeChange", diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index d484af70..ecde23dc 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -5,12 +5,17 @@ import type { ActionMessage, AllButtonNames, AnyFunction, + ButtonPlacement, + ButtonPlacementChange, ContentSendOnlyMessageMappings, ContentToBackgroundSendOnlyMessageMappings, ExtensionSendOnlyMessageMappings, + FeatureToMultiButtonMap, MessageMappings, MessageSource, Messages, + MultiButtonChange, + MultiButtonFeatureNames, Nullable, OnScreenDisplayPosition, Path, @@ -18,6 +23,7 @@ import type { PlayerQualityFallbackStrategy, Selector, SendDataMessage, + SingleButtonChange, SingleButtonFeatureNames, SingleButtonNames, YoutubePlayerQualityLevel @@ -706,3 +712,35 @@ export function deepMerge(target: Record, source: Record>; + } = {}; + const singleButtonChanges: { [K in SingleButtonFeatureNames]?: { new: ButtonPlacement; old: ButtonPlacement } } = {}; + + Object.keys(changes.buttonPlacement).forEach((button) => { + const buttonName = button; + const multiButtonFeatureNames = findKeyByValue(buttonName as Exclude); + + if (multiButtonFeatureNames) { + const featureButtons = featureToMultiButtonsMap.get(multiButtonFeatureNames) || []; + if (featureButtons.includes(buttonName)) { + if (!multiButtonChanges[multiButtonFeatureNames]) { + multiButtonChanges[multiButtonFeatureNames] = {}; + } + // eslint-disable-next-line prefer-destructuring + multiButtonChanges[multiButtonFeatureNames]![buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]] = + changes.buttonPlacement[buttonName]; + } + } else if (Object.keys(changes.buttonPlacement).includes(buttonName)) { + // eslint-disable-next-line prefer-destructuring + singleButtonChanges[buttonName as SingleButtonFeatureNames] = changes.buttonPlacement[buttonName]; + } + }); + + return { multiButtonChanges: multiButtonChanges as MultiButtonChange, singleButtonChanges: singleButtonChanges as SingleButtonChange }; +} From b1ce52c0768cf70c3c67c052865197f9570311da Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Wed, 22 May 2024 23:05:50 -0400 Subject: [PATCH 17/77] refactor: improve groupButtonChanges func --- src/utils/utilities.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index ecde23dc..1cec8b58 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -724,21 +724,19 @@ export function groupButtonChanges(changes: ButtonPlacementChange): { Object.keys(changes.buttonPlacement).forEach((button) => { const buttonName = button; + if (Object.keys(changes.buttonPlacement).includes(buttonName)) + // eslint-disable-next-line prefer-destructuring + return (singleButtonChanges[buttonName as SingleButtonFeatureNames] = changes.buttonPlacement[buttonName]); const multiButtonFeatureNames = findKeyByValue(buttonName as Exclude); - - if (multiButtonFeatureNames) { - const featureButtons = featureToMultiButtonsMap.get(multiButtonFeatureNames) || []; - if (featureButtons.includes(buttonName)) { - if (!multiButtonChanges[multiButtonFeatureNames]) { - multiButtonChanges[multiButtonFeatureNames] = {}; - } - // eslint-disable-next-line prefer-destructuring - multiButtonChanges[multiButtonFeatureNames]![buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]] = - changes.buttonPlacement[buttonName]; + if (multiButtonFeatureNames === undefined) return; + const featureButtons = featureToMultiButtonsMap.get(multiButtonFeatureNames) || []; + if (featureButtons.includes(buttonName)) { + if (!multiButtonChanges[multiButtonFeatureNames]) { + multiButtonChanges[multiButtonFeatureNames] = {}; } - } else if (Object.keys(changes.buttonPlacement).includes(buttonName)) { // eslint-disable-next-line prefer-destructuring - singleButtonChanges[buttonName as SingleButtonFeatureNames] = changes.buttonPlacement[buttonName]; + multiButtonChanges[multiButtonFeatureNames]![buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]] = + changes.buttonPlacement[buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]]; } }); From 1de79604408f2087cf65edc6a63ea2a14d4b6ea5 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Wed, 22 May 2024 23:54:41 -0400 Subject: [PATCH 18/77] refactor: Improve multi button types --- src/types/index.ts | 21 +++++++++++++++++---- src/utils/utilities.ts | 13 +++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/types/index.ts b/src/types/index.ts index 55337710..c5835464 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -11,6 +11,7 @@ export type Nullable = T | null; export type AnyFunction = (...args: any[]) => void; export type Writeable = { -readonly [P in keyof T]: T[P] }; export type DeepWriteable = { -readonly [P in keyof T]: DeepWriteable }; +export type DeepPartial = { [P in keyof T]?: DeepPartial }; export type WithId = `#${S}`; export type Prettify = { [K in keyof T]: T[K]; @@ -120,7 +121,12 @@ export const buttonPlacements = ["below_player", "feature_menu", "player_control export type ButtonPlacement = (typeof buttonPlacements)[number]; export const featureMenuOpenTypes = ["click", "hover"] as const; export type MultiButtonChange = { - [K in MultiButtonFeatureNames]: Record; + [K in MultiButtonFeatureNames]: { + [Button in keyof FeatureToMultiButtonMap[K]]: { + new: ButtonPlacement; + old: ButtonPlacement; + }; + }; }; export type SingleButtonChange = { [K in SingleButtonFeatureNames]: { new: ButtonPlacement; old: ButtonPlacement } }; export type ButtonPlacementChange = { @@ -151,12 +157,19 @@ export type SingleButtonFeatureNames = Exclude< export type MultiButtonNames = Exclude; export type MultiButtonFeatureNames = ExtractButtonFeatureNames<`pages.content.features.${string}.buttons.${string}.label` & TOptionsKeys>; export type FeatureToMultiButtonMap = { - [K in MultiButtonFeatureNames]: (keyof EnUS["pages"]["content"]["features"][K]["buttons"])[]; + [K in MultiButtonFeatureNames]: { + [Button in keyof EnUS["pages"]["content"]["features"][K]["buttons"]]: ""; + }; }; const featureToMultiButtonMapEntries: FeatureToMultiButtonMap = { - playbackSpeedButtons: ["increasePlaybackSpeedButton" as const, "decreasePlaybackSpeedButton" as const] + playbackSpeedButtons: { + decreasePlaybackSpeedButton: "", + increasePlaybackSpeedButton: "" + } }; -export const featureToMultiButtonsMap = new Map(Object.entries(featureToMultiButtonMapEntries)); +export const featureToMultiButtonsMap = new Map( + Object.keys(featureToMultiButtonMapEntries).map((key) => [key, Object.keys(featureToMultiButtonMapEntries[key])]) +); export type FeatureMenuItemIconId = `yte-${AllButtonNames}-icon`; export type FeatureMenuItemId = `yte-feature-${AllButtonNames}-menuitem`; export type FeatureMenuItemLabelId = `yte-${AllButtonNames}-label`; diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index 1cec8b58..0ec21abc 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -5,17 +5,16 @@ import type { ActionMessage, AllButtonNames, AnyFunction, - ButtonPlacement, ButtonPlacementChange, ContentSendOnlyMessageMappings, ContentToBackgroundSendOnlyMessageMappings, + DeepPartial, ExtensionSendOnlyMessageMappings, FeatureToMultiButtonMap, MessageMappings, MessageSource, Messages, MultiButtonChange, - MultiButtonFeatureNames, Nullable, OnScreenDisplayPosition, Path, @@ -717,10 +716,8 @@ export function groupButtonChanges(changes: ButtonPlacementChange): { multiButtonChanges: MultiButtonChange; singleButtonChanges: SingleButtonChange; } { - const multiButtonChanges: { - [K in MultiButtonFeatureNames]?: Partial>; - } = {}; - const singleButtonChanges: { [K in SingleButtonFeatureNames]?: { new: ButtonPlacement; old: ButtonPlacement } } = {}; + const multiButtonChanges: DeepPartial = {}; + const singleButtonChanges: DeepPartial = {}; Object.keys(changes.buttonPlacement).forEach((button) => { const buttonName = button; @@ -735,8 +732,8 @@ export function groupButtonChanges(changes: ButtonPlacementChange): { multiButtonChanges[multiButtonFeatureNames] = {}; } // eslint-disable-next-line prefer-destructuring - multiButtonChanges[multiButtonFeatureNames]![buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]] = - changes.buttonPlacement[buttonName as FeatureToMultiButtonMap[typeof multiButtonFeatureNames][number]]; + multiButtonChanges[multiButtonFeatureNames]![buttonName as keyof FeatureToMultiButtonMap[typeof multiButtonFeatureNames]] = + changes.buttonPlacement[buttonName as keyof FeatureToMultiButtonMap[typeof multiButtonFeatureNames]]; } }); From d57d9ad1714353f07d04bdfeff3760d9b5ee2b36 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Thu, 23 May 2024 00:14:03 -0400 Subject: [PATCH 19/77] refactor: Use KeyOfUnions type to fix type error --- src/types/index.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/types/index.ts b/src/types/index.ts index c5835464..4d2f0737 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -12,6 +12,7 @@ export type AnyFunction = (...args: any[]) => void; export type Writeable = { -readonly [P in keyof T]: T[P] }; export type DeepWriteable = { -readonly [P in keyof T]: DeepWriteable }; export type DeepPartial = { [P in keyof T]?: DeepPartial }; +export type KeysOfUnion = T extends T ? keyof T : never; export type WithId = `#${S}`; export type Prettify = { [K in keyof T]: T[K]; @@ -168,7 +169,11 @@ const featureToMultiButtonMapEntries: FeatureToMultiButtonMap = { } }; export const featureToMultiButtonsMap = new Map( - Object.keys(featureToMultiButtonMapEntries).map((key) => [key, Object.keys(featureToMultiButtonMapEntries[key])]) + Object.keys(featureToMultiButtonMapEntries).map((key) => [ + key, + // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion + Object.keys(featureToMultiButtonMapEntries[key]) as KeysOfUnion[] + ]) ); export type FeatureMenuItemIconId = `yte-${AllButtonNames}-icon`; export type FeatureMenuItemId = `yte-feature-${AllButtonNames}-menuitem`; From dd9b089b68fd3fd750025439cd88536b4c0b8382 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Thu, 23 May 2024 00:38:46 -0400 Subject: [PATCH 20/77] fix: continue when old and new placement is the same --- src/pages/embedded/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index a39a470d..a4e9948a 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -654,7 +654,8 @@ window.addEventListener("DOMContentLoaded", function () { for (const [featureName, changes] of Object.entries(multiButtonChanges)) { switch (featureName) { case "playbackSpeedButtons": { - for (const [buttonName, { old: oldPlacement }] of Object.entries(changes)) { + for (const [buttonName, { new: newPlacement, old: oldPlacement }] of Object.entries(changes)) { + if (oldPlacement === newPlacement) continue; const increasePlaybackSpeedButtonFuncs = getFeatureFunctions( "increasePlaybackSpeedButton", buttonName === "decreasePlaybackSpeedButton" ? multiButtonChanges[featureName]["increasePlaybackSpeedButton"].old : oldPlacement @@ -677,7 +678,8 @@ window.addEventListener("DOMContentLoaded", function () { } } } - for (const [featureName, { old: oldPlacement }] of Object.entries(singleButtonChanges)) { + for (const [featureName, { new: newPlacement, old: oldPlacement }] of Object.entries(singleButtonChanges)) { + if (oldPlacement === newPlacement) continue; const featureFuncs = getFeatureFunctions(featureName, oldPlacement); await featureFuncs.remove(); await featureFuncs.add(); From eeac7f1054f468986c5c485fb2f36c23ea4bf1b1 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Thu, 23 May 2024 01:05:55 -0400 Subject: [PATCH 21/77] refactor: Improve language change for multi feature buttons --- src/pages/embedded/index.ts | 49 ++++++++++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/pages/embedded/index.ts b/src/pages/embedded/index.ts index a4e9948a..ee3b23e6 100644 --- a/src/pages/embedded/index.ts +++ b/src/pages/embedded/index.ts @@ -60,6 +60,8 @@ import { type AllButtonNames, type ButtonPlacement, type ExtensionSendOnlyMessageMappings, + type FeatureToMultiButtonMap, + type KeysOfUnion, type Messages, type MultiButtonFeatureNames, type MultiButtonNames, @@ -481,17 +483,30 @@ window.addEventListener("DOMContentLoaded", function () { data: { language } } = message; window.i18nextInstance = await i18nService(language); + const { + data: { options } + } = await waitForSpecificMessage("options", "request_data", "content"); if (featuresInMenu.size > 0) { updateFeatureMenuTitle(window.i18nextInstance.t("pages.content.features.featureMenu.button.label")); for (const feature of featuresInMenu) { const featureName = findKeyByValue(feature as MultiButtonNames) ?? (feature as SingleButtonFeatureNames); if (featureToMultiButtonsMap.has(featureName)) { - updateFeatureMenuItemLabel( - feature, - window.i18nextInstance.t( - `pages.content.features.${featureName as MultiButtonFeatureNames}.buttons.${feature as MultiButtonNames}.label` - ) - ); + const multiFeatureName = featureName as MultiButtonFeatureNames; + const multiButtonName = feature as MultiButtonNames; + switch (multiFeatureName) { + case "playbackSpeedButtons": { + updateFeatureMenuItemLabel( + feature, + window.i18nextInstance.t( + `pages.content.features.${multiFeatureName}.buttons.${multiButtonName}.label` as `pages.content.features.${typeof multiFeatureName}.buttons.${KeysOfUnion}.label`, + { + SPEED: options.playback_buttons_speed + } + ) + ); + break; + } + } } else { updateFeatureMenuItemLabel( feature, @@ -514,12 +529,22 @@ window.addEventListener("DOMContentLoaded", function () { ); } else { if (featureToMultiButtonsMap.has(featureName)) { - updateFeatureMenuItemLabel( - feature, - window.i18nextInstance.t( - `pages.content.features.${featureName as MultiButtonFeatureNames}.buttons.${feature as MultiButtonNames}.label` - ) - ); + const multiFeatureName = featureName as MultiButtonFeatureNames; + const multiButtonName = feature as MultiButtonNames; + switch (multiFeatureName) { + case "playbackSpeedButtons": { + updateFeatureMenuItemLabel( + feature, + window.i18nextInstance.t( + `pages.content.features.${multiFeatureName}.buttons.${multiButtonName}.label` as `pages.content.features.${typeof multiFeatureName}.buttons.${KeysOfUnion}.label`, + { + SPEED: options.playback_buttons_speed + } + ) + ); + break; + } + } } else { updateFeatureButtonTitle( feature, From 6196636253456b4cb3ba3f5c842e5e7065e8efe9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:07 +0000 Subject: [PATCH 22/77] build(deps-dev): bump nodemon from 3.1.0 to 3.1.1 Bumps [nodemon](https://github.com/remy/nodemon) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/remy/nodemon/releases) - [Commits](https://github.com/remy/nodemon/compare/v3.1.0...v3.1.1) --- updated-dependencies: - dependency-name: nodemon dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4458175d..403f8bb7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@formkit/auto-animate": "^0.8.1", "@monaco-editor/react": "^4.6.0", - "@rollup/rollup-linux-x64-gnu": "^4.14.3", "@tanstack/react-query": "^5.18.0", "dotenv": "^16.3.1", "i18next": "^23.7.3", @@ -6972,9 +6971,9 @@ "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" }, "node_modules/nodemon": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.0.tgz", - "integrity": "sha512-xqlktYlDMCepBJd43ZQhjWwMw2obW/JRvkrLxq5RCNcuDDX1DbcPT+qT1IlIIdf+DhnWs90JpTMe+Y5KxOchvA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.1.tgz", + "integrity": "sha512-k43xGaDtaDIcufn0Fc6fTtsdKSkV/hQzoQFigNH//GaKta28yoKVYXCnV+KXRqfT/YzsFaQU9VdeEG+HEyxr6A==", "dev": true, "dependencies": { "chokidar": "^3.5.2", From ab24504d6ef814a12011f2a611a612d6c61cd1f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:19 +0000 Subject: [PATCH 23/77] build(deps): bump @rollup/rollup-linux-x64-gnu from 4.17.2 to 4.18.0 Bumps [@rollup/rollup-linux-x64-gnu](https://github.com/rollup/rollup) from 4.17.2 to 4.18.0. - [Release notes](https://github.com/rollup/rollup/releases) - [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md) - [Commits](https://github.com/rollup/rollup/compare/v4.17.2...v4.18.0) --- updated-dependencies: - dependency-name: "@rollup/rollup-linux-x64-gnu" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4458175d..224aa5be 100644 --- a/package-lock.json +++ b/package-lock.json @@ -910,9 +910,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.17.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.17.2.tgz", - "integrity": "sha512-Hy7pLwByUOuyaFC6mAr7m+oMC+V7qyifzs/nW2OJfC8H4hbCzOX07Ov0VFk/zP3kBsELWNFi7rJtgbKYsav9QQ==", + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.18.0.tgz", + "integrity": "sha512-xuglR2rBVHA5UsI8h8UbX4VJ470PtGCf5Vpswh7p2ukaqBGFTnsfzxUBetoWBWymHMxbIG0Cmx7Y9qDZzr648w==", "cpu": [ "x64" ], From 635bb81caeb08bb88478f349e866eb3ccee5b079 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:29 +0000 Subject: [PATCH 24/77] build(deps-dev): bump @types/node from 20.12.7 to 20.12.12 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 20.12.7 to 20.12.12. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4458175d..97b011c6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@formkit/auto-animate": "^0.8.1", "@monaco-editor/react": "^4.6.0", - "@rollup/rollup-linux-x64-gnu": "^4.14.3", "@tanstack/react-query": "^5.18.0", "dotenv": "^16.3.1", "i18next": "^23.7.3", @@ -1692,9 +1691,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.12.7", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz", - "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==", + "version": "20.12.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz", + "integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==", "dependencies": { "undici-types": "~5.26.4" } From 0c12f8d06a0fcb7c93dff7e404e5e72dd1e30e22 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:41 +0000 Subject: [PATCH 25/77] build(deps-dev): bump eslint-plugin-tailwindcss from 3.15.1 to 3.17.0 Bumps [eslint-plugin-tailwindcss](https://github.com/francoismassart/eslint-plugin-tailwindcss) from 3.15.1 to 3.17.0. - [Release notes](https://github.com/francoismassart/eslint-plugin-tailwindcss/releases) - [Commits](https://github.com/francoismassart/eslint-plugin-tailwindcss/compare/v3.15.1...v3.17.0) --- updated-dependencies: - dependency-name: eslint-plugin-tailwindcss dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4458175d..fa0f3ebb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@formkit/auto-animate": "^0.8.1", "@monaco-editor/react": "^4.6.0", - "@rollup/rollup-linux-x64-gnu": "^4.14.3", "@tanstack/react-query": "^5.18.0", "dotenv": "^16.3.1", "i18next": "^23.7.3", @@ -4732,16 +4731,16 @@ } }, "node_modules/eslint-plugin-tailwindcss": { - "version": "3.15.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.15.1.tgz", - "integrity": "sha512-4RXRMIaMG07C2TBEW1k0VM4+dDazz1kxcZhkK4zirvmHGZTA4jnlSO2kq5mamuSPi+Wo17dh2SlC8IyFBuCd7Q==", + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-tailwindcss/-/eslint-plugin-tailwindcss-3.17.0.tgz", + "integrity": "sha512-Ofl7tNh57a3W8BKHstKZSkD2gSCEkw54ycwZ958IK9zUR8TiNYdp8b0WGoLWLeyOAbeF1VPVJFBnlkJeIM2kVg==", "dev": true, "dependencies": { "fast-glob": "^3.2.5", "postcss": "^8.4.4" }, "engines": { - "node": ">=12.13.0" + "node": ">=14.0.0" }, "peerDependencies": { "tailwindcss": "^3.4.0" From 86fa37405d087577998f6569966d9635f0bead7e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 01:16:53 +0000 Subject: [PATCH 26/77] build(deps-dev): bump semantic-release from 23.0.8 to 23.1.1 Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 23.0.8 to 23.1.1. - [Release notes](https://github.com/semantic-release/semantic-release/releases) - [Commits](https://github.com/semantic-release/semantic-release/compare/v23.0.8...v23.1.1) --- updated-dependencies: - dependency-name: semantic-release dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 166 ++++++++++++++++++++++++++++++---------------- 1 file changed, 107 insertions(+), 59 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4458175d..109165c9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "dependencies": { "@formkit/auto-animate": "^0.8.1", "@monaco-editor/react": "^4.6.0", - "@rollup/rollup-linux-x64-gnu": "^4.14.3", "@tanstack/react-query": "^5.18.0", "dotenv": "^16.3.1", "i18next": "^23.7.3", @@ -969,6 +968,12 @@ "win32" ] }, + "node_modules/@sec-ant/readable-stream": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", + "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", + "dev": true + }, "node_modules/@semantic-release/changelog": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@semantic-release/changelog/-/changelog-6.0.3.tgz", @@ -6083,6 +6088,18 @@ "node": ">=8" } }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", @@ -10216,6 +10233,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse-ms": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse5": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz", @@ -10658,6 +10687,21 @@ "node": ">=6.0.0" } }, + "node_modules/pretty-ms": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.0.0.tgz", + "integrity": "sha512-E9e9HJ9R9NasGOgPaPE8VMeiPKAyWR5jcFpNnwIejslIhWqdqOrb2wShBsncMPUb+BcCd2OPYfh7p2W6oemTng==", + "dev": true, + "dependencies": { + "parse-ms": "^4.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -11327,9 +11371,9 @@ } }, "node_modules/semantic-release": { - "version": "23.0.8", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.0.8.tgz", - "integrity": "sha512-yZkuWcTTfh5h/DrR4Q4QvJSARJdb6wjwn/sN0qKMYEkvwaVFek8YWfrgtL8oWaRdl0fLte0Y1wWMzLbwoaII1g==", + "version": "23.1.1", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.1.1.tgz", + "integrity": "sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==", "dev": true, "dependencies": { "@semantic-release/commit-analyzer": "^12.0.0", @@ -11341,7 +11385,7 @@ "cosmiconfig": "^9.0.0", "debug": "^4.0.0", "env-ci": "^11.0.0", - "execa": "^8.0.0", + "execa": "^9.0.0", "figures": "^6.0.0", "find-versions": "^6.0.0", "get-stream": "^6.0.0", @@ -11378,6 +11422,18 @@ "node": ">=18" } }, + "node_modules/semantic-release/node_modules/@sindresorhus/merge-streams": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", + "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/semantic-release/node_modules/aggregate-error": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-5.0.0.tgz", @@ -11422,47 +11478,54 @@ } }, "node_modules/semantic-release/node_modules/execa": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", - "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-9.1.0.tgz", + "integrity": "sha512-lSgHc4Elo2m6bUDhc3Hl/VxvUDJdQWI40RZ4KMY9bKRc+hgMOT7II/JjbNDhI8VnMtrCb7U/fhpJIkLORZozWw==", "dev": true, "dependencies": { + "@sindresorhus/merge-streams": "^4.0.0", "cross-spawn": "^7.0.3", - "get-stream": "^8.0.1", - "human-signals": "^5.0.0", - "is-stream": "^3.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^5.1.0", - "onetime": "^6.0.0", + "figures": "^6.1.0", + "get-stream": "^9.0.0", + "human-signals": "^7.0.0", + "is-plain-obj": "^4.1.0", + "is-stream": "^4.0.1", + "npm-run-path": "^5.2.0", + "pretty-ms": "^9.0.0", "signal-exit": "^4.1.0", - "strip-final-newline": "^3.0.0" + "strip-final-newline": "^4.0.0", + "yoctocolors": "^2.0.0" }, "engines": { - "node": ">=16.17" + "node": ">=18" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, "node_modules/semantic-release/node_modules/execa/node_modules/get-stream": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", - "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", + "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", "dev": true, + "dependencies": { + "@sec-ant/readable-stream": "^0.4.1", + "is-stream": "^4.0.1" + }, "engines": { - "node": ">=16" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/semantic-release/node_modules/human-signals": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", - "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-7.0.0.tgz", + "integrity": "sha512-74kytxOUSvNbjrT9KisAbaTZ/eJwD/LrbM/kh5j0IhPuJzwuA19dWvniFGwBzN9rVjg+O/e+F310PjObDXS+9Q==", "dev": true, "engines": { - "node": ">=16.17.0" + "node": ">=18.18.0" } }, "node_modules/semantic-release/node_modules/indent-string": { @@ -11478,24 +11541,12 @@ } }, "node_modules/semantic-release/node_modules/is-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", - "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", - "dev": true, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/semantic-release/node_modules/mimic-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", - "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", + "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -11516,21 +11567,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/semantic-release/node_modules/onetime": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", - "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", - "dev": true, - "dependencies": { - "mimic-fn": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/semantic-release/node_modules/p-reduce": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/p-reduce/-/p-reduce-3.0.0.tgz", @@ -11577,12 +11613,12 @@ } }, "node_modules/semantic-release/node_modules/strip-final-newline": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", - "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", + "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", "dev": true, "engines": { - "node": ">=12" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -13631,6 +13667,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.0.2.tgz", + "integrity": "sha512-Ct97huExsu7cWeEjmrXlofevF8CvzUglJ4iGUet5B8xn1oumtAZBpHU4GzYuoE6PVqcZ5hghtBrSlhwHuR1Jmw==", + "dev": true, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zip-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", From 27a2bd5929892ac10ad54e6d27ffbb90cd3ee922 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Sat, 1 Jun 2024 16:07:09 -0400 Subject: [PATCH 27/77] chore: update translation context screenshots --- .../Button_Labels.png | Bin 9054 -> 5813 bytes ...tton_Name_Hide_End_Screen_Cards_Button.png | Bin 0 -> 5251 bytes .../Buttons/Hide_End_Screen_Cards_Button.png | Bin 0 -> 2904 bytes .../Buttons/Show_End_Screen_Cards_Button.png | Bin 0 -> 3161 bytes .../Feature Menu/Feature_Menu.png | Bin 15073 -> 24213 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 assets/translation context screenshots/Button Placement Settings/Button_Name_Hide_End_Screen_Cards_Button.png create mode 100644 assets/translation context screenshots/YouTube Page/Buttons/Hide_End_Screen_Cards_Button.png create mode 100644 assets/translation context screenshots/YouTube Page/Buttons/Show_End_Screen_Cards_Button.png diff --git a/assets/translation context screenshots/Button Placement Settings/Button_Labels.png b/assets/translation context screenshots/Button Placement Settings/Button_Labels.png index eab1a83911729a6bb1c1f6398fdb625ee08fcbb5..652e4458ace7dfdf7df75eb95296130bcc848256 100644 GIT binary patch literal 5813 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 WySDcSbg>xVXlZL2XyA~xk^ck2TrWNV literal 9054 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 F{|~b{Orrn* diff --git a/assets/translation context screenshots/Button Placement Settings/Button_Name_Hide_End_Screen_Cards_Button.png b/assets/translation context screenshots/Button Placement Settings/Button_Name_Hide_End_Screen_Cards_Button.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6e9d88232bc90a45e1e41fe7714d27f8b5b566 GIT binary patch literal 5251 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 literal 0 HcmV?d00001 diff --git a/assets/translation context screenshots/YouTube Page/Buttons/Hide_End_Screen_Cards_Button.png b/assets/translation context screenshots/YouTube Page/Buttons/Hide_End_Screen_Cards_Button.png new file mode 100644 index 0000000000000000000000000000000000000000..474502380bc64c57af6bf4548e44517873ef6638 GIT binary patch literal 2904 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 literal 15073 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 Date: Sun, 2 Jun 2024 01:03:01 -0400 Subject: [PATCH 28/77] feat: Disable button's placement select when button isn't enabled #504 --- src/components/Settings/Settings.tsx | 3 ++- src/types/index.ts | 10 ++++++++++ src/utils/utilities.ts | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/components/Settings/Settings.tsx b/src/components/Settings/Settings.tsx index 8abf294c..949d9252 100644 --- a/src/components/Settings/Settings.tsx +++ b/src/components/Settings/Settings.tsx @@ -13,7 +13,7 @@ import { availableLocales, type i18nInstanceType, i18nService, localeDirection, import { buttonNames, youtubePlaybackSpeedButtonsRates, youtubePlayerSpeedRates } from "@/src/types"; import { configurationImportSchema, defaultConfiguration as defaultSettings } from "@/src/utils/constants"; import { updateStoredSettings } from "@/src/utils/updateStoredSettings"; -import { cn, deepMerge, formatDateForFileName, getPathValue, parseStoredValue } from "@/src/utils/utilities"; +import { cn, deepMerge, formatDateForFileName, getPathValue, isButtonSelectDisabled, parseStoredValue } from "@/src/utils/utilities"; import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { Suspense, createContext, useContext, useEffect, useRef, useState } from "react"; import { MdOutlineOpenInNew } from "react-icons/md"; @@ -537,6 +537,7 @@ export default function Settings() { const label = t(`settings.sections.buttonPlacement.select.buttonNames.${feature}`); return ( ); +export const buttonNameToSettingName = { + decreasePlaybackSpeedButton: "enable_playback_speed_buttons", + hideEndScreenCardsButton: "enable_hide_end_screen_cards_button", + increasePlaybackSpeedButton: "enable_playback_speed_buttons", + loopButton: "enable_loop_button", + maximizePlayerButton: "enable_maximize_player_button", + openTranscriptButton: "enable_open_transcript_button", + screenshotButton: "enable_screenshot_button", + volumeBoostButton: "enable_volume_boost" +} satisfies Record; export type ButtonPlacementConfigurationMap = { [ButtonName in AllButtonNames]: ButtonPlacement; }; diff --git a/src/utils/utilities.ts b/src/utils/utilities.ts index 0ec21abc..fcb7ac52 100644 --- a/src/utils/utilities.ts +++ b/src/utils/utilities.ts @@ -25,11 +25,12 @@ import type { SingleButtonChange, SingleButtonFeatureNames, SingleButtonNames, - YoutubePlayerQualityLevel + YoutubePlayerQualityLevel, + configuration } from "../types"; import type { SVGElementAttributes } from "./SVGElementAttributes"; -import { featureToMultiButtonsMap, youtubePlayerQualityLevels } from "../types"; +import { buttonNameToSettingName, featureToMultiButtonsMap, youtubePlayerQualityLevels } from "../types"; import { type FeatureName, eventManager } from "./EventManager"; export const isStrictEqual = (value1: unknown) => (value2: unknown) => value1 === value2; @@ -739,3 +740,14 @@ export function groupButtonChanges(changes: ButtonPlacementChange): { return { multiButtonChanges: multiButtonChanges as MultiButtonChange, singleButtonChanges: singleButtonChanges as SingleButtonChange }; } +export function isButtonSelectDisabled(buttonName: AllButtonNames, settings: configuration) { + switch (buttonName) { + case "volumeBoostButton": { + return settings.volume_boost_mode === "global" || settings[buttonNameToSettingName[buttonName]] === false; + } + default: { + const { [buttonName]: settingName } = buttonNameToSettingName; + return settings[settingName] === false; + } + } +} From 2a427476629c8aaca0f3ec99efcc897a711dba4e Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Sun, 2 Jun 2024 16:40:50 -0400 Subject: [PATCH 29/77] refactor: Return existing notification array if length is zero --- src/hooks/useNotifications/provider.tsx | 30 +++++++++---------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/src/hooks/useNotifications/provider.tsx b/src/hooks/useNotifications/provider.tsx index 8f4ecb2f..cfdeb0a0 100644 --- a/src/hooks/useNotifications/provider.tsx +++ b/src/hooks/useNotifications/provider.tsx @@ -46,30 +46,22 @@ export const NotificationsProvider = ({ children }: NotificationProviderProps) = let animationFrameId: null | number = null; const updateNotifications = () => { const now = Date.now(); - setNotifications((notifications) => { - return notifications - .map((notification) => { - const timePassed = now - (notification.timestamp ?? now); - const { removeAfterMs: progressBarDuration } = notification; - const progress = Math.max(100 - (timePassed / (progressBarDuration ?? 3000)) * 100, 0); - if (progress <= 0) { - // Automatically hide the notification when progress reaches 0 - return null; - } - return { - ...notification, - progress - }; - }) - .filter(Boolean); + setNotifications((prevNotifications) => { + if (prevNotifications.length === 0) return prevNotifications; + return prevNotifications.reduce((acc: Notification[], notification) => { + const elapsed = now - (notification.timestamp ?? now); + const progress = Math.max(100 - (elapsed / (notification.removeAfterMs ?? 3000)) * 100, 0); + if (progress > 0) { + acc.push({ ...notification, progress }); + } + return acc; + }, []); }); animationFrameId = requestAnimationFrame(updateNotifications); }; updateNotifications(); return () => { - if (animationFrameId !== null) { - cancelAnimationFrame(animationFrameId); - } + if (animationFrameId !== null) cancelAnimationFrame(animationFrameId); }; }, []); const contextValue = { addNotification, notifications, removeNotification } satisfies NotificationsContextProps; From 16856dfa7a1d4c7cdb6d712089391a6b1728b751 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:26:08 +0000 Subject: [PATCH 30/77] build(deps-dev): bump eslint-plugin-react from 7.34.1 to 7.34.2 Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.34.1 to 7.34.2. - [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases) - [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.34.1...v7.34.2) --- updated-dependencies: - dependency-name: eslint-plugin-react dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1685652a..72152484 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4633,29 +4633,29 @@ } }, "node_modules/eslint-plugin-react": { - "version": "7.34.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz", - "integrity": "sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw==", + "version": "7.34.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.34.2.tgz", + "integrity": "sha512-2HCmrU+/JNigDN6tg55cRDKCQWicYAPB38JGSFDQt95jDm8rrvSUo7YPkOIm5l6ts1j1zCvysNcasvfTMQzUOw==", "dev": true, "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlast": "^1.2.4", + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", "array.prototype.flatmap": "^1.3.2", "array.prototype.toreversed": "^1.1.2", "array.prototype.tosorted": "^1.1.3", "doctrine": "^2.1.0", - "es-iterator-helpers": "^1.0.17", + "es-iterator-helpers": "^1.0.19", "estraverse": "^5.3.0", "jsx-ast-utils": "^2.4.1 || ^3.0.0", "minimatch": "^3.1.2", - "object.entries": "^1.1.7", - "object.fromentries": "^2.0.7", - "object.hasown": "^1.1.3", - "object.values": "^1.1.7", + "object.entries": "^1.1.8", + "object.fromentries": "^2.0.8", + "object.hasown": "^1.1.4", + "object.values": "^1.2.0", "prop-types": "^15.8.1", "resolve": "^2.0.0-next.5", "semver": "^6.3.1", - "string.prototype.matchall": "^4.0.10" + "string.prototype.matchall": "^4.0.11" }, "engines": { "node": ">=4" From facc7891ce4747e707be0a650161fe789dc051f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:26:23 +0000 Subject: [PATCH 31/77] build(deps-dev): bump semantic-release from 23.1.1 to 24.0.0 Bumps [semantic-release](https://github.com/semantic-release/semantic-release) from 23.1.1 to 24.0.0. - [Release notes](https://github.com/semantic-release/semantic-release/releases) - [Commits](https://github.com/semantic-release/semantic-release/compare/v23.1.1...v24.0.0) --- updated-dependencies: - dependency-name: semantic-release dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- package-lock.json | 179 ++++++++++++++-------------------------------- package.json | 2 +- 2 files changed, 54 insertions(+), 127 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1685652a..7c4eef6c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,7 +60,7 @@ "nodemon": "^3.0.1", "postcss": "^8.4.31", "prettier": "^3.0.3", - "semantic-release": "^23.0.0", + "semantic-release": "^24.0.0", "tailwind-merge": "^2.0.0", "tailwindcss": "^3.3.6", "ts-json-as-const": "^1.0.7", @@ -993,14 +993,15 @@ } }, "node_modules/@semantic-release/commit-analyzer": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-12.0.0.tgz", - "integrity": "sha512-qG+md5gdes+xa8zP7lIo1fWE17zRdO8yMCaxh9lyL65TQleoSv8WHHOqRURfghTytUh+NpkSyBprQ5hrkxOKVQ==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/commit-analyzer/-/commit-analyzer-13.0.0.tgz", + "integrity": "sha512-KtXWczvTAB1ZFZ6B4O+w8HkfYm/OgQb1dUGNFZtDgQ0csggrmkq8sTxhd+lwGF8kMb59/RnG9o4Tn7M/I8dQ9Q==", "dev": true, "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "import-from-esm": "^1.0.3", "lodash-es": "^4.17.21", @@ -1428,15 +1429,15 @@ } }, "node_modules/@semantic-release/release-notes-generator": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-13.0.0.tgz", - "integrity": "sha512-LEeZWb340keMYuREMyxrODPXJJ0JOL8D/mCl74B4LdzbxhtXV2LrPN2QBEcGJrlQhoqLO0RhxQb6masHytKw+A==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@semantic-release/release-notes-generator/-/release-notes-generator-14.0.0.tgz", + "integrity": "sha512-XRxwr4e46yUMaXT8KGFBlRJlp5+NOMaufdq8qaEWlcJ7cT4Pn/iRmDGglZ2TgDe6GVP+u1boXFEnSs7N8Yzhng==", "dev": true, "dependencies": { - "conventional-changelog-angular": "^7.0.0", - "conventional-changelog-writer": "^7.0.0", - "conventional-commits-filter": "^4.0.0", - "conventional-commits-parser": "^5.0.0", + "conventional-changelog-angular": "^8.0.0", + "conventional-changelog-writer": "^8.0.0", + "conventional-commits-filter": "^5.0.0", + "conventional-commits-parser": "^6.0.0", "debug": "^4.0.0", "get-stream": "^7.0.0", "import-from-esm": "^1.0.3", @@ -3414,62 +3415,58 @@ } }, "node_modules/conventional-changelog-angular": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz", - "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-8.0.0.tgz", + "integrity": "sha512-CLf+zr6St0wIxos4bmaKHRXWAcsCXrJU6F4VdNDrGRK3B8LDLKoX3zuMV5GhtbGkVR/LohZ6MT6im43vZLSjmA==", "dev": true, "dependencies": { "compare-func": "^2.0.0" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/conventional-changelog-writer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-7.0.1.tgz", - "integrity": "sha512-Uo+R9neH3r/foIvQ0MKcsXkX642hdm9odUp7TqgFS7BsalTcjzRlIfWZrZR1gbxOozKucaKt5KAbjW8J8xRSmA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-8.0.0.tgz", + "integrity": "sha512-TQcoYGRatlAnT2qEWDON/XSfnVG38JzA7E0wcGScu7RElQBkg9WWgZd1peCWFcWDh1xfb2CfsrcvOn1bbSzztA==", "dev": true, "dependencies": { - "conventional-commits-filter": "^4.0.0", + "@types/semver": "^7.5.5", + "conventional-commits-filter": "^5.0.0", "handlebars": "^4.7.7", - "json-stringify-safe": "^5.0.1", - "meow": "^12.0.1", - "semver": "^7.5.2", - "split2": "^4.0.0" + "meow": "^13.0.0", + "semver": "^7.5.2" }, "bin": { - "conventional-changelog-writer": "cli.mjs" + "conventional-changelog-writer": "dist/cli/index.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/conventional-commits-filter": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-4.0.0.tgz", - "integrity": "sha512-rnpnibcSOdFcdclpFwWa+pPlZJhXE7l+XK04zxhbWrhgpR96h33QLz8hITTXbcYICxVr3HZFtbtUAQ+4LdBo9A==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-5.0.0.tgz", + "integrity": "sha512-tQMagCOC59EVgNZcC5zl7XqO30Wki9i9J3acbUvkaosCT6JX3EeFwJD7Qqp4MCikRnzS18WXV3BLIQ66ytu6+Q==", "dev": true, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/conventional-commits-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz", - "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-6.0.0.tgz", + "integrity": "sha512-TbsINLp48XeMXR8EvGjTnKGsZqBemisPoyWESlpRyR8lif0lcwzqz+NMtYSj1ooF/WYjSuu7wX0CtdeeMEQAmA==", "dev": true, "dependencies": { - "is-text-path": "^2.0.0", - "JSONStream": "^1.3.5", - "meow": "^12.0.1", - "split2": "^4.0.0" + "meow": "^13.0.0" }, "bin": { - "conventional-commits-parser": "cli.mjs" + "conventional-commits-parser": "dist/cli/index.js" }, "engines": { - "node": ">=16" + "node": ">=18" } }, "node_modules/convert-hrtime": { @@ -5736,9 +5733,9 @@ } }, "node_modules/import-meta-resolve": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.0.0.tgz", - "integrity": "sha512-okYUR7ZQPH+efeuMJGlq4f8ubUgO50kByRPyt/Cy1Io4PSRsPjxME+YlVaCOx+NIToW7hCsZNFJyTPFFKepRSA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==", "dev": true, "funding": { "type": "github", @@ -6208,18 +6205,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-text-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz", - "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==", - "dev": true, - "dependencies": { - "text-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/is-typed-array": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", @@ -6441,12 +6426,6 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "dev": true - }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -6471,31 +6450,6 @@ "graceful-fs": "^4.1.6" } }, - "node_modules/jsonparse": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", - "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", - "dev": true, - "engines": [ - "node >= 0.2.0" - ] - }, - "node_modules/JSONStream": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", - "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", - "dev": true, - "dependencies": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" - }, - "bin": { - "JSONStream": "bin.js" - }, - "engines": { - "node": "*" - } - }, "node_modules/jsx-ast-utils": { "version": "3.3.5", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", @@ -6792,12 +6746,12 @@ } }, "node_modules/meow": { - "version": "12.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz", - "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==", + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, "engines": { - "node": ">=16.10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -10937,9 +10891,9 @@ } }, "node_modules/read-pkg-up/node_modules/type-fest": { - "version": "4.17.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.17.0.tgz", - "integrity": "sha512-9flrz1zkfLRH3jO3bLflmTxryzKMxVa7841VeMgBaNQGY6vH4RCcpN/sQLB7mQQYh1GZ5utT2deypMuCy4yicw==", + "version": "4.18.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.18.3.tgz", + "integrity": "sha512-Q08/0IrpvM+NMY9PA2rti9Jb+JejTddwmwmVQGskAlhtcrw1wsRzoR6ode6mR+OAabNa75w/dxedSUY2mlphaQ==", "dev": true, "engines": { "node": ">=16" @@ -11371,16 +11325,16 @@ } }, "node_modules/semantic-release": { - "version": "23.1.1", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-23.1.1.tgz", - "integrity": "sha512-qqJDBhbtHsjUEMsojWKGuL5lQFCJuPtiXKEIlFKyTzDDGTAE/oyvznaP8GeOr5PvcqBJ6LQz4JCENWPLeehSpA==", + "version": "24.0.0", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-24.0.0.tgz", + "integrity": "sha512-v46CRPw+9eI3ZuYGF2oAjqPqsfbnfFTwLBgQsv/lch4goD09ytwOTESMN4QIrx/wPLxUGey60/NMx+ANQtWRsA==", "dev": true, "dependencies": { - "@semantic-release/commit-analyzer": "^12.0.0", + "@semantic-release/commit-analyzer": "^13.0.0-beta.1", "@semantic-release/error": "^4.0.0", "@semantic-release/github": "^10.0.0", "@semantic-release/npm": "^12.0.0", - "@semantic-release/release-notes-generator": "^13.0.0", + "@semantic-release/release-notes-generator": "^14.0.0-beta.1", "aggregate-error": "^5.0.0", "cosmiconfig": "^9.0.0", "debug": "^4.0.0", @@ -11980,15 +11934,6 @@ "integrity": "sha512-sh8PWc/ftMqAAdFiBu6Fy6JUOYjqDJBJvIhpfDMyHrr0Rbp5liZqd4TjtQ/RgfLjKFZb+LMx5hpml5qOWy0qvg==", "dev": true }, - "node_modules/split2": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", - "dev": true, - "engines": { - "node": ">= 10.x" - } - }, "node_modules/state-local": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/state-local/-/state-local-1.0.7.tgz", @@ -12570,18 +12515,6 @@ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, - "node_modules/text-extensions": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz", - "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -12609,12 +12542,6 @@ "node": ">=0.8" } }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", - "dev": true - }, "node_modules/through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", diff --git a/package.json b/package.json index b9955524..cc408989 100644 --- a/package.json +++ b/package.json @@ -75,7 +75,7 @@ "nodemon": "^3.0.1", "postcss": "^8.4.31", "prettier": "^3.0.3", - "semantic-release": "^23.0.0", + "semantic-release": "^24.0.0", "tailwind-merge": "^2.0.0", "tailwindcss": "^3.3.6", "ts-json-as-const": "^1.0.7", From 5a11050f2f659c1a62f10f864e79a169ec8a0dc5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:26:45 +0000 Subject: [PATCH 32/77] build(deps-dev): bump @typescript-eslint/eslint-plugin Bumps [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) from 7.8.0 to 7.11.0. - [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases) - [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md) - [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v7.11.0/packages/eslint-plugin) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 129 +++++++++++++++++++++------------------------- 1 file changed, 59 insertions(+), 70 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1685652a..a8dea573 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1744,12 +1744,6 @@ "@types/node": "*" } }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, "node_modules/@types/webextension-polyfill": { "version": "0.10.7", "resolved": "https://registry.npmjs.org/@types/webextension-polyfill/-/webextension-polyfill-0.10.7.tgz", @@ -1763,21 +1757,19 @@ "dev": true }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.8.0.tgz", - "integrity": "sha512-gFTT+ezJmkwutUPmB0skOj3GZJtlEGnlssems4AjkVweUPGj7jRwwqg0Hhg7++kPGJqKtTYx+R05Ftww372aIg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.11.0.tgz", + "integrity": "sha512-P+qEahbgeHW4JQ/87FuItjBj8O3MYv5gELDzr8QaQ7fsll1gSMTYb6j87MYyxwf3DtD7uGFB9ShwgmCJB5KmaQ==", "dev": true, "dependencies": { "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/type-utils": "7.8.0", - "@typescript-eslint/utils": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", - "debug": "^4.3.4", + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/type-utils": "7.11.0", + "@typescript-eslint/utils": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "graphemer": "^1.4.0", "ignore": "^5.3.1", "natural-compare": "^1.4.0", - "semver": "^7.6.0", "ts-api-utils": "^1.3.0" }, "engines": { @@ -1798,13 +1790,13 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1815,9 +1807,9 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1828,12 +1820,12 @@ } }, "node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -1890,13 +1882,13 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.8.0.tgz", - "integrity": "sha512-H70R3AefQDQpz9mGv13Uhi121FNMh+WEaRqcXTX09YEDky21km4dV1ZXJIp8QjXc4ZaVkXVdohvWDzbnbHDS+A==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.11.0.tgz", + "integrity": "sha512-WmppUEgYy+y1NTseNMJ6mCFxt03/7jTOy08bcg7bxJJdsM4nuhnchyBbE8vryveaJUf62noH7LodPSo5Z0WUCg==", "dev": true, "dependencies": { - "@typescript-eslint/typescript-estree": "7.8.0", - "@typescript-eslint/utils": "7.8.0", + "@typescript-eslint/typescript-estree": "7.11.0", + "@typescript-eslint/utils": "7.11.0", "debug": "^4.3.4", "ts-api-utils": "^1.3.0" }, @@ -1917,9 +1909,9 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -1930,13 +1922,13 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1958,12 +1950,12 @@ } }, "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { @@ -2016,18 +2008,15 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.8.0.tgz", - "integrity": "sha512-L0yFqOCflVqXxiZyXrDr80lnahQfSOfc9ELAAZ75sqicqp2i36kEZZGuUymHNFoYOqxRT05up760b4iGsl02nQ==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.11.0.tgz", + "integrity": "sha512-xlAWwPleNRHwF37AhrZurOxA1wyXowW4PqVXZVUNCLjB48CqdPJoJWkrpH2nij9Q3Lb7rtWindtoXwxjxlKKCA==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.15", - "@types/semver": "^7.5.8", - "@typescript-eslint/scope-manager": "7.8.0", - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/typescript-estree": "7.8.0", - "semver": "^7.6.0" + "@typescript-eslint/scope-manager": "7.11.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/typescript-estree": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2041,13 +2030,13 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/scope-manager": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.8.0.tgz", - "integrity": "sha512-viEmZ1LmwsGcnr85gIq+FCYI7nO90DVbE37/ll51hjv9aG+YZMb4WDE2fyWpUR4O/UrhGRpYXK/XajcGTk2B8g==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.11.0.tgz", + "integrity": "sha512-27tGdVEiutD4POirLZX4YzT180vevUURJl4wJGmm6TrQoiYwuxTIY98PBp6L2oN+JQxzE0URvYlzJaBHIekXAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0" + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0" }, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2058,9 +2047,9 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.8.0.tgz", - "integrity": "sha512-wf0peJ+ZGlcH+2ZS23aJbOv+ztjeeP8uQ9GgwMJGVLx/Nj9CJt17GWgWWoSmoRVKAX2X+7fzEnAjxdvK2gqCLw==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.11.0.tgz", + "integrity": "sha512-MPEsDRZTyCiXkD4vd3zywDCifi7tatc4K37KqTprCvaXptP7Xlpdw0NR2hRJTetG5TxbWDB79Ys4kLmHliEo/w==", "dev": true, "engines": { "node": "^18.18.0 || >=20.0.0" @@ -2071,13 +2060,13 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.8.0.tgz", - "integrity": "sha512-5pfUCOwK5yjPaJQNy44prjCwtr981dO8Qo9J9PwYXZ0MosgAbfEMB008dJ5sNo3+/BN6ytBPuSvXUg9SAqB0dg==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.11.0.tgz", + "integrity": "sha512-cxkhZ2C/iyi3/6U9EPc5y+a6csqHItndvN/CzbNXTNrsC3/ASoYQZEt9uMaEp+xFNjasqQyszp5TumAVKKvJeQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", - "@typescript-eslint/visitor-keys": "7.8.0", + "@typescript-eslint/types": "7.11.0", + "@typescript-eslint/visitor-keys": "7.11.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2099,12 +2088,12 @@ } }, "node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.8.0.tgz", - "integrity": "sha512-q4/gibTNBQNA0lGyYQCmWRS5D15n8rXh4QjK3KV+MBPlTYHpfBUT3D3PaPR/HeNiI9W6R7FvlkcGhNyAoP+caA==", + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.11.0.tgz", + "integrity": "sha512-7syYk4MzjxTEk0g/w3iqtgxnFQspDJfn6QKD36xMuuhTzjcxY7F8EmBLnALjVyaOF1/bVocu3bS/2/F7rXrveQ==", "dev": true, "dependencies": { - "@typescript-eslint/types": "7.8.0", + "@typescript-eslint/types": "7.11.0", "eslint-visitor-keys": "^3.4.3" }, "engines": { From 83843df08fea46b403cbf13f1b7b58e6420e011c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:27:04 +0000 Subject: [PATCH 33/77] build(deps-dev): bump vite from 5.2.10 to 5.2.12 Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.2.10 to 5.2.12. - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v5.2.12/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1685652a..9076c263 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13138,9 +13138,9 @@ } }, "node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", + "version": "5.2.12", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.12.tgz", + "integrity": "sha512-/gC8GxzxMK5ntBwb48pR32GGhENnjtY30G4A0jemunsBkiEZFw60s8InGpN8gkhHEkjnRK1aSAxeQgwvFhUHAA==", "dependencies": { "esbuild": "^0.20.1", "postcss": "^8.4.38", From 1aea9a18e9a35290d1652c73e6d799b6743af040 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 01:27:16 +0000 Subject: [PATCH 34/77] build(deps-dev): bump prettier from 3.2.5 to 3.3.0 Bumps [prettier](https://github.com/prettier/prettier) from 3.2.5 to 3.3.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.2.5...3.3.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1685652a..aa36c237 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10661,9 +10661,9 @@ } }, "node_modules/prettier": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.2.5.tgz", - "integrity": "sha512-3/GWa9aOC0YeD7LUfvOG2NiDyhOWRvt1k+rcKhOuYnMY24iiCphgneUfJDyFXd6rZCAnuLBv6UeAULtrhT/F4A==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.0.tgz", + "integrity": "sha512-J9odKxERhCQ10OC2yb93583f6UnYutOeiV5i0zEDS7UGTdUt0u+y8erxl3lBKvwo/JHyyoEdXjwp4dke9oyZ/g==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" From b53edd7cfe4e6802bc28a3155a6625d125c15cf6 Mon Sep 17 00:00:00 2001 From: VampireChicken12 Date: Mon, 3 Jun 2024 16:28:36 -0400 Subject: [PATCH 35/77] fix: color pickers opening when they shouldn't --- src/components/Inputs/ColorPicker/ColorPicker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Inputs/ColorPicker/ColorPicker.tsx b/src/components/Inputs/ColorPicker/ColorPicker.tsx index 80a4227f..91abe7bf 100644 --- a/src/components/Inputs/ColorPicker/ColorPicker.tsx +++ b/src/components/Inputs/ColorPicker/ColorPicker.tsx @@ -23,7 +23,7 @@ const ColorPicker: React.FC = ({ className, disabled, id, labe false ); const togglePickerVisibility = () => setIsColorPickerVisible(!isColorPickerVisible); - useClickOutside(colorPickerRef, togglePickerVisibility); + useClickOutside(colorPickerRef, () => (isColorPickerVisible ? togglePickerVisibility() : void 0)); return (