Skip to content

feat(medium): Optimize Spotify Track Selection UI for High Density#9547

Open
arii wants to merge 4 commits into
leaderfrom
ui-ux-spotify-track-selection-optimization-14059094504088146715
Open

feat(medium): Optimize Spotify Track Selection UI for High Density#9547
arii wants to merge 4 commits into
leaderfrom
ui-ux-spotify-track-selection-optimization-14059094504088146715

Conversation

@arii
Copy link
Copy Markdown
Owner

@arii arii commented Mar 16, 2026

Description

This PR optimizes the Spotify track selection UI for better information density and visual clarity on mobile devices.

Fixes #9309

Change Type: ✨ New feature (non-breaking change adding functionality)

Related Issues

Closes #9309

Changes Made

  • High-Density Layout: Replaced the bulky table in PlaylistTracksDisplay and the loose list in PlaylistDetails with ultra-compact Material-UI lists (dense, py: 0.5).
  • Album Thumbnails: Added rounded album art thumbnails to each track using ListItemAvatar.
  • Metadata Mapping: Enhanced the Spotify tracks API route to include full album objects, fixing the "Unknown Album" bug.
  • Consistent Typography: Standardized metadata display using body2 and caption variants with a bullet point separator.
  • Accessibility: Ensured interactive targets maintain a minimum 40px height for WCAG 2.1 compliance.

Testing

Successfully ran unit tests and verified the visual changes with Playwright screenshots.

Original PR Body

This PR optimizes the Spotify track selection UI for better information density and visual clarity on mobile devices.

Key Changes:

  • High-Density Layout: Replaced the bulky table in PlaylistTracksDisplay and the loose list in PlaylistDetails with ultra-compact Material-UI lists (dense, py: 0.5).
  • Album Thumbnails: Added rounded album art thumbnails to each track using ListItemAvatar.
  • Metadata Mapping: Enhanced the Spotify tracks API route to include full album objects, fixing the "Unknown Album" bug.
  • Consistent Typography: Standardized metadata display using body2 and caption variants with a bullet point separator.
  • Accessibility: Ensured interactive targets maintain a minimum 40px height for WCAG 2.1 compliance.
  • Verification: Successfully ran unit tests and verified the visual changes with Playwright screenshots.

Fixes #9309


PR created automatically by Jules for task 14059094504088146715 started by @arii

@google-labs-jules
Copy link
Copy Markdown
Contributor

👋 Jules, reporting for duty! I'm here to lend a hand with this pull request.

When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down.

I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job!

For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with @jules. You can find this option in the Pull Request section of your global Jules UI settings. You can always switch back!

New to Jules? Learn more at jules.google/docs.


For security, I will only act on instructions from the user who triggered this task.

@github-actions
Copy link
Copy Markdown
Contributor

👋 Welcome to HRM!

Thanks for your contribution. This repository uses Gemini AI for automated triage, code review, and generation.

🤖 Gemini Manual Trigger Quick Reference

Command Action
@gemini-bot Run AI Code Review (PR only)
@gemini-triage Run Issue Triage
@gemini-coder <task> Generate Code
@create-review-issues Create issues from review (PR only)
@gemini-help Show this help message
@pr-squash Squash PR commits (PR only)
@conflict-resolve Resolve merge conflicts (PR only)

For more details and GitHub CLI examples, see the Manual Trigger Guide.

@github-actions github-actions Bot changed the title Optimize Spotify Track Selection UI for High Density feat(medium): Optimize Spotify Track Selection UI for High Density Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

ℹ️ Gemini Review Disabled

Automatic review is currently disabled via GEMINI_ENABLE_PR_REVIEW. To run review manually:

Via Comment:

@gemini-bot

Via GitHub Actions:

  1. Go to Actions → Reusable Gemini Review
  2. Click "Run workflow"
  3. Enter PR number: 9547

Via GitHub CLI:

gh workflow run reusable-gemini-review.yml -f pr_number=9547

🤖 Manual Trigger Quick Reference

Command Action
@gemini-bot Run AI Code Review (PR only)
@gemini-triage Run Issue Triage
@gemini-coder <task> Generate Code
@create-review-issues Create issues from review (PR only)
@gemini-help Show this help message

Full reference: Manual Trigger Guide

To re-enable: Set repository variable GEMINI_ENABLE_PR_REVIEW=true

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Manual Trigger Quick Reference

Command Action
@gemini-bot Run AI Code Review (PR only)
@gemini-triage Run Issue Triage
@gemini-coder <task> Generate Code
@create-review-issues Create issues from review (PR only)
@gemini-help Show this help message

Manual Trigger Guide

