mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
Send/preview sticker packs embedded in photo
This commit is contained in:
parent
9c3f541115
commit
9bb7ff60de
@ -23,6 +23,7 @@ static_library(
|
|||||||
"//submodules/SwipeToDismissGesture:SwipeToDismissGesture",
|
"//submodules/SwipeToDismissGesture:SwipeToDismissGesture",
|
||||||
"//submodules/CheckNode:CheckNode",
|
"//submodules/CheckNode:CheckNode",
|
||||||
"//submodules/AppBundle:AppBundle",
|
"//submodules/AppBundle:AppBundle",
|
||||||
|
"//submodules/StickerPackPreviewUI:StickerPackPreviewUI",
|
||||||
],
|
],
|
||||||
frameworks = [
|
frameworks = [
|
||||||
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
"$SDKROOT/System/Library/Frameworks/Foundation.framework",
|
||||||
|
|||||||
@ -10,6 +10,8 @@ import TelegramPresentationData
|
|||||||
import AccountContext
|
import AccountContext
|
||||||
import RadialStatusNode
|
import RadialStatusNode
|
||||||
import PhotoResources
|
import PhotoResources
|
||||||
|
import AppBundle
|
||||||
|
import StickerPackPreviewUI
|
||||||
|
|
||||||
enum ChatMediaGalleryThumbnail: Equatable {
|
enum ChatMediaGalleryThumbnail: Equatable {
|
||||||
case image(ImageMediaReference)
|
case image(ImageMediaReference)
|
||||||
@ -156,6 +158,7 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
private let imageNode: TransformImageNode
|
private let imageNode: TransformImageNode
|
||||||
fileprivate let _ready = Promise<Void>()
|
fileprivate let _ready = Promise<Void>()
|
||||||
fileprivate let _title = Promise<String>()
|
fileprivate let _title = Promise<String>()
|
||||||
|
fileprivate let _rightBarButtonItem = Promise<UIBarButtonItem?>()
|
||||||
private let statusNodeContainer: HighlightableButtonNode
|
private let statusNodeContainer: HighlightableButtonNode
|
||||||
private let statusNode: RadialStatusNode
|
private let statusNode: RadialStatusNode
|
||||||
private let footerContentNode: ChatItemGalleryFooterContentNode
|
private let footerContentNode: ChatItemGalleryFooterContentNode
|
||||||
@ -230,10 +233,30 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
} else {
|
} else {
|
||||||
self._ready.set(.single(Void()))
|
self._ready.set(.single(Void()))
|
||||||
}
|
}
|
||||||
|
if imageReference.media.flags.contains(.hasStickers) {
|
||||||
|
let rightBarButtonItem = UIBarButtonItem(image: UIImage(bundleImageName: "Media Gallery/Stickers"), style: .plain, target: self, action: #selector(self.openStickersButtonPressed))
|
||||||
|
self._rightBarButtonItem.set(.single(rightBarButtonItem))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.contextAndMedia = (self.context, imageReference.abstract)
|
self.contextAndMedia = (self.context, imageReference.abstract)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@objc func openStickersButtonPressed() {
|
||||||
|
guard let (context, media) = self.contextAndMedia else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let _ = (stickerPacksAttachedToMedia(postbox: context.account.postbox, network: context.account.network, media: media)
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] packs in
|
||||||
|
guard let strongSelf = self, !packs.isEmpty else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let baseNavigationController = strongSelf.baseNavigationController()
|
||||||
|
baseNavigationController?.view.endEditing(true)
|
||||||
|
let controller = StickerPackScreen(context: context, stickerPacks: packs, sendSticker: nil)
|
||||||
|
(baseNavigationController?.topViewController as? ViewController)?.present(controller, in: .window(.root), with: nil)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func setFile(context: AccountContext, fileReference: FileMediaReference) {
|
func setFile(context: AccountContext, fileReference: FileMediaReference) {
|
||||||
if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) {
|
if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) {
|
||||||
if var largestSize = fileReference.media.dimensions {
|
if var largestSize = fileReference.media.dimensions {
|
||||||
@ -447,6 +470,10 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
|||||||
return self._title.get()
|
return self._title.get()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override func rightBarButtonItem() -> Signal<UIBarButtonItem?, NoError> {
|
||||||
|
return self._rightBarButtonItem.get()
|
||||||
|
}
|
||||||
|
|
||||||
override func footerContent() -> Signal<GalleryFooterContentNode?, NoError> {
|
override func footerContent() -> Signal<GalleryFooterContentNode?, NoError> {
|
||||||
return .single(self.footerContentNode)
|
return .single(self.footerContentNode)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -872,12 +872,12 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
private func longPressMedia(_ media: InstantPageMedia) {
|
private func longPressMedia(_ media: InstantPageMedia) {
|
||||||
let controller = ContextMenuController(actions: [ContextMenuAction(content: .text(title: self.strings.Conversation_ContextMenuCopy, accessibilityLabel: self.strings.Conversation_ContextMenuCopy), action: { [weak self] in
|
let controller = ContextMenuController(actions: [ContextMenuAction(content: .text(title: self.strings.Conversation_ContextMenuCopy, accessibilityLabel: self.strings.Conversation_ContextMenuCopy), action: { [weak self] in
|
||||||
if let strongSelf = self, let image = media.media as? TelegramMediaImage {
|
if let strongSelf = self, let image = media.media as? TelegramMediaImage {
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: nil, partialReference: nil)
|
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
let _ = copyToPasteboard(context: strongSelf.context, postbox: strongSelf.context.account.postbox, mediaReference: .standalone(media: media)).start()
|
let _ = copyToPasteboard(context: strongSelf.context, postbox: strongSelf.context.account.postbox, mediaReference: .standalone(media: media)).start()
|
||||||
}
|
}
|
||||||
}), ContextMenuAction(content: .text(title: self.strings.Conversation_LinkDialogSave, accessibilityLabel: self.strings.Conversation_LinkDialogSave), action: { [weak self] in
|
}), ContextMenuAction(content: .text(title: self.strings.Conversation_LinkDialogSave, accessibilityLabel: self.strings.Conversation_LinkDialogSave), action: { [weak self] in
|
||||||
if let strongSelf = self, let image = media.media as? TelegramMediaImage {
|
if let strongSelf = self, let image = media.media as? TelegramMediaImage {
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: nil, partialReference: nil)
|
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
let _ = saveToCameraRoll(context: strongSelf.context, postbox: strongSelf.context.account.postbox, mediaReference: .standalone(media: media)).start()
|
let _ = saveToCameraRoll(context: strongSelf.context, postbox: strongSelf.context.account.postbox, mediaReference: .standalone(media: media)).start()
|
||||||
}
|
}
|
||||||
}), ContextMenuAction(content: .text(title: self.strings.Conversation_ContextMenuShare, accessibilityLabel: self.strings.Conversation_ContextMenuShare), action: { [weak self] in
|
}), ContextMenuAction(content: .text(title: self.strings.Conversation_ContextMenuShare, accessibilityLabel: self.strings.Conversation_ContextMenuShare), action: { [weak self] in
|
||||||
|
|||||||
@ -120,7 +120,7 @@ public struct InstantPageGalleryEntry: Equatable {
|
|||||||
if let dimensions = file.dimensions {
|
if let dimensions = file.dimensions {
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource))
|
||||||
}
|
}
|
||||||
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: file.immediateThumbnailData, reference: nil, partialReference: nil)
|
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: file.immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
return InstantImageGalleryItem(context: context, presentationData: presentationData, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions)
|
return InstantImageGalleryItem(context: context, presentationData: presentationData, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions)
|
||||||
}
|
}
|
||||||
} else if let embedWebpage = self.media.media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = embedWebpage.content {
|
} else if let embedWebpage = self.media.media as? TelegramMediaWebpage, case let .Loaded(webpageContent) = embedWebpage.content {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ final class InstantPagePlayableVideoNode: ASDisplayNode, InstantPageNode, Galler
|
|||||||
|
|
||||||
var imageReference: ImageMediaReference?
|
var imageReference: ImageMediaReference?
|
||||||
if let file = media.media as? TelegramMediaFile, let presentation = smallestImageRepresentation(file.previewRepresentations) {
|
if let file = media.media as? TelegramMediaFile, let presentation = smallestImageRepresentation(file.previewRepresentations) {
|
||||||
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [presentation], immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [presentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
imageReference = ImageMediaReference.webPage(webPage: WebpageReference(webPage), media: image)
|
imageReference = ImageMediaReference.webPage(webPage: WebpageReference(webPage), media: image)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -418,7 +418,7 @@ private func loadLegacyMessages(account: TemporaryAccount, basePath: String, acc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
parsedMedia.append(TelegramMediaImage(imageId: mediaId, representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil))
|
parsedMedia.append(TelegramMediaImage(imageId: mediaId, representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))
|
||||||
} else if let item = item as? TGVideoMediaAttachment {
|
} else if let item = item as? TGVideoMediaAttachment {
|
||||||
let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64())
|
let mediaId = MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64())
|
||||||
var representations: [TelegramMediaImageRepresentation] = []
|
var representations: [TelegramMediaImageRepresentation] = []
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import AccountContext
|
|||||||
import ImageCompression
|
import ImageCompression
|
||||||
import MimeTypes
|
import MimeTypes
|
||||||
import LocalMediaResources
|
import LocalMediaResources
|
||||||
|
import LegacyUI
|
||||||
|
|
||||||
public func guessMimeTypeByFileExtension(_ ext: String) -> String {
|
public func guessMimeTypeByFileExtension(_ ext: String) -> String {
|
||||||
return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary"
|
return TGMimeTypeMap.mimeType(forExtension: ext) ?? "application/binary"
|
||||||
@ -132,13 +133,15 @@ public func legacyAssetPickerItemGenerator() -> ((Any?, String?, [Any]?, String?
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// let stickers = (dict["stickers"] as? [TGDocumentMediaAttachment]).map { document -> FileMediaReference in
|
let stickers = (dict["stickers"] as? [TGDocumentMediaAttachment])?.compactMap { document -> FileMediaReference? in
|
||||||
// if let sticker = stickerFromLegacyDocument(document) {
|
if let sticker = stickerFromLegacyDocument(document) {
|
||||||
// return FileMediaReference.standalone(media: sticker)
|
return FileMediaReference.standalone(media: sticker)
|
||||||
// }
|
} else {
|
||||||
// }
|
return nil
|
||||||
|
}
|
||||||
|
} ?? []
|
||||||
var result: [AnyHashable : Any] = [:]
|
var result: [AnyHashable : Any] = [:]
|
||||||
result["item" as NSString] = LegacyAssetItemWrapper(item: .image(data: .image(image), thumbnail: thumbnail, caption: caption, stickers: []), timer: (dict["timer"] as? NSNumber)?.intValue, groupedId: (dict["groupedId"] as? NSNumber)?.int64Value)
|
result["item" as NSString] = LegacyAssetItemWrapper(item: .image(data: .image(image), thumbnail: thumbnail, caption: caption, stickers: stickers), timer: (dict["timer"] as? NSNumber)?.intValue, groupedId: (dict["groupedId"] as? NSNumber)?.int64Value)
|
||||||
return result
|
return result
|
||||||
} else if (dict["type"] as! NSString) == "cloudPhoto" {
|
} else if (dict["type"] as! NSString) == "cloudPhoto" {
|
||||||
let asset = dict["asset"] as! TGMediaAsset
|
let asset = dict["asset"] as! TGMediaAsset
|
||||||
@ -319,8 +322,23 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
|
|||||||
let resource = LocalFileReferenceMediaResource(localFilePath: tempFilePath, randomId: randomId)
|
let resource = LocalFileReferenceMediaResource(localFilePath: tempFilePath, randomId: randomId)
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource))
|
||||||
|
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
var imageFlags: TelegramMediaImageFlags = []
|
||||||
|
|
||||||
|
var stickerFiles: [TelegramMediaFile] = []
|
||||||
|
if !stickers.isEmpty {
|
||||||
|
for fileReference in stickers {
|
||||||
|
stickerFiles.append(fileReference.media)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var attributes: [MessageAttribute] = []
|
var attributes: [MessageAttribute] = []
|
||||||
|
|
||||||
|
if !stickerFiles.isEmpty {
|
||||||
|
attributes.append(EmbeddedMediaStickersMessageAttribute(files: stickerFiles))
|
||||||
|
imageFlags.insert(.hasStickers)
|
||||||
|
}
|
||||||
|
|
||||||
|
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: imageFlags)
|
||||||
if let timer = item.timer, timer > 0 && timer <= 60 {
|
if let timer = item.timer, timer > 0 && timer <= 60 {
|
||||||
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: Int32(timer), countdownBeginTime: nil))
|
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: Int32(timer), countdownBeginTime: nil))
|
||||||
}
|
}
|
||||||
@ -337,7 +355,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
|
|||||||
let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: arc4random64())
|
let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: arc4random64())
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource))
|
||||||
|
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
var attributes: [MessageAttribute] = []
|
var attributes: [MessageAttribute] = []
|
||||||
if let timer = item.timer, timer > 0 && timer <= 60 {
|
if let timer = item.timer, timer > 0 && timer <= 60 {
|
||||||
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: Int32(timer), countdownBeginTime: nil))
|
attributes.append(AutoremoveTimeoutMessageAttribute(timeout: Int32(timer), countdownBeginTime: nil))
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import SwiftSignalKit
|
|||||||
import Display
|
import Display
|
||||||
import StickerResources
|
import StickerResources
|
||||||
|
|
||||||
func stickerFromLegacyDocument(_ documentAttachment: TGDocumentMediaAttachment) -> TelegramMediaFile? {
|
public func stickerFromLegacyDocument(_ documentAttachment: TGDocumentMediaAttachment) -> TelegramMediaFile? {
|
||||||
if documentAttachment.isSticker() {
|
if documentAttachment.isSticker() {
|
||||||
for case let sticker as TGDocumentAttributeSticker in documentAttachment.attributes {
|
for case let sticker as TGDocumentAttributeSticker in documentAttachment.attributes {
|
||||||
var attributes: [TelegramMediaFileAttribute] = []
|
var attributes: [TelegramMediaFileAttribute] = []
|
||||||
|
|||||||
@ -115,7 +115,7 @@ final class ThemeGridSearchItemNode: GridItemNode {
|
|||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
||||||
}
|
}
|
||||||
if !representations.isEmpty {
|
if !representations.isEmpty {
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
updateImageSignal = mediaGridMessagePhoto(account: item.account, photoReference: .standalone(media: tmpImage), fullRepresentationSize: CGSize(width: 512, height: 512))
|
updateImageSignal = mediaGridMessagePhoto(account: item.account, photoReference: .standalone(media: tmpImage), fullRepresentationSize: CGSize(width: 512, height: 512))
|
||||||
} else {
|
} else {
|
||||||
updateImageSignal = .complete()
|
updateImageSignal = .complete()
|
||||||
|
|||||||
@ -418,7 +418,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
|
|||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource))
|
||||||
}
|
}
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
|
|
||||||
signal = chatMessagePhoto(postbox: context.account.postbox, photoReference: .standalone(media: tmpImage))
|
signal = chatMessagePhoto(postbox: context.account.postbox, photoReference: .standalone(media: tmpImage))
|
||||||
fetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .media(media: .standalone(media: tmpImage), resource: imageResource))
|
fetchSignal = fetchedMediaResource(mediaBox: context.account.postbox.mediaBox, reference: .media(media: .standalone(media: tmpImage), resource: imageResource))
|
||||||
|
|||||||
@ -480,7 +480,7 @@ public final class ShareController: ViewController {
|
|||||||
if !text.isEmpty {
|
if !text.isEmpty {
|
||||||
messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil))
|
messages.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil))
|
||||||
}
|
}
|
||||||
messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil)), replyToMessageId: nil, localGroupingKey: nil))
|
messages.append(.message(text: "", attributes: [], mediaReference: .standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])), replyToMessageId: nil, localGroupingKey: nil))
|
||||||
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
|
shareSignals.append(enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messages))
|
||||||
}
|
}
|
||||||
case let .media(mediaReference):
|
case let .media(mediaReference):
|
||||||
@ -586,7 +586,7 @@ public final class ShareController: ViewController {
|
|||||||
case let .quote(text, url):
|
case let .quote(text, url):
|
||||||
collectableItems.append(CollectableExternalShareItem(url: "", text: "\"\(text)\"\n\n\(url)", author: nil, timestamp: nil, mediaReference: nil))
|
collectableItems.append(CollectableExternalShareItem(url: "", text: "\"\(text)\"\n\n\(url)", author: nil, timestamp: nil, mediaReference: nil))
|
||||||
case let .image(representations):
|
case let .image(representations):
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
collectableItems.append(CollectableExternalShareItem(url: "", text: "", author: nil, timestamp: nil, mediaReference: .standalone(media: media)))
|
collectableItems.append(CollectableExternalShareItem(url: "", text: "", author: nil, timestamp: nil, mediaReference: .standalone(media: media)))
|
||||||
case let .media(mediaReference):
|
case let .media(mediaReference):
|
||||||
collectableItems.append(CollectableExternalShareItem(url: "", text: "", author: nil, timestamp: nil, mediaReference: mediaReference))
|
collectableItems.append(CollectableExternalShareItem(url: "", text: "", author: nil, timestamp: nil, mediaReference: mediaReference))
|
||||||
@ -770,7 +770,7 @@ public final class ShareController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func saveToCameraRoll(representations: [ImageRepresentationWithReference]) {
|
private func saveToCameraRoll(representations: [ImageRepresentationWithReference]) {
|
||||||
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let media = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations.map({ $0.representation }), immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
let context: AccountContext
|
let context: AccountContext
|
||||||
if self.currentContext.account.id == self.currentAccount.id {
|
if self.currentContext.account.id == self.currentAccount.id {
|
||||||
context = self.currentContext
|
context = self.currentContext
|
||||||
|
|||||||
@ -0,0 +1,18 @@
|
|||||||
|
import Foundation
|
||||||
|
import Postbox
|
||||||
|
|
||||||
|
public class EmbeddedMediaStickersMessageAttribute: MessageAttribute {
|
||||||
|
public let files: [TelegramMediaFile]
|
||||||
|
|
||||||
|
public init(files: [TelegramMediaFile]) {
|
||||||
|
self.files = files
|
||||||
|
}
|
||||||
|
|
||||||
|
required public init(decoder: PostboxDecoder) {
|
||||||
|
self.files = decoder.decodeObjectArrayWithDecoderForKey("files")
|
||||||
|
}
|
||||||
|
|
||||||
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
|
encoder.encodeObjectArray(self.files, forKey: "files")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -39,6 +39,16 @@ public enum TelegramMediaImageReference: PostboxCoding, Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct TelegramMediaImageFlags: OptionSet {
|
||||||
|
public var rawValue: Int32
|
||||||
|
|
||||||
|
public init(rawValue: Int32) {
|
||||||
|
self.rawValue = rawValue
|
||||||
|
}
|
||||||
|
|
||||||
|
public static let hasStickers = TelegramMediaImageFlags(rawValue: 1 << 0)
|
||||||
|
}
|
||||||
|
|
||||||
public final class TelegramMediaImage: Media, Equatable {
|
public final class TelegramMediaImage: Media, Equatable {
|
||||||
public let imageId: MediaId
|
public let imageId: MediaId
|
||||||
public let representations: [TelegramMediaImageRepresentation]
|
public let representations: [TelegramMediaImageRepresentation]
|
||||||
@ -46,17 +56,19 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
public let reference: TelegramMediaImageReference?
|
public let reference: TelegramMediaImageReference?
|
||||||
public let partialReference: PartialMediaReference?
|
public let partialReference: PartialMediaReference?
|
||||||
public let peerIds: [PeerId] = []
|
public let peerIds: [PeerId] = []
|
||||||
|
public let flags: TelegramMediaImageFlags
|
||||||
|
|
||||||
public var id: MediaId? {
|
public var id: MediaId? {
|
||||||
return self.imageId
|
return self.imageId
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(imageId: MediaId, representations: [TelegramMediaImageRepresentation], immediateThumbnailData: Data?, reference: TelegramMediaImageReference?, partialReference: PartialMediaReference?) {
|
public init(imageId: MediaId, representations: [TelegramMediaImageRepresentation], immediateThumbnailData: Data?, reference: TelegramMediaImageReference?, partialReference: PartialMediaReference?, flags: TelegramMediaImageFlags) {
|
||||||
self.imageId = imageId
|
self.imageId = imageId
|
||||||
self.representations = representations
|
self.representations = representations
|
||||||
self.immediateThumbnailData = immediateThumbnailData
|
self.immediateThumbnailData = immediateThumbnailData
|
||||||
self.reference = reference
|
self.reference = reference
|
||||||
self.partialReference = partialReference
|
self.partialReference = partialReference
|
||||||
|
self.flags = flags
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -65,6 +77,7 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
self.immediateThumbnailData = decoder.decodeDataForKey("itd")
|
self.immediateThumbnailData = decoder.decodeDataForKey("itd")
|
||||||
self.reference = decoder.decodeObjectForKey("rf", decoder: { TelegramMediaImageReference(decoder: $0) }) as? TelegramMediaImageReference
|
self.reference = decoder.decodeObjectForKey("rf", decoder: { TelegramMediaImageReference(decoder: $0) }) as? TelegramMediaImageReference
|
||||||
self.partialReference = decoder.decodeAnyObjectForKey("prf", decoder: { PartialMediaReference(decoder: $0) }) as? PartialMediaReference
|
self.partialReference = decoder.decodeAnyObjectForKey("prf", decoder: { PartialMediaReference(decoder: $0) }) as? PartialMediaReference
|
||||||
|
self.flags = TelegramMediaImageFlags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -87,6 +100,7 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
} else {
|
} else {
|
||||||
encoder.encodeNil(forKey: "prf")
|
encoder.encodeNil(forKey: "prf")
|
||||||
}
|
}
|
||||||
|
encoder.encodeInt32(self.flags.rawValue, forKey: "fl")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func representationForDisplayAtSize(_ size: PixelDimensions) -> TelegramMediaImageRepresentation? {
|
public func representationForDisplayAtSize(_ size: PixelDimensions) -> TelegramMediaImageRepresentation? {
|
||||||
@ -130,6 +144,9 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
if self.partialReference != other.partialReference {
|
if self.partialReference != other.partialReference {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if self.flags != other.flags {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -152,6 +169,9 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
if self.partialReference != other.partialReference {
|
if self.partialReference != other.partialReference {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if self.flags != other.flags {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
@ -162,7 +182,7 @@ public final class TelegramMediaImage: Media, Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func withUpdatedPartialReference(_ partialReference: PartialMediaReference?) -> TelegramMediaImage {
|
public func withUpdatedPartialReference(_ partialReference: PartialMediaReference?) -> TelegramMediaImage {
|
||||||
return TelegramMediaImage(imageId: self.imageId, representations: self.representations, immediateThumbnailData: self.immediateThumbnailData, reference: self.reference, partialReference: partialReference)
|
return TelegramMediaImage(imageId: self.imageId, representations: self.representations, immediateThumbnailData: self.immediateThumbnailData, reference: self.reference, partialReference: partialReference, flags: self.flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -149,6 +149,7 @@ private var declaredEncodables: Void = {
|
|||||||
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
declareEncodable(RestrictedContentMessageAttribute.self, f: { RestrictedContentMessageAttribute(decoder: $0) })
|
||||||
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
declareEncodable(SendScheduledMessageImmediatelyAction.self, f: { SendScheduledMessageImmediatelyAction(decoder: $0) })
|
||||||
declareEncodable(WalletCollection.self, f: { WalletCollection(decoder: $0) })
|
declareEncodable(WalletCollection.self, f: { WalletCollection(decoder: $0) })
|
||||||
|
declareEncodable(EmbeddedMediaStickersMessageAttribute.self, f: { EmbeddedMediaStickersMessageAttribute(decoder: $0) })
|
||||||
|
|
||||||
return
|
return
|
||||||
}()
|
}()
|
||||||
|
|||||||
@ -55,7 +55,7 @@ private func convertForwardedMediaForSecretChat(_ media: Media) -> Media {
|
|||||||
if let file = media as? TelegramMediaFile {
|
if let file = media as? TelegramMediaFile {
|
||||||
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: file.partialReference, resource: file.resource, previewRepresentations: file.previewRepresentations, immediateThumbnailData: file.immediateThumbnailData, mimeType: file.mimeType, size: file.size, attributes: file.attributes)
|
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: arc4random64()), partialReference: file.partialReference, resource: file.resource, previewRepresentations: file.previewRepresentations, immediateThumbnailData: file.immediateThumbnailData, mimeType: file.mimeType, size: file.size, attributes: file.attributes)
|
||||||
} else if let image = media as? TelegramMediaImage {
|
} else if let image = media as? TelegramMediaImage {
|
||||||
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference)
|
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: image.representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference, flags: [])
|
||||||
} else {
|
} else {
|
||||||
return media
|
return media
|
||||||
}
|
}
|
||||||
@ -82,6 +82,8 @@ private func filterMessageAttributesForOutgoingMessage(_ attributes: [MessageAtt
|
|||||||
return true
|
return true
|
||||||
case _ as OutgoingScheduleInfoMessageAttribute:
|
case _ as OutgoingScheduleInfoMessageAttribute:
|
||||||
return true
|
return true
|
||||||
|
case _ as EmbeddedMediaStickersMessageAttribute:
|
||||||
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,7 +55,7 @@ public func outgoingMessageWithChatContextResult(to peerId: PeerId, results: Cha
|
|||||||
arc4random_buf(&randomId, 8)
|
arc4random_buf(&randomId, 8)
|
||||||
let thumbnailResource = thumbnail.resource
|
let thumbnailResource = thumbnail.resource
|
||||||
let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128)
|
let imageDimensions = thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128)
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource)], immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
return .message(text: caption, attributes: attributes, mediaReference: .standalone(media: tmpImage), replyToMessageId: nil, localGroupingKey: nil)
|
return .message(text: caption, attributes: attributes, mediaReference: .standalone(media: tmpImage), replyToMessageId: nil, localGroupingKey: nil)
|
||||||
} else {
|
} else {
|
||||||
return .message(text: caption, attributes: attributes, mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)
|
return .message(text: caption, attributes: attributes, mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil)
|
||||||
|
|||||||
@ -350,6 +350,22 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
|
|||||||
flags |= 1 << 1
|
flags |= 1 << 1
|
||||||
ttlSeconds = autoremoveAttribute.timeout
|
ttlSeconds = autoremoveAttribute.timeout
|
||||||
}
|
}
|
||||||
|
var stickers: [Api.InputDocument]?
|
||||||
|
for attribute in attributes {
|
||||||
|
if let attribute = attribute as? EmbeddedMediaStickersMessageAttribute {
|
||||||
|
var stickersValue: [Api.InputDocument] = []
|
||||||
|
for file in attribute.files {
|
||||||
|
if let resource = file.resource as? CloudDocumentMediaResource, let fileReference = resource.fileReference {
|
||||||
|
stickersValue.append(Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: fileReference)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !stickersValue.isEmpty {
|
||||||
|
stickers = stickersValue
|
||||||
|
flags |= 1 << 0
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
return postbox.transaction { transaction -> Api.InputPeer? in
|
return postbox.transaction { transaction -> Api.InputPeer? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||||
}
|
}
|
||||||
@ -357,10 +373,10 @@ private func uploadedMediaImageContent(network: Network, postbox: Postbox, trans
|
|||||||
|> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
|> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
||||||
if let inputPeer = inputPeer {
|
if let inputPeer = inputPeer {
|
||||||
if autoremoveAttribute != nil {
|
if autoremoveAttribute != nil {
|
||||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: nil, ttlSeconds: ttlSeconds), text), reuploadInfo: nil)))
|
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds), text), reuploadInfo: nil)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return network.request(Api.functions.messages.uploadMedia(peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(flags: flags, file: file, stickers: nil, ttlSeconds: ttlSeconds)))
|
return network.request(Api.functions.messages.uploadMedia(peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds)))
|
||||||
|> mapError { _ -> PendingMessageUploadError in return .generic }
|
|> mapError { _ -> PendingMessageUploadError in return .generic }
|
||||||
|> mapToSignal { result -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
|> mapToSignal { result -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
||||||
switch result {
|
switch result {
|
||||||
|
|||||||
@ -712,7 +712,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
resources.append((resource, thumb.makeData()))
|
resources.append((resource, thumb.makeData()))
|
||||||
}
|
}
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
||||||
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
parsedMedia.append(image)
|
parsedMedia.append(image)
|
||||||
}
|
}
|
||||||
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
||||||
@ -910,7 +910,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
resources.append((resource, thumb.makeData()))
|
resources.append((resource, thumb.makeData()))
|
||||||
}
|
}
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
||||||
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
parsedMedia.append(image)
|
parsedMedia.append(image)
|
||||||
}
|
}
|
||||||
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
||||||
@ -1144,7 +1144,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
|
|||||||
resources.append((resource, thumb.makeData()))
|
resources.append((resource, thumb.makeData()))
|
||||||
}
|
}
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size)))
|
||||||
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
parsedMedia.append(image)
|
parsedMedia.append(image)
|
||||||
}
|
}
|
||||||
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
case let .decryptedMessageMediaAudio(duration, mimeType, size, key, iv):
|
||||||
|
|||||||
@ -102,7 +102,7 @@ public func standaloneUploadedImage(account: Account, peerId: PeerId, text: Stri
|
|||||||
|> mapToSignal { result -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
|
|> mapToSignal { result -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .encryptedFile(id, accessHash, size, dcId, _):
|
case let .encryptedFile(id, accessHash, size, dcId, _):
|
||||||
return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int32(data.count), datacenterId: Int(dcId), key: key))], immediateThumbnailData: nil, reference: nil, partialReference: nil)))))
|
return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: arc4random64()), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int32(data.count), datacenterId: Int(dcId), key: key))], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])))))
|
||||||
case .encryptedFileEmpty:
|
case .encryptedFileEmpty:
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import Postbox
|
import Postbox
|
||||||
import TelegramApi
|
import TelegramApi
|
||||||
|
import SwiftSignalKit
|
||||||
import SyncCore
|
import SyncCore
|
||||||
|
|
||||||
func telegramStickerPachThumbnailRepresentationFromApiSize(datacenterId: Int32, size: Api.PhotoSize) -> TelegramMediaImageRepresentation? {
|
func telegramStickerPachThumbnailRepresentationFromApiSize(datacenterId: Int32, size: Api.PhotoSize) -> TelegramMediaImageRepresentation? {
|
||||||
@ -49,3 +49,27 @@ extension StickerPackCollectionInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func stickerPacksAttachedToMedia(postbox: Postbox, network: Network, media: AnyMediaReference) -> Signal<[StickerPackReference], NoError> {
|
||||||
|
let inputMedia: Api.InputStickeredMedia
|
||||||
|
if let imageReference = media.concrete(TelegramMediaImage.self), let reference = imageReference.media.reference, case let .cloud(imageId, accessHash, fileReference) = reference {
|
||||||
|
inputMedia = .inputStickeredMediaPhoto(id: Api.InputPhoto.inputPhoto(id: imageId, accessHash: accessHash, fileReference: Buffer(data: fileReference ?? Data())))
|
||||||
|
} else if let fileReference = media.concrete(TelegramMediaFile.self), let resource = fileReference.media.resource as? CloudDocumentMediaResource {
|
||||||
|
inputMedia = .inputStickeredMediaDocument(id: Api.InputDocument.inputDocument(id: resource.fileId, accessHash: resource.accessHash, fileReference: Buffer(data: resource.fileReference ?? Data())))
|
||||||
|
} else {
|
||||||
|
return .single([])
|
||||||
|
}
|
||||||
|
return network.request(Api.functions.messages.getAttachedStickers(media: inputMedia))
|
||||||
|
|> map { result -> [StickerPackReference] in
|
||||||
|
return result.map { pack in
|
||||||
|
switch pack {
|
||||||
|
case let .stickerSetCovered(set, _), let .stickerSetMultiCovered(set, _):
|
||||||
|
let info = StickerPackCollectionInfo(apiSet: set, namespace: Namespaces.ItemCollection.CloudStickerPacks)
|
||||||
|
return .id(id: info.id.id, accessHash: info.accessHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|> `catch` { _ -> Signal<[StickerPackReference], NoError> in
|
||||||
|
return .single([])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -32,9 +32,14 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
|
|||||||
|
|
||||||
func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
|
func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
|
||||||
switch photo {
|
switch photo {
|
||||||
case let .photo(_, id, accessHash, fileReference, _, sizes, dcId):
|
case let .photo(flags, id, accessHash, fileReference, _, sizes, dcId):
|
||||||
let (immediateThumbnailData, representations) = telegramMediaImageRepresentationsFromApiSizes(datacenterId: dcId, photoId: id, accessHash: accessHash, fileReference: fileReference.makeData(), sizes: sizes)
|
let (immediateThumbnailData, representations) = telegramMediaImageRepresentationsFromApiSizes(datacenterId: dcId, photoId: id, accessHash: accessHash, fileReference: fileReference.makeData(), sizes: sizes)
|
||||||
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudImage, id: id), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: .cloud(imageId: id, accessHash: accessHash, fileReference: fileReference.makeData()), partialReference: nil)
|
var imageFlags: TelegramMediaImageFlags = []
|
||||||
|
let hasStickers = (flags & (1 << 0)) != 0
|
||||||
|
if hasStickers {
|
||||||
|
imageFlags.insert(.hasStickers)
|
||||||
|
}
|
||||||
|
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudImage, id: id), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: .cloud(imageId: id, accessHash: accessHash, fileReference: fileReference.makeData()), partialReference: nil, flags: imageFlags)
|
||||||
case .photoEmpty:
|
case .photoEmpty:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
22
submodules/TelegramUI/Images.xcassets/Media Gallery/Stickers.imageset/Contents.json
vendored
Normal file
22
submodules/TelegramUI/Images.xcassets/Media Gallery/Stickers.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "GalleryEmbeddedStickersIcon@2x.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"filename" : "GalleryEmbeddedStickersIcon@3x.png",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.7 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.6 KiB |
@ -225,7 +225,7 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont
|
|||||||
if updatedImageResource {
|
if updatedImageResource {
|
||||||
if let imageResource = imageResource {
|
if let imageResource = imageResource {
|
||||||
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource)
|
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource)
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
updateImageSignal = chatMessagePhoto(postbox: self.account.postbox, photoReference: .standalone(media: tmpImage))
|
updateImageSignal = chatMessagePhoto(postbox: self.account.postbox, photoReference: .standalone(media: tmpImage))
|
||||||
} else {
|
} else {
|
||||||
updateImageSignal = .complete()
|
updateImageSignal = .complete()
|
||||||
|
|||||||
@ -220,7 +220,7 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
|||||||
|
|
||||||
var photo: TelegramMediaImage?
|
var photo: TelegramMediaImage?
|
||||||
if !new.isEmpty {
|
if !new.isEmpty {
|
||||||
photo = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: new, immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
photo = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: new, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
let action = TelegramMediaActionType.photoUpdated(image: photo)
|
let action = TelegramMediaActionType.photoUpdated(image: photo)
|
||||||
|
|||||||
@ -310,7 +310,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
|
|||||||
updateImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true)
|
updateImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true)
|
||||||
} else {
|
} else {
|
||||||
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(CGSize(width: fittedImageDimensions.width * 2.0, height: fittedImageDimensions.height * 2.0)), resource: imageResource)
|
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(CGSize(width: fittedImageDimensions.width * 2.0, height: fittedImageDimensions.height * 2.0)), resource: imageResource)
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
updateImageSignal = chatMessagePhoto(postbox: item.account.postbox, photoReference: .standalone(media: tmpImage))
|
updateImageSignal = chatMessagePhoto(postbox: item.account.postbox, photoReference: .standalone(media: tmpImage))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -161,7 +161,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me
|
|||||||
let thumbnailResource = LocalFileMediaResource(fileId: arc4random64())
|
let thumbnailResource = LocalFileMediaResource(fileId: arc4random64())
|
||||||
postbox.mediaBox.storeResourceData(thumbnailResource.id, data: smallestData)
|
postbox.mediaBox.storeResourceData(thumbnailResource.id, data: smallestData)
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource))
|
||||||
let updatedImage = TelegramMediaImage(imageId: image.imageId, representations: representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference)
|
let updatedImage = TelegramMediaImage(imageId: image.imageId, representations: representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference, flags: [])
|
||||||
return .single(.standalone(media: updatedImage))
|
return .single(.standalone(media: updatedImage))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -252,7 +252,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode {
|
|||||||
updateIconImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true)
|
updateIconImageSignal = chatMessageSticker(account: item.account, file: stickerFile, small: false, fetched: true)
|
||||||
} else {
|
} else {
|
||||||
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource)
|
let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource)
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
|
||||||
updateIconImageSignal = chatWebpageSnippetPhoto(account: item.account, photoReference: .standalone(media: tmpImage))
|
updateIconImageSignal = chatWebpageSnippetPhoto(account: item.account, photoReference: .standalone(media: tmpImage))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -264,7 +264,7 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
|
|||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource))
|
||||||
}
|
}
|
||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
thumbnailSignal = chatMessagePhotoDatas(postbox: account.postbox, photoReference: .standalone(media: tmpImage), autoFetchFullSize: false)
|
thumbnailSignal = chatMessagePhotoDatas(postbox: account.postbox, photoReference: .standalone(media: tmpImage), autoFetchFullSize: false)
|
||||||
|> mapToSignal { value -> Signal<UIImage, NoError> in
|
|> mapToSignal { value -> Signal<UIImage, NoError> in
|
||||||
let thumbnailData = value._0
|
let thumbnailData = value._0
|
||||||
|
|||||||
@ -138,7 +138,7 @@ final class WebSearchItemNode: GridItemNode {
|
|||||||
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource))
|
||||||
}
|
}
|
||||||
if !representations.isEmpty {
|
if !representations.isEmpty {
|
||||||
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil)
|
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])
|
||||||
updateImageSignal = mediaGridMessagePhoto(account: item.account, photoReference: .standalone(media: tmpImage))
|
updateImageSignal = mediaGridMessagePhoto(account: item.account, photoReference: .standalone(media: tmpImage))
|
||||||
} else {
|
} else {
|
||||||
updateImageSignal = .complete()
|
updateImageSignal = .complete()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user