mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 11:25:38 +00:00
Generate thumbnails for PDFs sent via share extension
This commit is contained in:
parent
0144957e82
commit
1293d565d0
@ -209,7 +209,7 @@ func fetchICloudFileResource(resource: ICloudFileResource) -> Signal<MediaResour
|
|||||||
if resource.thumbnail {
|
if resource.thumbnail {
|
||||||
let tempFile = TempBox.shared.tempFile(fileName: "thumb.jpg")
|
let tempFile = TempBox.shared.tempFile(fileName: "thumb.jpg")
|
||||||
var data = Data()
|
var data = Data()
|
||||||
if let image = generatePdfPreviewImage(url: url, size: CGSize(width: 320.0, height: 320.0)), let jpegData = UIImageJPEGRepresentation(image, 0.5) {
|
if let image = generatePdfPreviewImage(url: url, size: CGSize(width: 256, height: 256.0)), let jpegData = UIImageJPEGRepresentation(image, 0.5) {
|
||||||
data = jpegData
|
data = jpegData
|
||||||
}
|
}
|
||||||
if let _ = try? data.write(to: URL(fileURLWithPath: tempFile.path)) {
|
if let _ = try? data.write(to: URL(fileURLWithPath: tempFile.path)) {
|
||||||
|
|||||||
@ -3,7 +3,13 @@ import UIKit
|
|||||||
import Display
|
import Display
|
||||||
|
|
||||||
func generatePdfPreviewImage(url: URL, size: CGSize) -> UIImage? {
|
func generatePdfPreviewImage(url: URL, size: CGSize) -> UIImage? {
|
||||||
guard let document = CGPDFDocument(url as CFURL) else { return nil }
|
guard let data = try? Data(contentsOf: url, options: .mappedIfSafe) else { return nil }
|
||||||
|
return generatePdfPreviewImage(data: data, size: size)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generatePdfPreviewImage(data: Data, size: CGSize) -> UIImage? {
|
||||||
|
guard let provider = CGDataProvider(data: data as CFData) else { return nil }
|
||||||
|
guard let document = CGPDFDocument(provider) else { return nil }
|
||||||
guard let firstPage = document.page(at: 1) else { return nil }
|
guard let firstPage = document.page(at: 1) else { return nil }
|
||||||
|
|
||||||
let context = DrawingContext(size: size)
|
let context = DrawingContext(size: size)
|
||||||
|
|||||||
@ -222,27 +222,25 @@ public class ShareRootControllerImpl {
|
|||||||
let requestUserInteraction: ([UnpreparedShareItemContent]) -> Signal<[PreparedShareItemContent], NoError> = { content in
|
let requestUserInteraction: ([UnpreparedShareItemContent]) -> Signal<[PreparedShareItemContent], NoError> = { content in
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
switch content[0] {
|
switch content[0] {
|
||||||
case let .contact(data):
|
case let .contact(data):
|
||||||
let controller = deviceContactInfoController(context: context, subject: .filter(peer: nil, contactId: nil, contactData: data, completion: { peer, contactData in
|
let controller = deviceContactInfoController(context: context, subject: .filter(peer: nil, contactId: nil, contactData: data, completion: { peer, contactData in
|
||||||
let phone = contactData.basicData.phoneNumbers[0].value
|
let phone = contactData.basicData.phoneNumbers[0].value
|
||||||
if let vCardData = contactData.serializedVCard() {
|
if let vCardData = contactData.serializedVCard() {
|
||||||
subscriber.putNext([.media(.media(.standalone(media: TelegramMediaContact(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumber: phone, peerId: nil, vCardData: vCardData))))])
|
subscriber.putNext([.media(.media(.standalone(media: TelegramMediaContact(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumber: phone, peerId: nil, vCardData: vCardData))))])
|
||||||
|
}
|
||||||
|
subscriber.putCompletion()
|
||||||
|
}), cancelled: {
|
||||||
|
cancelImpl?()
|
||||||
|
})
|
||||||
|
|
||||||
|
if let strongSelf = self, let window = strongSelf.mainWindow {
|
||||||
|
controller.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
|
||||||
|
window.present(controller, on: .root)
|
||||||
}
|
}
|
||||||
subscriber.putCompletion()
|
break
|
||||||
}), cancelled: {
|
|
||||||
cancelImpl?()
|
|
||||||
})
|
|
||||||
|
|
||||||
if let strongSelf = self, let window = strongSelf.mainWindow {
|
|
||||||
controller.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
|
|
||||||
window.present(controller, on: .root)
|
|
||||||
}
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
return EmptyDisposable
|
||||||
return ActionDisposable {
|
} |> runOn(Queue.mainQueue())
|
||||||
}
|
|
||||||
} |> runOn(Queue.mainQueue())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let sentItems: ([PeerId], [PreparedShareItemContent], Account) -> Signal<ShareControllerExternalStatus, NoError> = { peerIds, contents, account in
|
let sentItems: ([PeerId], [PreparedShareItemContent], Account) -> Signal<ShareControllerExternalStatus, NoError> = { peerIds, contents, account in
|
||||||
@ -271,17 +269,17 @@ public class ShareRootControllerImpl {
|
|||||||
return .single(.done)
|
return .single(.done)
|
||||||
}
|
}
|
||||||
switch state {
|
switch state {
|
||||||
case .preparing:
|
case .preparing:
|
||||||
return .single(.preparing)
|
return .single(.preparing)
|
||||||
case let .progress(value):
|
case let .progress(value):
|
||||||
return .single(.progress(value))
|
return .single(.progress(value))
|
||||||
case let .userInteractionRequired(value):
|
case let .userInteractionRequired(value):
|
||||||
return requestUserInteraction(value)
|
return requestUserInteraction(value)
|
||||||
|> mapToSignal { contents -> Signal<ShareControllerExternalStatus, NoError> in
|
|> mapToSignal { contents -> Signal<ShareControllerExternalStatus, NoError> in
|
||||||
return sentItems(peerIds, contents, account)
|
return sentItems(peerIds, contents, account)
|
||||||
}
|
}
|
||||||
case let .done(contents):
|
case let .done(contents):
|
||||||
return sentItems(peerIds, contents, account)
|
return sentItems(peerIds, contents, account)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -338,7 +336,7 @@ public class ShareRootControllerImpl {
|
|||||||
self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
|
self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
|
||||||
})])
|
})])
|
||||||
strongSelf.mainWindow?.present(controller, on: .root)
|
strongSelf.mainWindow?.present(controller, on: .root)
|
||||||
}, completed: {}))
|
}, completed: {}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -178,7 +178,12 @@ private func preparedShareItem(account: Account, to peerId: PeerId, value: [Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), mimeType: mimeType, attributes: [.FileName(fileName: fileName ?? "file")], hintFileIsLarge: data.count > 5 * 1024 * 1024)
|
var thumbnailData: Data?
|
||||||
|
if mimeType == "application/pdf", let image = generatePdfPreviewImage(data: data, size: CGSize(width: 256.0, height: 256.0)), let jpegData = UIImageJPEGRepresentation(image, 0.5) {
|
||||||
|
thumbnailData = jpegData
|
||||||
|
}
|
||||||
|
|
||||||
|
return standaloneUploadedFile(account: account, peerId: peerId, text: "", source: .data(data), thumbnailData: thumbnailData, mimeType: mimeType, attributes: [.FileName(fileName: fileName ?? "file")], hintFileIsLarge: data.count > 5 * 1024 * 1024)
|
||||||
|> mapError { _ -> Void in return Void() }
|
|> mapError { _ -> Void in return Void() }
|
||||||
|> mapToSignal { event -> Signal<PreparedShareItem, Void> in
|
|> mapToSignal { event -> Signal<PreparedShareItem, Void> in
|
||||||
switch event {
|
switch event {
|
||||||
|
|||||||
@ -553,7 +553,7 @@ static void set_bits(uint8_t *bytes, int32_t bitOffset, int32_t numBits, int32_t
|
|||||||
// add output reader to reader
|
// add output reader to reader
|
||||||
[iPodAssetReader addOutput: readerOutput];
|
[iPodAssetReader addOutput: readerOutput];
|
||||||
|
|
||||||
if (! [iPodAssetReader startReading]) {
|
if (![iPodAssetReader startReading]) {
|
||||||
NSLog(@"Unable to start reading!");
|
NSLog(@"Unable to start reading!");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
@ -563,7 +563,6 @@ static void set_bits(uint8_t *bytes, int32_t bitOffset, int32_t numBits, int32_t
|
|||||||
int _waveformPeakCount = 0;
|
int _waveformPeakCount = 0;
|
||||||
|
|
||||||
while (iPodAssetReader.status == AVAssetReaderStatusReading) {
|
while (iPodAssetReader.status == AVAssetReaderStatusReading) {
|
||||||
// Check if the available buffer space is enough to hold at least one cycle of the sample data
|
|
||||||
CMSampleBufferRef nextBuffer = [readerOutput copyNextSampleBuffer];
|
CMSampleBufferRef nextBuffer = [readerOutput copyNextSampleBuffer];
|
||||||
|
|
||||||
if (nextBuffer) {
|
if (nextBuffer) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user