@arii arii added the not reviewed The review could not be performed or completed successfully. label Mar 16, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Manual Trigger Quick Reference

Command Action
@gemini-bot Run AI Code Review (PR only)
@gemini-triage Run Issue Triage
@gemini-coder <task> Generate Code
@create-review-issues Create issues from review (PR only)
@gemini-help Show this help message

Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 17, 2026
@arii arii marked this pull request as ready for review March 17, 2026 08:00
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 17, 2026
@arii
Copy link
Copy Markdown
Owner Author

arii commented Mar 17, 2026

🤖 AI Technical Audit

PR Review: Spotify Track Selection UI Optimization

Architectural Impact

This PR shifts the data contract between the Spotify API route and the UI, moving from flattened properties (e.g., albumArt) to nested objects. While this improves data richness, it introduces inconsistencies across the codebase where different components now expect different shapes for the same domain entity. The build failures in the GitHub checks are likely due to the mismatch between these new types and existing component props.

Anti-AI-Slop

  1. STALE FEATURES: The PR description mentions replacing the "bulky table" and "loose list," but PlaylistDetails.tsx contains a massive block of duplicated code where the new List is appended before the old List rather than replacing it.
  2. CODE RATIO: This PR adds approximately 120 lines but fails to remove the deprecated logic in PlaylistDetails.tsx. Removing the old tracks.map loop and merging redundant metadata mapping logic would save ~40 lines.
  3. OVER-ENGINEERING: Adding duration_ms alongside duration in the API response creates data redundancy. We should stick to one naming convention.
  4. DUPLICATE HOOKS/TYPES: The Track interface in PlaylistTracksDisplay.tsx is redefined locally instead of extending SpotifyPlaylistItem from @/types/core, leading to the type check failures seen in the logs.

File-by-File Analysis

app/api/spotify/playlists/[playlistId]/tracks/route.ts

  • Problem: Redundant duration fields. Both duration and duration_ms are sent in the payload.
  • Implementation Sample:
// Remove duration, use duration_ms consistently across the app
return {
  id: track.id,
  name: track.name,
  artists: track.artists.map((a) => a.name).join(', '),
  album: {
    name: track.album.name,
    images: track.album.images,
  },
  duration_ms: track.duration_ms,
  uri: track.uri,
};

components/Playlist/PlaylistTracksDisplay.tsx

  • Problem: Use of track.album?.images?.[2]?.url is brittle. If an album has only 1 image, this will be undefined. Also, the local Track interface is causing Build/Type Check failures.
  • Implementation Sample:
// Use a fallback for images safely
const albumThumbnail = track.album?.images?.slice(-1)[0]?.url || ''; 

components/Spotify/PlaylistDetails.tsx

  • Problem: Critical Error. The new list UI is pasted inside the InfiniteScroll component above the old list UI. The old list UI is not removed, resulting in duplicated content and broken layout.
  • Problem: artistNames logic is duplicated from the API route. The UI should trust the API's formatted string or the API should only send the array.

GitHub Checks Correlation

  • Lint Check Failure: Likely caused by unused imports (e.g., MusicNote vs MusicNoteIcon) and the duplicated mapping logic in PlaylistDetails.tsx.
  • Type Check Failure: The Track interface in PlaylistTracksDisplay does not match the updated SpotifyPlaylistItem in types/core.ts.
  • Build Check Failure: Directly resulting from the TypeScript errors mentioned above.

Review automatically published via RepoAuditor.

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 18, 2026
@arii
Copy link
Copy Markdown
Owner Author

arii commented Mar 18, 2026

🤖 AI Technical Audit

Code Review - PR #9547

Architectural Impact

This PR transitions the Spotify track selection from a heavy Table-based layout to a high-density List-based architecture. This significantly improves mobile UX but introduces several breaking changes in internal data contracts (e.g., changing duration to duration_ms and moving from index-based playback to URI-based playback). While these changes align better with the Spotify API, they have caused build failures in the type-checking and linting stages.

Anti-AI-Slop Directives

  1. OVERLY VERBOSE COMMENTS: The comment // components/Spotify/PlaylistDetails.tsx in PlaylistDetails.tsx was correctly removed.
  2. OVER-ENGINEERING: The getArtistNames helper in lib/spotify.ts handles three different types of artist inputs. This complexity stems from inconsistent typing in SpotifyPlaylistItem. Standardizing the type would be better than adding defensive logic.
  3. DUPLICATE HOOKS/TYPES: The SpotifyPlaylistItem interface in types/core.ts now contains redundant fields: imageUrl (old) vs album.images (new).
  4. CODE RATIO: Found ~15 lines of redundant code in PlaylistTracksDisplay.tsx and types/core.ts. Specifically, the duplicate Play/Pause logic within both the TrackListItem and its parent container.
  5. STALE FEATURES: Verified that the Material-UI Table components were removed in favor of List in PlaylistTracksDisplay.tsx.

