mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-23 14:45:21 +00:00
[WIP] Stories
This commit is contained in:
@@ -76,8 +76,12 @@ private func storeImage(context: DrawingContext, mediaBox: MediaBox, resourceId:
|
||||
switch imageType {
|
||||
case .blurredThumbnail:
|
||||
representationId = "blurred32"
|
||||
case let .square(width):
|
||||
representationId = "shm\(width)"
|
||||
case let .square(width, aspectRatio):
|
||||
if aspectRatio == 1.0 {
|
||||
representationId = "shm\(width)"
|
||||
} else {
|
||||
representationId = "shm\(width)-\(aspectRatio)"
|
||||
}
|
||||
}
|
||||
let path = mediaBox.cachedRepresentationPathForId(resourceId.stringRepresentation, representationId: representationId, keepDuration: .general)
|
||||
|
||||
@@ -229,7 +233,7 @@ public final class DirectMediaImageCache {
|
||||
|
||||
fileprivate enum ImageType {
|
||||
case blurredThumbnail
|
||||
case square(width: Int)
|
||||
case square(width: Int, aspectRatio: CGFloat)
|
||||
}
|
||||
|
||||
private let account: Account
|
||||
@@ -243,13 +247,17 @@ public final class DirectMediaImageCache {
|
||||
switch imageType {
|
||||
case .blurredThumbnail:
|
||||
representationId = "blurred32"
|
||||
case let .square(width):
|
||||
representationId = "shm\(width)"
|
||||
case let .square(width, aspectRatio):
|
||||
if aspectRatio == 1.0 {
|
||||
representationId = "shm\(width)"
|
||||
} else {
|
||||
representationId = "shm\(width)-\(aspectRatio)"
|
||||
}
|
||||
}
|
||||
return self.account.postbox.mediaBox.cachedRepresentationPathForId(resourceId.stringRepresentation, representationId: representationId, keepDuration: .general)
|
||||
}
|
||||
|
||||
private func getLoadSignal(width: Int, userLocation: MediaResourceUserLocation, userContentType: MediaResourceUserContentType, resource: MediaResourceReference, resourceSizeLimit: Int64) -> Signal<UIImage?, NoError>? {
|
||||
private func getLoadSignal(width: Int, aspectRatio: CGFloat, userLocation: MediaResourceUserLocation, userContentType: MediaResourceUserContentType, resource: MediaResourceReference, resourceSizeLimit: Int64) -> Signal<UIImage?, NoError>? {
|
||||
return Signal { subscriber in
|
||||
let fetch = fetchedMediaResource(
|
||||
mediaBox: self.account.postbox.mediaBox,
|
||||
@@ -282,7 +290,7 @@ public final class DirectMediaImageCache {
|
||||
|
||||
let data = dataSignal.start(next: { data in
|
||||
if let data = data, let image = UIImage(data: data) {
|
||||
let scaledSize = CGSize(width: CGFloat(width), height: CGFloat(width))
|
||||
let scaledSize = CGSize(width: CGFloat(width), height: floor(CGFloat(width) / aspectRatio))
|
||||
guard let scaledContext = DrawingContext(size: scaledSize, scale: 1.0, opaque: true) else {
|
||||
subscriber.putNext(nil)
|
||||
subscriber.putCompletion()
|
||||
@@ -294,7 +302,7 @@ public final class DirectMediaImageCache {
|
||||
context.draw(image.cgImage!, in: imageRect)
|
||||
}
|
||||
|
||||
if let scaledImage = storeImage(context: scaledContext, mediaBox: self.account.postbox.mediaBox, resourceId: resource.resource.id, imageType: .square(width: width)) {
|
||||
if let scaledImage = storeImage(context: scaledContext, mediaBox: self.account.postbox.mediaBox, resourceId: resource.resource.id, imageType: .square(width: width, aspectRatio: aspectRatio)) {
|
||||
subscriber.putNext(scaledImage)
|
||||
subscriber.putCompletion()
|
||||
}
|
||||
@@ -342,8 +350,16 @@ public final class DirectMediaImageCache {
|
||||
private func getResource(message: Message, file: TelegramMediaFile, width: Int) -> (resource: MediaResourceReference, size: Int64)? {
|
||||
return self.getProgressiveSize(mediaReference: MediaReference.message(message: MessageReference(message), media: file).abstract, width: width, representations: file.previewRepresentations)
|
||||
}
|
||||
|
||||
private func getResource(peer: PeerReference, story: StoryListContext.Item, image: TelegramMediaImage, width: Int) -> (resource: MediaResourceReference, size: Int64)? {
|
||||
return self.getProgressiveSize(mediaReference: MediaReference.story(peer: peer, id: story.id, media: image).abstract, width: width, representations: image.representations)
|
||||
}
|
||||
|
||||
private func getImageSynchronous(message: Message, userLocation: MediaResourceUserLocation, media: Media, width: Int, possibleWidths: [Int], includeBlurred: Bool) -> GetMediaResult? {
|
||||
private func getResource(peer: PeerReference, story: StoryListContext.Item, file: TelegramMediaFile, width: Int) -> (resource: MediaResourceReference, size: Int64)? {
|
||||
return self.getProgressiveSize(mediaReference: MediaReference.story(peer: peer, id: story.id, media: file).abstract, width: width, representations: file.previewRepresentations)
|
||||
}
|
||||
|
||||
private func getImageSynchronous(message: Message, userLocation: MediaResourceUserLocation, media: Media, width: Int, aspectRatio: CGFloat, possibleWidths: [Int], includeBlurred: Bool) -> GetMediaResult? {
|
||||
var immediateThumbnailData: Data?
|
||||
var resource: (resource: MediaResourceReference, size: Int64)?
|
||||
if let image = media as? TelegramMediaImage {
|
||||
@@ -367,11 +383,11 @@ public final class DirectMediaImageCache {
|
||||
var resultImage: UIImage?
|
||||
for otherWidth in possibleWidths.reversed() {
|
||||
if otherWidth == width {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth)))), let image = loadImage(data: data) {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth, aspectRatio: aspectRatio)))), let image = loadImage(data: data) {
|
||||
return GetMediaResult(image: image, blurredImage: blurredImage, loadSignal: nil)
|
||||
}
|
||||
} else {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth)))), let image = loadImage(data: data) {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth, aspectRatio: aspectRatio)))), let image = loadImage(data: data) {
|
||||
resultImage = image
|
||||
}
|
||||
}
|
||||
@@ -387,12 +403,12 @@ public final class DirectMediaImageCache {
|
||||
}
|
||||
}
|
||||
|
||||
return GetMediaResult(image: resultImage, blurredImage: blurredImage, loadSignal: self.getLoadSignal(width: width, userLocation: userLocation, userContentType: .image, resource: resource.resource, resourceSizeLimit: resource.size))
|
||||
return GetMediaResult(image: resultImage, blurredImage: blurredImage, loadSignal: self.getLoadSignal(width: width, aspectRatio: aspectRatio, userLocation: userLocation, userContentType: .image, resource: resource.resource, resourceSizeLimit: resource.size))
|
||||
}
|
||||
|
||||
public func getImage(message: Message, media: Media, width: Int, possibleWidths: [Int], includeBlurred: Bool = false, synchronous: Bool) -> GetMediaResult? {
|
||||
if synchronous {
|
||||
return self.getImageSynchronous(message: message, userLocation: .peer(message.id.peerId), media: media, width: width, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
return self.getImageSynchronous(message: message, userLocation: .peer(message.id.peerId), media: media, width: width, aspectRatio: 1.0, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
} else {
|
||||
var immediateThumbnailData: Data?
|
||||
if let image = media as? TelegramMediaImage {
|
||||
@@ -405,7 +421,93 @@ public final class DirectMediaImageCache {
|
||||
blurredImage = blurredImageValue
|
||||
}
|
||||
return GetMediaResult(image: nil, blurredImage: blurredImage, loadSignal: Signal { subscriber in
|
||||
let result = self.getImageSynchronous(message: message, userLocation: .peer(message.id.peerId), media: media, width: width, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
let result = self.getImageSynchronous(message: message, userLocation: .peer(message.id.peerId), media: media, width: width, aspectRatio: 1.0, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
guard let result = result else {
|
||||
subscriber.putNext(nil)
|
||||
subscriber.putCompletion()
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
|
||||
if let image = result.image {
|
||||
subscriber.putNext(image)
|
||||
}
|
||||
|
||||
if let signal = result.loadSignal {
|
||||
return signal.start(next: subscriber.putNext, error: subscriber.putError, completed: subscriber.putCompletion)
|
||||
} else {
|
||||
subscriber.putCompletion()
|
||||
|
||||
return EmptyDisposable
|
||||
}
|
||||
}
|
||||
|> runOn(.concurrentDefaultQueue()))
|
||||
}
|
||||
}
|
||||
|
||||
private func getImageSynchronous(peer: PeerReference, story: StoryListContext.Item, userLocation: MediaResourceUserLocation, media: Media, width: Int, aspectRatio: CGFloat, possibleWidths: [Int], includeBlurred: Bool) -> GetMediaResult? {
|
||||
var immediateThumbnailData: Data?
|
||||
var resource: (resource: MediaResourceReference, size: Int64)?
|
||||
if let image = media as? TelegramMediaImage {
|
||||
immediateThumbnailData = image.immediateThumbnailData
|
||||
resource = self.getResource(peer: peer, story: story, image: image, width: width)
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
immediateThumbnailData = file.immediateThumbnailData
|
||||
resource = self.getResource(peer: peer, story: story, file: file, width: width)
|
||||
}
|
||||
|
||||
guard let resource = resource else {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
var blurredImage: UIImage?
|
||||
if includeBlurred, let data = immediateThumbnailData.flatMap(decodeTinyThumbnail), let image = loadImage(data: data), let blurredImageValue = generateBlurredThumbnail(image: image, adjustSaturation: true) {
|
||||
blurredImage = blurredImageValue
|
||||
}
|
||||
|
||||
var resultImage: UIImage?
|
||||
for otherWidth in possibleWidths.reversed() {
|
||||
if otherWidth == width {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth, aspectRatio: aspectRatio)))), let image = loadImage(data: data) {
|
||||
return GetMediaResult(image: image, blurredImage: blurredImage, loadSignal: nil)
|
||||
}
|
||||
} else {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .square(width: otherWidth, aspectRatio: aspectRatio)))), let image = loadImage(data: data) {
|
||||
resultImage = image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if resultImage == nil {
|
||||
if let data = try? Data(contentsOf: URL(fileURLWithPath: self.getCachePath(resourceId: resource.resource.resource.id, imageType: .blurredThumbnail))), let image = loadImage(data: data) {
|
||||
resultImage = image
|
||||
} else if let data = immediateThumbnailData.flatMap(decodeTinyThumbnail), let image = loadImage(data: data) {
|
||||
if let blurredImageValue = generateBlurredThumbnail(image: image) {
|
||||
resultImage = blurredImageValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GetMediaResult(image: resultImage, blurredImage: blurredImage, loadSignal: self.getLoadSignal(width: width, aspectRatio: aspectRatio, userLocation: userLocation, userContentType: .image, resource: resource.resource, resourceSizeLimit: resource.size))
|
||||
}
|
||||
|
||||
public func getImage(peer: PeerReference, story: StoryListContext.Item, media: Media, width: Int, aspectRatio: CGFloat, possibleWidths: [Int], includeBlurred: Bool = false, synchronous: Bool) -> GetMediaResult? {
|
||||
if synchronous {
|
||||
return self.getImageSynchronous(peer: peer, story: story, userLocation: .peer(peer.id), media: media, width: width, aspectRatio: aspectRatio, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
} else {
|
||||
var immediateThumbnailData: Data?
|
||||
if let image = media as? TelegramMediaImage {
|
||||
immediateThumbnailData = image.immediateThumbnailData
|
||||
} else if let file = media as? TelegramMediaFile {
|
||||
immediateThumbnailData = file.immediateThumbnailData
|
||||
}
|
||||
var blurredImage: UIImage?
|
||||
if includeBlurred, let data = immediateThumbnailData.flatMap(decodeTinyThumbnail), let image = loadImage(data: data), let blurredImageValue = generateBlurredThumbnail(image: image, adjustSaturation: true) {
|
||||
blurredImage = blurredImageValue
|
||||
}
|
||||
return GetMediaResult(image: nil, blurredImage: blurredImage, loadSignal: Signal { subscriber in
|
||||
let result = self.getImageSynchronous(peer: peer, story: story, userLocation: .peer(peer.id), media: media, width: width, aspectRatio: aspectRatio, possibleWidths: possibleWidths, includeBlurred: includeBlurred)
|
||||
guard let result = result else {
|
||||
subscriber.putNext(nil)
|
||||
subscriber.putCompletion()
|
||||
|
||||
Reference in New Issue
Block a user