Skip to content

Conversation

@sozercan
Copy link
Owner

No description provided.

Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Signed-off-by: Sertac Ozercan <sozercan@gmail.com>
Copilot AI review requested due to automatic review settings December 28, 2025 07:07
@sozercan sozercan closed this Dec 28, 2025
@sozercan sozercan reopened this Dec 28, 2025
@sozercan sozercan merged commit a7f7cee into main Dec 28, 2025
8 of 12 checks passed
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds sharing functionality and URL scheme support to Kaset. Users can now share songs, playlists, albums, and artists via the native macOS share sheet, and open songs directly using the kaset:// URL scheme. The PR also removes the ErrorPresenter service and its documentation.

  • Implements native macOS sharing for all content types using NSSharingServicePicker
  • Adds custom URL scheme (kaset://) for opening songs from external sources
  • Removes ErrorPresenter service and documentation

Reviewed changes

Copilot reviewed 20 out of 20 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
Views/macOS/SharedViews/ShareContextMenu.swift New file providing context menu items for sharing content via NSSharingServicePicker
Core/Services/ShareService.swift Defines Shareable protocol and implements it for Song, Playlist, Album, and Artist with YouTube Music URL generation
Core/Services/URLHandler.swift Parses YouTube Music URLs and custom kaset:// scheme URLs to extract content identifiers
App/KasetApp.swift Integrates URL handling with .onOpenURL modifier to play songs from custom scheme
App/Info.plist Registers kaset:// custom URL scheme with the system
Tests/KasetTests/URLHandlerTests.swift Comprehensive test suite for URL parsing functionality
Tests/KasetTests/ShareableTests.swift Test suite for Shareable protocol implementations
Views/macOS/TopSongsView.swift Adds share context menu item for songs
Views/macOS/SearchView.swift Adds share context menu items for songs, albums, artists, and playlists
Views/macOS/QueueView.swift Adds share context menu item for songs in queue
Views/macOS/PlaylistDetailView.swift Adds share context menu item for playlist tracks
Views/macOS/LikedMusicView.swift Adds share context menu item for liked songs
Views/macOS/HomeView.swift Adds share context menu items for all home section items
Views/macOS/ArtistDetailView.swift Adds share context menu item for artist songs
Views/macOS/SharedViews/FavoritesSection.swift Adds share context menu item for favorite items
README.md Documents new sharing and URL scheme features
docs/architecture.md Removes ErrorPresenter documentation
Tests/KasetTests/SwiftTestingHelpers/Tags.swift Updates service tag documentation to remove ErrorPresenter reference
Core/Utilities/DiagnosticsLogger.swift Adds new logger for app lifecycle and URL handling events
Kaset.xcodeproj/project.pbxproj Updates Xcode project with new files and removes ErrorPresenter

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Divider()

FavoritesContextMenu.menuItem(for: album, manager: self.favoritesManager)

Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Missing Divider before ShareContextMenu. For consistency with other menu items in this file (see song and playlist cases), there should be a Divider separating the FavoritesContextMenu from the ShareContextMenu.

Suggested change
Divider()

Copilot uses AI. Check for mistakes.
Divider()

FavoritesContextMenu.menuItem(for: artist, manager: self.favoritesManager)

Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Missing Divider before ShareContextMenu. For consistency with other menu items in this file (see song and playlist cases), there should be a Divider separating the FavoritesContextMenu from the ShareContextMenu.

Suggested change
Divider()

Copilot uses AI. Check for mistakes.

FavoritesContextMenu.menuItem(for: album, manager: self.favoritesManager)

ShareContextMenu.menuItem(for: album)
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Missing Divider before ShareContextMenu. For consistency with other menu items in this view (see song and playlist cases), there should be a Divider separating the FavoritesContextMenu from the ShareContextMenu.

Copilot uses AI. Check for mistakes.

FavoritesContextMenu.menuItem(for: artist, manager: self.favoritesManager)

ShareContextMenu.menuItem(for: artist)
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Missing Divider before ShareContextMenu. For consistency with other menu items in this view (see song and playlist cases), there should be a Divider separating the FavoritesContextMenu from the ShareContextMenu.

Copilot uses AI. Check for mistakes.
guard let keyWindow = NSApp.keyWindow else { return }
let windowPoint = keyWindow.convertPoint(fromScreen: mouseLocation)
let rect = NSRect(origin: windowPoint, size: CGSize(width: 1, height: 1))
picker.show(relativeTo: rect, of: keyWindow.contentView!, preferredEdge: .minY)
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Forced unwrapping with the ! operator could cause a crash if contentView is nil. While this is unlikely in typical scenarios, it's better to use optional binding or a guard statement to handle this case safely, especially since the code already checks for window existence.

Copilot uses AI. Check for mistakes.
let windowPoint = window.convertPoint(fromScreen: mouseLocation)

// Find the view at this point, or use contentView as fallback
let targetView = window.contentView?.hitTest(windowPoint) ?? window.contentView!
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

Forced unwrapping with the ! operator could cause a crash if contentView is nil. Consider using optional binding or a guard statement with an early return to handle this case safely.

Copilot uses AI. Check for mistakes.
@sozercan sozercan deleted the share branch January 3, 2026 22:55
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.

2 participants