File-by-File Analysis

1. app/api/spotify/playlists/[playlistId]/tracks/route.ts

Problem: Changed field name from duration to duration_ms. This is a breaking change for any consumer not updated in this PR.
Implementation Sample:

// Recommendation: Keep both temporarily or ensure all consumers are migrated.
return {
  // ...
  duration_ms: track.duration_ms,
  duration: track.duration_ms // Alias for backward compatibility
}

2. components/Playlist/PlaylistTracksDisplay.tsx

Problem: Logic duplication. The TrackListItem is passed an onClick that handles play/pause, but the secondaryAction also contains a Play/Pause IconButton with its own logic. This creates a confusing UI where two different elements do the same thing but are managed separately.
Implementation Sample:

// Simplify by removing the IconButton from secondaryAction if the whole row is clickable
secondaryAction={
  <Typography variant="caption">
    {formatDuration(track.duration_ms)}
  </Typography>
}

3. utils/socketManager.ts

Problem: Use of as any cast. This explains the Type Check failure in CI.
Implementation Sample:

// Instead of as any, use proper type guarding or cast to the specific interface
if (commandMsg.offset) {
  spotifyCommandParams.offset = commandMsg.offset as SpotifyCommandParameters['offset'];
}

GitHub Checks Correlation

  • Type Check Failure: Caused by the property name change duration -> duration_ms in PlaylistTracksDisplay and the as any cast in socketManager.ts.
  • Lint Check Failure: Likely due to the unused MusicNoteIcon or improper import ordering in TrackListItem.tsx.

Review automatically published via RepoAuditor.

arii added a commit that referenced this pull request Mar 18, 2026
- Keep `duration` field alongside `duration_ms` for backward compatibility in API responses and types.
- Standardize `SpotifyPlaylistItem` type by simplifying `artists` to a `string` and removing redundant `imageUrl`.
- Remove redundant Play/Pause `IconButton` in `PlaylistTracksDisplay` and handle clicks on the row directly.
- Migrate index-based playback to URI-based playback in `PlaylistTracksDisplay`.
- Fix TypeScript error in `socketManager.ts` by replacing `as any` cast.
- Resolve unused imports linting issues.
- Update related unit tests to match architecture changes.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
arii added a commit that referenced this pull request Mar 19, 2026
- Fix `TypeError` regarding `offset: { uri }` in `PlaylistTracksDisplay` and `spotify-selection/page.tsx` by updating `useSpotifyCommand` payload type to accept either `position` or `uri`.
- Fix `SpotifyCommandParameters` TS error in `socketManager.ts` by explicitly importing `SpotifyCommandParameters`.

