Skip to content

Medium Quality Support#312

Merged
n-ce merged 19 commits into
mainfrom
horizon
Jun 6, 2025
Merged

Medium Quality Support#312
n-ce merged 19 commits into
mainfrom
horizon

Conversation

@n-ce
Copy link
Copy Markdown
Owner

@n-ce n-ce commented Jun 6, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new audio quality selector with low, medium, and high options.
    • Added a toggle for queue prefetching in playback settings.
    • Updated the UI to display current audio quality and codec instead of a bitrate selector.
  • Improvements

    • Enhanced localization with new and updated UI text, including new sorting options and clearer support messages.
    • Refined playback settings for better clarity and usability.
    • Improved stream selection logic for preferred audio quality and codec.
    • Simplified startup behavior and search UI.
    • Updated app description wording for clarity.
  • Bug Fixes

    • Prefetching of the next audio item now only occurs if the prefetch setting is enabled.
  • Chores

    • Updated several dependencies to their latest versions.
    • Replaced dynamic build date with a static build identifier.
  • Style

    • Updated player footer styles for improved layout and readability.

JKzeta and others added 11 commits June 1, 2025 22:03
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Jun 6, 2025

Walkthrough

The updates introduce a new audio quality selection mechanism, replacing the previous high-quality toggle and bitrate selector with a more flexible quality preference system. The UI and state management are updated accordingly. The stream selection logic is centralized via a new utility function, and various dependencies and localization strings are updated. Minor UI and CSS refinements are also included.

Changes

File(s) Change Summary
index.html, src/stylesheets/home.css, src/lib/dom.ts Renamed player selectors container and replaced bitrate selector with a quality view paragraph; updated related CSS and DOM exports.
package.json Updated versions of hls.js, @netlify/blobs, @netlify/edge-functions, and @types/node.
src/components/Settings/app.ts, src/components/Settings/playback.ts Simplified settings handlers; replaced HQ toggle with audio quality dropdown; added prefetch toggle.
src/components/WatchVideo.ts, src/modules/setAudioStreams.ts Refactored audio stream selection to use new preferredStream utility; removed direct array access and bitrate selector logic.
src/lib/store.ts Replaced hq with quality property; added prefetch and stricter types for several properties.
src/lib/utils.ts Added preferredStream function for selecting audio streams; removed renderCollection.
src/locales/en.json Updated and added localization strings for new settings and sorting options.
src/modules/hls.ts Updated HLS level selection to use new quality property.
src/modules/start.ts Removed bitrate selector logic; streamlined HLS and share action handling; removed fallback UI.
src/scripts/audioEvents.ts Prefetch logic now respects new prefetch state property.
README.md, vite.config.ts Simplified README description; replaced dynamic build string with static string.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SettingsUI
    participant Store
    participant Utils
    participant AudioPlayer

    User->>SettingsUI: Selects audio quality (low/medium/high)
    SettingsUI->>Store: Updates state.quality
    User->>AudioPlayer: Requests playback
    AudioPlayer->>Utils: Calls preferredStream(audioStreams)
    Utils->>Store: Reads state.quality and state.codec
    Utils-->>AudioPlayer: Returns preferred AudioStream
    AudioPlayer->>AudioPlayer: Sets source to selected stream
Loading

Poem

A bunny with ears so long and neat,
Hopped through the code for a quality treat.
No more toggles—just choose what you hear,
Low, medium, or high, the options are clear!
With streams now picked by clever design,
This rabbit says, "Your music will shine!"
🐇🎶


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d155008 and 7ce7183.

📒 Files selected for processing (2)
  • README.md (1 hunks)
  • src/lib/store.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • README.md
  • src/lib/store.ts
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@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: 3

🧹 Nitpick comments (5)
vite.config.ts (1)

13-13: Consider keeping year information for better build identification.

While simplifying the build string format aligns with UI refinements, removing the year could make it difficult to distinguish builds created in different years, potentially complicating debugging and version tracking in production environments.

Consider keeping the year for better build identification:

