Emoji improvents

This commit is contained in:
Ali 2022-08-02 21:40:15 +04:00
parent 489c410aca
commit cd6d2a3b9d
15 changed files with 260 additions and 29 deletions

View File

@ -91,7 +91,7 @@ final class InstantPageMediaPlaylistItem: SharedMediaPlaylistItem {
if file.fileName?.lowercased().hasSuffix(".ogg") == true {
albumArt = nil
} else {
albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .standalone(media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .standalone(media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
}
return SharedMediaPlaybackDisplayData.music(title: updatedTitle, performer: updatedPerformer, albumArt: albumArt, long: false)

View File

@ -473,9 +473,9 @@ public final class ListMessageFileItemNode: ListMessageNode {
if !voice {
if file.fileName?.lowercased().hasSuffix(".ogg") == true {
iconImage = .albumArt(file, SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(title: "", performer: "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(title: "", performer: "", isThumbnail: false)))
iconImage = .albumArt(file, SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: "", performer: "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: "", performer: "", isThumbnail: false)))
} else {
iconImage = .albumArt(file, SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(title: title ?? "", performer: performer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(title: title ?? "", performer: performer ?? "", isThumbnail: false)))
iconImage = .albumArt(file, SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: title ?? "", performer: performer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: title ?? "", performer: performer ?? "", isThumbnail: false)))
}
} else {
titleText = NSAttributedString(string: " ", font: audioTitleFont, textColor: item.presentationData.theme.theme.list.itemPrimaryTextColor)

View File

@ -25,11 +25,13 @@ public struct ExternalMusicAlbumArtResourceId {
}
public class ExternalMusicAlbumArtResource: Equatable {
public let file: FileMediaReference?
public let title: String
public let performer: String
public let isThumbnail: Bool
public init(title: String, performer: String, isThumbnail: Bool) {
public init(file: FileMediaReference?, title: String, performer: String, isThumbnail: Bool) {
self.file = file
self.title = title
self.performer = performer
self.isThumbnail = isThumbnail
@ -40,6 +42,9 @@ public class ExternalMusicAlbumArtResource: Equatable {
}
public static func ==(lhs: ExternalMusicAlbumArtResource, rhs: ExternalMusicAlbumArtResource) -> Bool {
if lhs.file?.media.fileId != rhs.file?.media.fileId {
return false
}
if lhs.title != rhs.title {
return false
}
@ -53,8 +58,10 @@ public class ExternalMusicAlbumArtResource: Equatable {
}
}
public func fetchExternalMusicAlbumArtResource(engine: TelegramEngine, resource: ExternalMusicAlbumArtResource) -> Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error> {
return Signal { subscriber in
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)
/*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
@ -151,5 +158,5 @@ public func fetchExternalMusicAlbumArtResource(engine: TelegramEngine, resource:
fetchDisposable.dispose()
}
}
}
}*/
}

View File

@ -2592,7 +2592,7 @@ public func albumArtThumbnailData(engine: TelegramEngine, thumbnail: ExternalMus
return engine.resources.custom(
id: thumbnail.id.stringRepresentation,
fetch: EngineMediaResource.Fetch {
return fetchExternalMusicAlbumArtResource(engine: engine, resource: thumbnail)
return fetchExternalMusicAlbumArtResource(engine: engine, file: thumbnail.file, resource: thumbnail)
},
attemptSynchronously: attemptSynchronously
)
@ -2613,7 +2613,7 @@ public func albumArtThumbnailData(engine: TelegramEngine, thumbnail: ExternalMus
})
}
private func albumArtFullSizeDatas(engine: TelegramEngine, thumbnail: ExternalMusicAlbumArtResource, fullSize: ExternalMusicAlbumArtResource, autoFetchFullSize: Bool = true) -> Signal<Tuple3<Data?, Data?, Bool>, NoError> {
private func albumArtFullSizeDatas(engine: TelegramEngine, file: FileMediaReference?, thumbnail: ExternalMusicAlbumArtResource, fullSize: ExternalMusicAlbumArtResource, autoFetchFullSize: Bool = true) -> Signal<Tuple3<Data?, Data?, Bool>, NoError> {
return engine.resources.custom(
id: fullSize.id.stringRepresentation,
fetch: nil,
@ -2629,14 +2629,14 @@ private func albumArtFullSizeDatas(engine: TelegramEngine, thumbnail: ExternalMu
engine.resources.custom(
id: thumbnail.id.stringRepresentation,
fetch: EngineMediaResource.Fetch {
return fetchExternalMusicAlbumArtResource(engine: engine, resource: thumbnail)
return fetchExternalMusicAlbumArtResource(engine: engine, file: file, resource: thumbnail)
},
attemptSynchronously: false
),
engine.resources.custom(
id: fullSize.id.stringRepresentation,
fetch: autoFetchFullSize ? EngineMediaResource.Fetch {
return fetchExternalMusicAlbumArtResource(engine: engine, resource: fullSize)
return fetchExternalMusicAlbumArtResource(engine: engine, file: file, resource: fullSize)
} : nil,
attemptSynchronously: false
)
@ -2749,7 +2749,7 @@ public func playerAlbumArt(postbox: Postbox, engine: TelegramEngine, fileReferen
return Tuple(thumbnailData, nil, false)
}
} else {
immediateArtworkData = albumArtFullSizeDatas(engine: engine, thumbnail: albumArt.thumbnailResource, fullSize: albumArt.fullSizeResource)
immediateArtworkData = albumArtFullSizeDatas(engine: engine, file: fileReference, thumbnail: albumArt.thumbnailResource, fullSize: albumArt.fullSizeResource)
}
}

View File

@ -8,7 +8,7 @@ public struct MediaResourceId: Equatable, Hashable {
}
}
public protocol MediaResource {
public protocol MediaResource: AnyObject {
var id: MediaResourceId { get }
var size: Int64? { get }
var streamable: Bool { get }

View File

@ -363,6 +363,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1770371538] = { return Api.InputWallPaper.parse_inputWallPaperNoFile($0) }
dict[1913199744] = { return Api.InputWallPaper.parse_inputWallPaperSlug($0) }
dict[-1678949555] = { return Api.InputWebDocument.parse_inputWebDocument($0) }
dict[-193992412] = { return Api.InputWebFileLocation.parse_inputWebFileAudioAlbumThumbLocation($0) }
dict[-1625153079] = { return Api.InputWebFileLocation.parse_inputWebFileGeoPointLocation($0) }
dict[-1036396922] = { return Api.InputWebFileLocation.parse_inputWebFileLocation($0) }
dict[1048946971] = { return Api.Invoice.parse_invoice($0) }

View File

@ -54,11 +54,21 @@ public extension Api {
}
public extension Api {
enum InputWebFileLocation: TypeConstructorDescription {
case inputWebFileAudioAlbumThumbLocation(flags: Int32, document: Api.InputDocument?, title: String?, performer: String?)
case inputWebFileGeoPointLocation(geoPoint: Api.InputGeoPoint, accessHash: Int64, w: Int32, h: Int32, zoom: Int32, scale: Int32)
case inputWebFileLocation(url: String, accessHash: Int64)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self {
case .inputWebFileAudioAlbumThumbLocation(let flags, let document, let title, let performer):
if boxed {
buffer.appendInt32(-193992412)
}
serializeInt32(flags, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {document!.serialize(buffer, true)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(title!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 1) != 0 {serializeString(performer!, buffer: buffer, boxed: false)}
break
case .inputWebFileGeoPointLocation(let geoPoint, let accessHash, let w, let h, let zoom, let scale):
if boxed {
buffer.appendInt32(-1625153079)
@ -82,6 +92,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) {
switch self {
case .inputWebFileAudioAlbumThumbLocation(let flags, let document, let title, let performer):
return ("inputWebFileAudioAlbumThumbLocation", [("flags", String(describing: flags)), ("document", String(describing: document)), ("title", String(describing: title)), ("performer", String(describing: performer))])
case .inputWebFileGeoPointLocation(let geoPoint, let accessHash, let w, let h, let zoom, let scale):
return ("inputWebFileGeoPointLocation", [("geoPoint", String(describing: geoPoint)), ("accessHash", String(describing: accessHash)), ("w", String(describing: w)), ("h", String(describing: h)), ("zoom", String(describing: zoom)), ("scale", String(describing: scale))])
case .inputWebFileLocation(let url, let accessHash):
@ -89,6 +101,28 @@ public extension Api {
}
}
public static func parse_inputWebFileAudioAlbumThumbLocation(_ reader: BufferReader) -> InputWebFileLocation? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Api.InputDocument?
if Int(_1!) & Int(1 << 0) != 0 {if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.InputDocument
} }
var _3: String?
if Int(_1!) & Int(1 << 1) != 0 {_3 = parseString(reader) }
var _4: String?
if Int(_1!) & Int(1 << 1) != 0 {_4 = parseString(reader) }
let _c1 = _1 != nil
let _c2 = (Int(_1!) & Int(1 << 0) == 0) || _2 != nil
let _c3 = (Int(_1!) & Int(1 << 1) == 0) || _3 != nil
let _c4 = (Int(_1!) & Int(1 << 1) == 0) || _4 != nil
if _c1 && _c2 && _c3 && _c4 {
return Api.InputWebFileLocation.inputWebFileAudioAlbumThumbLocation(flags: _1!, document: _2, title: _3, performer: _4)
}
else {
return nil
}
}
public static func parse_inputWebFileGeoPointLocation(_ reader: BufferReader) -> InputWebFileLocation? {
var _1: Api.InputGeoPoint?
if let signature = reader.readInt32() {

View File

@ -82,9 +82,3 @@ extension SecretFileMediaResource: TelegramCloudMediaResource, TelegramMultipart
return .inputEncryptedFileLocation(id: self.fileId, accessHash: self.accessHash)
}
}
extension WebFileReferenceMediaResource {
var apiInputLocation: Api.InputWebFileLocation {
return .inputWebFileLocation(url: self.url, accessHash: self.accessHash)
}
}

View File

@ -56,6 +56,7 @@ private enum MultipartFetchDownloadError {
case reuploadToCdn(masterDatacenterId: Int32, token: Data)
case revalidateMediaReference
case hashesMissing
case fatal
}
private enum MultipartFetchGenericLocationResult {
@ -347,7 +348,7 @@ private enum MultipartFetchSource {
case let .web(_, location):
return download.request(Api.functions.upload.getWebFile(location: location, offset: Int32(offset), limit: Int32(limit)), tag: tag, continueInBackground: continueInBackground)
|> mapError { error -> MultipartFetchDownloadError in
return .generic
return .fatal
}
|> mapToSignal { result -> Signal<Data, MultipartFetchDownloadError> in
switch result {
@ -448,6 +449,7 @@ private final class MultipartFetchManager {
let continueInBackground: Bool
let partReady: (Int64, Data) -> Void
let reportCompleteSize: (Int64) -> Void
let finishWithError: (MediaResourceDataFetchError) -> Void
private let useMainConnection: Bool
private var source: MultipartFetchSource
@ -472,7 +474,7 @@ private final class MultipartFetchManager {
private var fetchSpeedRecords: [FetchSpeedRecord] = []
private var totalFetchedByteCount: Int = 0
init(resource: TelegramMediaResource, parameters: MediaResourceFetchParameters?, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int64?, location: MultipartFetchMasterLocation, postbox: Postbox, network: Network, revalidationContext: MediaReferenceRevalidationContext?, partReady: @escaping (Int64, Data) -> Void, reportCompleteSize: @escaping (Int64) -> Void, useMainConnection: Bool) {
init(resource: TelegramMediaResource, parameters: MediaResourceFetchParameters?, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, encryptionKey: SecretFileEncryptionKey?, decryptedSize: Int64?, location: MultipartFetchMasterLocation, postbox: Postbox, network: Network, revalidationContext: MediaReferenceRevalidationContext?, partReady: @escaping (Int64, Data) -> Void, reportCompleteSize: @escaping (Int64) -> Void, finishWithError: @escaping (MediaResourceDataFetchError) -> Void, useMainConnection: Bool) {
self.resource = resource
self.parameters = parameters
self.consumerId = Int64.random(in: Int64.min ... Int64.max)
@ -528,6 +530,7 @@ private final class MultipartFetchManager {
self.source = .master(location: location, download: DownloadWrapper(consumerId: self.consumerId, datacenterId: location.datacenterId, isCdn: false, network: network, useMainConnection: self.useMainConnection))
self.partReady = partReady
self.reportCompleteSize = reportCompleteSize
self.finishWithError = finishWithError
self.rangesDisposable = (intervals
|> deliverOn(self.queue)).start(next: { [weak self] intervals in
@ -734,6 +737,8 @@ private final class MultipartFetchManager {
switch error {
case .generic:
break
case .fatal:
strongSelf.finishWithError(.generic)
case .revalidateMediaReference:
if !strongSelf.revalidatingMediaReference && !strongSelf.revalidatedMediaReference {
strongSelf.revalidatingMediaReference = true
@ -821,7 +826,7 @@ public func resourceFetchInfo(resource: TelegramMediaResource) -> MediaResourceF
func multipartFetch(postbox: Postbox, network: Network, mediaReferenceRevalidationContext: MediaReferenceRevalidationContext?, resource: TelegramMediaResource, datacenterId: Int, size: Int64?, intervals: Signal<[(Range<Int64>, MediaBoxFetchPriority)], NoError>, parameters: MediaResourceFetchParameters?, encryptionKey: SecretFileEncryptionKey? = nil, decryptedSize: Int64? = nil, continueInBackground: Bool = false, useMainConnection: Bool = false) -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> {
return Signal { subscriber in
let location: MultipartFetchMasterLocation
if let resource = resource as? WebFileReferenceMediaResource {
if let resource = resource as? MediaResourceWithWebFileReference {
location = .web(Int32(datacenterId), resource.apiInputLocation)
} else {
location = .generic(Int32(datacenterId), { resource, resourceReference, fileReference in
@ -876,6 +881,8 @@ func multipartFetch(postbox: Postbox, network: Network, mediaReferenceRevalidati
}, reportCompleteSize: { size in
subscriber.putNext(.resourceSizeUpdated(size))
subscriber.putCompletion()
}, finishWithError: { error in
subscriber.putError(error)
}, useMainConnection: useMainConnection)
manager.start()

View File

@ -49,7 +49,7 @@ func fetchResource(account: Account, resource: MediaResource, intervals: Signal<
} else if let cloudResource = resource as? TelegramMultipartFetchableResource {
return .single(.dataPart(resourceOffset: 0, data: Data(), range: 0 ..< 0, complete: false))
|> then(fetchCloudMediaLocation(account: account, resource: cloudResource, datacenterId: cloudResource.datacenterId, size: resource.size == 0 ? nil : resource.size, intervals: intervals, parameters: parameters))
} else if let webFileResource = resource as? WebFileReferenceMediaResource {
} else if let webFileResource = resource as? MediaResourceWithWebFileReference {
return currentWebDocumentsHostDatacenterId(postbox: account.postbox, isTestingEnvironment: account.testingEnvironment)
|> castError(MediaResourceDataFetchError.self)
|> mapToSignal { datacenterId -> Signal<MediaResourceDataFetchResult, MediaResourceDataFetchError> in

View File

@ -1,5 +1,6 @@
import Foundation
import Postbox
import TelegramApi
public struct CloudFileMediaResourceId: Hashable, Equatable {
let datacenterId: Int
@ -664,7 +665,11 @@ public struct WebFileReferenceMediaResourceId: Hashable, Equatable {
}
}
public final class WebFileReferenceMediaResource: TelegramMediaResource {
protocol MediaResourceWithWebFileReference: TelegramMediaResource {
var apiInputLocation: Api.InputWebFileLocation { get }
}
public final class WebFileReferenceMediaResource: TelegramMediaResource, MediaResourceWithWebFileReference {
public let url: String
public let actualSize: Int64
public var size: Int64? {
@ -705,8 +710,71 @@ public final class WebFileReferenceMediaResource: TelegramMediaResource {
return false
}
}
var apiInputLocation: Api.InputWebFileLocation {
return .inputWebFileLocation(url: self.url, accessHash: self.accessHash)
}
}
final class AlbumCoverResource: TelegramMediaResource, MediaResourceWithWebFileReference {
var id: MediaResourceId {
return MediaResourceId("AlbumCoverResource-\(self.datacenterId)-\(self.title)-\(self.performer)")
}
let datacenterId: Int
let size: Int64? = nil
func isEqual(to: MediaResource) -> Bool {
return self === to
}
var fileReference: Data? {
if let file = self.file, let resource = file.media.resource as? CloudDocumentMediaResource {
return resource.fileReference
} else {
return nil
}
}
let file: FileMediaReference?
let title: String
let performer: String
init(datacenterId: Int, file: FileMediaReference?, title: String, performer: String) {
self.datacenterId = datacenterId
self.file = file
self.title = title
self.performer = performer
}
init(decoder: PostboxDecoder) {
preconditionFailure()
}
func encode(_ encoder: PostboxEncoder) {
}
var apiInputLocation: Api.InputWebFileLocation {
var flags: Int32 = 0
var document: Api.InputDocument?
if let file = self.file, let resource = file.media.resource as? CloudDocumentMediaResource {
document = .inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data()))
flags |= 1 << 0
}
if !self.title.isEmpty {
flags |= 1 << 1
}
if !self.performer.isEmpty {
flags |= 1 << 1
}
return .inputWebFileAudioAlbumThumbLocation(
flags: flags,
document: document,
title: self.title.isEmpty ? nil : self.title,
performer: self.performer.isEmpty ? nil : self.performer
)
}
}
public struct SecretFileMediaResourceId: Hashable, Equatable {
public let fileId: Int64

View File

@ -1,10 +1,59 @@
import Foundation
import SwiftSignalKit
import Postbox
import TelegramApi
public typealias EngineTempBox = TempBox
public typealias EngineTempBoxFile = TempBoxFile
func bufferedFetch(_ signal: Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error>) -> Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error> {
return Signal { subscriber in
final class State {
var data = Data()
var isCompleted: Bool = false
init() {
}
}
let state = Atomic<State>(value: State())
return signal.start(next: { value in
switch value {
case let .dataPart(_, data, _, _):
let _ = state.with { state in
state.data.append(data)
}
case let .moveTempFile(file):
let _ = state.with { state in
state.isCompleted = true
}
subscriber.putNext(.moveTempFile(file: file))
case .resourceSizeUpdated:
break
default:
assert(false)
break
}
}, error: { error in
subscriber.putError(error)
}, completed: {
let tempFile = state.with { state -> TempBoxFile? in
if state.isCompleted {
return nil
} else {
let tempFile = TempBox.shared.tempFile(fileName: "data")
let _ = try? state.data.write(to: URL(fileURLWithPath: tempFile.path), options: .atomic)
return tempFile
}
}
if let tempFile = tempFile {
subscriber.putNext(.moveTempFile(file: tempFile))
}
subscriber.putCompletion()
})
}
}
public final class EngineMediaResource: Equatable {
public enum CacheTimeout {
case `default`
@ -29,7 +78,14 @@ public final class EngineMediaResource: Equatable {
public final class Fetch {
public enum Result {
case dataPart(resourceOffset: Int64, data: Data, range: Range<Int64>, complete: Bool)
case resourceSizeUpdated(Int64)
case progressUpdated(Float)
case replaceHeader(data: Data, range: Range<Int64>)
case moveLocalFile(path: String)
case moveTempFile(file: TempBoxFile)
case copyLocalItem(MediaResourceDataFetchCopyLocalItem)
case reset
}
public enum Error {
@ -189,6 +245,9 @@ public extension TelegramEngine {
switch result {
case let .moveTempFile(file):
mappedResult = .tempFile(file)
default:
assert(false)
return
}
subscriber.putNext(mappedResult)
}, completed: {
@ -219,6 +278,53 @@ public extension TelegramEngine {
}
}
}
public func fetchAlbumCover(file: FileMediaReference?, title: String, performer: String) -> Signal<EngineMediaResource.Fetch.Result, EngineMediaResource.Fetch.Error> {
let datacenterId: Int
if let resource = file?.media.resource as? CloudDocumentMediaResource {
datacenterId = resource.datacenterId
} else {
datacenterId = self.account.network.datacenterId
}
let resource = AlbumCoverResource(datacenterId: datacenterId, file: file, title: title, performer: performer)
return bufferedFetch(multipartFetch(postbox: self.account.postbox, network: self.account.network, mediaReferenceRevalidationContext: self.account.mediaReferenceRevalidationContext, resource: resource, datacenterId: datacenterId, size: nil, intervals: .single([(0 ..< Int64.max, .default)]), parameters: MediaResourceFetchParameters(
tag: nil,
info: TelegramCloudMediaResourceFetchInfo(
reference: MediaResourceReference.standalone(resource: resource),
preferBackgroundReferenceRevalidation: false,
continueInBackground: false
),
isRandomAccessAllowed: true
))
|> map { result -> EngineMediaResource.Fetch.Result in
switch result {
case let .dataPart(resourceOffset, data, range, complete):
return .dataPart(resourceOffset: resourceOffset, data: data, range: range, complete: complete)
case let .resourceSizeUpdated(size):
return .resourceSizeUpdated(size)
case let .progressUpdated(value):
return .progressUpdated(value)
case let .replaceHeader(data, range):
return .replaceHeader(data: data, range: range)
case let .moveLocalFile(path):
return .moveLocalFile(path: path)
case let .moveTempFile(file):
return .moveTempFile(file: file)
case let .copyLocalItem(item):
return .copyLocalItem(item)
case .reset:
return .reset
}
}
|> mapError { error -> EngineMediaResource.Fetch.Error in
switch error {
case .generic:
return .generic
}
})
}
public func cancelAllFetches(id: String) {
preconditionFailure()

View File

@ -158,6 +158,7 @@ public final class EmojiSuggestionsComponent: Component {
}
}
private let blurView: BlurredBackgroundView
private let backgroundLayer: SimpleShapeLayer
private let scrollView: UIScrollView
@ -168,11 +169,19 @@ public final class EmojiSuggestionsComponent: Component {
private var visibleLayers: [MediaId: InlineStickerItemLayer] = [:]
override init(frame: CGRect) {
self.blurView = BlurredBackgroundView(color: .clear, enableBlur: true)
self.blurView.layer.shadowColor = UIColor(white: 0.0, alpha: 1.0).cgColor
self.blurView.layer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.blurView.layer.shadowRadius = 15.0
self.blurView.layer.shadowOpacity = 0.15
self.backgroundLayer = SimpleShapeLayer()
self.backgroundLayer.shadowColor = UIColor(white: 0.0, alpha: 1.0).cgColor
/*self.backgroundLayer.shadowColor = UIColor(white: 0.0, alpha: 1.0).cgColor
self.backgroundLayer.shadowOffset = CGSize(width: 0.0, height: 2.0)
self.backgroundLayer.shadowRadius = 15.0
self.backgroundLayer.shadowOpacity = 0.15
self.backgroundLayer.shadowOpacity = 0.15*/
self.blurView.layer.mask = self.backgroundLayer
self.scrollView = UIScrollView()
@ -197,6 +206,7 @@ public final class EmojiSuggestionsComponent: Component {
self.scrollView.delegate = self
self.scrollView.clipsToBounds = true
self.addSubview(self.blurView)
self.layer.addSublayer(self.backgroundLayer)
self.addSubview(self.scrollView)
@ -317,6 +327,8 @@ public final class EmojiSuggestionsComponent: Component {
path.addArc(tangent1End: CGPoint(x: size.width, y: 0.0), tangent2End: CGPoint(x: size.width - radius, y: 0.0), radius: radius)
path.addLine(to: CGPoint(x: radius, y: 0.0))
self.blurView.frame = CGRect(origin: CGPoint(), size: size)
self.blurView.update(size: size, transition: .immediate)
self.backgroundLayer.frame = CGRect(origin: CGPoint(), size: size)
self.backgroundLayer.path = path
self.backgroundLayer.shadowPath = path
@ -326,7 +338,9 @@ public final class EmojiSuggestionsComponent: Component {
let height: CGFloat = 54.0
if self.component?.theme !== component.theme {
self.backgroundLayer.fillColor = component.theme.list.plainBackgroundColor.cgColor
//self.backgroundLayer.fillColor = component.theme.list.plainBackgroundColor.cgColor
self.backgroundLayer.fillColor = UIColor.black.cgColor
self.blurView.updateColor(color: component.theme.list.plainBackgroundColor.withMultipliedAlpha(0.6), transition: .immediate)
}
var resetScrollingPosition = false
if self.component?.files != component.files {

View File

@ -1496,7 +1496,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
}
}
image = playerAlbumArt(postbox: context.account.postbox, engine: context.engine, fileReference: .message(message: MessageReference(message), media: file), albumArt: .init(thumbnailResource: ExternalMusicAlbumArtResource(title: title ?? "", performer: performer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(title: title ?? "", performer: performer ?? "", isThumbnail: false)), thumbnail: true, overlayColor: UIColor(white: 0.0, alpha: 0.3), drawPlaceholderWhenEmpty: false, attemptSynchronously: !animated)
image = playerAlbumArt(postbox: context.account.postbox, engine: context.engine, fileReference: .message(message: MessageReference(message), media: file), albumArt: .init(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: title ?? "", performer: performer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(message), media: file), title: title ?? "", performer: performer ?? "", isThumbnail: false)), thumbnail: true, overlayColor: UIColor(white: 0.0, alpha: 0.3), drawPlaceholderWhenEmpty: false, attemptSynchronously: !animated)
}
}
let statusNode = SemanticStatusNode(backgroundNodeColor: backgroundNodeColor, foregroundNodeColor: foregroundNodeColor, image: image, overlayForegroundNodeColor: presentationData.theme.theme.chat.message.mediaOverlayControlColors.foregroundColor)

View File

@ -111,7 +111,7 @@ final class MessageMediaPlaylistItem: SharedMediaPlaylistItem {
if file.fileName?.lowercased().hasSuffix(".ogg") == true {
albumArt = nil
} else {
albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
albumArt = SharedMediaPlaybackAlbumArt(thumbnailResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: true), fullSizeResource: ExternalMusicAlbumArtResource(file: .message(message: MessageReference(self.message), media: file), title: updatedTitle ?? "", performer: updatedPerformer ?? "", isThumbnail: false))
}
return SharedMediaPlaybackDisplayData.music(title: updatedTitle, performer: updatedPerformer, albumArt: albumArt, long: CGFloat(duration) > 10.0 * 60.0)