Co-authored-by: arii <342438+arii@users.noreply.github.com>
arii added a commit that referenced this pull request Mar 19, 2026
…9547) (#9585)

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
@arii arii added the not reviewed The review could not be performed or completed successfully. label Mar 20, 2026
@arii
Copy link
Copy Markdown
Owner Author

arii commented Mar 23, 2026

🤖 AI Technical Audit

PR Review: Spotify Track Selection UI Optimization

Summary

This PR introduces a high-density track listing UI using MUI's dense list components and standardizes the track item into a reusable TrackListItem component. It also fixes a bug regarding missing album metadata and improves the playback logic to use track URIs instead of indices.

Anti-AI-Slop Section

  1. OVERLY VERBOSE COMMENTS: Removed the legacy file path comment in PlaylistTracksDisplay.tsx (Line 1).
  2. OVER-ENGINEERING: The getArtistNames utility in lib/spotify.ts is defensive but slightly redundant given that the API route now standardizes artists into a string. However, keeping it for type-safety across different call sites.
  3. DUPLICATE HOOKS/TYPES: The SpotifyPlaylistItem interface in types/core.ts was updated, but SpotifyCommandParameters and SpotifyCommandMessage were updated separately. These should ideally share the offset definition to prevent drift.
  4. CODE RATIO:
    • Deleted ~45 lines in PlaylistTracksDisplay.tsx by removing the manual Table implementation and pagination logic.
    • Removed 15+ lines of redundant test code in PlaylistDetails.test.tsx.
    • Potential Deletion: The limit and total state variables in PlaylistTracksDisplay are now unused since pagination was removed in favor of a flat list (Line 24-26). They should be deleted.
  5. STALE FEATURES: The PR successfully deleted the old Table-based layout in favor of the List-based layout.

File-by-File Analysis

app/api/spotify/playlists/[playlistId]/tracks/route.ts

  • Problem: Changing duration to duration_ms is a breaking change for any client not updated in this PR.
  • Implementation Sample:
    // Maintain backward compatibility if needed, or ensure all consumers are updated.
    return {
      // ...
      duration_ms: track.duration_ms, // New
      duration: track.duration_ms,    // Legacy fallback
    }

components/Playlist/PlaylistTracksDisplay.tsx

  • Problem: The pagination logic was removed (fetchTracks now hardcodes limit=50), but the offset and total states remain in the component, causing unnecessary re-renders.
  • Implementation Sample:
    // DELETE these lines
    const [offset, setOffset] = useState(0)
    const [total, setTotal] = useState(0)

components/Spotify/TrackListItem.tsx

  • Problem: The Avatar component uses a string URL directly. If the URL is empty, it falls back to the icon, but it lacks an alt attribute for accessibility.
  • Implementation Sample:
    <Avatar
      variant="rounded"
      src={albumThumbnail}
      alt={track.name} // Added for A11y
      sx={{ width: 32, height: 32 }}
    >

Architectural Impact

Moving from index-based playback (offset: { position: index }) to URI-based playback (offset: { uri }) is a significant improvement. Index-based playback is fragile when lists are filtered or reordered. Standardizing the UI into TrackListItem reduces maintenance overhead for future Spotify-related views.

Review automatically published via RepoAuditor.

@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 23, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 26, 2026
@arii
Copy link
Copy Markdown
Owner Author

arii commented Mar 26, 2026

@pr-squash

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 26, 2026

🤖 Command Operation Status

Squash: Failed


Triggered by: @arii via comment

## Description

This PR optimizes the Spotify track selection UI for better information density and visual clarity on mobile devices.

Fixes #9309

## Change Type: ✨ New feature (non-breaking change adding functionality)

## Related Issues

Closes #9309

## Changes Made

- **High-Density Layout:** Replaced the bulky table in `PlaylistTracksDisplay` and the loose list in `PlaylistDetails` with ultra-compact Material-UI lists (`dense`, `py: 0.5`).
- **Album Thumbnails:** Added rounded album art thumbnails to each track using `ListItemAvatar`.
- **Metadata Mapping:** Enhanced the Spotify tracks API route to include full album objects, fixing the "Unknown Album" bug.
- **Consistent Typography:** Standardized metadata display using `body2` and `caption` variants with a bullet point separator.
- **Accessibility:** Ensured interactive targets maintain a minimum 40px height for WCAG 2.1 compliance.

## Testing

Successfully ran unit tests and verified the visual changes with Playwright screenshots.

<details>
<summary>Original PR Body</summary>

This PR optimizes the Spotify track selection UI for better information density and visual clarity on mobile devices.

### Key Changes:
- **High-Density Layout:** Replaced the bulky table in `PlaylistTracksDisplay` and the loose list in `PlaylistDetails` with ultra-compact Material-UI lists (`dense`, `py: 0.5`).
- **Album Thumbnails:** Added rounded album art thumbnails to each track using `ListItemAvatar`.
- **Metadata Mapping:** Enhanced the Spotify tracks API route to include full album objects, fixing the "Unknown Album" bug.
- **Consistent Typography:** Standardized metadata display using `body2` and `caption` variants with a bullet point separator.
- **Accessibility:** Ensured interactive targets maintain a minimum 40px height for WCAG 2.1 compliance.
- **Verification:** Successfully ran unit tests and verified the visual changes with Playwright screenshots.

Fixes #9309

---
*PR created automatically by Jules for task [14059094504088146715](https://jules.google.com/task/14059094504088146715) started by @arii*
</details>
@github-actions
Copy link
Copy Markdown
Contributor

✅ Commits squashed successfully!

🤖 Gemini Manual Trigger Guide

@arii arii force-pushed the ui-ux-spotify-track-selection-optimization-14059094504088146715 branch from 1ec258d to 7e498e7 Compare March 26, 2026 03:27
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 26, 2026
@arii
Copy link
Copy Markdown
Owner Author

arii commented Mar 26, 2026

@Gemini-bot

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Mar 26, 2026

🤖 Command Operation Status

Review: Failed


Triggered by: @arii via comment

Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com>
Co-authored-by: arii <342438+arii@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🤖 Gemini Review Skipped

Review was skipped for the following reason: Gemini review is globally disabled

🤖 Gemini Manual Trigger Guide

@arii arii added not reviewed The review could not be performed or completed successfully. and removed not reviewed The review could not be performed or completed successfully. labels Mar 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

UI/UX: Optimize Spotify Track Selection for High Density and Visual Clarity

1 participant