-((today = new Date()) => `${today.getDate()} ${today.toLocaleString('default', { month: 'short' })}`)()
+((today = new Date()) => `${today.getDate()} ${today.toLocaleString('default', { month: 'short' })} ${today.getFullYear()}`)()

Alternatively, if space is a concern, consider using a shorter year format:

-((today = new Date()) => `${today.getDate()} ${today.toLocaleString('default', { month: 'short' })}`)()
+((today = new Date()) => `${today.getDate()} ${today.toLocaleString('default', { month: 'short' })} '${today.getFullYear().toString().slice(-2)}`)()
src/stylesheets/home.css (1)

118-125:

Details

❓ Verification inconclusive

Verify the negative left margin alignment.

The paragraph styles look good overall, but the negative left margin of -3ch could be fragile and may not work consistently across different fonts or viewport sizes.

Consider testing this margin adjustment across different browsers and font configurations to ensure consistent alignment:


🏁 Script executed:

#!/bin/bash
# Description: Search for similar margin adjustments in the codebase to check for patterns

# Test: Look for other negative margin usage patterns
rg -A 2 -B 2 "margin.*-.*ch" --type css

Length of output: 460


Verify negative left margin consistency

The only occurrence of a negative ch-based margin is in your paragraph style, which may render differently across fonts, viewport sizes, or browsers:

File: src/stylesheets/home.css
Lines: 118–125

p {
  font-size: 0.9rem;
  font-style: italic;
  text-align: center;
  font-weight: 700;
  margin-left: -3ch;
  opacity: 0.5;
}

Please test this alignment in major browsers and with different font families. If you encounter inconsistencies, consider alternatives such as:

  • text-indent with a negative ch value
  • adjusting container padding instead of a negative margin
  • centering via flexbox or grid and offsetting with transforms
src/lib/utils.ts (1)

57-81: Well-designed stream selection logic with minor improvement suggestions.

The preferredStream function effectively handles codec detection and quality-based stream selection. The implementation correctly falls back from opus to aac when codec support is unavailable.

Consider these improvements:

  1. Add error handling for edge cases:
 export async function preferredStream(audioStreams: AudioStream[]) {
+  if (!audioStreams || audioStreams.length === 0) {
+    throw new Error('No audio streams provided');
+  }
+
   const preferedCodec: 'opus' | 'aac' = state.codec === 'any' ? ((await store.player.supportsOpus) ? 'opus' : 'aac') : state.codec;
  1. Fix typo and add fallback stream selection:
-  const preferedCodec: 'opus' | 'aac' = state.codec === 'any' ? ((await store.player.supportsOpus) ? 'opus' : 'aac') : state.codec;
+  const preferredCodec: 'opus' | 'aac' = state.codec === 'any' ? ((await store.player.supportsOpus) ? 'opus' : 'aac') : state.codec;
   const itags = ({
     low: {
       opus: [600, 249, 251],
       aac: [599, 139, 140]
     },
     medium: {
       opus: [250, 249],
       aac: [139, 140]
     },
     high: {
       opus: [251],
       aac: [140]
     }
-  })[state.quality || 'medium'][preferedCodec];
+  })[state.quality || 'medium'][preferredCodec];
   let stream!: AudioStream;
   for (const itag of itags) {
     if (stream?.url) continue;
     const v = audioStreams.find(v => v.url.includes(`itag=${itag}`));
     if (v) stream = v;
   }
 
+  // Fallback to first available stream if no preferred stream found
+  if (!stream && audioStreams.length > 0) {
+    stream = audioStreams[0];
+  }
+
   return stream;
 }
index.html (1)

196-218: Consider the implications of moving dynamic content to static HTML.

The addition of extensive static content (logo, description, support information) to the searchlist container represents a significant change from dynamic rendering. While this can improve initial load performance, it reduces flexibility for internationalization and customization.

Consider whether this content should remain dynamic for better maintainability:

<!-- Alternative: Keep a simpler static structure with dynamic content injection -->
<div id="searchlist">
  <div id="welcomeContent" class="hide"></div>
</div>

This would allow the content to be populated dynamically while maintaining the performance benefits when search results are displayed.

