Skip to content

Dev#1115

Merged
VampireChicken12 merged 40 commits into
mainfrom
dev
Dec 19, 2025
Merged

Dev#1115
VampireChicken12 merged 40 commits into
mainfrom
dev

Conversation

@VampireChicken12
Copy link
Copy Markdown
Member

@VampireChicken12 VampireChicken12 commented Dec 19, 2025

Summary by CodeRabbit

  • New Features

    • Automatically disable autoplay when loading videos.
    • Hide sidebar recommended videos with a new toggle option.
    • Split playlist management into separate "Mark as unwatched" and "Remove video" buttons.
    • Added "Both" screenshot save option to save simultaneously to file and clipboard.
  • Chores

    • Updated dependencies: monaco-editor, @eslint/compat, and @types/archiver versions.

✏️ Tip: You can customize this high-level summary in your review settings.

dnicolson and others added 30 commits November 20, 2025 22:18
Co-authored-by: Nathan <45531575+VampireChicken12@users.noreply.github.com>
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.46.3 to 8.47.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.47.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.47.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.38.0 to 9.39.1.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.1/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.39.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [monaco-editor](https://github.com/microsoft/monaco-editor) from 0.54.0 to 0.55.1.
- [Release notes](https://github.com/microsoft/monaco-editor/releases)
- [Changelog](https://github.com/microsoft/monaco-editor/blob/main/CHANGELOG.md)
- [Commits](microsoft/monaco-editor@v0.54.0...v0.55.1)

---
updated-dependencies:
- dependency-name: monaco-editor
  dependency-version: 0.55.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.21 to 10.4.22.
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](postcss/autoprefixer@10.4.21...10.4.22)

---
updated-dependencies:
- dependency-name: autoprefixer
  dependency-version: 10.4.22
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [i18next](https://github.com/i18next/i18next) from 25.6.0 to 25.6.3.
- [Release notes](https://github.com/i18next/i18next/releases)
- [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md)
- [Commits](i18next/i18next@v25.6.0...v25.6.3)

---
updated-dependencies:
- dependency-name: i18next
  dependency-version: 25.6.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Put the class for hiding end screen cards on the `div#movie_player` and
specify in the css to hide the relevant descendants. Also including to
hide the ending endscreen as I assume that for most people, those "cards"
are "end screen cards" and not some other "watch more crumbs" or
similar.

The reason for putting the flag on the top class is that the actual end
screen cards don't always have time to be loaded before the relevant
code is executed and thus won't be hidden.
To allow the use case where you want to screenshot to clipboard but
still want to have it stored to file as well for future reference.
Bumps [zod](https://github.com/colinhacks/zod) from 4.1.12 to 4.1.13.
- [Release notes](https://github.com/colinhacks/zod/releases)
- [Commits](colinhacks/zod@v4.1.12...v4.1.13)

---
updated-dependencies:
- dependency-name: zod
  dependency-version: 4.1.13
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.1.12 to 7.2.4.
- [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/v7.2.4/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.2.4
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.47.0 to 8.48.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.48.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.48.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@types/archiver](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/archiver) from 6.0.4 to 7.0.0.
- [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases)
- [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/archiver)

---
updated-dependencies:
- dependency-name: "@types/archiver"
  dependency-version: 7.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [nodemon](https://github.com/remy/nodemon) from 3.1.10 to 3.1.11.
- [Release notes](https://github.com/remy/nodemon/releases)
- [Commits](remy/nodemon@v3.1.10...v3.1.11)

---
updated-dependencies:
- dependency-name: nodemon
  dependency-version: 3.1.11
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
VampireChicken12 and others added 8 commits December 12, 2025 05:40
Bumps [autoprefixer](https://github.com/postcss/autoprefixer) from 10.4.22 to 10.4.23.
- [Release notes](https://github.com/postcss/autoprefixer/releases)
- [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md)
- [Commits](postcss/autoprefixer@10.4.22...10.4.23)

---
updated-dependencies:
- dependency-name: autoprefixer
  dependency-version: 10.4.23
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@rollup/rollup-linux-x64-gnu](https://github.com/rollup/rollup) from 4.52.5 to 4.53.3.
- [Release notes](https://github.com/rollup/rollup/releases)
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md)
- [Commits](rollup/rollup@v4.52.5...v4.53.3)

---
updated-dependencies:
- dependency-name: "@rollup/rollup-linux-x64-gnu"
  dependency-version: 4.53.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@eslint/compat](https://github.com/eslint/rewrite/tree/HEAD/packages/compat) from 1.4.1 to 2.0.0.
- [Release notes](https://github.com/eslint/rewrite/releases)
- [Changelog](https://github.com/eslint/rewrite/blob/main/packages/compat/CHANGELOG.md)
- [Commits](https://github.com/eslint/rewrite/commits/compat-v2.0.0/packages/compat)

---
updated-dependencies:
- dependency-name: "@eslint/compat"
  dependency-version: 2.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [typescript-eslint](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint) from 8.48.0 to 8.49.0.
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.49.0/packages/typescript-eslint)

---
updated-dependencies:
- dependency-name: typescript-eslint
  dependency-version: 8.49.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Bumps [@eslint/js](https://github.com/eslint/eslint/tree/HEAD/packages/js) from 9.39.1 to 9.39.2.
- [Release notes](https://github.com/eslint/eslint/releases)
- [Commits](https://github.com/eslint/eslint/commits/v9.39.2/packages/js)

---
updated-dependencies:
- dependency-name: "@eslint/js"
  dependency-version: 9.39.2
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 19, 2025

Walkthrough

This pull request introduces substantial feature additions and settings restructuring across the extension. It adds two new user-facing features (hideSidebarRecommendedVideos and automaticallyDisableAutoPlay), refactors playlist management buttons into separate remove/reset toggles, adds a "both" option to screenshot save formats, updates localization strings with consistent casing across 25+ locale files, and normalizes UI setting titles throughout the application.

Changes

Cohort / File(s) Summary
Dependency Updates
package.json
Updated monaco-editor to ^0.55.1, @eslint/compat to ^2.0.0, and @types/archiver to ^7.0.0.
Localization Files
public/locales/*
Comprehensive translation updates across all 24 locale files including: restructured settings with consistent casing (e.g., "On-Screen Display Settings" → "On-screen display settings"), added new feature keys (automaticallyDisableAutoPlay, hideSidebarRecommendedVideos, playlistManagement), replaced enablePlaylistManagementButtons with separate button entries, and added "Both (File and Clipboard)" screenshot save option.
Localization Type Definitions
public/locales/en-US.json.d.ts
Added TypeScript definitions for new playlistManagement section with markAsUnwatchedButton and removeVideoButton features, automaticallyDisableAutoPlay, hideSidebarRecommendedVideos, and updated title casing for consistency.
Core Settings UI
src/components/Settings/Settings.tsx
Added "both" option to ScreenshotSaveAsOptions, removed enable_playlist_management_buttons, and replaced with separate enable_playlist_remove_button and enable_playlist_reset_button settings; introduced new hideSidebarRecommendedVideos and automaticallyDisableAutoPlay toggles under Miscellaneous section.
Auto-play Disable Feature
src/features/automaticallyDisableAutoPlay/index.ts
New module exporting disableAutomaticallyDisableAutoPlay() and enableAutomaticallyDisableAutoPlay() functions to control YouTube's autoplay toggle.
Sidebar Recommendations Feature
src/features/hideSidebarRecommendedVideos/index.css, src/features/hideSidebarRecommendedVideos/index.ts
New feature module adding CSS rule to hide recommended videos sidebar and exporting enable/disable functions with message-based option retrieval.
Audio Track Handling
src/features/defaultToOriginalAudioTrack/index.ts
Added ParsedAudioTrack type, implemented helper functions findDefaultTrack and parseAudioTrack, refactored enable/disable logic to use parsed track structure with name-based comparisons.
End Screen Cards
src/features/hideEndScreenCards/index.css, src/features/hideEndScreenCards/index.ts
Scoped CSS hiding logic to div#movie_player.yte-hide-end-screen-cards; refactored TypeScript to use single-element modifyElementClassList instead of multi-element approach and simplified isEndScreenCardsHidden check.
Playlist Management Buttons
src/features/playlistManagementButtons/ActionButton/index.css, src/features/playlistManagementButtons/index.ts
Added light/dark theme hover styles; refactored to read enable_playlist_remove_button and enable_playlist_reset_button separately, implemented conditional button creation with improved DOM selectors and icon handling.
Playback Speed
src/features/playerSpeed/index.ts
Made event handlers async, added updateSpeedButtons helper to synchronize speed button tooltips with player state, integrated calculatePlaybackButtonSpeed and updatePlaybackSpeedButtonTooltip utilities.
Other Features
src/features/hidePlaylistRecommendationsFromHomePage/index.ts, src/features/maximizePlayerButton/index.css, src/features/remainingTime/index.ts, src/features/saveToWatchLaterButton/index.ts, src/features/screenshotButton/index.ts, src/features/videoHistory/index.ts
Minor improvements: added isHomePage guard, formatting fix, removed Shorts logic, added page disposal cleanup hook, refactored clipboard/file-saving logic, replaced DOM query with async waitForElement.
Type Definitions and Constants
src/types/index.ts, src/utils/constants.ts, src/global.d.ts
Added "both" to screenshotTypes; introduced enable_automatically_disable_autoplay and enable_hide_sidebar_recommended_videos; replaced enable_playlist_management_buttons with enable_playlist_remove_button and enable_playlist_reset_button; added new extension message types; updated defaultConfiguration and configurationImportSchema; changed audioTrack type from interface to Record<string, unknown>.
Content and Embedded Page Handlers
src/pages/content/index.ts, src/pages/embedded/index.ts
Added storage change handlers for new features and split playlist flags, dispatching corresponding extension messages; integrated new feature enable/disable sequences and message watchers in embedded page initialization.
i18n Localization Percentages
src/i18n/constants.ts
Updated localePercentages for multiple locales reflecting changes in translation coverage (e.g., de-DE: 23→52, es-ES: 40→77, ja-JP: 84→80).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas requiring extra attention:

  • Localization consistency: Verify all 24+ locale files follow the same structural and naming pattern changes (settings title casing, new feature keys, screenshot "both" option placement).
  • Playlist management refactoring: Ensure the split of enable_playlist_management_buttons into separate remove/reset buttons is correctly wired across Settings.tsx, types, content script handlers, feature implementation, and message dispatching.
  • New features integration: Review automaticallyDisableAutoPlay and hideSidebarRecommendedVideos for proper initialization, message handling, DOM element targeting, and cleanup.
  • CSS scoping: Confirm hideEndScreenCards CSS change to div#movie_player scoping is compatible with all player states and zoom levels.
  • Type system updates: Verify audioTrack type change from interface to Record<string, unknown> doesn't break existing audio track access patterns in defaultToOriginalAudioTrack and related utilities.
  • Message dispatching flow: Check that new extension messages (automaticallyDisableAutoPlayChange, hideSidebarRecommendedVideosChange, playlistRemoveButtonChange, playlistResetButtonChange) are correctly mapped and handled across content and embedded pages.

Possibly related PRs

  • PR #1076: Splits enable_playlist_management_buttons into separate enable_playlist_remove_button and enable_playlist_reset_button flags across types, settings, and feature logic.
  • PR #1094: Adds "both" screenshot save option to screenshotButton feature and updates corresponding locale keys and types.
  • PR #1093: Updates hideEndScreenCards feature with CSS scoping to div#movie_player and single-element modifyElementClassList refactoring.

Suggested labels

released


🐰 A rabbit hops through the settings today,
Two buttons split where one held sway,
Sidebars hide, autoplay sleeps tight,
While screenshots grab in both—what a sight!
Twenty tongues whisper the same refrain,
In lowercase letters, clarity gained.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title check ❓ Inconclusive The pull request title 'Dev' is vague and generic, providing no meaningful information about the changeset's actual content or purpose. Replace 'Dev' with a descriptive title that summarizes the main changes, such as 'Add playlist management features and sidebar recommendations hiding' or similar.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 19

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
public/locales/sv-SE.json (1)

2-2: Critical: Incorrect langCode for Swedish locale.

The langCode is set to "en-US" but this is a Swedish (sv-SE) localization file. This will cause the extension to misidentify the locale.

🔎 Proposed fix
-	"langCode": "en-US",
+	"langCode": "sv-SE",
public/locales/uk-UA.json (2)

278-323: Many strings in Ukrainian locale file are not translated.

Several new feature labels and titles remain in English instead of being translated to Ukrainian. This affects user experience for Ukrainian-speaking users. The untranslated strings include:

  • Lines 281-306: automaticTheaterMode, automaticallyDisableAmbientMode, automaticallyDisableAutoPlay, automaticallyDisableClosedCaptions, automaticallyEnableClosedCaptions, automaticallyMaximizePlayer, automaticallyShowMoreVideosOnEndScreen
  • Lines 308-327: copyTimestampUrlButton, defaultToOriginalAudioTrack, enableMarkAsUnwatchedButton, enableRemoveVideoButton, enableSaveToWatchLaterButton
  • Lines 368-371: hideSidebarRecommendedVideos

Consider adding Ukrainian translations for these strings or tracking them as a follow-up task.


217-229: Section titles remain in English.

These section titles should be translated to Ukrainian for consistency:

  • Line 217: "Button placement settings"
  • Line 229: "Custom CSS settings"
  • Line 469: "On-screen display settings"
🟡 Minor comments (37)
public/locales/zh-TW.json-288-291 (1)

288-291: New feature text needs Traditional Chinese translation.

The newly added automaticallyDisableAutoPlay feature has English text for both label and title. Please provide Traditional Chinese translations for these user-facing strings.

public/locales/zh-TW.json-139-139 (1)

139-139: Missing Traditional Chinese translations for section titles and option text.

Several user-facing strings remain in English instead of Traditional Chinese:

  • Line 139: screenshotButtonFileFormat text
  • Line 217: "Button placement settings"
  • Line 229: "Custom CSS settings"
  • Line 469: "On-screen display settings"
  • Line 660: "YouTube API V3 key"
  • Line 703: "YouTube deep dark settings"

This creates an inconsistent user experience for Traditional Chinese speakers. Consider translating these strings to maintain consistency with the rest of the locale file.

Also applies to: 217-217, 229-229, 469-469, 660-660, 703-703

public/locales/zh-TW.json-316-323 (1)

316-323: Multiple new/restructured features need Traditional Chinese translations.

The following features under miscellaneous.features have English text instead of Traditional Chinese:

  • enableMarkAsUnwatchedButton (lines 316-319) - split from previous playlist management buttons
  • enableRemoveVideoButton (lines 320-323) - split from previous playlist management buttons
  • hideSidebarRecommendedVideos (lines 368-371) - new feature

Please translate these user-facing strings to Traditional Chinese.

Also applies to: 368-371

public/locales/zh-TW.json-523-535 (1)

523-535: New playlist management section and screenshot option need Traditional Chinese translations.

The newly added playlistManagement section (lines 523-535) and the "both" screenshot save option (line 555) contain English text:

  • Section title: "Playlist management settings"
  • markAsUnwatchedButton label and title
  • removeVideoButton label and title
  • Screenshot saveAs.both: "Both (File and Clipboard)"

Please provide Traditional Chinese translations for all these strings to maintain localization consistency.

Also applies to: 555-555

public/locales/ko-KR.json-229-229 (1)

229-229: Missing Korean translation for section title.

The title "Custom CSS settings" should be translated to Korean for consistency with other section titles in this locale file.

public/locales/ko-KR.json-703-703 (1)

703-703: Missing Korean translation for section title.

The title "YouTube deep dark settings" should be translated to Korean for consistency with other section titles in this locale file.

public/locales/ko-KR.json-139-139 (1)

139-139: Missing Korean translation for option disabled message.

This user-facing message should be translated to Korean. The message explains when the screenshot file format option can be configured.

public/locales/ko-KR.json-469-469 (1)

469-469: Missing Korean translation for section title.

The title "On-screen display settings" should be translated to Korean for consistency with other section titles in this locale file.

public/locales/ko-KR.json-288-291 (1)

288-291: Missing Korean translation for new feature.

The automaticallyDisableAutoPlay feature has English strings in a Korean locale file. Both label and title should be translated to Korean for consistency with other features like automaticTheaterMode (lines 280-283) which has proper Korean translations.

public/locales/ko-KR.json-368-371 (1)

368-371: Missing Korean translation for new feature.

The hideSidebarRecommendedVideos feature has English strings. Please provide Korean translations for label and title.

public/locales/ko-KR.json-523-535 (1)

523-535: Missing Korean translations for entire new section.

The new playlistManagement section has all English strings including the section title and both feature labels/titles. Please translate all strings to Korean:

  • title: "Playlist management settings"
  • markAsUnwatchedButton.label and title
  • removeVideoButton.label and title
public/locales/ko-KR.json-217-217 (1)

217-217: Missing Korean translation for section title.

This is a Korean localization file, but the section title remains in English. This creates an inconsistent UI experience for Korean users. Please provide a Korean translation for "Button placement settings".

public/locales/ko-KR.json-660-660 (1)

660-660: Missing Korean translation for section title.

The title "YouTube API V3 key" should be translated to Korean for consistency with other section titles.

public/locales/ko-KR.json-555-555 (1)

555-555: Missing Korean translation for new option.

The new both option is in English while the adjacent options (clipboard: "클립보드로 복사", file: "파일로 저장") are in Korean. Please translate "Both (File and Clipboard)" to Korean for consistency.

public/locales/ko-KR.json-316-323 (1)

316-323: Missing Korean translations for playlist management features.

Both enableMarkAsUnwatchedButton and enableRemoveVideoButton have English strings. These user-facing labels and titles should be translated to Korean.

public/locales/sv-SE.json-526-526 (1)

526-526: Fix spacing in Swedish compound label.

Line 526 contains "label": "Markera som ej seddknapp" which violates Swedish grammar. The adjective "sedd" should be separated from "knapp" by a space. Change to: "Markera som ej sedd knapp".

public/locales/it-IT.json-316-323 (1)

316-323: Clarify Italian word order in button feature labels.

The current Italian translations have awkward word order that may confuse users:

  • Line 317: "Marca come pulsante non visto" (literal: "Mark as button unwatched")
  • Line 321: "Rimuovi pulsante video" (literal: "Remove button video")

These should follow standard Italian word order for button descriptions:

  • "Pulsante 'Contrassegna come non visto'" or "Pulsante marca come non visto"
  • "Pulsante 'Rimuovi video'" or "Pulsante rimuovi video"

Note that the actual button labels at lines 539 and 541 ("Contrassegna come non visto" and "Rimuovi video") are correct.

🔎 Suggested fix for clearer Italian labels
 					"enableMarkAsUnwatchedButton": {
-						"label": "Marca come pulsante non visto",
+						"label": "Pulsante 'Contrassegna come non visto'",
 						"title": "Aggiungi un pulsante alle voci della lista riproduzioni per contrassegnare i video come non visti"
 					},
 					"enableRemoveVideoButton": {
-						"label": "Rimuovi pulsante video",
+						"label": "Pulsante 'Rimuovi video'",
 						"title": "Aggiungi un pulsante alle voci della lista riproduzioni per rimuovere i video da essa"
 					},
public/locales/it-IT.json-523-535 (1)

523-535: Correct Italian terminology for "playlist".

Line 534 uses "scaletta" (schedule/setlist) which is incorrect for "playlist management settings". The proper Italian translation should be:

  • "Impostazioni gestione playlist" (using the borrowed English term, which is standard in Italian)
  • OR "Impostazioni gestione lista di riproduzione" (fully Italian term)

Additionally, lines 526-527 and 530-531 have the same word order issues flagged in lines 316-323 (see previous comment).

🔎 Suggested fix for correct terminology
 			"playlistManagement": {
 				"features": {
 					"markAsUnwatchedButton": {
-						"label": "Marca come pulsante non visto",
+						"label": "Pulsante 'Contrassegna come non visto'",
 						"title": "Aggiunge un pulsante per marcare i video come non visti"
 					},
 					"removeVideoButton": {
-						"label": "Rimuovi pulsante video",
+						"label": "Pulsante 'Rimuovi video'",
 						"title": "Aggiunge un pulsante per rimuovere i video dalla lista riproduzioni"
 					}
 				},
-				"title": "Impostazioni gestione scaletta"
+				"title": "Impostazioni gestione playlist"
 			},
public/locales/pl-PL.json-368-371 (1)

368-371: New feature added correctly, but translation is missing.

The hideSidebarRecommendedVideos feature is structured correctly and follows the naming convention. However, like the automaticallyDisableAutoPlay feature, the label and title remain in English.

Consider providing Polish translations for this feature to maintain consistency with the rest of the Polish localization file.

public/locales/pl-PL.json-523-535 (1)

523-535: New playlist management section added, but translations are missing.

A new playlistManagement section has been properly structured to consolidate playlist-related features. This is a good organizational improvement. However, all text in this section (title and feature labels/titles) remains in English rather than Polish.

Consider translating this entire section to Polish to maintain consistency with the localization file's purpose.

public/locales/pl-PL.json-288-291 (1)

288-291: New feature added correctly, but translation is missing.

The automaticallyDisableAutoPlay feature is structured correctly and follows the naming convention of similar features. However, the label and title are in English rather than Polish.

📝 Example Polish translation

While I'm not a Polish translator, consider translating to something like:

 "automaticallyDisableAutoPlay": {
-  "label": "Automatically disable autoplay",
-  "title": "Automatically disables autoplay when you load a video"
+  "label": "Automatycznie wyłącz autoodtwarzanie",
+  "title": "Automatycznie wyłącza autoodtwarzanie podczas ładowania filmu"
 }

Note: Please verify with a native Polish speaker.

src/features/videoHistory/index.ts-33-36 (1)

33-36: Inconsistent artist channel detection patterns.

Lines 33-36 use the new async waitForElement pattern, but line 79 in setupVideoHistory still uses the synchronous querySelector pattern for the same check. This creates inconsistent behavior between the two functions.

🔎 Recommended fix for consistency

Update line 79 to match the new async pattern:

 	await waitForAllElements(["#owner #upload-info #channel-name"]);
-	const isOfficialArtistChannel = document.querySelector("#owner #upload-info #channel-name .badge-style-type-verified-artist") !== null;
+	const isOfficialArtistChannel =
+		(await waitForElement(
+			"#owner #upload-info #channel-name svg path[d='M9.03 2.242 8.272 3H7.2A4.2 4.2 0 003 7.2v1.072l-.758.758a4.2 4.2 0 000 5.94l.758.758V16.8A4.2 4.2 0 007.2 21h1.072l.758.758a4.2 4.2 0 005.94 0l.758-.758H16.8a4.2 4.2 0 004.2-4.2v-1.072l.758-.758a4.2 4.2 0 000-5.94L21 8.272V7.2A4.2 4.2 0 0016.8 3h-1.072l-.758-.758a4.2 4.2 0 00-5.94 0Zm7.73 6.638a.5.5 0 01.241.427v1.743a.256.256 0 01-.386.219L14.001 9.7v4.55a2.75 2.75 0 11-2-2.646V6.888a.5.5 0 01.759-.428l4 2.42Z']"
+		)) !== null;

Committable suggestion skipped: line range outside the PR's diff.

public/locales/ru-RU.json-139-139 (1)

139-139: Missing Russian translation.

The string "screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option" is in English instead of Russian. This should be translated to match the rest of the Russian locale.

public/locales/ru-RU.json-288-291 (1)

288-291: New features missing Russian translations.

All new feature strings are in English:

  • automaticallyDisableAutoPlay (lines 288-291)
  • enableMarkAsUnwatchedButton and enableRemoveVideoButton (lines 316-323)
  • hideSidebarRecommendedVideos (lines 368-371)
  • playlistManagement section (lines 523-535)
  • "both": "Both (File and Clipboard)" (line 555)

Consider adding Russian translations for consistency with the rest of the locale file.

Also applies to: 316-323, 368-371, 523-535, 555-555

public/locales/ru-RU.json-217-217 (1)

217-217: Section titles reverted to English.

Several section titles that should be in Russian are now in English:

  • Line 217: "title": "Button placement settings"
  • Line 229: "title": "Custom CSS settings"
  • Line 469: "title": "On-screen display settings"
  • Line 660: "title": "YouTube API V3 key"
  • Line 703: "title": "YouTube deep dark settings"

These appear to be regressions from previously translated Russian strings. Please restore or provide Russian translations.

Also applies to: 229-229, 469-469, 660-660, 703-703

public/locales/es-ES.json-555-555 (1)

555-555: Missing Spanish translation for screenshot save option.

The "Both (File and Clipboard)" option should be translated.

-"both": "Both (File and Clipboard)",
+"both": "Ambos (Archivo y Portapapeles)",
public/locales/es-ES.json-523-535 (1)

523-535: Missing Spanish translations in playlistManagement section.

The entire playlistManagement section contains English strings that should be translated.

 "playlistManagement": {
 	"features": {
 		"markAsUnwatchedButton": {
-			"label": "Mark as unwatched button",
-			"title": "Adds a button to mark videos as unwatched"
+			"label": "Botón para marcar como no visto",
+			"title": "Añade un botón para marcar vídeos como no vistos"
 		},
 		"removeVideoButton": {
-			"label": "Remove video button",
-			"title": "Adds a button to remove videos from the playlist"
+			"label": "Botón para eliminar vídeo",
+			"title": "Añade un botón para eliminar vídeos de la lista de reproducción"
 		}
 	},
-	"title": "Playlist management settings"
+	"title": "Ajustes de gestión de listas de reproducción"
 }
public/locales/es-ES.json-288-291 (1)

288-291: Missing Spanish translation for new feature.

The automaticallyDisableAutoPlay label and title are in English. These should be translated to Spanish for consistency with the rest of the locale file.

 "automaticallyDisableAutoPlay": {
-	"label": "Automatically disable autoplay",
-	"title": "Automatically disables autoplay when you load a video"
+	"label": "Desactivar reproducción automática automáticamente",
+	"title": "Desactiva automáticamente la reproducción automática cuando cargas un vídeo"
 }
public/locales/es-ES.json-217-217 (1)

217-217: Section title not translated.

The buttonPlacement.title value "Button placement settings" should be translated to Spanish.

-"title": "Button placement settings"
+"title": "Ajustes de colocación de botones"
public/locales/tr-TR.json-288-291 (1)

288-291: Incomplete Turkish translation for new feature.

The automaticallyDisableAutoPlay feature labels remain in English. Consider adding Turkish translations for consistency with other localized strings in this file.

public/locales/tr-TR.json-368-371 (1)

368-371: Missing Turkish translation for sidebar feature.

The hideSidebarRecommendedVideos feature remains in English. Add Turkish translation.

public/locales/tr-TR.json-316-323 (1)

316-323: Incomplete Turkish translations for playlist management buttons.

Both enableMarkAsUnwatchedButton and enableRemoveVideoButton labels and titles are in English. Add Turkish translations for consistency.

public/locales/tr-TR.json-523-535 (1)

523-535: Entire playlist management section untranslated.

The new playlistManagement section (title and all feature labels/titles) is in English. This section should be translated to Turkish for consistency.

public/locales/uk-UA.json-523-535 (1)

523-535: New playlistManagement section looks correct but strings are untranslated.

The structure of the new playlistManagement section is correctly added, but the feature labels and titles should be translated to Ukrainian.

src/features/playlistManagementButtons/index.ts-22-24 (1)

22-24: Minor typo in constant name: THUMBAIL_OVERLAY_SELECTOR.

Should be THUMBNAIL_OVERLAY_SELECTOR (missing 'N').

🔎 Proposed fix
 const PLAYLIST_ITEM_SELECTOR = "ytd-playlist-video-list-renderer ytd-playlist-video-renderer";
-const THUMBAIL_OVERLAY_SELECTOR = "#overlays ytd-thumbnail-overlay-resume-playback-renderer";
+const THUMBNAIL_OVERLAY_SELECTOR = "#overlays ytd-thumbnail-overlay-resume-playback-renderer";

Remember to update usages at lines 75 and 108.

Committable suggestion skipped: line range outside the PR's diff.

public/locales/ja-JP.json-139-139 (1)

139-139: Multiple untranslated strings in Japanese locale.

Similar to the pt-BR locale, several strings remain in English within the Japanese locale file, including section titles, new feature labels/titles, and UI options.

This creates a mixed-language experience for Japanese-speaking users. Consider tracking these for translation or leveraging Crowdin/translation workflows to fill in the gaps.

Also applies to: 217-217, 229-229, 288-291, 316-323, 368-371, 469-469, 523-535, 555-555, 660-660, 703-703

public/locales/pt-BR.json-139-139 (1)

139-139: Multiple untranslated strings in Brazilian Portuguese locale.

Several strings remain in English within the Portuguese locale file, including:

  • Section titles (lines 217, 229, 469, 660, 703)
  • New feature labels/titles (lines 288-291, 316-323, 368-371, 523-535)
  • UI options (lines 139, 555)

This creates an inconsistent experience for Portuguese-speaking users. Consider adding placeholder translations or tracking these for future translation.

Also applies to: 217-217, 229-229, 288-291, 316-323, 368-371, 469-469, 523-535, 555-555, 660-660, 703-703

🧹 Nitpick comments (13)
public/locales/ko-KR.json (1)

1-707: Consider tracking untranslated strings across all locale files.

This file has numerous untranslated English strings in a Korean locale file. Based on the AI summary, this restructuring affects 25 localization files. Consider creating a tracking issue to ensure all new feature strings are properly translated across all supported locales before release, as incomplete translations degrade user experience for non-English users.

Would you like me to open an issue to track the translation work needed for the new features?

public/locales/sv-SE.json (1)

469-469: Mixed English and Swedish in title.

The On-Screen Display settings title mixes English ("On-Screen") with Swedish ("skärminställningar"). For consistency, consider fully translating to Swedish or using an established Swedish term for on-screen display.

🔎 Suggested improvement
-				"title": "On-Screen skärminställningar",
+				"title": "Skärmvisningsinställningar",

Alternative if "On-Screen Display" is a recognized technical term:

-				"title": "On-Screen skärminställningar",
+				"title": "On-Screen Display-inställningar",
public/locales/it-IT.json (1)

703-703: Consider clarifying "Impostazioni scure di YouTube".

The phrase "Impostazioni scure" (literally "dark settings") is grammatically awkward in Italian. Consider one of these alternatives:

  • "Impostazioni tema scuro di YouTube" (YouTube dark theme settings)
  • "Impostazioni YouTube Deep Dark" (keeping the "Deep Dark" branding)

The current phrasing may confuse users about what this setting controls.

src/features/remainingTime/index.ts (2)

21-21: Consider moving the watch page guard earlier.

The guard is currently placed after waiting for the options message (lines 16-20). Moving it before the waitForSpecificMessage call would avoid unnecessary message waiting on non-watch pages.

🔎 Proposed refactor
 export async function setupRemainingTime() {
+	if (!isWatchPage()) return;
 	// Wait for the "options" message from the content script
 	const {
 		data: {
 			options: { enable_remaining_time }
 		}
 	} = await waitForSpecificMessage("options", "request_data", "content");
-	if (!isWatchPage()) return;
 	// If remaining time option is disabled, return
 	if (!enable_remaining_time) return;

36-42: Consider simplifying the live video handling logic.

The current logic for handling live videos is functional but somewhat convoluted, checking for the remaining time element twice and using complex conditionals. Consider this clearer alternative:

🔎 Proposed refactor for improved readability
-	const remainingTimeElementExists = (await waitForElement("span#ytp-time-remaining")) !== null;
-	if (playerVideoData.isLive && !remainingTimeElementExists) return;
-	const remainingTimeElement = (await waitForElement("span#ytp-time-remaining")) ?? document.createElement("span");
-	// If the video is live return
-	if (playerVideoData.isLive && remainingTimeElementExists) {
+	const existingRemainingTimeElement = await waitForElement("span#ytp-time-remaining");
+	// For live videos, remove any existing remaining time display and return
+	if (playerVideoData.isLive) {
+		if (existingRemainingTimeElement) {
-		remainingTimeElement.remove();
+			existingRemainingTimeElement.remove();
+		}
+		return;
 	}
-	if (!remainingTimeElementExists) {
+	const remainingTimeElement = existingRemainingTimeElement ?? document.createElement("span");
+	if (!existingRemainingTimeElement) {
 		remainingTimeElement.id = "ytp-time-remaining";
 		remainingTimeElement.textContent = remainingTime;
 		timeDisplay.insertAdjacentElement("beforeend", remainingTimeElement);
 	}
public/locales/pl-PL.json (2)

555-555: New "Both" screenshot option added correctly, but translation is missing.

The new "Both (File and Clipboard)" option is properly integrated with the existing screenshot save options and correctly referenced in the validation message at line 139. However, the text is in English rather than Polish.

Consider translating to Polish, for example: "Oba (Plik i schowek)" (please verify with a native speaker).


1-707: Overall: Partial Polish translation throughout the file.

This Polish localization file contains numerous English strings throughout (e.g., lines 105, 109, 124, and many feature labels/titles in the miscellaneous section). While the newly added features in this PR follow this existing pattern, consider tracking the completion of Polish translations separately to fully realize the purpose of this localization file.

This is not a blocker for this PR if the project accepts partial translations or uses English as a fallback.

src/features/playerSpeed/index.ts (1)

171-179: Consider caching options to reduce message passing overhead.

The updateSpeedButtons function fetches options via waitForSpecificMessage on every speed change. If speed changes are frequent (e.g., via slider), this could create unnecessary message-passing overhead.

💡 Optional optimization

Consider caching the playback_buttons_speed value and only fetching on settings changes:

+let cachedPlaybackButtonSpeed: number | null = null;
+
 async function updateSpeedButtons(playerSpeed: number) {
-	const {
-		data: {
-			options: { playback_buttons_speed: playbackSpeedPerClick }
-		}
-	} = await waitForSpecificMessage("options", "request_data", "content");
+	if (cachedPlaybackButtonSpeed === null) {
+		const {
+			data: {
+				options: { playback_buttons_speed: playbackSpeedPerClick }
+			}
+		} = await waitForSpecificMessage("options", "request_data", "content");
+		cachedPlaybackButtonSpeed = playbackSpeedPerClick;
+	}
+	const playbackSpeedPerClick = cachedPlaybackButtonSpeed;
 	await updatePlaybackSpeedButtonTooltip("increasePlaybackSpeedButton", calculatePlaybackButtonSpeed(playerSpeed, playbackSpeedPerClick, "increase"));
 	await updatePlaybackSpeedButtonTooltip("decreasePlaybackSpeedButton", calculatePlaybackButtonSpeed(playerSpeed, playbackSpeedPerClick, "decrease"));
 }

Then invalidate the cache when settings change by listening for option change messages.

src/features/hideSidebarRecommendedVideos/index.ts (1)

5-10: Unnecessary async modifier.

The disableHideSidebarRecommendedVideos function is marked as async but contains no await expressions. Consider removing the async keyword for clarity, or if the caller expects a Promise, keep it for API consistency with enableHideSidebarRecommendedVideos.

🔎 Suggested fix
-export async function disableHideSidebarRecommendedVideos() {
+export function disableHideSidebarRecommendedVideos() {
 	modifyElementClassList("remove", {
 		className: "yte-hide-sidebar-recommended-videos",
 		element: document.querySelector(sidebarRecommendedVideosSelector)
 	});
 }
src/features/automaticallyDisableAutoPlay/index.ts (1)

17-34: Logic is correct but function naming is confusing.

The autoplay state check on line 31 is correct (aria-checked === "true" means autoplay is enabled). However, the function name enableAutomaticallyDisableAutoPlay is confusing—it reads as "enable the auto-disable feature" but actually enables (turns on) autoplay when the feature is enabled.

Consider renaming for clarity:

  • disableAutomaticallyDisableAutoPlaydisableAutoplay
  • enableAutomaticallyDisableAutoPlayenableAutoplayIfFeatureEnabled or checkAndDisableAutoplay
src/pages/embedded/index.ts (1)

961-965: Consider consolidating duplicate handler logic.

Both playlistRemoveButtonChange and playlistResetButtonChange execute identical logic. Consider consolidating them for maintainability:

🔎 Proposed refactor
-	case "playlistRemoveButtonChange":
-	case "playlistResetButtonChange": {
+	case "playlistRemoveButtonChange":
+	case "playlistResetButtonChange": {
 		await disablePlaylistManagementButtons();
 		await enablePlaylistManagementButtons();
 		break;
 	}

(No change needed—already consolidated. This is good practice.)

src/features/playlistManagementButtons/index.ts (1)

73-75: Variable shadowing — removeButton and resetButton are redeclared.

Lines 73-74 declare removeButton and resetButton by querying the DOM, but lines 78 and 99 redeclare variables with the same names using const. While JavaScript allows this due to block scoping, it reduces code clarity and makes it harder to track which variable is being referenced.

Consider renaming the outer variables to existingRemoveButton and existingResetButton for clarity.

🔎 Proposed refactor for clarity
-const removeButton = item.querySelector(".yte-remove-button");
-const resetButton = item.querySelector(".yte-reset-button");
+const existingRemoveButton = item.querySelector(".yte-remove-button");
+const existingResetButton = item.querySelector(".yte-reset-button");
 const resumeOverlay = item.querySelector(THUMBAIL_OVERLAY_SELECTOR);

-if (enable_playlist_remove_button && !removeButton) {
+if (enable_playlist_remove_button && !existingRemoveButton) {
 	const removeButton = createActionButton({
src/pages/content/index.ts (1)

434-442: Minor inconsistency: single underscore vs double underscore prefix.

Line 434 uses _oldValue (single underscore) while the convention throughout this file is __oldValue (double underscore) for unused parameters. This is a minor stylistic inconsistency.

🔎 Proposed fix for consistency
-enable_playlist_remove_button: (_oldValue, newValue) => {
+enable_playlist_remove_button: (__oldValue, newValue) => {
 	sendExtensionOnlyMessage("playlistRemoveButtonChange", {
 		playlistRemoveButtonEnabled: newValue
 	});
 },
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between e57f3b0 and 1385d1e.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (48)
  • README.md (1 hunks)
  • package.json (2 hunks)
  • public/locales/ca-ES.json (11 hunks)
  • public/locales/cs-CZ.json (11 hunks)
  • public/locales/de-DE.json (18 hunks)
  • public/locales/en-GB.json (11 hunks)
  • public/locales/en-US.json (11 hunks)
  • public/locales/en-US.json.d.ts (11 hunks)
  • public/locales/es-ES.json (20 hunks)
  • public/locales/fa-IR.json (11 hunks)
  • public/locales/fr-FR.json (11 hunks)
  • public/locales/he-IL.json (11 hunks)
  • public/locales/hi-IN.json (11 hunks)
  • public/locales/it-IT.json (10 hunks)
  • public/locales/ja-JP.json (11 hunks)
  • public/locales/ko-KR.json (11 hunks)
  • public/locales/nl-NL.json (11 hunks)
  • public/locales/pl-PL.json (11 hunks)
  • public/locales/pt-BR.json (11 hunks)
  • public/locales/ru-RU.json (11 hunks)
  • public/locales/sv-SE.json (9 hunks)
  • public/locales/tr-TR.json (11 hunks)
  • public/locales/uk-UA.json (11 hunks)
  • public/locales/vi-VN.json (11 hunks)
  • public/locales/zh-CN.json (6 hunks)
  • public/locales/zh-TW.json (11 hunks)
  • src/components/Settings/Settings.tsx (3 hunks)
  • src/features/automaticallyDisableAutoPlay/index.ts (1 hunks)
  • src/features/defaultToOriginalAudioTrack/index.ts (3 hunks)
  • src/features/hideEndScreenCards/index.css (1 hunks)
  • src/features/hideEndScreenCards/index.ts (2 hunks)
  • src/features/hidePlaylistRecommendationsFromHomePage/index.ts (2 hunks)
  • src/features/hideSidebarRecommendedVideos/index.css (1 hunks)
  • src/features/hideSidebarRecommendedVideos/index.ts (1 hunks)
  • src/features/maximizePlayerButton/index.css (1 hunks)
  • src/features/playerSpeed/index.ts (6 hunks)
  • src/features/playlistManagementButtons/ActionButton/index.css (1 hunks)
  • src/features/playlistManagementButtons/index.ts (7 hunks)
  • src/features/remainingTime/index.ts (3 hunks)
  • src/features/saveToWatchLaterButton/index.ts (1 hunks)
  • src/features/screenshotButton/index.ts (1 hunks)
  • src/features/videoHistory/index.ts (2 hunks)
  • src/global.d.ts (1 hunks)
  • src/i18n/constants.ts (1 hunks)
  • src/pages/content/index.ts (3 hunks)
  • src/pages/embedded/index.ts (9 hunks)
  • src/types/index.ts (7 hunks)
  • src/utils/constants.ts (6 hunks)
🧰 Additional context used
🧬 Code graph analysis (14)
src/features/saveToWatchLaterButton/index.ts (1)
src/features/openYouTubeSettingsOnHover/index.ts (1)
  • disableOpenYouTubeSettingsOnHover (6-8)
src/features/hideEndScreenCards/index.css (1)
src/features/automaticallyShowMoreVideosOnEndScreen/utils.ts (2)
  • showMoreVideosOnEndScreen (14-23)
  • hideMoreVideosOnEndScreen (3-12)
src/features/automaticallyDisableAutoPlay/index.ts (2)
src/utils/utilities.ts (3)
  • waitForElement (807-824)
  • waitForSpecificMessage (833-860)
  • isWatchPage (575-578)
src/types/index.ts (1)
  • YouTubePlayerDiv (550-550)
src/features/remainingTime/index.ts (2)
src/utils/utilities.ts (2)
  • isWatchPage (575-578)
  • waitForElement (807-824)
src/types/index.ts (1)
  • YouTubePlayerDiv (550-550)
src/features/hideSidebarRecommendedVideos/index.ts (1)
src/utils/utilities.ts (3)
  • modifyElementClassList (580-583)
  • waitForSpecificMessage (833-860)
  • waitForElement (807-824)
src/features/videoHistory/index.ts (1)
src/utils/utilities.ts (1)
  • waitForElement (807-824)
src/features/defaultToOriginalAudioTrack/index.ts (1)
src/types/index.ts (1)
  • Nullable (29-29)
src/features/hideEndScreenCards/index.ts (1)
src/utils/utilities.ts (1)
  • modifyElementClassList (580-583)
src/features/hidePlaylistRecommendationsFromHomePage/index.ts (1)
src/utils/utilities.ts (1)
  • isHomePage (542-545)
src/pages/content/index.ts (1)
src/utils/utilities.ts (1)
  • sendExtensionOnlyMessage (744-758)
src/features/playerSpeed/index.ts (2)
src/utils/utilities.ts (1)
  • waitForSpecificMessage (833-860)
src/features/playbackSpeedButtons/index.ts (2)
  • updatePlaybackSpeedButtonTooltip (24-62)
  • calculatePlaybackButtonSpeed (14-22)
src/components/Settings/Settings.tsx (3)
src/components/Settings/components/Setting.tsx (1)
  • Setting (42-74)
src/components/Settings/components/SettingSection.tsx (1)
  • SettingSection (9-24)
src/components/Settings/components/SettingTitle.tsx (1)
  • SettingTitle (3-6)
src/features/screenshotButton/index.ts (3)
src/features/buttonPlacement/utils.ts (1)
  • getFeatureButton (35-37)
src/utils/utilities.ts (1)
  • createTooltip (231-327)
src/types/index.ts (1)
  • Nullable (29-29)
src/features/playlistManagementButtons/index.ts (3)
src/utils/utilities.ts (2)
  • waitForSpecificMessage (833-860)
  • IsDarkMode (538-541)
src/features/playlistManagementButtons/ActionButton/index.ts (1)
  • createActionButton (24-69)
src/features/playlistLength/utils.ts (1)
  • getPlaylistId (178-181)

Comment thread public/locales/fr-FR.json
"specificOption": {
"featureMenu": "Configure at least one button to be placed in the feature menu to configure this option.",
"screenshotButtonFileFormat": "Set screenshot save type to 'File' to configure this option"
"screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing French translation.

This is a French localization file (fr-FR.json), but the text is in English. All user-facing strings should be translated to French.

🔎 Suggested French translation
-				"screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option"
+				"screenshotButtonFileFormat": "Définir le type de sauvegarde de capture d'écran sur 'Fichier' ou 'Les deux' pour configurer cette option"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option"
"screenshotButtonFileFormat": "Définir le type de sauvegarde de capture d'écran sur 'Fichier' ou 'Les deux' pour configurer cette option"
🤖 Prompt for AI Agents
In public/locales/fr-FR.json around line 139 the value for
"screenshotButtonFileFormat" is still in English; replace it with a French
translation by updating the JSON value to: Définissez le type d'enregistrement
des captures d'écran sur « Fichier » ou « Les deux » pour configurer cette
option.

Comment thread public/locales/fr-FR.json
"title": "Place the {{BUTTON_NAME}} {{PLACEMENT}}"
},
"title": "Button Placement Settings"
"title": "Button placement settings"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing French translations for section titles.

These section titles are in English but should be in French for the fr-FR locale.

🔎 Suggested French translations
-				"title": "Button placement settings"
+				"title": "Paramètres de placement des boutons"
-				"title": "Custom CSS settings"
+				"title": "Paramètres CSS personnalisés"

Also applies to: 229-229

🤖 Prompt for AI Agents
In public/locales/fr-FR.json around lines 217 and 229, the section titles are
still in English; replace them with French equivalents — for line 217 change
"Button placement settings" to "Paramètres de placement du bouton" and update
the similar title at line 229 to its corresponding French translation (e.g.,
"Paramètres du bouton" or the specific section title in French), ensuring
punctuation and JSON string quoting remain correct.

Comment thread public/locales/fr-FR.json
Comment on lines +288 to +291
"automaticallyDisableAutoPlay": {
"label": "Automatically disable autoplay",
"title": "Automatically disables autoplay when you load a video"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing French translations for new feature.

The new "automaticallyDisableAutoPlay" feature strings are in English and need French translations.

🔎 Suggested French translations
 					"automaticallyDisableAutoPlay": {
-						"label": "Automatically disable autoplay",
-						"title": "Automatically disables autoplay when you load a video"
+						"label": "Désactiver automatiquement la lecture automatique",
+						"title": "Désactive automatiquement la lecture automatique lors du chargement d'une vidéo"
 					},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"automaticallyDisableAutoPlay": {
"label": "Automatically disable autoplay",
"title": "Automatically disables autoplay when you load a video"
},
"automaticallyDisableAutoPlay": {
"label": "Désactiver automatiquement la lecture automatique",
"title": "Désactive automatiquement la lecture automatique lors du chargement d'une vidéo"
},
🤖 Prompt for AI Agents
In public/locales/fr-FR.json around lines 288 to 291 the
"automaticallyDisableAutoPlay" values are still in English; replace the "label"
and "title" strings with French translations (e.g. label: "Désactiver
automatiquement la lecture automatique", title: "Désactive automatiquement la
lecture automatique lorsque vous chargez une vidéo"), keep the key names and
JSON structure intact, ensure proper escaping of quotes/characters and valid
JSON formatting, and run a quick JSON lint to verify no syntax errors.

Comment thread public/locales/fr-FR.json
Comment on lines +316 to 323
"enableMarkAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Add a button to playlist items to mark videos as unwatched"
},
"enableRemoveVideoButton": {
"label": "Remove video button",
"title": "Add a button to playlist items to remove videos from the playlist"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing French translations for playlist management features.

These new feature strings are in English and need French translations.

🔎 Suggested French translations
 					"enableMarkAsUnwatchedButton": {
-						"label": "Mark as unwatched button",
-						"title": "Add a button to playlist items to mark videos as unwatched"
+						"label": "Bouton marquer comme non regardé",
+						"title": "Ajoute un bouton aux éléments de playlist pour marquer les vidéos comme non regardées"
 					},
 					"enableRemoveVideoButton": {
-						"label": "Remove video button",
-						"title": "Add a button to playlist items to remove videos from the playlist"
+						"label": "Bouton supprimer la vidéo",
+						"title": "Ajoute un bouton aux éléments de playlist pour supprimer des vidéos de la playlist"
 					},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"enableMarkAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Add a button to playlist items to mark videos as unwatched"
},
"enableRemoveVideoButton": {
"label": "Remove video button",
"title": "Add a button to playlist items to remove videos from the playlist"
},
"enableMarkAsUnwatchedButton": {
"label": "Bouton marquer comme non regardé",
"title": "Ajoute un bouton aux éléments de playlist pour marquer les vidéos comme non regardées"
},
"enableRemoveVideoButton": {
"label": "Bouton supprimer la vidéo",
"title": "Ajoute un bouton aux éléments de playlist pour supprimer des vidéos de la playlist"
},
🤖 Prompt for AI Agents
In public/locales/fr-FR.json around lines 316 to 323 the new playlist feature
strings are still in English; update the values to French. Replace "Mark as
unwatched button" with "Bouton « Marquer comme non lu »" and its title with
"Ajouter un bouton aux éléments de la playlist pour marquer les vidéos comme non
lues", and replace "Remove video button" with "Bouton « Supprimer la vidéo »"
and its title with "Ajouter un bouton aux éléments de la playlist pour supprimer
des vidéos de la playlist".

Comment thread public/locales/fr-FR.json
Comment on lines +368 to +371
"hideSidebarRecommendedVideos": {
"label": "Hide recommended videos",
"title": "Hides the sidebar that recommends videos"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Missing French translations for sidebar feature.

The new "hideSidebarRecommendedVideos" feature strings are in English and need French translations.

🔎 Suggested French translations
 					"hideSidebarRecommendedVideos": {
-						"label": "Hide recommended videos",
-						"title": "Hides the sidebar that recommends videos"
+						"label": "Masquer les vidéos recommandées",
+						"title": "Masque la barre latérale qui recommande des vidéos"
 					},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"hideSidebarRecommendedVideos": {
"label": "Hide recommended videos",
"title": "Hides the sidebar that recommends videos"
},
"hideSidebarRecommendedVideos": {
"label": "Masquer les vidéos recommandées",
"title": "Masque la barre latérale qui recommande des vidéos"
},
🤖 Prompt for AI Agents
In public/locales/fr-FR.json around lines 368 to 371, the
"hideSidebarRecommendedVideos" entry is still in English; replace the "label"
and "title" values with French translations (e.g., label: "Masquer les vidéos
recommandées", title: "Masque la barre latérale qui recommande des vidéos") so
the UI displays French text for this feature; keep the key name unchanged and
ensure the JSON string formatting and commas remain valid.

Comment on lines +12 to +14
const isAutoPlayOn = autoPlayButtonElemChecked.getAttribute("aria-checked") === "false";
if (!isAutoPlayOn) return;
autoPlayButtonElem.click();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: Inverted autoplay state logic.

The logic for determining autoplay state is inverted. Line 12 sets isAutoPlayOn to true when aria-checked === "false", but YouTube's autoplay toggle uses:

  • aria-checked="true" → autoplay is enabled
  • aria-checked="false" → autoplay is disabled

This causes the function to click the button only when autoplay is already disabled, which is the opposite of the intended behavior.

🔎 Proposed fix
-	const isAutoPlayOn = autoPlayButtonElemChecked.getAttribute("aria-checked") === "false";
+	const isAutoPlayOn = autoPlayButtonElemChecked.getAttribute("aria-checked") === "true";
 	if (!isAutoPlayOn) return;
 	autoPlayButtonElem.click();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const isAutoPlayOn = autoPlayButtonElemChecked.getAttribute("aria-checked") === "false";
if (!isAutoPlayOn) return;
autoPlayButtonElem.click();
const isAutoPlayOn = autoPlayButtonElemChecked.getAttribute("aria-checked") === "true";
if (!isAutoPlayOn) return;
autoPlayButtonElem.click();
🤖 Prompt for AI Agents
In src/features/automaticallyDisableAutoPlay/index.ts around lines 12 to 14, the
autoplay state check is inverted: currently isAutoPlayOn is set true when
aria-checked === "false", causing the button to be clicked only when autoplay is
already disabled; change the comparison to check for aria-checked === "true" (or
invert the boolean logic) so isAutoPlayOn correctly reflects that autoplay is
enabled, and ensure the code clicks the button only when autoplay is enabled
(i.e., if (!isAutoPlayOn) return; autoPlayButtonElem.click();).

Comment on lines +58 to 71
function parseAudioTrack(obj: Record<string, unknown>): Nullable<ParsedAudioTrack> {
for (const key of Object.keys(obj)) {
const { [key]: value } = obj;
if (value && typeof value === "object" && !Array.isArray(value) && "name" in value && "isDefault" in value) {
return {
isDefault: value.isDefault as boolean,
name: value.name as string,
track: obj
};
}
}

return null;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "*.ts" -o -name "*.tsx" | head -20

Repository: YouTube-Enhancer/extension

Length of output: 986


🏁 Script executed:

cd src && find . -type f \( -name "*.ts" -o -name "*.tsx" \) -path "*defaultToOriginalAudioTrack*"

Repository: YouTube-Enhancer/extension

Length of output: 117


🏁 Script executed:

rg "ParsedAudioTrack" --type ts -A 3 -B 1

Repository: YouTube-Enhancer/extension

Length of output: 1689


🏁 Script executed:

rg "parseAudioTrack" --type ts -A 2 -B 2

Repository: YouTube-Enhancer/extension

Length of output: 1485


🏁 Script executed:

cat -n src/features/defaultToOriginalAudioTrack/index.ts

Repository: YouTube-Enhancer/extension

Length of output: 3371


🏁 Script executed:

rg "type audioTrack" --type ts -A 5 | head -20

Repository: YouTube-Enhancer/extension

Length of output: 331


🏁 Script executed:

find . -path "*node_modules/@types/youtube-player*" -name "*.d.ts" 2>/dev/null | head -5

Repository: YouTube-Enhancer/extension

Length of output: 52


🏁 Script executed:

cat -n src/global.d.ts | head -100

Repository: YouTube-Enhancer/extension

Length of output: 3439


Add type validation before casting to prevent runtime errors.

The function uses type assertions (as boolean, as string) without validating that the properties actually have the expected types. If isDefault is not a boolean or name is not a string, the returned ParsedAudioTrack will have incorrect types, potentially causing runtime errors in consuming code.

Additionally, the parsing logic iterates through all object keys looking for any nested object with name and isDefault properties. This could match unintended nested objects if multiple exist, and the assumption about the track structure may be fragile.

Recommended fix:

 function parseAudioTrack(obj: Record<string, unknown>): Nullable<ParsedAudioTrack> {
 	for (const key of Object.keys(obj)) {
 		const { [key]: value } = obj;
-		if (value && typeof value === "object" && !Array.isArray(value) && "name" in value && "isDefault" in value) {
+		if (
+			value &&
+			typeof value === "object" &&
+			!Array.isArray(value) &&
+			"name" in value &&
+			"isDefault" in value &&
+			typeof value.name === "string" &&
+			typeof value.isDefault === "boolean"
+		) {
 			return {
-				isDefault: value.isDefault as boolean,
-				name: value.name as string,
+				isDefault: value.isDefault,
+				name: value.name,
 				track: obj
 			};
 		}
 	}
-
 	return null;
 }
🤖 Prompt for AI Agents
In src/features/defaultToOriginalAudioTrack/index.ts around lines 58-71, the
parser currently casts value.name and value.isDefault without runtime checks and
may match unintended nested objects; change the logic to perform explicit type
guards before casting (e.g., ensure typeof value === "object" &&
!Array.isArray(value) && typeof (value as any).name === "string" && typeof
(value as any).isDefault === "boolean"), only accept the object that satisfies
those checks (returning a ParsedAudioTrack with correctly typed fields),
restrict which nested object you consider (avoid matching unrelated nested
objects—e.g., only inspect top-level entries expected to be tracks or add a
specific key filter), and handle multiple matches deterministically (return
first valid or null) so no unsafe type assertions are used.

Comment on lines +83 to +88
onClick: async () => {
const playlistId = getPlaylistId()!;
const {
data: { setVideoId }
} = item as YTDPlaylistVideoRenderer;
await removeFromPlaylist(youtube, playlistId, setVideoId);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Non-null assertion on getPlaylistId() may cause runtime errors.

The non-null assertion (!) on line 84 assumes getPlaylistId() will never return null, but this function can return null if the list parameter is not in the URL. If the playlist ID is missing, this will cause the removeFromPlaylist call to fail or behave unexpectedly.

🔎 Proposed fix with null check
 onClick: async () => {
-	const playlistId = getPlaylistId()!;
+	const playlistId = getPlaylistId();
+	if (!playlistId) {
+		throw new Error("Playlist ID not found");
+	}
 	const {
 		data: { setVideoId }
 	} = item as YTDPlaylistVideoRenderer;
 	await removeFromPlaylist(youtube, playlistId, setVideoId);
 },
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
onClick: async () => {
const playlistId = getPlaylistId()!;
const {
data: { setVideoId }
} = item as YTDPlaylistVideoRenderer;
await removeFromPlaylist(youtube, playlistId, setVideoId);
onClick: async () => {
const playlistId = getPlaylistId();
if (!playlistId) {
throw new Error("Playlist ID not found");
}
const {
data: { setVideoId }
} = item as YTDPlaylistVideoRenderer;
await removeFromPlaylist(youtube, playlistId, setVideoId);
🤖 Prompt for AI Agents
In src/features/playlistManagementButtons/index.ts around lines 83 to 88, the
code uses a non-null assertion on getPlaylistId() which can return null; change
this to explicitly check the result, handle the null case (early return, show a
user-facing error/toast, or disable the action) and only call removeFromPlaylist
when playlistId is non-null; ensure any async flow is preserved and consider
logging the missing playlistId for debugging.

Comment on lines +116 to +120
if (enable_playlist_remove_button && removeButton) {
removeButton.prepend(resetButton);
} else {
menu.prepend(resetButton);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Incorrect DOM prepend logic — reset button becomes a child of remove button.

Line 117 calls removeButton.prepend(resetButton), which makes resetButton a child element inside removeButton. This is likely unintended; the reset button should be placed adjacent to (before) the remove button, not inside it.

🔎 Proposed fix using insertBefore
-if (enable_playlist_remove_button && removeButton) {
-	removeButton.prepend(resetButton);
+const existingRemoveButton = item.querySelector(".yte-remove-button");
+if (enable_playlist_remove_button && existingRemoveButton) {
+	menu.insertBefore(resetButton, existingRemoveButton);
 } else {
 	menu.prepend(resetButton);
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/features/playlistManagementButtons/index.ts around lines 116 to 120, the
code calls removeButton.prepend(resetButton) which inserts resetButton as a
child of removeButton; instead, insert resetButton as a sibling before
removeButton on the parent container. Replace the prepend call with a
parent-level insertion (e.g. menu.insertBefore(resetButton, removeButton) or
removeButton.before(resetButton)) and ensure both menu and removeButton are
non-null before calling to avoid runtime errors.

Comment on lines +49 to +53
document.addEventListener("yt-action", async (event) => {
if ((event as CustomEvent).detail.actionName === "yt-prepare-page-dispose") {
await disableSaveToWatchLaterButton();
}
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Potential memory leak: event listener is never removed.

The yt-action event listener is added to the document but never cleaned up, even when the feature is disabled. This listener will persist across page navigations and continue triggering, potentially causing memory leaks and unexpected behavior.

🔎 Recommended fix

Store the listener reference and remove it in the disable function:

+let pageDisposeListener: ((event: Event) => Promise<void>) | null = null;
+
 export async function disableSaveToWatchLaterButton() {
 	if (videosObserver) {
 		videosObserver.disconnect();
 		videosObserver = null;
 	}
+	if (pageDisposeListener) {
+		document.removeEventListener("yt-action", pageDisposeListener);
+		pageDisposeListener = null;
+	}
 
 	document.querySelectorAll(".yte-save-to-watch-later-button").forEach((saveButton) => {
 		saveButton.closest("yt-lockup-view-model")!.querySelector("h3")!.style.paddingRight = "0";
 		saveButton.remove();
 	});
 }
 
 export async function enableSaveToWatchLaterButton() {
 	const {
 		data: {
 			options: { enable_save_to_watch_later_button }
 		}
 	} = await waitForSpecificMessage("options", "request_data", "content");
 
 	if (!enable_save_to_watch_later_button || (!isHomePage() && !isSubscriptionsPage())) {
 		return;
 	}
 
-	document.addEventListener("yt-action", async (event) => {
+	pageDisposeListener = async (event: Event) => {
 		if ((event as CustomEvent).detail.actionName === "yt-prepare-page-dispose") {
 			await disableSaveToWatchLaterButton();
 		}
-	});
+	};
+	document.addEventListener("yt-action", pageDisposeListener);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
document.addEventListener("yt-action", async (event) => {
if ((event as CustomEvent).detail.actionName === "yt-prepare-page-dispose") {
await disableSaveToWatchLaterButton();
}
});
let pageDisposeListener: ((event: Event) => Promise<void>) | null = null;
export async function disableSaveToWatchLaterButton() {
if (videosObserver) {
videosObserver.disconnect();
videosObserver = null;
}
if (pageDisposeListener) {
document.removeEventListener("yt-action", pageDisposeListener);
pageDisposeListener = null;
}
document.querySelectorAll(".yte-save-to-watch-later-button").forEach((saveButton) => {
saveButton.closest("yt-lockup-view-model")!.querySelector("h3")!.style.paddingRight = "0";
saveButton.remove();
});
}
export async function enableSaveToWatchLaterButton() {
const {
data: {
options: { enable_save_to_watch_later_button }
}
} = await waitForSpecificMessage("options", "request_data", "content");
if (!enable_save_to_watch_later_button || (!isHomePage() && !isSubscriptionsPage())) {
return;
}
pageDisposeListener = async (event: Event) => {
if ((event as CustomEvent).detail.actionName === "yt-prepare-page-dispose") {
await disableSaveToWatchLaterButton();
}
};
document.addEventListener("yt-action", pageDisposeListener);
}

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 9

🧹 Nitpick comments (1)
public/locales/de-DE.json (1)

288-291: Consider translating the new feature labels and titles.

The newly added automaticallyDisableAutoPlay feature has English labels and titles. For consistency with the rest of the German locale file, consider translating these strings:

  • Label: "Automatically disable autoplay" → German translation
  • Title: "Automatically disables autoplay when you load a video" → German translation
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1385d1e and 962a1ec.

📒 Files selected for processing (3)
  • public/locales/de-DE.json (19 hunks)
  • public/locales/hi-IN.json (13 hunks)
  • public/locales/ja-JP.json (13 hunks)
🔇 Additional comments (3)
public/locales/hi-IN.json (2)

5-6: LGTM: Message string updates

The Hindi translations for video resumption and volume setting messages are properly formatted with correct placeholder syntax.


139-139: LGTM: Title normalization and screenshot format expansion

The title updates across multiple settings sections provide consistent casing and formatting. The addition of the "Both (File and Clipboard)" option for screenshot save type (line 555) properly extends the feature, and the help text at line 139 correctly references this new option.

JSON structure is valid throughout the file.

Also applies to: 217-217, 229-229, 469-469, 555-555, 660-660, 703-703

public/locales/de-DE.json (1)

555-555: LGTM! The "Both" option is properly integrated.

The addition of the "Both (File and Clipboard)" option for screenshot saving is correctly implemented and properly referenced in the related help text at line 139.

Comment thread public/locales/de-DE.json
Comment on lines +316 to +322
"enableMarkAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Add a button to playlist items to mark videos as unwatched"
},
"enableRemoveVideoButton": {
"label": "Remove video button",
"title": "Add a button to playlist items to remove videos from the playlist"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for references to both old and new playlist management feature keys

echo "=== Searching for OLD keys (enableMarkAsUnwatchedButton, enableRemoveVideoButton) ==="
rg -n "enableMarkAsUnwatchedButton|enableRemoveVideoButton" --type ts --type tsx --type js --type jsx -g '!**/locales/**' 2>/dev/null || echo "No matches found"

echo ""
echo "=== Searching for NEW keys (markAsUnwatchedButton, removeVideoButton) ==="
rg -n "markAsUnwatchedButton|removeVideoButton" --type ts --type tsx --type js --type jsx -g '!**/locales/**' 2>/dev/null || echo "No matches found"

echo ""
echo "=== Searching for playlistManagement context ==="
rg -n "playlistManagement" --type ts --type tsx --type js --type jsx -A 3 -B 3 2>/dev/null || echo "No matches found"

Repository: YouTube-Enhancer/extension

Length of output: 331


🏁 Script executed:

#!/bin/bash
# Read the specific sections of de-DE.json to examine the duplication

echo "=== Lines 316-322 (old keys in miscellaneous.features) ==="
sed -n '316,322p' public/locales/de-DE.json

echo ""
echo "=== Lines 523-535 (new playlistManagement section) ==="
sed -n '523,535p' public/locales/de-DE.json

echo ""
echo "=== Full context around line 316 ==="
sed -n '310,330p' public/locales/de-DE.json

echo ""
echo "=== Full context around line 523 ==="
sed -n '515,540p' public/locales/de-DE.json

Repository: YouTube-Enhancer/extension

Length of output: 2735


Remove the duplicate playlist management keys from miscellaneous.features.

The locale file contains two sets of similar playlist management feature keys:

  • Old: enableMarkAsUnwatchedButton and enableRemoveVideoButton in miscellaneous.features (lines 316-322)
  • New: markAsUnwatchedButton and removeVideoButton in playlistManagement.features (lines 523-535)

Both sets are unused in the codebase. Remove the old keys from miscellaneous.features as they appear to be leftover from a previous implementation and should not coexist with the new playlistManagement section.

🤖 Prompt for AI Agents
public/locales/de-DE.json around lines 316 to 322: remove the old playlist
management entries inside miscellaneous.features ("enableMarkAsUnwatchedButton"
and "enableRemoveVideoButton") so only the new keys under
playlistManagement.features remain; after removing those two key objects, ensure
the JSON remains valid (fix commas/whitespace) and run a quick search to confirm
there are no remaining references to those old keys.

Comment thread public/locales/hi-IN.json
Comment on lines +288 to +291
"automaticallyDisableAutoPlay": {
"label": "Automatically disable autoplay",
"title": "Automatically disables autoplay when you load a video"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incomplete Hindi translation for new feature

The automaticallyDisableAutoPlay feature has been added with English text instead of Hindi translations. Users with the Hindi locale will see English strings for this feature.

🤖 Prompt for AI Agents
In public/locales/hi-IN.json around lines 288 to 291, the new key
"automaticallyDisableAutoPlay" contains English strings; replace them with
accurate Hindi translations for both "label" and "title" (e.g., provide a
concise Hindi label and a descriptive Hindi title explaining that autoplay is
disabled automatically when a video loads), ensuring the JSON string values
remain properly escaped and preserve existing indentation and formatting.

Comment thread public/locales/hi-IN.json
Comment on lines +316 to 323
"enableMarkAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Add a button to playlist items to mark videos as unwatched"
},
"enableRemoveVideoButton": {
"label": "Remove video button",
"title": "Add a button to playlist items to remove videos from the playlist"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Incomplete Hindi translations for playlist management features

Both enableMarkAsUnwatchedButton and enableRemoveVideoButton features contain English text instead of Hindi translations.

🤖 Prompt for AI Agents
In public/locales/hi-IN.json around lines 316 to 323, the
"enableMarkAsUnwatchedButton" and "enableRemoveVideoButton" entries currently
contain English text; replace both "label" and "title" values with Hindi
translations. For enableMarkAsUnwatchedButton use label "अनवॉच्ड के रूप में
मार्क करें" and title "वीडियो को अनवॉच्ड के रूप में मार्क करने के लिए प्लेलिस्ट
आइटम में एक बटन जोड़ें", and for enableRemoveVideoButton use label "वीडियो
हटाएँ" and title "प्लेलिस्ट से वीडियो हटाने के लिए प्लेलिस्ट आइटम में एक बटन
जोड़ें". Ensure the JSON strings preserve existing quoting and comma placement.

Comment thread public/locales/hi-IN.json
Comment on lines +523 to +535
"playlistManagement": {
"features": {
"markAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Adds a button to mark videos as unwatched"
},
"removeVideoButton": {
"label": "Remove video button",
"title": "Adds a button to remove videos from the playlist"
}
},
"title": "Playlist management settings"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

New playlist management section structure is correct, but translations are incomplete

The new playlistManagement section has been properly added with correct JSON structure and follows the existing pattern for settings sections. However, all strings remain in English instead of Hindi.

The structural refactoring separating playlist management features into a dedicated section is appropriate.

🤖 Prompt for AI Agents
In public/locales/hi-IN.json around lines 523 to 535 the new playlistManagement
section is present but the strings are still in English; replace the English
values for "label" and "title" under
playlistManagement.features.markAsUnwatchedButton and
playlistManagement.features.removeVideoButton (and the playlistManagement.title)
with proper Hindi translations, preserving the JSON keys and punctuation,
matching the existing translation style and tone, and ensure the resulting JSON
remains valid (proper quotes/commas/escaping).

Comment thread public/locales/ja-JP.json
"specificOption": {
"featureMenu": "Configure at least one button to be placed in the feature menu to configure this option.",
"screenshotButtonFileFormat": "Set screenshot save type to 'File' to configure this option"
"screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Translate specific option message to Japanese.

The screenshotButtonFileFormat message (Line 139) in the optionDisabled.specificOption section is in English: "Set screenshot save type to 'File' or 'Both' to configure this option". This message is displayed to users when certain options are disabled and should be translated to Japanese.

🔎 Suggested Japanese translation
-					"screenshotButtonFileFormat": "Set screenshot save type to 'File' or 'Both' to configure this option"
+					"screenshotButtonFileFormat": "このオプションを設定するには、スクリーンショット保存タイプを「ファイル」または「両方」に設定してください"
🤖 Prompt for AI Agents
In public/locales/ja-JP.json around line 139, the message for
optionDisabled.specificOption.screenshotButtonFileFormat is still in English;
replace it with a Japanese translation. Update the value to:
"このオプションを設定するには、スクリーンショットの保存形式を「ファイル」または「両方」に設定してください".

Comment thread public/locales/ja-JP.json
"title": "{{PLACEMENT}}に{{BUTTON_NAME}}を置き方する"
},
"title": "ボタン置き方設定"
"title": "Button placement settings"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Localize section titles for Japanese users.

Multiple section titles have been changed to English in this Japanese locale file:

  • Line 217: "Button placement settings"
  • Line 229: "Custom CSS settings"
  • Line 469: "On-screen display settings"
  • Line 660: "YouTube API V3 key"
  • Line 703: "YouTube deep dark settings"

These titles are displayed directly to Japanese-speaking users and should be translated to Japanese for proper localization.

🔎 Suggested Japanese translations
-				"title": "Button placement settings"
+				"title": "ボタン配置設定"
-				"title": "Custom CSS settings"
+				"title": "カスタムCSS設定"
-				"title": "On-screen display settings",
+				"title": "オンスクリーンディスプレイの設定",
-				"title": "YouTube API V3 key"
+				"title": "YouTube API V3キー"
-				"title": "YouTube deep dark settings"
+				"title": "YouTubeディープダーク設定"

Also applies to: 229-229, 469-469, 660-660, 703-703

🤖 Prompt for AI Agents
public/locales/ja-JP.json lines 217, 229, 469, 660, 703: the issue is multiple
section titles left in English; replace each English title with the appropriate
Japanese translation so the locale is fully localized — specifically change
"Button placement settings" to "ボタン配置設定", "Custom CSS settings" to "カスタムCSS設定",
"On-screen display settings" to "画面表示設定", "YouTube API V3 key" to "YouTube API
V3 キー", and "YouTube deep dark settings" to "YouTube ダークモード設定".

Comment thread public/locales/ja-JP.json
Comment on lines +288 to +291
"automaticallyDisableAutoPlay": {
"label": "Automatically disable autoplay",
"title": "Automatically disables autoplay when you load a video"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Translate new feature labels to Japanese.

Several new features have English labels and titles in this Japanese locale file:

  • automaticallyDisableAutoPlay (Lines 288-291): "Automatically disable autoplay" and description
  • enableMarkAsUnwatchedButton (Lines 316-319): "Mark as unwatched button" and description
  • enableRemoveVideoButton (Lines 320-323): "Remove video button" and description
  • hideSidebarRecommendedVideos (Lines 368-371): "Hide recommended videos" and description

These user-facing strings should be translated to Japanese for consistency with the rest of the locale file.

🔎 Suggested Japanese translations
 					"automaticallyDisableAutoPlay": {
-						"label": "Automatically disable autoplay",
-						"title": "Automatically disables autoplay when you load a video"
+						"label": "自動再生を自動的に無効にする",
+						"title": "動画の読み込み時に自動再生を自動的に無効にする"
 					},
 					"enableMarkAsUnwatchedButton": {
-						"label": "Mark as unwatched button",
-						"title": "Add a button to playlist items to mark videos as unwatched"
+						"label": "未視聴としてマークするボタン",
+						"title": "プレイリストアイテムに動画を未視聴としてマークするボタンを追加する"
 					},
 					"enableRemoveVideoButton": {
-						"label": "Remove video button",
-						"title": "Add a button to playlist items to remove videos from the playlist"
+						"label": "動画を削除するボタン",
+						"title": "プレイリストアイテムから動画を削除するボタンを追加する"
 					},
 					"hideSidebarRecommendedVideos": {
-						"label": "Hide recommended videos",
-						"title": "Hides the sidebar that recommends videos"
+						"label": "おすすめ動画を非表示",
+						"title": "おすすめ動画のサイドバーを非表示にする"
 					},

Also applies to: 316-323, 368-371

🤖 Prompt for AI Agents
In public/locales/ja-JP.json around lines 288-291, 316-323, and 368-371 the new
keys (automaticallyDisableAutoPlay, enableMarkAsUnwatchedButton,
enableRemoveVideoButton, hideSidebarRecommendedVideos) still have English
label/title values; replace those English strings with accurate Japanese
translations for both "label" and "title"/"description" fields, preserving
existing JSON structure, key names, punctuation and escaping, and ensure commas
and indentation remain valid so the file stays valid JSON.

Comment thread public/locales/ja-JP.json
Comment on lines +523 to +535
"playlistManagement": {
"features": {
"markAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Adds a button to mark videos as unwatched"
},
"removeVideoButton": {
"label": "Remove video button",
"title": "Adds a button to remove videos from the playlist"
}
},
"title": "Playlist management settings"
},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Translate playlistManagement section to Japanese.

The entire new playlistManagement section (Lines 523-535) contains English text:

  • Section title: "Playlist management settings"
  • Feature labels and titles for markAsUnwatchedButton and removeVideoButton

This section should be fully translated to Japanese for Japanese-speaking users.

🔎 Suggested Japanese translations
 			"playlistManagement": {
 				"features": {
 					"markAsUnwatchedButton": {
-						"label": "Mark as unwatched button",
-						"title": "Adds a button to mark videos as unwatched"
+						"label": "未視聴としてマークするボタン",
+						"title": "動画を未視聴としてマークするボタンを追加する"
 					},
 					"removeVideoButton": {
-						"label": "Remove video button",
-						"title": "Adds a button to remove videos from the playlist"
+						"label": "動画を削除するボタン",
+						"title": "プレイリストから動画を削除するボタンを追加する"
 					}
 				},
-				"title": "Playlist management settings"
+				"title": "プレイリスト管理設定"
 			},
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"playlistManagement": {
"features": {
"markAsUnwatchedButton": {
"label": "Mark as unwatched button",
"title": "Adds a button to mark videos as unwatched"
},
"removeVideoButton": {
"label": "Remove video button",
"title": "Adds a button to remove videos from the playlist"
}
},
"title": "Playlist management settings"
},
"playlistManagement": {
"features": {
"markAsUnwatchedButton": {
"label": "未視聴としてマークするボタン",
"title": "動画を未視聴としてマークするボタンを追加する"
},
"removeVideoButton": {
"label": "動画を削除するボタン",
"title": "プレイリストから動画を削除するボタンを追加する"
}
},
"title": "プレイリスト管理設定"
},
🤖 Prompt for AI Agents
In public/locales/ja-JP.json around lines 523 to 535, the playlistManagement
section is still in English; replace the English strings with Japanese
translations: change "Playlist management settings" to "プレイリスト管理設定", "Mark as
unwatched button" to "未視聴に戻すボタン", its title "Adds a button to mark videos as
unwatched" to "動画を未視聴に戻すボタンを追加します", "Remove video button" to "動画を削除ボタン", and its
title "Adds a button to remove videos from the playlist" to
"プレイリストから動画を削除するボタンを追加します".

Comment thread public/locales/ja-JP.json
"title": "動画をスクリーンショット撮るするボタンをビデオ・プレーヤーに追加する"
},
"saveAs": {
"both": "Both (File and Clipboard)",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Translate screenshot "both" option to Japanese.

The new both option for screenshot save type (Line 555) is in English: "Both (File and Clipboard)". The adjacent options on Lines 556-557 (clipboard and file) are properly localized in Japanese. This creates an inconsistent user experience within the same dropdown.

🔎 Suggested Japanese translation
-					"both": "Both (File and Clipboard)",
+					"both": "両方(ファイルとクリップボード)",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"both": "Both (File and Clipboard)",
"both": "両方(ファイルとクリップボード)",
🤖 Prompt for AI Agents
In public/locales/ja-JP.json around line 555, the "both" screenshot option is
still in English ("Both (File and Clipboard)"); replace it with the Japanese
translation "両方(ファイルとクリップボード)" so it matches the adjacent localized keys and
provides a consistent dropdown experience.

@VampireChicken12 VampireChicken12 merged commit 598b4d3 into main Dec 19, 2025
6 checks passed
@github-project-automation github-project-automation Bot moved this from Todo to Done - Released in YouTube Enhancer Dec 19, 2025
@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.31.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@github-actions
Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 1.32.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@coderabbitai coderabbitai Bot mentioned this pull request Feb 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Done - Released

Development

Successfully merging this pull request may close these issues.

3 participants