diff --git a/Nuage.xcodeproj/project.pbxproj b/Nuage.xcodeproj/project.pbxproj index 6d3cd71..299771a 100644 --- a/Nuage.xcodeproj/project.pbxproj +++ b/Nuage.xcodeproj/project.pbxproj @@ -53,7 +53,7 @@ 49978AF725AE3E8F00D5C30F /* SoundCloudIdentifiable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49978AF625AE3E8F00D5C30F /* SoundCloudIdentifiable.swift */; }; 4999998525B0844A00F42D9B /* Waveform.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999998425B0844A00F42D9B /* Waveform.swift */; }; 4999998D25B0886700F42D9B /* WaveformView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4999998C25B0886700F42D9B /* WaveformView.swift */; }; - 49C5229C258C238C00F2D18C /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 49C5229B258C238C00F2D18C /* SDWebImageSwiftUI */; }; + 49B154C525C4685D00CE9511 /* URLImage in Frameworks */ = {isa = PBXBuildFile; productRef = 49B154C425C4685D00CE9511 /* URLImage */; }; 49E1DB6C25B0BBF0009B1D41 /* ResourceRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E1DB6B25B0BBF0009B1D41 /* ResourceRequest.swift */; }; 49E6259D25BE1E7E005BEF8C /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49E6259C25BE1E7E005BEF8C /* WebView.swift */; }; 49FA14BB2589635800CEF925 /* ArrayView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49FA14BA2589635800CEF925 /* ArrayView.swift */; }; @@ -142,7 +142,7 @@ buildActionMask = 2147483647; files = ( 498286F825969AE800147DBE /* Introspect in Frameworks */, - 49C5229C258C238C00F2D18C /* SDWebImageSwiftUI in Frameworks */, + 49B154C525C4685D00CE9511 /* URLImage in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -356,8 +356,8 @@ ); name = Nuage; packageProductDependencies = ( - 49C5229B258C238C00F2D18C /* SDWebImageSwiftUI */, 498286F725969AE800147DBE /* Introspect */, + 49B154C425C4685D00CE9511 /* URLImage */, ); productName = Nuage; productReference = 4969F3C5257CFA7F0048E29B /* Nuage.app */; @@ -431,8 +431,8 @@ ); mainGroup = 4969F3BC257CFA7F0048E29B; packageReferences = ( - 49C5229A258C238C00F2D18C /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */, 498286F625969AE800147DBE /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */, + 49B154C325C4685D00CE9511 /* XCRemoteSwiftPackageReference "url-image" */, ); productRefGroup = 4969F3C6257CFA7F0048E29B /* Products */; projectDirPath = ""; @@ -847,12 +847,12 @@ minimumVersion = 0.1.2; }; }; - 49C5229A258C238C00F2D18C /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */ = { + 49B154C325C4685D00CE9511 /* XCRemoteSwiftPackageReference "url-image" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/SDWebImage/SDWebImageSwiftUI.git"; + repositoryURL = "https://github.com/dmytro-anokhin/url-image"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 1.5.0; + minimumVersion = 2.2.1; }; }; /* End XCRemoteSwiftPackageReference section */ @@ -863,10 +863,10 @@ package = 498286F625969AE800147DBE /* XCRemoteSwiftPackageReference "SwiftUI-Introspect" */; productName = Introspect; }; - 49C5229B258C238C00F2D18C /* SDWebImageSwiftUI */ = { + 49B154C425C4685D00CE9511 /* URLImage */ = { isa = XCSwiftPackageProductDependency; - package = 49C5229A258C238C00F2D18C /* XCRemoteSwiftPackageReference "SDWebImageSwiftUI" */; - productName = SDWebImageSwiftUI; + package = 49B154C325C4685D00CE9511 /* XCRemoteSwiftPackageReference "url-image" */; + productName = URLImage; }; /* End XCSwiftPackageProductDependency section */ }; diff --git a/Nuage/Audio/StreamPlayer.swift b/Nuage/Audio/StreamPlayer.swift index a42309a..0950004 100644 --- a/Nuage/Audio/StreamPlayer.swift +++ b/Nuage/Audio/StreamPlayer.swift @@ -10,7 +10,7 @@ import AppKit import AVFoundation import Combine import MediaPlayer -import SDWebImage +import URLImage protocol Streamable { @@ -151,13 +151,15 @@ class StreamPlayer: ObservableObject { MPNowPlayingInfoCenter.default().nowPlayingInfo = info if let artworkURL = self.currentStream?.artworkURL { - SDWebImageManager.shared.loadImage(with: artworkURL, options: .lowPriority, progress: nil) { (image, data, error, cacheType, finished, url) in - if let image = image { + URLImageService.shared.remoteImagePublisher(artworkURL) + .sink(receiveCompletion: { _ in }, + receiveValue: { imageInfo in + let image = NSImage(cgImage: imageInfo.cgImage, size: imageInfo.size) let artwork = MPMediaItemArtwork(boundsSize: image.size) { _ in return image } info[MPMediaItemPropertyArtwork] = artwork MPNowPlayingInfoCenter.default().nowPlayingInfo = info - } - } + }) + .store(in: &self.subscriptions) } }).store(in: &subscriptions) } diff --git a/Nuage/Externals.swift b/Nuage/Externals.swift index 22a89d4..e3c277d 100644 --- a/Nuage/Externals.swift +++ b/Nuage/Externals.swift @@ -9,6 +9,7 @@ import Foundation import SwiftUI import Combine +import URLImage struct FillableSysteImageStyle: ButtonStyle { @@ -172,3 +173,28 @@ extension User { } } + +func RemoteImage(url: URL?, width: CGFloat, height: CGFloat, cornerRadius: CGFloat) -> AnyView { + let placeholder = Rectangle() + .foregroundColor(.gray) + .frame(width: width, height: height) + .cornerRadius(cornerRadius) + + guard let url = url else { + return AnyView(placeholder) + } + + let image = URLImage(url: url, + empty: { placeholder }, + inProgress: { _ in placeholder }, + failure: { _, _ in placeholder }, + content: { image in + image.resizable() + .cornerRadius(cornerRadius) + }) + .frame(width: width, height: height) + + return AnyView(image) +} + + diff --git a/Nuage/Views/Lists/PostList.swift b/Nuage/Views/Lists/PostList.swift index b64212d..f07bd1b 100644 --- a/Nuage/Views/Lists/PostList.swift +++ b/Nuage/Views/Lists/PostList.swift @@ -7,7 +7,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct PostList: View { @@ -36,16 +35,13 @@ struct PostList: View { return AnyView(VStack(alignment: .leading) { HStack(spacing: 10) { StackNavigationLink(destination: UserView(user: post.user)) { - WebImage(url: post.user.avatarURL) - .resizable() - .frame(width: 30, height: 30) - .cornerRadius(15) + RemoteImage(url: post.user.avatarURL, width: 30, height: 30, cornerRadius: 15) Text("\(post.user.username) \(action)") } } Spacer() .frame(height: 18) - + if case let .track(track) = post.item { StackNavigationLink(destination: TrackView(track: track)) { TrackRow(track: track, onLike: toggleLikeCurrentTrack, onReblog: repostCurrentTrack) @@ -57,7 +53,7 @@ struct PostList: View { PlaylistRow(playlist: playlist, onLike: toggleLikeCurrentTrack, onReblog: repostCurrentTrack) .onTapGesture(count: 2, perform: onPlay) } - + Divider() }) } diff --git a/Nuage/Views/Lists/Rows/PlaylistRow.swift b/Nuage/Views/Lists/Rows/PlaylistRow.swift index 345fc49..b541d1e 100644 --- a/Nuage/Views/Lists/Rows/PlaylistRow.swift +++ b/Nuage/Views/Lists/Rows/PlaylistRow.swift @@ -6,7 +6,6 @@ // import SwiftUI -import SDWebImageSwiftUI struct PlaylistRow: View { @@ -25,11 +24,7 @@ struct PlaylistRow: View { return HStack(alignment: .top, spacing: 10) { VStack(alignment: .leading) { - WebImage(url: artworkURL) - .resizable() - .placeholder { Rectangle().foregroundColor(.gray) } - .frame(width: 100, height: 100) - .cornerRadius(6) + RemoteImage(url: artworkURL, width: 100, height: 100, cornerRadius: 6) Spacer() HStack { Button(action: onLike) { diff --git a/Nuage/Views/Lists/Rows/TrackRow.swift b/Nuage/Views/Lists/Rows/TrackRow.swift index 051bce5..5005649 100644 --- a/Nuage/Views/Lists/Rows/TrackRow.swift +++ b/Nuage/Views/Lists/Rows/TrackRow.swift @@ -6,7 +6,6 @@ // import SwiftUI -import SDWebImageSwiftUI struct TrackRow: View { @@ -25,11 +24,7 @@ struct TrackRow: View { HStack(alignment: .top, spacing: 10) { VStack(alignment: .leading) { - WebImage(url: track.artworkURL) - .resizable() - .placeholder { Rectangle().foregroundColor(.gray) } - .frame(width: 100, height: 100) - .cornerRadius(6) + RemoteImage(url: track.artworkURL, width: 100, height: 100, cornerRadius: 6) Spacer() HStack { Button(action: onLike) { diff --git a/Nuage/Views/Lists/SearchList.swift b/Nuage/Views/Lists/SearchList.swift index f5cc411..3300d13 100644 --- a/Nuage/Views/Lists/SearchList.swift +++ b/Nuage/Views/Lists/SearchList.swift @@ -7,7 +7,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct SearchList: View { diff --git a/Nuage/Views/Lists/TrackList.swift b/Nuage/Views/Lists/TrackList.swift index 9147d9e..ea75535 100644 --- a/Nuage/Views/Lists/TrackList.swift +++ b/Nuage/Views/Lists/TrackList.swift @@ -8,7 +8,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct TrackList: View { diff --git a/Nuage/Views/MainView.swift b/Nuage/Views/MainView.swift index 4fb1fab..9ada0c4 100644 --- a/Nuage/Views/MainView.swift +++ b/Nuage/Views/MainView.swift @@ -8,9 +8,9 @@ import SwiftUI import Combine -import SDWebImageSwiftUI -import Introspect import AppKit +import URLImage +import Introspect struct MainView: View { @@ -107,10 +107,7 @@ struct MainView: View { Text(SoundCloud.shared.user?.username ?? "Profile") .bold() .foregroundColor(.secondary) -// WebImage(url: SoundCloud.shared.user?.avatarURL) -// .resizable() -// .frame(width: 30, height: 30) -// .cornerRadius(15) + RemoteImage(url: SoundCloud.shared.user?.avatarURL, width: 30, height: 30, cornerRadius: 15) } } .buttonStyle(PlainButtonStyle()) diff --git a/Nuage/Views/PlayerView.swift b/Nuage/Views/PlayerView.swift index 979a943..ef836b5 100644 --- a/Nuage/Views/PlayerView.swift +++ b/Nuage/Views/PlayerView.swift @@ -7,7 +7,6 @@ // import SwiftUI -import SDWebImageSwiftUI struct PlayerView: View { @@ -19,10 +18,7 @@ struct PlayerView: View { return HStack { if let track = player.currentStream { StackNavigationLink(destination: TrackView(track: track)) { - WebImage(url: player.currentStream?.artworkURL) - .resizable() - .frame(width: 50, height: 50) - .cornerRadius(/*@START_MENU_TOKEN@*/3.0/*@END_MENU_TOKEN@*/) + RemoteImage(url: player.currentStream?.artworkURL, width: 50, height: 50, cornerRadius: 3) VStack { Text(player.currentStream?.title ?? "") .frame(maxWidth: 100, alignment: .leading) diff --git a/Nuage/Views/ProfileView.swift b/Nuage/Views/ProfileView.swift index 271b23a..34a09b6 100644 --- a/Nuage/Views/ProfileView.swift +++ b/Nuage/Views/ProfileView.swift @@ -7,7 +7,6 @@ // import SwiftUI -import SDWebImageSwiftUI struct ProfileView: View { @@ -15,9 +14,7 @@ struct ProfileView: View { var body: some View { HStack { - WebImage(url: user.avatarURL) - .frame(width: 100, height: 100) - .cornerRadius(50) + RemoteImage(url: user.avatarURL, width: 100, height: 100, cornerRadius: 50) Text(user.username) } .frame(minWidth: 200) diff --git a/Nuage/Views/TrackView.swift b/Nuage/Views/TrackView.swift index 679f84c..f8eac6c 100644 --- a/Nuage/Views/TrackView.swift +++ b/Nuage/Views/TrackView.swift @@ -8,7 +8,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct TrackView: View { @@ -23,11 +22,7 @@ struct TrackView: View { VStack(alignment: .leading) { HStack(alignment: .bottom, spacing: 10) { VStack(alignment: .leading) { - WebImage(url: track.artworkURL) - .resizable() - .placeholder { Rectangle().foregroundColor(.gray) } - .frame(width: 100, height: 100) - .cornerRadius(6) + RemoteImage(url: track.artworkURL, width: 100, height: 100, cornerRadius: 6) } if let waveform = waveform { WaveformView(waveform: waveform) diff --git a/Nuage/Views/UserList.swift b/Nuage/Views/UserList.swift index fda5059..9396e42 100644 --- a/Nuage/Views/UserList.swift +++ b/Nuage/Views/UserList.swift @@ -8,7 +8,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct UserList: View { @@ -40,9 +39,7 @@ struct UserRow: View { var body: some View { HStack { - WebImage(url: user.avatarURL) - .frame(width: 50, height: 50) - .cornerRadius(25) + RemoteImage(url: user.avatarURL, width: 50, height: 50, cornerRadius: 25) VStack(alignment: .leading) { Text(user.username) .bold() diff --git a/Nuage/Views/UserView.swift b/Nuage/Views/UserView.swift index 8067b1a..add4745 100644 --- a/Nuage/Views/UserView.swift +++ b/Nuage/Views/UserView.swift @@ -7,7 +7,6 @@ import SwiftUI import Combine -import SDWebImageSwiftUI struct UserView: View { @@ -18,10 +17,7 @@ struct UserView: View { var body: some View { VStack { HStack { - WebImage(url: user.avatarURL) - .resizable() - .frame(width: 50, height: 50) - .cornerRadius(25) + RemoteImage(url: user.avatarURL, width: 50, height: 50, cornerRadius: 25) VStack(alignment: .leading) { Text(user.username) .bold()