Fix music art in lists and system now playing

This commit is contained in:
Ilya Laktyushin
2023-01-07 22:14:03 +04:00
parent 5e28da23bc
commit 45ecce6770
4 changed files with 30 additions and 132 deletions

View File

@@ -1193,6 +1193,10 @@ public final class ListMessageFileItemNode: ListMessageNode {
let _ = extensionTextApply()
strongSelf.currentIconImage = iconImage
if let updateIconImageSignal, let iconImage, case .albumArt = iconImage {
strongSelf.iconStatusNode.setBackgroundImage(updateIconImageSignal)
}
if let iconImageApply = iconImageApply {
if let updateImageSignal = updateIconImageSignal {

View File

@@ -60,103 +60,4 @@ public class ExternalMusicAlbumArtResource: Equatable {
public func fetchExternalMusicAlbumArtResource(engine: TelegramEngine, file: FileMediaReference?, resource: ExternalMusicAlbumArtResource) -> Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error> {
return engine.resources.fetchAlbumCover(file: file, title: resource.title, performer: resource.performer, isThumbnail: resource.isThumbnail)
/*return Signal { subscriber in
if resource.performer.isEmpty || resource.performer.lowercased().trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) == "unknown artist" || resource.title.isEmpty {
subscriber.putError(.generic)
return EmptyDisposable
} else {
let excludeWords: [String] = [
" vs. ",
" vs ",
" versus ",
" ft. ",
" ft ",
" featuring ",
" feat. ",
" feat ",
" presents ",
" pres. ",
" pres ",
" and ",
" & ",
" . "
]
var performer = resource.performer
for word in excludeWords {
performer = performer.replacingOccurrences(of: word, with: " ")
}
let metaUrl = "https://itunes.apple.com/search?term=\(urlEncodedStringFromString("\(performer) \(resource.title)"))&entity=song&limit=4"
let title = resource.title.lowercased()
let isMix = title.contains("remix") || title.contains("mixed")
let fetchDisposable = MetaDisposable()
let disposable = fetchHttpResource(url: metaUrl).start(next: { result in
if case let .dataPart(_, data, _, complete) = result, complete {
guard let dict = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {
subscriber.putError(.generic)
return
}
guard let results = dict["results"] as? [Any] else {
subscriber.putError(.generic)
return
}
var matchingResult: Any?
for result in results {
if let result = result as? [String: Any] {
let title = ((result["trackCensoredName"] as? String) ?? (result["trackName"] as? String))?.lowercased() ?? ""
let resultIsMix = title.contains("remix") || title.contains("mixed")
if isMix == resultIsMix {
matchingResult = result
break
}
}
}
if matchingResult == nil {
matchingResult = results.first
}
guard let result = matchingResult as? [String: Any] else {
subscriber.putError(.generic)
return
}
guard var artworkUrl = result["artworkUrl100"] as? String else {
subscriber.putError(.generic)
return
}
if !resource.isThumbnail {
artworkUrl = artworkUrl.replacingOccurrences(of: "100x100", with: "600x600")
}
if artworkUrl.isEmpty {
subscriber.putError(.generic)
return
} else {
fetchDisposable.set(engine.resources.httpData(url: artworkUrl).start(next: { next in
let file = EngineTempBox.shared.tempFile(fileName: "image.jpg")
let _ = try? next.write(to: URL(fileURLWithPath: file.path))
subscriber.putNext(.moveTempFile(file: file))
}, completed: {
subscriber.putCompletion()
}))
}
}
})
return ActionDisposable {
disposable.dispose()
fetchDisposable.dispose()
}
}
}*/
}

View File

@@ -857,6 +857,25 @@ public final class SemanticStatusNode: ASControlNode {
self.setNeedsDisplay()
}
}
public func setBackgroundImage(_ image: Signal<(TransformImageArguments) -> DrawingContext?, NoError>) {
let start = CACurrentMediaTime()
self.disposable = combineLatest(queue: Queue.mainQueue(), image, self.hasLayoutPromise.get()).start(next: { [weak self] transform, ready in
guard let strongSelf = self, ready else {
return
}
let context = transform(TransformImageArguments(corners: ImageCorners(radius: strongSelf.bounds.width / 2.0), imageSize: strongSelf.bounds.size, boundingSize: strongSelf.bounds.size, intrinsicInsets: UIEdgeInsets()))
let previousAppearanceContext = strongSelf.appearanceContext
strongSelf.appearanceContext = strongSelf.appearanceContext.withUpdatedBackgroundImage(context?.generateImage())
if CACurrentMediaTime() - start > 0.3 {
strongSelf.transitionContext = SemanticStatusNodeTransitionContext(startTime: CACurrentMediaTime(), duration: 0.18, previousStateContext: nil, previousAppearanceContext: previousAppearanceContext, completion: {})
strongSelf.updateAnimations()
}
strongSelf.setNeedsDisplay()
})
}
private var animator: ConstantDisplayLinkAnimator?
@@ -889,23 +908,8 @@ public final class SemanticStatusNode: ASControlNode {
self.isOpaque = false
self.displaysAsynchronously = true
if let image = image {
let start = CACurrentMediaTime()
self.disposable = combineLatest(queue: Queue.mainQueue(), image, self.hasLayoutPromise.get()).start(next: { [weak self] transform, ready in
guard let strongSelf = self, ready else {
return
}
let context = transform(TransformImageArguments(corners: ImageCorners(radius: strongSelf.bounds.width / 2.0), imageSize: strongSelf.bounds.size, boundingSize: strongSelf.bounds.size, intrinsicInsets: UIEdgeInsets()))
let previousAppearanceContext = strongSelf.appearanceContext
strongSelf.appearanceContext = strongSelf.appearanceContext.withUpdatedBackgroundImage(context?.generateImage())
if CACurrentMediaTime() - start > 0.3 {
strongSelf.transitionContext = SemanticStatusNodeTransitionContext(startTime: CACurrentMediaTime(), duration: 0.18, previousStateContext: nil, previousAppearanceContext: previousAppearanceContext, completion: {})
strongSelf.updateAnimations()
}
strongSelf.setNeedsDisplay()
})
if let image {
self.setBackgroundImage(image)
}
}

View File

@@ -2,6 +2,7 @@ import Foundation
import SwiftSignalKit
import AVFoundation
import MobileCoreServices
import Display
import Postbox
import TelegramCore
import MediaPlayer
@@ -325,23 +326,11 @@ public final class MediaManagerImpl: NSObject, MediaManager {
|> distinctUntilChanged(isEqual: { $0?.0 === $1?.0 && $0?.1 == $1?.1 })
|> mapToSignal { value -> Signal<UIImage?, NoError> in
if let (account, value) = value {
return albumArtThumbnailData(engine: TelegramEngine(account: account), thumbnail: value.fullSizeResource)
|> map { data -> UIImage? in
return data.flatMap(UIImage.init(data:))
return playerAlbumArt(postbox: account.postbox, engine: TelegramEngine(account: account), fileReference: value.fullSizeResource.file, albumArt: value, thumbnail: false)
|> map { generator -> UIImage? in
let arguments = TransformImageArguments(corners: ImageCorners(), imageSize: CGSize(width: 640, height: 640), boundingSize: CGSize(width: 640, height: 640), intrinsicInsets: .zero)
return generator(arguments)?.generateImage()
}
/*return Signal { subscriber in
let fetched = account.postbox.mediaBox.fetchedResource(value.fullSizeResource, parameters: nil).start()
let data = account.postbox.mediaBox.resourceData(value.fullSizeResource, pathExtension: nil, option: .complete(waitUntilFetchStatus: false)).start(next: { data in
if data.complete, let value = try? Data(contentsOf: URL(fileURLWithPath: data.path)) {
subscriber.putNext(UIImage(data: value))
subscriber.putCompletion()
}
})
return ActionDisposable {
fetched.dispose()
data.dispose()
}
}*/
} else {
return .single(nil)
}