src/lib/libraryUtils.ts (1)

87-104: Well-implemented renderCollection function with proper typing.

The new renderCollection function effectively uses uhtml for efficient DOM rendering and the StreamItem component for consistent UI. The function signature allows for flexible usage with different fragments and optional draggable behavior.

Minor optimization suggestion: Consider destructuring the mapped object properties for better readability:

export function renderCollection(
  data: (DOMStringMap | CollectionItem)[],
  draggable = false,
  fragment: DocumentFragment | HTMLDivElement = listContainer
) {
  render(fragment, html`${data.map(v => {
-    StreamItem({
-      id: v.id || '',
-      href: hostResolver(`/watch?v=${v.id}`),
-      title: v.title || '',
-      author: v.author,
-      duration: v.duration || '',
-      channelUrl: v.channelUrl,
-      draggable: draggable
-    })
+    const { id = '', title = '', author, duration = '', channelUrl } = v;
+    return StreamItem({
+      id,
+      href: hostResolver(`/watch?v=${id}`),
+      title,
+      author,
+      duration,
+      channelUrl,
+      draggable
+    });
  })
    }`);
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f29ecdf and 5fc0a99.

📒 Files selected for processing (26)
  • index.html (6 hunks)
  • package.json (1 hunks)
  • src/components/Settings/app.ts (3 hunks)
  • src/components/Settings/personalize.ts (1 hunks)
  • src/components/Settings/playback.ts (2 hunks)
  • src/components/SuperCollectionList.ts (2 hunks)
  • src/components/WatchVideo.ts (4 hunks)
  • src/lib/dom.ts (1 hunks)
  • src/lib/libraryUtils.ts (3 hunks)
  • src/lib/store.ts (5 hunks)
  • src/lib/utils.ts (2 hunks)
  • src/locales/en.json (4 hunks)
  • src/locales/es.json (3 hunks)
  • src/modules/hls.ts (1 hunks)
  • src/modules/listUtils.ts (1 hunks)
  • src/modules/setAudioStreams.ts (2 hunks)
  • src/modules/start.ts (4 hunks)
  • src/modules/supermix.ts (1 hunks)
  • src/scripts/audioEvents.ts (1 hunks)
  • src/scripts/library.ts (2 hunks)
  • src/scripts/list.ts (1 hunks)
  • src/scripts/queue.ts (3 hunks)
  • src/scripts/theme.ts (1 hunks)
  • src/stylesheets/home.css (1 hunks)
  • src/stylesheets/upcoming.css (1 hunks)
  • vite.config.ts (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (8)
src/scripts/library.ts (2)
src/lib/utils.ts (1)
  • notify (84-96)
src/scripts/i18n.ts (1)
  • i18n (44-49)
src/modules/hls.ts (1)
src/lib/store.ts (1)
  • state (4-47)
src/scripts/audioEvents.ts (1)
src/lib/store.ts (2)
  • state (4-47)
  • store (64-158)
src/scripts/theme.ts (1)
src/lib/store.ts (2)
  • state (4-47)
  • store (64-158)
src/lib/utils.ts (1)
src/lib/store.ts (2)
  • state (4-47)
  • store (64-158)
src/components/Settings/app.ts (1)
src/lib/store.ts (2)
  • state (4-47)
  • setState (57-61)
src/lib/libraryUtils.ts (2)
src/lib/dom.ts (2)
  • listContainer (25-25)
  • listTitle (33-33)
src/lib/utils.ts (1)
  • hostResolver (26-30)
src/modules/setAudioStreams.ts (2)
src/lib/utils.ts (3)
  • preferredStream (57-81)
  • handleXtags (114-122)
  • proxyHandler (33-44)
src/lib/dom.ts (1)
  • qualityView (42-42)
🔇 Additional comments (57)
src/modules/supermix.ts (1)

2-2: LGTM: Consistent import refactoring.

The import path change for renderCollection aligns with the refactoring seen across other files where this function was moved to libraryUtils for better module organization.

src/scripts/list.ts (1)

2-2: LGTM: Import refactoring properly implemented.

The renderCollection import has been correctly moved from utils to libraryUtils, maintaining consistency with the broader refactoring effort while preserving existing functionality.

Also applies to: 5-5

src/scripts/library.ts (2)

6-6: LGTM: Added import for notification system.

Good addition of the notify function import to support the improved user feedback mechanism.


49-49:

Details

✅ Verification successful

Verify that UI reflects imported data without page reload.

Excellent UX improvement replacing the jarring location.reload() with a user-friendly notification. However, please ensure that the library UI components automatically update to reflect the newly imported data without requiring manual navigation or refresh.


🏁 Script executed:

#!/bin/bash
# Description: Check if library UI components have reactive updates after data changes
# Expected: Find event listeners or reactive patterns that update UI when library data changes

echo "Searching for library UI update patterns..."
rg -A 3 -B 3 "saveDB|getDB" --type ts
echo ""
echo "Searching for reactive library updates..."
ast-grep --pattern 'addEventListener($_, $_)'
echo ""
echo "Searching for library UI rendering triggers..."
rg -A 5 "renderCollection|library.*render" --type ts

Length of output: 23084


UI Auto-Update Confirmed
The final saveDB call in importLibrary emits a dbchange event, and key components subscribe to it to re-render immediately—no manual reload required.

• src/lib/libraryUtils.ts – saveDB dispatches dbchange
• src/components/SuperCollectionList.ts – listens for dbchange and re-renders the collection list
• src/modules/cloudSync.ts – updates the sync button on dbchange

src/modules/hls.ts (1)

12-13: LGTM! Correctly implements the quality refactoring.

The change from state.hq to state.quality === 'high' properly aligns with the multi-level quality system refactoring. The logic correctly selects the high-quality audio codec level when quality is set to 'high'.

package.json (2)

10-10: LGTM! HLS.js version update supports the feature changes.

The update from 1.6.4 to 1.6.5 aligns with the HLS functionality improvements in this PR.


15-17: LGTM! Routine dev dependency updates.

The minor version updates for development dependencies appear to be maintenance updates.

src/components/Settings/personalize.ts (1)

50-50: LGTM! Consistent property rename from customTheme to customColor.

All references to state.customTheme have been correctly updated to state.customColor while maintaining the same logic flow for custom color handling.

Also applies to: 54-54, 62-62

src/lib/dom.ts (1)

42-42: LGTM! Adds quality display element export.

The new qualityView export correctly references the quality display paragraph element, supporting the UI refactoring from dropdown selector to display-only quality indicator.

src/scripts/theme.ts (1)

112-112: LGTM: Property name updated to match state object.

The change correctly updates the reference from state.customTheme to state.customColor, aligning with the property rename in the state object. The logic and fallback behavior remain unchanged.

src/stylesheets/home.css (1)

111-116: LGTM: Selector rename and improved flex alignment.

The selector change from #playerSelectors to #playerFooter aligns with the DOM structure update, and adding align-items: center improves the flex container layout.

src/scripts/audioEvents.ts (1)

158-158: LGTM: Excellent optimization for conditional prefetching.

Making the prefetch behavior conditional on state.prefetch is a smart optimization that prevents unnecessary network requests when prefetching is disabled by the user. This respects user preferences and can improve performance and bandwidth usage.

src/modules/listUtils.ts (1)

70-70:

Details

✅ Verification successful

Verify server compatibility with payload structure change.

This change modifies the POST payload from sending the entire data object to sending only Object.values(data) as an array. This could be a breaking change if the server expects the full object structure with keys.

Please verify that the /blob endpoint can handle this new payload format.

Test the endpoint compatibility:


🏁 Script executed:

#!/bin/bash
# Description: Test if the /blob endpoint accepts the new payload format

# Test: Check if there are any API documentation or tests for the /blob endpoint
rg -A 10 -B 5 "/blob" --type ts --type js

# Look for any server-side implementation or documentation
fd -e md -e txt -e json | xargs rg -l "blob.*endpoint|/blob.*api"

Length of output: 3258


🏁 Script executed:

#!/bin/bash
# Display the contents of the Netlify Edge Function handling `/blob`
sed -n '1,200p' netlify/edge-functions/blobs.ts

Length of output: 1062


/blob endpoint accepts any JSON payload shape.

The Netlify Edge Function simply does const data = await req.json() and stores it via setJSON, without inspecting object keys, so posting an array is fully supported. No server-side changes are required.

src/locales/en.json (4)

44-44: LGTM: Improved clarity for search filter.

Changing "search_filter_date" to "Time" provides better user-friendly labeling for the date/time filter option.


63-63: LGTM: Added user feedback for library import.

The new "library_imported" message provides useful feedback to users when library import operations complete successfully.


76-77: LGTM: Added sorting options for improved accessibility.

The new sorting labels "list_sort_title" and "list_sort_author" enhance the sorting UI with clearer labeling.


110-111: LGTM: Updated audio settings labels to reflect new functionality.

The rename from "settings_hq_audio" to "settings_audio_quality" and addition of "settings_prefetch" correctly align with the multi-level quality selector and new prefetch feature.

src/components/SuperCollectionList.ts (3)

10-12: LGTM: Simplified state access pattern.

The refactoring eliminates the intermediate name variable and directly uses defaultSuperCollection from state, making the code more straightforward.


31-31: LGTM: Consistent local state update.

Directly updating the local defaultSuperCollection variable maintains consistency with the simplified state management approach.


37-37: LGTM: Direct state property usage.

Using defaultSuperCollection directly in the loadData call aligns with the overall simplification of state management.

src/components/Settings/playback.ts (2)

16-31: LGTM: Well-implemented quality selector.

The replacement of the HQ audio toggle with a multi-level quality selector (low/medium/high) provides users with more granular control over audio quality. The implementation correctly updates the quality state and includes proper type casting.


47-47: LGTM: Added proper type casting for codec preference.

The explicit type casting ensures type safety when updating the codec state with the selected value.

src/components/WatchVideo.ts (3)

5-5: LGTM: Added preferredStream utility import.

The import of preferredStream utility supports the new stream selection logic that replaces manual quality-based array manipulation.


195-197: LGTM: Improved stream selection with preferredStream utility.

The replacement of direct array access with preferredStream(handleXtags(audioArray)) provides better stream selection logic based on user preferences for quality and codec. This aligns well with the overall refactoring goals.


158-158:

Details

❓ Verification inconclusive

Verify the proxyHandler boolean parameter.

The proxyHandler calls now include a second true parameter. This change should be verified to ensure it aligns with the updated proxy handling behavior.

Also applies to: 174-174


🏁 Script executed:

#!/bin/bash
# Search for proxyHandler function definition to understand the second parameter
ast-grep --pattern 'function proxyHandler($_, $_) { $$$ }'
ast-grep --pattern 'const proxyHandler = ($_, $_) => { $$$ }'
ast-grep --pattern 'proxyHandler($_, $_)'

Length of output: 1186


Confirm prefetch flag usage in proxyHandler calls

We recently introduced a second prefetch: boolean parameter to proxyHandler (defaulting to false). In the WatchVideo component all calls are now passing true, which skips the “insert” title update:

• src/components/WatchVideo.ts:158
video.src = proxyHandler(_.target.value, true);
• src/components/WatchVideo.ts:174
video.src = proxyHandler(_.value, true);
• src/components/WatchVideo.ts:197
audio.src = proxyHandler(stream.url, true);

Please verify that bypassing the title update by setting prefetch to true is intentional for these cases.

src/lib/utils.ts (1)

1-1: LGTM! Import statement correctly updated.

The import statement has been properly updated to reflect the new dependencies needed for the preferredStream function.

index.html (4)

120-120: Good semantic improvement in container naming.

Renaming playerSelectors to playerFooter better describes the container's purpose and aligns with the removal of the bitrate selector UI.


136-136: Appropriate replacement of bitrate selector with quality display.

The change from an interactive <select> element to a display-only <p> element aligns with the new programmatic stream selection approach using the preferredStream function.


304-309: Excellent accessibility improvement with ARIA labels.

Adding data-translation-aria-label attributes for the sort buttons improves accessibility by providing proper labels for screen readers while maintaining the icon-only visual design.


149-149:

Details

✅ Verification successful

Verify the header removal doesn't impact functionality.

The removal of the <header> element from the upcoming section simplifies the UI structure. Ensure this doesn't break any functionality that might have depended on the header element.


🏁 Script executed:

#!/bin/bash
# Description: Check for any references to the upcoming section header that might be broken
# Expected: No references to upcoming header that would break functionality

# Search for references to upcoming header elements
rg -A 3 -B 3 "upcoming.*header|header.*upcoming" --type css --type ts --type js

Length of output: 81


🏁 Script executed:

#!/bin/bash
# Locate the index.html file
index_file=$(fd index.html)

echo "Found index.html at: $index_file"

# Show the context around the snippet (lines 130–180)
echo "=== Lines 130–180 of index.html ==="
sed -n '130,180p' "$index_file"

# Search for any references to "upcoming" in HTML, JS, or CSS
echo "=== Searching for 'upcoming' references ==="
rg -n "upcoming" -C3 --type html --type js --type css

# Search for any <header> tags in HTML to see where they were removed
echo "=== Searching for <header> tags in HTML ==="
rg -n "<header" -C2 --type html

Length of output: 5729


🏁 Script executed:

#!/bin/bash
# Locate the upcoming.css file
css_file=$(fd upcoming.css)

echo "Found upcoming.css at: $css_file"

# Show the first 200 lines of upcoming.css
echo "=== upcoming.css (1–200) ==="
sed -n '1,200p' "$css_file"

# Search for any CSS rules targeting a header within the upcoming section
echo "=== Checking for header selectors in upcoming.css ==="
rg -n "section#upcoming\s*header|#upcoming\s*>.*header|header.*#upcoming" -C2 "$css_file" || echo "No header-specific selectors found in upcoming.css"

Length of output: 1673


No issues found with <header> removal in the Upcoming section

All checks confirm that dropping the <header> from <section id="upcoming"> has no side-effects:

  • No CSS rules in src/stylesheets/upcoming.css target a header under #upcoming.
  • No JS/TS code refers to a header inside the Upcoming section.
  • The HTML navigation link (<a href="/upcoming">…</a>) remains intact and drives the same functionality.

You can safely merge this change.

src/stylesheets/upcoming.css (2)

6-21: Excellent responsive grid layout implementation.

The transition from a basic list to a CSS grid layout with responsive behavior significantly improves the UI:

  • Two-column layout by default, three columns in landscape orientation
  • Proper spacing with gap and padding
  • Visual enhancement with background color and rounded corners
  • Better width utilization (96% vs previous implicit width)

22-64: Well-designed interaction states and visual hierarchy.

The styling improvements for list items provide excellent UX:

  • Text truncation with ellipsis prevents layout breaks
  • Color-coded .on states for different queue tool buttons (purple, yellow, cyan, red, blue)
  • Subtle hover effects with dotted underlines
  • Proper spacing and visual hierarchy

The removal of the previous filter invert hover effect in favor of the more subtle underline is a good design decision.

src/components/Settings/app.ts (3)

64-65: Good simplification by removing unnecessary conditional check.

The removal of the conditional check for state.linkHost existence is appropriate since the state object always has this property initialized (even if empty string). This simplifies the code without losing functionality.


83-83: Good simplification by removing unnecessary conditional check.

Similar to the linkHost change, removing the conditional check for state.dlFormat is appropriate since the property is always initialized.


100-100: Good simplification by removing unnecessary conditional check.

Consistent with other changes, removing the conditional check simplifies the code appropriately.

src/scripts/queue.ts (3)

56-61: Improved separation of concerns for shuffle functionality.

The refactoring separates the shuffle state toggle (handled by the inner <i> element) from the actual shuffle operation (handled by the main button). This provides better UX by allowing users to toggle shuffle mode without immediately shuffling the queue.


190-191: Good defensive programming with explicit id validation.

Adding an explicit check for id existence and early return prevents potential runtime errors when processing queue items without valid identifiers.


199-212: Improved clarity in removal logic with conditional shuffle behavior.

The introduction of removeState boolean makes the code more readable and the conditional shuffle call (if (state.shuffle && !removeState)) ensures shuffling only occurs for playback actions, not deletions.

src/modules/setAudioStreams.ts (2)

1-3: Clean import refactoring aligns with new stream selection approach.

The import changes properly reflect the shift from manual bitrate selector manipulation to utility-based stream selection using preferredStream and handleXtags. The replacement of bitrateSelector with qualityView aligns with the UI changes mentioned in the AI summary.


27-29: Excellent simplification of stream selection logic.

The refactor successfully moves complex stream selection logic to utility functions, making this module much cleaner and more maintainable. The three-line implementation handles:

  1. Stream filtering and selection via handleXtags and preferredStream
  2. UI update with quality/codec display
  3. Audio source assignment with proper proxying

This is a significant improvement in code organization and separation of concerns.

src/modules/start.ts (5)

3-4: Good import cleanup removes unused dependencies.

Removing unused imports (proxyHandler, bitrateSelector, audio, render/html from uhtml) improves bundle size and code clarity. The remaining imports are all actively used in the module.


12-12: HLS addition to state destructuring is consistent with usage.

Adding HLS to the destructured state object properly exposes it for the conditional HLS handling below.


34-35: Simplified HLS module initialization.

The updated HLS handling is more direct - when HLS is enabled and not using legacy player, it imports and initializes the HLS module. This removes the previous bitrate selector manipulation that's no longer needed.


52-52: More specific shareAction condition improves type safety.

Changing from shareAction to shareAction === 'download' is more explicit and aligns with the stricter typing mentioned in the AI summary ('play' | 'watch' | 'download').


64-69: UI rendering responsibility shifted to static HTML.

Clearing searchlist.innerHTML before populating search results is good practice. The removal of fallback UI rendering logic suggests this responsibility has been moved to static HTML in index.html, which could improve initial page load performance.

src/locales/es.json (4)

69-73: Improved specificity in collection-related action labels.

The updates to explicitly mention "colección" in the action labels (list_delete, list_rename, list_share, list_radio, list_sort) provide better clarity for Spanish users about what these actions operate on.


86-90: Enhanced clarity in collection and action labels.

The changes to actions_menu_debug_info ("Ver detalles") and collection selector labels improve user understanding. The "Escúchar más tarde" correction (adding accent) is a proper Spanish spelling improvement.


95-97: Updated labels align with new PWA functionality.

The changes to "Enlaces de host" and "Acción para compartir a PWA" reflect the updated PWA share functionality mentioned in the AI summary, providing appropriate Spanish translations for these features.


168-169: New localization keys support expanded filtering and watch features.

The addition of upcoming_filter_ytm and settings_pwa_watch keys provides Spanish translations for new features, maintaining localization completeness as functionality expands.

src/lib/libraryUtils.ts (2)

1-1: Import changes look correct for the refactoring.

The updated imports properly bring in hostResolver (used in the new renderCollection function) and StreamItem component, while removing the old renderCollection import that was moved to this file.

Also applies to: 5-5


113-113: Improved display logic for shared collections.

The introduction of the display variable provides consistent labeling for shared collections, improving UX by showing "Shared Collection" instead of the raw ID. The implementation correctly handles both shared and regular collections.

Also applies to: 117-117, 147-147

src/lib/store.ts (6)

9-9: Good addition of prefetch control.

The new prefetch boolean provides users with control over queue prefetching behavior, which can help manage bandwidth usage.


11-11: Excellent upgrade from binary to granular quality control.

Replacing the simple hq boolean with a three-tier quality system ('low' | 'medium' | 'high') provides much better user control over audio quality and aligns with the PR's "Medium Quality Support" objective.


14-14: Improved type safety with string literal unions.

The addition of specific type constraints for dlFormat, shareAction, and codec properties enhances type safety and prevents invalid values. This is a good defensive programming practice.

Also applies to: 29-29, 32-32


72-72: Well-structured qualities array for HLS metadata.

The addition of the qualities array with proper typing for HLS stream metadata supports the enhanced quality selection system. The Record type ensures consistent structure for URL, bitrate, and codec information.

Also applies to: 107-107


157-157:

Details

✅ Verification successful

Verify dlFormat property mapping.

The store initialization now uses state.dlFormat instead of a previously used property. Ensure this mapping is correct and that dlFormat exists in the state object.


🏁 Script executed:

#!/bin/bash
# Verify that dlFormat is properly defined in the state object and used consistently
rg "dlFormat" --type ts --type js -A 2 -B 2

Length of output: 873


State.dlFormat property mapping verified

The state object declares dlFormat ('opus' as typeof store.downloadFormat), and it’s consistently referenced in the store init (downloadFormat: state.dlFormat) as well as in the Settings component handlers. No further action needed.


16-16:

Details

❓ Verification inconclusive

Property rename needs verification across codebase.

The rename from customTheme to customColor makes the property name more descriptive. However, ensure all references to customTheme throughout the codebase have been updated.


🏁 Script executed:

#!/bin/bash
# Search for any remaining references to the old customTheme property
rg -i "customtheme" --type ts --type js --type tsx --type jsx

Length of output: 89


🏁 Script executed:

#!/bin/bash
# Properly search all JS/TS files for remaining 'customTheme' references
rg -i "customTheme" --glob "*.[tj]s?(x)"

Length of output: 189


#!/bin/bash
# Search TS/JS(X) files excluding node_modules for any remaining 'customTheme' references
find . -path './node_modules' -prune -o -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' \) \
  -exec grep -Hn "customTheme" {} +

Verify Complete Rename of customTheme to customColor

I wasn’t able to conclusively confirm via automated search, so please ensure there are no lingering references to the old property name.

• Check the renamed property in src/lib/store.ts (line 16):

customColor: '',

• Run this command to catch any remaining usages:

find . -path './node_modules' -prune -o -type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.js' -o -name '*.jsx' \) \
  -exec grep -Hn "customTheme" {} +

Comment thread src/components/Settings/playback.ts
Comment thread src/components/Settings/app.ts Outdated
Comment thread src/components/Settings/app.ts Outdated
n-ce and others added 5 commits June 6, 2025 13:33
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@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: 0

🧹 Nitpick comments (1)
README.md (1)

12-12: Fix grammar for clarity in application description.

The phrase is missing a connector before “modern browser features.” Consider adding “using” and a comma to improve readability and flow:

- > [**ytify**](https://ytify.pp.ua) is the fastest and the lightest centralised audio streaming web application modern browser features to squeeze out maximum efficiency.
+ > [**ytify**](https://ytify.pp.ua) is the fastest and the lightest centralised audio streaming web application, using modern browser features to squeeze out maximum efficiency.
🧰 Tools
🪛 LanguageTool

[uncategorized] ~12-~12: Possible missing comma found.
Context: ...ightest centralised audio streaming web application modern browser features to squeeze out ...

(AI_HYDRA_LEO_MISSING_COMMA)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 61c4263 and d155008.

📒 Files selected for processing (5)
  • README.md (1 hunks)
  • src/components/Settings/app.ts (2 hunks)
  • src/components/Settings/playback.ts (2 hunks)
  • src/lib/store.ts (4 hunks)
  • vite.config.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • vite.config.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/components/Settings/app.ts
  • src/components/Settings/playback.ts
  • src/lib/store.ts
🧰 Additional context used
🪛 LanguageTool
README.md

[uncategorized] ~12-~12: Possible missing comma found.
Context: ...ightest centralised audio streaming web application modern browser features to squeeze out ...

(AI_HYDRA_LEO_MISSING_COMMA)

@n-ce n-ce merged commit 1ed2fc5 into main Jun 6, 2025
2 checks passed
@n-ce n-ce deleted the horizon branch June 6, 2025 09:23
@coderabbitai coderabbitai Bot mentioned this pull request Jun 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant