Merge branch 'master' into experiments/call-session

This commit is contained in:
Ali 2022-11-04 16:58:08 +04:00
commit dee128fd20
93 changed files with 755 additions and 364 deletions

View File

@ -8186,16 +8186,16 @@ Sorry for the inconvenience.";
"ChatList.DeleteTopicConfirmationText" = "This will delete the topic with all its messages"; "ChatList.DeleteTopicConfirmationText" = "This will delete the topic with all its messages";
"ChatList.DeleteTopicConfirmationAction" = "Delete Topic"; "ChatList.DeleteTopicConfirmationAction" = "Delete Topic";
"Notification.TopicCreated" = "Topic created"; "Notification.ForumTopicCreated" = "Topic created";
"Notification.TopicClosed" = "Topic closed"; "Notification.ForumTopicClosed" = "Topic closed";
"Notification.TopicReopened" = "Topic reopened"; "Notification.ForumTopicReopened" = "Topic reopened";
"Notification.TopicClosedAuthor" = "%1$@ closed topic"; "Notification.ForumTopicClosedAuthor" = "%1$@ closed topic";
"Notification.TopicReopenedAuthor" = "%1$@ reopened topic"; "Notification.ForumTopicReopenedAuthor" = "%1$@ reopened topic";
"Notification.TopicRenamed" = "Topic renamed to \"%1$@\""; "Notification.ForumTopicRenamed" = "Topic renamed to \"%1$@\"";
"Notification.TopicRenamedAuthor" = "%1$@ changed the topic title to \"%2$@\""; "Notification.ForumTopicRenamedAuthor" = "%1$@ changed the topic title to \"%2$@\"";
"Notification.TopicIconChanged" = "Topic icon changed to %1$@"; "Notification.ForumTopicIconChanged" = "Topic icon changed to %1$@";
"Notification.TopicIconChangedAuthor" = "%1$@ changed the topic icon to %2$@"; "Notification.ForumTopicIconChangedAuthor" = "%1$@ changed the topic icon to %2$@";
"Notification.TopicRenamedIconChangedAuthor" = "%1$@ changed the topic title and icon to %2$@ %3$@"; "Notification.ForumTopicRenamedIconChangedAuthor" = "%1$@ changed the topic title and icon to %2$@ %3$@";
"Notification.OverviewTopicCreated" = "%1$@ %2$@ was created"; "Notification.OverviewTopicCreated" = "%1$@ %2$@ was created";
"Notification.OverviewTopicClosed" = "%1$@ closed %2$@ %3$@"; "Notification.OverviewTopicClosed" = "%1$@ closed %2$@ %3$@";
"Notification.OverviewTopicReopened" = "%1$@ reopened %2$@ %3$@"; "Notification.OverviewTopicReopened" = "%1$@ reopened %2$@ %3$@";

View File

@ -52,7 +52,7 @@ private func getCoveringViewSnaphot(window: Window1) -> UIImage? {
} }
return true return true
}) })
window.hostView.containerView.drawHierarchy(in: CGRect(origin: CGPoint(), size: unscaledSize), afterScreenUpdates: true) window.hostView.containerView.drawHierarchy(in: CGRect(origin: CGPoint(), size: unscaledSize), afterScreenUpdates: false)
window.forEachViewController({ controller in window.forEachViewController({ controller in
if let controller = controller as? PasscodeEntryController { if let controller = controller as? PasscodeEntryController {
controller.displayNode.alpha = 1.0 controller.displayNode.alpha = 1.0

View File

@ -519,7 +519,7 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in
f(.default) f(.default)
let _ = context.engine.peers.setForumChannelTopicPinned(id: peerId, threadId: threadId, isPinned: !isPinned).start() let _ = context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).start()
}))) })))
} }

View File

@ -3851,7 +3851,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
} }
private func setPeerThreadPinned(peerId: EnginePeer.Id, threadId: Int64, isPinned: Bool) { private func setPeerThreadPinned(peerId: EnginePeer.Id, threadId: Int64, isPinned: Bool) {
self.actionDisposables.add(self.context.engine.peers.setForumChannelTopicPinned(id: peerId, threadId: threadId, isPinned: isPinned).start()) self.actionDisposables.add(self.context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).start())
} }
public func maybeAskForPeerChatRemoval(peer: EngineRenderedPeer, joined: Bool = false, deleteGloballyIfPossible: Bool = false, completion: @escaping (Bool) -> Void, removed: @escaping () -> Void) { public func maybeAskForPeerChatRemoval(peer: EngineRenderedPeer, joined: Bool = false, deleteGloballyIfPossible: Bool = false, completion: @escaping (Bool) -> Void, removed: @escaping () -> Void) {

View File

@ -117,7 +117,7 @@ public struct InstantPageGalleryEntry: Equatable {
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
representations.append(contentsOf: file.previewRepresentations) representations.append(contentsOf: file.previewRepresentations)
if let dimensions = file.dimensions { if let dimensions = file.dimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
let image = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: file.immediateThumbnailData, reference: nil, partialReference: nil, flags: []) 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, itemId: self.index, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions) return InstantImageGalleryItem(context: context, presentationData: presentationData, itemId: self.index, imageReference: .webPage(webPage: WebpageReference(webPage), media: image), caption: caption, credit: credit, location: self.location, openUrl: openUrl, openUrlOptions: openUrlOptions)

View File

@ -484,7 +484,7 @@ class ItemListStickerPackItemNode: ItemListRevealOptionsItemNode {
thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
} }
} }

View File

@ -1411,7 +1411,7 @@
bool hasAnyTimers = false; bool hasAnyTimers = false;
if (editingContext != nil || grouping) if (editingContext != nil || grouping)
{ {
for (UIImage *asset in selectedItems) for (id<TGMediaEditableItem> asset in selectedItems)
{ {
if ([editingContext timerForItem:asset] != nil) { if ([editingContext timerForItem:asset] != nil) {
hasAnyTimers = true; hasAnyTimers = true;
@ -1434,7 +1434,7 @@
if (grouping && selectedItems.count > 1) if (grouping && selectedItems.count > 1)
groupedId = @([self generateGroupedId]); groupedId = @([self generateGroupedId]);
for (UIImage *asset in selectedItems) for (id<TGMediaEditableItem> asset in selectedItems)
{ {
NSAttributedString *caption = [editingContext captionForItem:asset]; NSAttributedString *caption = [editingContext captionForItem:asset];
if (editingContext.isForcedCaption) { if (editingContext.isForcedCaption) {
@ -1445,97 +1445,173 @@
} }
} }
if (intent == TGMediaAssetsControllerSendFileIntent) if ([asset isKindOfClass:[UIImage class]]) {
{ if (intent == TGMediaAssetsControllerSendFileIntent)
NSString *tempFileName = TGTemporaryFileName(nil); {
NSData *imageData = UIImageJPEGRepresentation(asset, 1.0); NSString *tempFileName = TGTemporaryFileName(nil);
[imageData writeToURL:[NSURL fileURLWithPath:tempFileName] atomically:true]; NSData *imageData = UIImageJPEGRepresentation((UIImage *)asset, 1.0);
[imageData writeToURL:[NSURL fileURLWithPath:tempFileName] atomically:true];
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict[@"type"] = @"file";
dict[@"tempFileUrl"] = [NSURL fileURLWithPath:tempFileName];
dict[@"fileName"] = [NSString stringWithFormat:@"IMG%03ld.jpg", i];
dict[@"mimeType"] = TGMimeTypeForFileUTI(@"image/jpeg");
dict[@"previewImage"] = asset;
if (groupedId != nil)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
[signals addObject:[SSignal single:generatedItem]];
i++;
num++;
} else {
id<TGMediaEditAdjustments> adjustments = [editingContext adjustmentsForItem:asset];
NSNumber *timer = [editingContext timerForItem:asset];
SSignal *inlineSignal = [[SSignal single:asset] map:^id(UIImage *image)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict[@"type"] = @"editedPhoto";
dict[@"image"] = image;
if (timer != nil)
dict[@"timer"] = timer;
if (groupedId != nil && !hasAnyTimers)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
return generatedItem;
}];
SSignal *assetSignal = inlineSignal;
SSignal *imageSignal = assetSignal;
if (editingContext != nil)
{
imageSignal = [[[[[editingContext imageSignalForItem:asset withUpdates:true] filter:^bool(id result)
{
return result == nil || ([result isKindOfClass:[UIImage class]] && !((UIImage *)result).degraded);
}] take:1] mapToSignal:^SSignal *(id result)
{
if (result == nil)
{
return [SSignal fail:nil];
}
else if ([result isKindOfClass:[UIImage class]])
{
UIImage *image = (UIImage *)result;
image.edited = true;
return [SSignal single:image];
}
return [SSignal complete];
}] onCompletion:^
{
__strong TGMediaEditingContext *strongEditingContext = editingContext;
[strongEditingContext description];
}];
}
[signals addObject:[[imageSignal map:^NSDictionary *(UIImage *image)
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict[@"type"] = @"editedPhoto";
dict[@"image"] = image;
if (adjustments.paintingData.stickers.count > 0)
dict[@"stickers"] = adjustments.paintingData.stickers;
if (timer != nil)
dict[@"timer"] = timer;
if (groupedId != nil && !hasAnyTimers)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
return generatedItem;
}] catch:^SSignal *(__unused id error)
{
return inlineSignal;
}]];
i++;
num++;
}
} else if ([asset isKindOfClass:[TGCameraCapturedVideo class]]) {
TGCameraCapturedVideo *video = (TGCameraCapturedVideo *)asset;
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; TGVideoEditAdjustments *adjustments = (TGVideoEditAdjustments *)[editingContext adjustmentsForItem:asset];
dict[@"type"] = @"file"; NSAttributedString *caption = [editingContext captionForItem:asset];
dict[@"tempFileUrl"] = [NSURL fileURLWithPath:tempFileName];
dict[@"fileName"] = [NSString stringWithFormat:@"IMG%03ld.jpg", i];
dict[@"mimeType"] = TGMimeTypeForFileUTI(@"image/jpeg");
dict[@"previewImage"] = asset;
if (groupedId != nil)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
[signals addObject:[SSignal single:generatedItem]];
i++;
num++;
} else {
id<TGMediaEditAdjustments> adjustments = [editingContext adjustmentsForItem:asset];
NSNumber *timer = [editingContext timerForItem:asset]; NSNumber *timer = [editingContext timerForItem:asset];
SSignal *inlineSignal = [[SSignal single:asset] map:^id(UIImage *image) UIImage *(^cropVideoThumbnail)(UIImage *, CGSize, CGSize, bool) = ^UIImage *(UIImage *image, CGSize targetSize, CGSize sourceSize, bool resize)
{ {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; if ([adjustments cropAppliedForAvatar:false] || adjustments.hasPainting || adjustments.toolsApplied)
dict[@"type"] = @"editedPhoto"; {
dict[@"image"] = image; CGRect scaledCropRect = CGRectMake(adjustments.cropRect.origin.x * image.size.width / adjustments.originalSize.width, adjustments.cropRect.origin.y * image.size.height / adjustments.originalSize.height, adjustments.cropRect.size.width * image.size.width / adjustments.originalSize.width, adjustments.cropRect.size.height * image.size.height / adjustments.originalSize.height);
UIImage *paintingImage = adjustments.paintingData.stillImage;
if (paintingImage == nil) {
paintingImage = adjustments.paintingData.image;
}
if (adjustments.toolsApplied) {
image = [PGPhotoEditor resultImageForImage:image adjustments:adjustments];
}
return TGPhotoEditorCrop(image, paintingImage, adjustments.cropOrientation, 0, scaledCropRect, adjustments.cropMirrored, targetSize, sourceSize, resize);
}
if (timer != nil) return image;
dict[@"timer"] = timer; };
if (groupedId != nil && !hasAnyTimers) CGSize imageSize = TGFillSize(asset.originalSize, CGSizeMake(512, 512));
dict[@"groupedId"] = groupedId; SSignal *trimmedVideoThumbnailSignal = [[video avAsset] mapToSignal:^SSignal *(AVURLAsset *avAsset) {
return [[TGMediaAssetImageSignals videoThumbnailForAVAsset:avAsset size:imageSize timestamp:CMTimeMakeWithSeconds(adjustments.trimStartValue, NSEC_PER_SEC)] map:^UIImage *(UIImage *image)
id generatedItem = descriptionGenerator(dict, caption, nil, nil); {
return generatedItem; return cropVideoThumbnail(image, TGScaleToFill(asset.originalSize, CGSizeMake(512, 512)), asset.originalSize, true);
}];
}]; }];
SSignal *assetSignal = inlineSignal; SSignal *(^inlineThumbnailSignal)(id<TGMediaEditableItem>) = ^SSignal *(id<TGMediaEditableItem> item)
SSignal *imageSignal = assetSignal;
if (editingContext != nil)
{ {
imageSignal = [[[[[editingContext imageSignalForItem:asset withUpdates:true] filter:^bool(id result) return [item thumbnailImageSignal];
{ };
return result == nil || ([result isKindOfClass:[UIImage class]] && !((UIImage *)result).degraded);
}] take:1] mapToSignal:^SSignal *(id result)
{
if (result == nil)
{
return [SSignal fail:nil];
}
else if ([result isKindOfClass:[UIImage class]])
{
UIImage *image = (UIImage *)result;
image.edited = true;
return [SSignal single:image];
}
return [SSignal complete];
}] onCompletion:^
{
__strong TGMediaEditingContext *strongEditingContext = editingContext;
[strongEditingContext description];
}];
}
[signals addObject:[[imageSignal map:^NSDictionary *(UIImage *image) SSignal *videoThumbnailSignal = [inlineThumbnailSignal(asset) map:^UIImage *(UIImage *image) {
{ return cropVideoThumbnail(image, image.size, image.size, false);
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; }];
dict[@"type"] = @"editedPhoto";
dict[@"image"] = image; SSignal *thumbnailSignal = adjustments.trimStartValue > FLT_EPSILON ? trimmedVideoThumbnailSignal : videoThumbnailSignal;
if (adjustments.paintingData.stickers.count > 0) TGMediaVideoConversionPreset preset = [TGMediaVideoConverter presetFromAdjustments:adjustments];
dict[@"stickers"] = adjustments.paintingData.stickers; CGSize dimensions = [TGMediaVideoConverter dimensionsFor:asset.originalSize adjustments:adjustments preset:preset];
NSTimeInterval duration = adjustments.trimApplied ? (adjustments.trimEndValue - adjustments.trimStartValue) : video.videoDuration;
if (timer != nil)
dict[@"timer"] = timer; [signals addObject:[thumbnailSignal mapToSignal:^id(UIImage *image)
if (groupedId != nil && !hasAnyTimers)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
return generatedItem;
}] catch:^SSignal *(__unused id error)
{ {
return inlineSignal; return [video.avAsset map:^id(AVURLAsset *avAsset) {
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
dict[@"type"] = @"cameraVideo";
dict[@"url"] = avAsset.URL;
dict[@"previewImage"] = image;
dict[@"adjustments"] = adjustments;
dict[@"dimensions"] = [NSValue valueWithCGSize:dimensions];
dict[@"duration"] = @(duration);
if (adjustments.paintingData.stickers.count > 0)
dict[@"stickers"] = adjustments.paintingData.stickers;
if (timer != nil)
dict[@"timer"] = timer;
else if (groupedId != nil && !hasAnyTimers)
dict[@"groupedId"] = groupedId;
id generatedItem = descriptionGenerator(dict, caption, nil, nil);
return generatedItem;
}];
}]]; }]];
i++;
i++; i++;
num++; num++;
} }

View File

@ -326,7 +326,7 @@ public func legacyEnqueueGifMessage(account: Account, data: Data, correlationId:
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
var randomId: Int64 = 0 var randomId: Int64 = 0
@ -368,7 +368,7 @@ public func legacyEnqueueVideoMessage(account: Account, data: Data, correlationI
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
var randomId: Int64 = 0 var randomId: Int64 = 0
@ -421,7 +421,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)!
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
} }
switch data { switch data {
@ -435,7 +435,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
let _ = try? scaledImageData.write(to: URL(fileURLWithPath: tempFilePath)) let _ = try? scaledImageData.write(to: URL(fileURLWithPath: tempFilePath))
let resource = LocalFileReferenceMediaResource(localFilePath: tempFilePath, randomId: randomId) let resource = LocalFileReferenceMediaResource(localFilePath: tempFilePath, randomId: randomId)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
var imageFlags: TelegramMediaImageFlags = [] var imageFlags: TelegramMediaImageFlags = []
@ -491,7 +491,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
let size = CGSize(width: CGFloat(asset.pixelWidth), height: CGFloat(asset.pixelHeight)) let size = CGSize(width: CGFloat(asset.pixelWidth), height: CGFloat(asset.pixelHeight))
let scaledSize = size.aspectFittedOrSmaller(CGSize(width: 1280.0, height: 1280.0)) let scaledSize = size.aspectFittedOrSmaller(CGSize(width: 1280.0, height: 1280.0))
let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: Int64.random(in: Int64.min ... Int64.max)) let resource = PhotoLibraryMediaResource(localIdentifier: asset.localIdentifier, uniqueId: Int64.random(in: Int64.min ... Int64.max))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let media = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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] = []
@ -540,7 +540,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)!
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
} }
@ -655,7 +655,7 @@ public func legacyAssetPickerEnqueueMessages(account: Account, signals: [Any]) -
let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)! let thumbnailImage = TGScaleImageToPixelSize(thumbnail, thumbnailSize)!
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
} }

View File

@ -13,13 +13,13 @@ public func mediaPasteboardScreen(
context: AccountContext, context: AccountContext,
updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil,
peer: EnginePeer, peer: EnginePeer,
subjects: [UIImage], subjects: [MediaPickerScreen.Subject.Media],
presentMediaPicker: @escaping (_ subject: MediaPickerScreen.Subject, _ saveEditedPhotos: Bool, _ bannedSendMedia: (Int32, Bool)?, _ present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void) -> Void, presentMediaPicker: @escaping (_ subject: MediaPickerScreen.Subject, _ saveEditedPhotos: Bool, _ bannedSendMedia: (Int32, Bool)?, _ present: @escaping (MediaPickerScreen, AttachmentMediaPickerContext?) -> Void) -> Void,
getSourceRect: (() -> CGRect?)? = nil getSourceRect: (() -> CGRect?)? = nil
) -> ViewController { ) -> ViewController {
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: peer.id), buttons: [.standalone], initialButton: .standalone) let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: peer.id), buttons: [.standalone], initialButton: .standalone)
controller.requestController = { _, present in controller.requestController = { _, present in
presentMediaPicker(.media(subjects.map { .image($0) }), false, nil, { mediaPicker, mediaPickerContext in presentMediaPicker(.media(subjects), false, nil, { mediaPicker, mediaPickerContext in
present(mediaPicker, mediaPickerContext) present(mediaPicker, mediaPickerContext)
}) })
} }

View File

@ -293,7 +293,7 @@ func presentLegacyMediaPickerGallery(context: AccountContext, peer: EnginePeer?,
model.interfaceView.setThumbnailSignalForItem { item in model.interfaceView.setThumbnailSignalForItem { item in
let imageSignal = SSignal(generator: { subscriber in let imageSignal = SSignal(generator: { subscriber in
var asset: PHAsset? var asset: PHAsset?
if let item = item as? TGCameraCapturedVideo { if let item = item as? TGCameraCapturedVideo, item.originalAsset != nil {
asset = item.originalAsset.backingAsset asset = item.originalAsset.backingAsset
} else if let item = item as? TGMediaAsset { } else if let item = item as? TGMediaAsset {
asset = item.backingAsset asset = item.backingAsset

View File

@ -11,6 +11,7 @@ swift_library(
], ],
deps = [ deps = [
"//submodules/TelegramCore:TelegramCore", "//submodules/TelegramCore:TelegramCore",
"//submodules/Postbox:Postbox",
], ],
visibility = [ visibility = [
"//visibility:public", "//visibility:public",

View File

@ -1,10 +1,20 @@
import Foundation import Foundation
import TelegramCore import TelegramCore
import Postbox
public extension Message {
func isRestricted(platform: String, contentSettings: ContentSettings) -> Bool {
if let attribute = self.restrictedContentAttribute {
return attribute.platformText(platform: platform, contentSettings: contentSettings) != nil
}
return false
}
}
public extension RestrictedContentMessageAttribute { public extension RestrictedContentMessageAttribute {
func platformText(platform: String, contentSettings: ContentSettings) -> String? { func platformText(platform: String, contentSettings: ContentSettings) -> String? {
for rule in self.rules { for rule in self.rules {
if rule.platform == "all" || rule.platform == "ios" { if rule.platform == "all" || rule.platform == "ios" || contentSettings.addContentRestrictionReasons.contains(rule.platform) {
if !contentSettings.ignoreContentRestrictionReasons.contains(rule.reason) { if !contentSettings.ignoreContentRestrictionReasons.contains(rule.reason) {
return rule.text return rule.text
} }

View File

@ -268,7 +268,7 @@ private final class ChatListViewSpaceState {
} }
postboxLog("allIndices not unique, repeated: \(debugRepeatedIndices)") postboxLog("allIndices not unique, repeated: \(debugRepeatedIndices)")
assert(false) //assert(false)
//preconditionFailure() //preconditionFailure()
} }
if Set(allEntityIds).count != allEntityIds.count { if Set(allEntityIds).count != allEntityIds.count {

View File

@ -174,7 +174,7 @@ func uploadCustomWallpaper(context: AccountContext, wallpaper: WallpaperGalleryE
let apply: () -> Void = { let apply: () -> Void = {
let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: nil) let settings = WallpaperSettings(blur: mode.contains(.blur), motion: mode.contains(.motion), colors: [], intensity: nil)
let wallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)], settings) let wallpaper: TelegramWallpaper = .image([TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), TelegramMediaImageRepresentation(dimensions: PixelDimensions(croppedImage.size), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], settings)
updateWallpaper(wallpaper) updateWallpaper(wallpaper)
DispatchQueue.main.async { DispatchQueue.main.async {
completion() completion()

View File

@ -407,7 +407,7 @@ public func editThemeController(context: AccountContext, mode: EditThemeControll
|> mapToSignal { wallpaper -> Signal<TelegramWallpaper?, NoError> in |> mapToSignal { wallpaper -> Signal<TelegramWallpaper?, NoError> in
if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper {
var convertedRepresentations: [ImageRepresentationWithReference] = [] var convertedRepresentations: [ImageRepresentationWithReference] = []
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
return wallpaperDatas(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) return wallpaperDatas(account: context.account, accountManager: context.sharedContext.accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|> mapToSignal { _, fullSizeData, complete -> Signal<TelegramWallpaper?, NoError> in |> mapToSignal { _, fullSizeData, complete -> Signal<TelegramWallpaper?, NoError> in
guard complete, let fullSizeData = fullSizeData else { guard complete, let fullSizeData = fullSizeData else {

View File

@ -207,7 +207,7 @@ final class SettingsThemeWallpaperNode: ASDisplayNode {
} }
let fullDimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) let fullDimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000)
let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))] let convertedFullRepresentations = [ImageRepresentationWithReference(representation: .init(dimensions: fullDimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))]
let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> let imageSignal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>
if wallpaper.isPattern { if wallpaper.isPattern {

View File

@ -473,7 +473,7 @@ final class ThemeAccentColorControllerNode: ASDisplayNode, UIScrollViewDelegate
for representation in file.file.previewRepresentations { for representation in file.file.previewRepresentations {
convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource)))
} }
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
} else if backgroundColors.count >= 2 { } else if backgroundColors.count >= 2 {
wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors.map { $0.rgb }, settings: WallpaperSettings(rotation: state.rotation))) wallpaper = .gradient(TelegramWallpaper.Gradient(id: nil, colors: backgroundColors.map { $0.rgb }, settings: WallpaperSettings(rotation: state.rotation)))
} else { } else {

View File

@ -108,10 +108,10 @@ final class ThemeGridSearchItemNode: GridItemNode {
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
if let imageResource = imageResource, let imageDimensions = imageDimensions { if let imageResource = imageResource, let imageDimensions = imageDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
if !representations.isEmpty { if !representations.isEmpty {
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])

View File

@ -252,7 +252,7 @@ final class ThemePreviewControllerNode: ASDisplayNode, UIScrollViewDelegate {
for representation in file.file.previewRepresentations { for representation in file.file.previewRepresentations {
convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: .wallpaper(wallpaper: .slug(file.slug), resource: representation.resource)))
} }
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError> let signal: Signal<(TransformImageArguments) -> DrawingContext?, NoError>
if wallpaper.isPattern { if wallpaper.isPattern {

View File

@ -383,7 +383,7 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
for representation in file.file.previewRepresentations { for representation in file.file.previewRepresentations {
convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: representation.resource, media: file.file, message: message, slug: file.slug))) convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: representation.resource, media: file.file, message: message, slug: file.slug)))
} }
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: file.file.resource, media: file.file, message: message, slug: file.slug))) convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: reference(for: file.file.resource, media: file.file, message: message, slug: file.slug)))
if wallpaper.isPattern { if wallpaper.isPattern {
var patternColors: [UIColor] = [] var patternColors: [UIColor] = []
@ -541,9 +541,9 @@ final class WallpaperGalleryItemNode: GalleryItemNode {
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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))

View File

@ -778,7 +778,8 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-761649164] = { return Api.Update.parse_updateChannelMessageForwards($0) } dict[-761649164] = { return Api.Update.parse_updateChannelMessageForwards($0) }
dict[-232346616] = { return Api.Update.parse_updateChannelMessageViews($0) } dict[-232346616] = { return Api.Update.parse_updateChannelMessageViews($0) }
dict[-1738720581] = { return Api.Update.parse_updateChannelParticipant($0) } dict[-1738720581] = { return Api.Update.parse_updateChannelParticipant($0) }
dict[-158027602] = { return Api.Update.parse_updateChannelPinnedTopic($0) } dict[422509539] = { return Api.Update.parse_updateChannelPinnedTopic($0) }
dict[-31881726] = { return Api.Update.parse_updateChannelPinnedTopics($0) }
dict[-366410403] = { return Api.Update.parse_updateChannelReadMessagesContents($0) } dict[-366410403] = { return Api.Update.parse_updateChannelReadMessagesContents($0) }
dict[277713951] = { return Api.Update.parse_updateChannelTooLong($0) } dict[277713951] = { return Api.Update.parse_updateChannelTooLong($0) }
dict[-1937192669] = { return Api.Update.parse_updateChannelUserTyping($0) } dict[-1937192669] = { return Api.Update.parse_updateChannelUserTyping($0) }

View File

@ -671,7 +671,8 @@ public extension Api {
case updateChannelMessageForwards(channelId: Int64, id: Int32, forwards: Int32) case updateChannelMessageForwards(channelId: Int64, id: Int32, forwards: Int32)
case updateChannelMessageViews(channelId: Int64, id: Int32, views: Int32) case updateChannelMessageViews(channelId: Int64, id: Int32, views: Int32)
case updateChannelParticipant(flags: Int32, channelId: Int64, date: Int32, actorId: Int64, userId: Int64, prevParticipant: Api.ChannelParticipant?, newParticipant: Api.ChannelParticipant?, invite: Api.ExportedChatInvite?, qts: Int32) case updateChannelParticipant(flags: Int32, channelId: Int64, date: Int32, actorId: Int64, userId: Int64, prevParticipant: Api.ChannelParticipant?, newParticipant: Api.ChannelParticipant?, invite: Api.ExportedChatInvite?, qts: Int32)
case updateChannelPinnedTopic(flags: Int32, channelId: Int64, topicId: Int32?) case updateChannelPinnedTopic(flags: Int32, channelId: Int64, topicId: Int32)
case updateChannelPinnedTopics(flags: Int32, channelId: Int64, order: [Int32]?)
case updateChannelReadMessagesContents(flags: Int32, channelId: Int64, topMsgId: Int32?, messages: [Int32]) case updateChannelReadMessagesContents(flags: Int32, channelId: Int64, topMsgId: Int32?, messages: [Int32])
case updateChannelTooLong(flags: Int32, channelId: Int64, pts: Int32?) case updateChannelTooLong(flags: Int32, channelId: Int64, pts: Int32?)
case updateChannelUserTyping(flags: Int32, channelId: Int64, topMsgId: Int32?, fromId: Api.Peer, action: Api.SendMessageAction) case updateChannelUserTyping(flags: Int32, channelId: Int64, topMsgId: Int32?, fromId: Api.Peer, action: Api.SendMessageAction)
@ -927,11 +928,23 @@ public extension Api {
break break
case .updateChannelPinnedTopic(let flags, let channelId, let topicId): case .updateChannelPinnedTopic(let flags, let channelId, let topicId):
if boxed { if boxed {
buffer.appendInt32(-158027602) buffer.appendInt32(422509539)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(channelId, buffer: buffer, boxed: false) serializeInt64(channelId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topicId!, buffer: buffer, boxed: false)} serializeInt32(topicId, buffer: buffer, boxed: false)
break
case .updateChannelPinnedTopics(let flags, let channelId, let order):
if boxed {
buffer.appendInt32(-31881726)
}
serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt64(channelId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order!.count))
for item in order! {
serializeInt32(item, buffer: buffer, boxed: false)
}}
break break
case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let messages): case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let messages):
if boxed { if boxed {
@ -1741,6 +1754,8 @@ public extension Api {
return ("updateChannelParticipant", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("date", String(describing: date)), ("actorId", String(describing: actorId)), ("userId", String(describing: userId)), ("prevParticipant", String(describing: prevParticipant)), ("newParticipant", String(describing: newParticipant)), ("invite", String(describing: invite)), ("qts", String(describing: qts))]) return ("updateChannelParticipant", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("date", String(describing: date)), ("actorId", String(describing: actorId)), ("userId", String(describing: userId)), ("prevParticipant", String(describing: prevParticipant)), ("newParticipant", String(describing: newParticipant)), ("invite", String(describing: invite)), ("qts", String(describing: qts))])
case .updateChannelPinnedTopic(let flags, let channelId, let topicId): case .updateChannelPinnedTopic(let flags, let channelId, let topicId):
return ("updateChannelPinnedTopic", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("topicId", String(describing: topicId))]) return ("updateChannelPinnedTopic", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("topicId", String(describing: topicId))])
case .updateChannelPinnedTopics(let flags, let channelId, let order):
return ("updateChannelPinnedTopics", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("order", String(describing: order))])
case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let messages): case .updateChannelReadMessagesContents(let flags, let channelId, let topMsgId, let messages):
return ("updateChannelReadMessagesContents", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("topMsgId", String(describing: topMsgId)), ("messages", String(describing: messages))]) return ("updateChannelReadMessagesContents", [("flags", String(describing: flags)), ("channelId", String(describing: channelId)), ("topMsgId", String(describing: topMsgId)), ("messages", String(describing: messages))])
case .updateChannelTooLong(let flags, let channelId, let pts): case .updateChannelTooLong(let flags, let channelId, let pts):
@ -2307,12 +2322,31 @@ public extension Api {
var _2: Int64? var _2: Int64?
_2 = reader.readInt64() _2 = reader.readInt64()
var _3: Int32? var _3: Int32?
if Int(_1!) & Int(1 << 0) != 0 {_3 = reader.readInt32() } _3 = reader.readInt32()
let _c1 = _1 != nil
let _c2 = _2 != nil
let _c3 = _3 != nil
if _c1 && _c2 && _c3 {
return Api.Update.updateChannelPinnedTopic(flags: _1!, channelId: _2!, topicId: _3!)
}
else {
return nil
}
}
public static func parse_updateChannelPinnedTopics(_ reader: BufferReader) -> Update? {
var _1: Int32?
_1 = reader.readInt32()
var _2: Int64?
_2 = reader.readInt64()
var _3: [Int32]?
if Int(_1!) & Int(1 << 0) != 0 {if let _ = reader.readInt32() {
_3 = Api.parseVector(reader, elementSignature: -1471112230, elementType: Int32.self)
} }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil let _c3 = (Int(_1!) & Int(1 << 0) == 0) || _3 != nil
if _c1 && _c2 && _c3 { if _c1 && _c2 && _c3 {
return Api.Update.updateChannelPinnedTopic(flags: _1!, channelId: _2!, topicId: _3) return Api.Update.updateChannelPinnedTopics(flags: _1!, channelId: _2!, order: _3)
} }
else { else {
return nil return nil

View File

@ -2443,6 +2443,26 @@ public extension Api.functions.channels {
}) })
} }
} }
public extension Api.functions.channels {
static func reorderPinnedForumTopics(channel: Api.InputChannel, order: [Int32]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer()
buffer.appendInt32(-529811367)
channel.serialize(buffer, true)
buffer.appendInt32(481674261)
buffer.appendInt32(Int32(order.count))
for item in order {
serializeInt32(item, buffer: buffer, boxed: false)
}
return (FunctionDescription(name: "channels.reorderPinnedForumTopics", parameters: [("channel", String(describing: channel)), ("order", String(describing: order))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer)
var result: Api.Updates?
if let signature = reader.readInt32() {
result = Api.parse(reader, signature: signature) as? Api.Updates
}
return result
})
}
}
public extension Api.functions.channels { public extension Api.functions.channels {
static func reorderUsernames(channel: Api.InputChannel, order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func reorderUsernames(channel: Api.InputChannel, order: [String]) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
@ -5364,16 +5384,17 @@ public extension Api.functions.messages {
} }
} }
public extension Api.functions.messages { public extension Api.functions.messages {
static func prolongWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func prolongWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMsgId: Int32?, topMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-362824498) buffer.appendInt32(2146648841)
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true) peer.serialize(buffer, true)
bot.serialize(buffer, true) bot.serialize(buffer, true)
serializeInt64(queryId, buffer: buffer, boxed: false) serializeInt64(queryId, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)} if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.prolongWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("queryId", String(describing: queryId)), ("replyToMsgId", String(describing: replyToMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in return (FunctionDescription(name: "messages.prolongWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("queryId", String(describing: queryId)), ("replyToMsgId", String(describing: replyToMsgId)), ("topMsgId", String(describing: topMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Bool? var result: Api.Bool?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -5718,9 +5739,9 @@ public extension Api.functions.messages {
} }
} }
public extension Api.functions.messages { public extension Api.functions.messages {
static func requestWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, url: String?, startParam: String?, themeParams: Api.DataJSON?, platform: String, replyToMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.WebViewResult>) { static func requestWebView(flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, url: String?, startParam: String?, themeParams: Api.DataJSON?, platform: String, replyToMsgId: Int32?, topMsgId: Int32?, sendAs: Api.InputPeer?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.WebViewResult>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-58219204) buffer.appendInt32(395003915)
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true) peer.serialize(buffer, true)
bot.serialize(buffer, true) bot.serialize(buffer, true)
@ -5729,8 +5750,9 @@ public extension Api.functions.messages {
if Int(flags) & Int(1 << 2) != 0 {themeParams!.serialize(buffer, true)} if Int(flags) & Int(1 << 2) != 0 {themeParams!.serialize(buffer, true)}
serializeString(platform, buffer: buffer, boxed: false) serializeString(platform, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 0) != 0 {serializeInt32(replyToMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 9) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)} if Int(flags) & Int(1 << 13) != 0 {sendAs!.serialize(buffer, true)}
return (FunctionDescription(name: "messages.requestWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("url", String(describing: url)), ("startParam", String(describing: startParam)), ("themeParams", String(describing: themeParams)), ("platform", String(describing: platform)), ("replyToMsgId", String(describing: replyToMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.WebViewResult? in return (FunctionDescription(name: "messages.requestWebView", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("bot", String(describing: bot)), ("url", String(describing: url)), ("startParam", String(describing: startParam)), ("themeParams", String(describing: themeParams)), ("platform", String(describing: platform)), ("replyToMsgId", String(describing: replyToMsgId)), ("topMsgId", String(describing: topMsgId)), ("sendAs", String(describing: sendAs))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.WebViewResult? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.WebViewResult? var result: Api.WebViewResult?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -6542,11 +6564,13 @@ public extension Api.functions.messages {
} }
} }
public extension Api.functions.messages { public extension Api.functions.messages {
static func unpinAllMessages(peer: Api.InputPeer) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.AffectedHistory>) { static func unpinAllMessages(flags: Int32, peer: Api.InputPeer, topMsgId: Int32?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.messages.AffectedHistory>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-265962357) buffer.appendInt32(-299714136)
serializeInt32(flags, buffer: buffer, boxed: false)
peer.serialize(buffer, true) peer.serialize(buffer, true)
return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("peer", String(describing: peer))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in if Int(flags) & Int(1 << 0) != 0 {serializeInt32(topMsgId!, buffer: buffer, boxed: false)}
return (FunctionDescription(name: "messages.unpinAllMessages", parameters: [("flags", String(describing: flags)), ("peer", String(describing: peer)), ("topMsgId", String(describing: topMsgId))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.messages.AffectedHistory? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.messages.AffectedHistory? var result: Api.messages.AffectedHistory?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {

View File

@ -6251,7 +6251,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
self.call.account.postbox.mediaBox.storeResourceData(resource.id, data: data) self.call.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
self.currentUpdatingAvatar = representation self.currentUpdatingAvatar = representation
self.updateAvatarPromise.set(.single((representation, 0.0))) self.updateAvatarPromise.set(.single((representation, 0.0)))
@ -6286,7 +6286,7 @@ public final class VoiceChatControllerImpl: ViewController, VoiceChatController
let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
self.currentUpdatingAvatar = representation self.currentUpdatingAvatar = representation
self.updateAvatarPromise.set(.single((representation, 0.0))) self.updateAvatarPromise.set(.single((representation, 0.0)))

View File

@ -93,7 +93,8 @@ enum AccountStateMutationOperation {
case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32) case ReadSecretOutbox(peerId: PeerId, maxTimestamp: Int32, actionTimestamp: Int32)
case AddPeerInputActivity(chatPeerId: PeerActivitySpace, peerId: PeerId?, activity: PeerInputActivity?) case AddPeerInputActivity(chatPeerId: PeerActivitySpace, peerId: PeerId?, activity: PeerInputActivity?)
case UpdatePinnedItemIds(PeerGroupId, AccountStateUpdatePinnedItemIdsOperation) case UpdatePinnedItemIds(PeerGroupId, AccountStateUpdatePinnedItemIdsOperation)
case UpdatePinnedTopic(peerId: PeerId, threadId: Int64?) case UpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool)
case UpdatePinnedTopicOrder(peerId: PeerId, threadIds: [Int64])
case ReadMessageContents((PeerId?, [Int32])) case ReadMessageContents((PeerId?, [Int32]))
case UpdateMessageImpressionCount(MessageId, Int32) case UpdateMessageImpressionCount(MessageId, Int32)
case UpdateMessageForwardsCount(MessageId, Int32) case UpdateMessageForwardsCount(MessageId, Int32)
@ -475,8 +476,12 @@ struct AccountMutableState {
self.addOperation(.UpdatePinnedItemIds(groupId, operation)) self.addOperation(.UpdatePinnedItemIds(groupId, operation))
} }
mutating func addUpdatePinnedTopic(peerId: PeerId, threadId: Int64?) { mutating func addUpdatePinnedTopic(peerId: PeerId, threadId: Int64, isPinned: Bool) {
self.addOperation(.UpdatePinnedTopic(peerId: peerId, threadId: threadId)) self.addOperation(.UpdatePinnedTopic(peerId: peerId, threadId: threadId, isPinned: isPinned))
}
mutating func addUpdatePinnedTopicOrder(peerId: PeerId, threadIds: [Int64]) {
self.addOperation(.UpdatePinnedTopicOrder(peerId: peerId, threadIds: threadIds))
} }
mutating func addReadMessagesContents(_ peerIdsAndMessageIds: (PeerId?, [Int32])) { mutating func addReadMessagesContents(_ peerIdsAndMessageIds: (PeerId?, [Int32])) {
@ -545,7 +550,7 @@ struct AccountMutableState {
mutating func addOperation(_ operation: AccountStateMutationOperation) { mutating func addOperation(_ operation: AccountStateMutationOperation) {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .ReadOutbox, .ReadGroupFeedInbox, .MergePeerPresences, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdatePeerChatUnreadMark, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilterOrder, .UpdateChatListFilter, .UpdateReadThread, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateMessagesPinned, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic:
break break
case let .AddMessages(messages, location): case let .AddMessages(messages, location):
for message in messages { for message in messages {

View File

@ -6,15 +6,16 @@ import TelegramApi
func imageRepresentationsForApiChatPhoto(_ photo: Api.ChatPhoto) -> [TelegramMediaImageRepresentation] { func imageRepresentationsForApiChatPhoto(_ photo: Api.ChatPhoto) -> [TelegramMediaImageRepresentation] {
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
switch photo { switch photo {
case let .chatPhoto(_, photoId, strippedThumb, dcId): case let .chatPhoto(flags, photoId, strippedThumb, dcId):
let hasVideo = (flags & (1 << 0)) != 0
let smallResource: TelegramMediaResource let smallResource: TelegramMediaResource
let fullSizeResource: TelegramMediaResource let fullSizeResource: TelegramMediaResource
smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .small, volumeId: nil, localId: nil) smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .small, volumeId: nil, localId: nil)
fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .fullSize, volumeId: nil, localId: nil) fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: photoId, sizeSpec: .fullSize, volumeId: nil, localId: nil)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo))
case .chatPhotoEmpty: case .chatPhotoEmpty:
break break
} }

View File

@ -478,7 +478,7 @@ extension ChatContextResultMessage {
if let replyMarkup = replyMarkup { if let replyMarkup = replyMarkup {
parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup) parsedReplyMarkup = ReplyMarkupMessageAttribute(apiMarkup: replyMarkup)
} }
self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, flags: parsedFlags), replyMarkup: parsedReplyMarkup) self = .invoice(media: TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: currency, totalAmount: totalAmount, startParam: "", extendedMedia: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), replyMarkup: parsedReplyMarkup)
} }
} }
} }

View File

@ -336,7 +336,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
extendedMedia = nil extendedMedia = nil
} }
return (TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: receiptMsgId.flatMap { MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }, currency: currency, totalAmount: totalAmount, startParam: startParam, extendedMedia: extendedMedia, flags: parsedFlags), nil, nil) return (TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: receiptMsgId.flatMap { MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) }, currency: currency, totalAmount: totalAmount, startParam: startParam, extendedMedia: extendedMedia, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion), nil, nil)
case let .messageMediaPoll(poll, results): case let .messageMediaPoll(poll, results):
switch poll { switch poll {
case let .poll(id, flags, question, answers, closePeriod, _): case let .poll(id, flags, question, answers, closePeriod, _):

View File

@ -134,13 +134,13 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
switch size { switch size {
case let .photoCachedSize(type, w, h, _): case let .photoCachedSize(type, w, h, _):
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSize(type, w, h, _): case let .photoSize(type, w, h, _):
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSizeProgressive(type, w, h, sizes): case let .photoSizeProgressive(type, w, h, sizes):
let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference) let resource = CloudDocumentSizeMediaResource(datacenterId: datacenterId, documentId: documentId, accessHash: accessHash, sizeSpec: type, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false))
case let .photoPathSize(_, data): case let .photoPathSize(_, data):
immediateThumbnailData = data.makeData() immediateThumbnailData = data.makeData()
case let .photoStrippedSize(_, data): case let .photoStrippedSize(_, data):

View File

@ -10,14 +10,14 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
switch size { switch size {
case let .photoCachedSize(type, w, h, _): case let .photoCachedSize(type, w, h, _):
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: nil, fileReference: fileReference) let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: nil, fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSize(type, w, h, size): case let .photoSize(type, w, h, size):
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference) let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(size), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSizeProgressive(type, w, h, sizes): case let .photoSizeProgressive(type, w, h, sizes):
if !sizes.isEmpty { if !sizes.isEmpty {
let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(sizes[sizes.count - 1]), fileReference: fileReference) let resource = CloudPhotoSizeMediaResource(datacenterId: datacenterId, photoId: photoId, accessHash: accessHash, sizeSpec: type, size: Int64(sizes[sizes.count - 1]), fileReference: fileReference)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false))
} }
case let .photoStrippedSize(_, data): case let .photoStrippedSize(_, data):
immediateThumbnailData = data.makeData() immediateThumbnailData = data.makeData()

View File

@ -7,7 +7,7 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
switch photo { switch photo {
case let .userProfilePhoto(flags, id, strippedThumb, dcId): case let .userProfilePhoto(flags, id, strippedThumb, dcId):
let _ = (flags & (1 << 0)) != 0 let hasVideo = (flags & (1 << 0)) != 0
let smallResource: TelegramMediaResource let smallResource: TelegramMediaResource
let fullSizeResource: TelegramMediaResource let fullSizeResource: TelegramMediaResource
@ -15,8 +15,8 @@ func parsedTelegramProfilePhoto(_ photo: Api.UserProfilePhoto) -> [TelegramMedia
smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .small, volumeId: nil, localId: nil) smallResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .small, volumeId: nil, localId: nil)
fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .fullSize, volumeId: nil, localId: nil) fullSizeResource = CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: .fullSize, volumeId: nil, localId: nil)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 80, height: 80), resource: smallResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData())) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: fullSizeResource, progressiveSizes: [], immediateThumbnailData: strippedThumb?.makeData(), hasVideo: hasVideo))
case .userProfilePhotoEmpty: case .userProfilePhotoEmpty:
break break
} }

View File

@ -367,21 +367,16 @@ func _internal_setForumChannelTopicClosed(account: Account, id: EnginePeer.Id, t
public enum SetForumChannelTopicPinnedError { public enum SetForumChannelTopicPinnedError {
case generic case generic
case limitReached(Int)
} }
func _internal_setForumChannelTopicPinned(account: Account, id: EnginePeer.Id, threadId: Int64, isPinned: Bool) -> Signal<Never, SetForumChannelTopicPinnedError> { func _internal_setForumChannelPinnedTopics(account: Account, id: EnginePeer.Id, threadIds: [Int64]) -> Signal<Never, SetForumChannelTopicPinnedError> {
return account.postbox.transaction { transaction -> Api.InputChannel? in return account.postbox.transaction { transaction -> Api.InputChannel? in
guard let inputChannel = transaction.getPeer(id).flatMap(apiInputChannel) else { guard let inputChannel = transaction.getPeer(id).flatMap(apiInputChannel) else {
return nil return nil
} }
if isPinned { transaction.setPeerPinnedThreads(peerId: id, threadIds: threadIds)
transaction.setPeerPinnedThreads(peerId: id, threadIds: [threadId])
} else {
if transaction.getPeerPinnedThreads(peerId: id).contains(threadId) {
transaction.setPeerPinnedThreads(peerId: id, threadIds: [])
}
}
return inputChannel return inputChannel
} }
@ -390,13 +385,10 @@ func _internal_setForumChannelTopicPinned(account: Account, id: EnginePeer.Id, t
guard let inputChannel = inputChannel else { guard let inputChannel = inputChannel else {
return .fail(.generic) return .fail(.generic)
} }
var flags: Int32 = 0
flags |= (1 << 2)
return account.network.request(Api.functions.channels.updatePinnedForumTopic( return account.network.request(Api.functions.channels.reorderPinnedForumTopics(
channel: inputChannel, channel: inputChannel,
topicId: Int32(clamping: threadId), order: threadIds.map(Int32.init(clamping:))
pinned: isPinned ? .boolTrue : .boolFalse
)) ))
|> mapError { _ -> SetForumChannelTopicPinnedError in |> mapError { _ -> SetForumChannelTopicPinnedError in
return .generic return .generic

View File

@ -101,7 +101,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: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int64(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []))))) return .single(.result(.media(.standalone(media: TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: Int64.random(in: Int64.min ... Int64.max)), representations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: SecretFileMediaResource(fileId: id, accessHash: accessHash, containerSize: size, decryptedSize: Int64(data.count), datacenterId: Int(dcId), key: key), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])))))
case .encryptedFileEmpty: case .encryptedFileEmpty:
return .fail(.generic) return .fail(.generic)
} }

View File

@ -4,22 +4,30 @@ import TelegramApi
import SwiftSignalKit import SwiftSignalKit
public struct ContentSettings: Equatable { public struct ContentSettings: Equatable {
public static var `default` = ContentSettings(ignoreContentRestrictionReasons: []) public static var `default` = ContentSettings(ignoreContentRestrictionReasons: [], addContentRestrictionReasons: [])
public var ignoreContentRestrictionReasons: Set<String> public var ignoreContentRestrictionReasons: Set<String>
public var addContentRestrictionReasons: [String]
public init(ignoreContentRestrictionReasons: Set<String>) { public init(ignoreContentRestrictionReasons: Set<String>, addContentRestrictionReasons: [String]) {
self.ignoreContentRestrictionReasons = ignoreContentRestrictionReasons self.ignoreContentRestrictionReasons = ignoreContentRestrictionReasons
self.addContentRestrictionReasons = addContentRestrictionReasons
} }
} }
extension ContentSettings { extension ContentSettings {
init(appConfiguration: AppConfiguration) { init(appConfiguration: AppConfiguration) {
var reasons: [String] = [] var reasons: [String] = []
if let data = appConfiguration.data, let reasonsData = data["ignore_restriction_reasons"] as? [String] { var addContentRestrictionReasons: [String] = []
reasons = reasonsData if let data = appConfiguration.data {
if let reasonsData = data["ignore_restriction_reasons"] as? [String] {
reasons = reasonsData
}
if let addContentRestrictionReasonsData = data["restriction_add_platforms"] as? [String] {
addContentRestrictionReasons = addContentRestrictionReasonsData
}
} }
self.init(ignoreContentRestrictionReasons: Set(reasons)) self.init(ignoreContentRestrictionReasons: Set(reasons), addContentRestrictionReasons: addContentRestrictionReasons)
} }
} }

View File

@ -114,6 +114,11 @@ private func peerIdsRequiringLocalChatStateFromUpdates(_ updates: [Api.Update])
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order):
if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId)
}
case let .updateFolderPeers(folderPeers, _, _): case let .updateFolderPeers(folderPeers, _, _):
for peer in folderPeers { for peer in folderPeers {
switch peer { switch peer {
@ -337,11 +342,16 @@ private func peerIdsRequiringLocalChatStateFromDifference(_ difference: Api.upda
peerIds.insert(messageId.peerId) peerIds.insert(messageId.peerId)
} }
switch update { switch update {
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order):
if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
default: }
break default:
break
} }
} }
case .differenceEmpty: case .differenceEmpty:
@ -359,11 +369,16 @@ private func peerIdsRequiringLocalChatStateFromDifference(_ difference: Api.upda
peerIds.insert(messageId.peerId) peerIds.insert(messageId.peerId)
} }
switch update { switch update {
case let .updateChannelTooLong(_, channelId, _): case let .updateChannelTooLong(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId)
case let .updateChannelPinnedTopics(_, channelId, order):
if order == nil {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
peerIds.insert(peerId) peerIds.insert(peerId)
default: }
break default:
break
} }
} }
case .differenceTooLong: case .differenceTooLong:
@ -725,6 +740,20 @@ private func sortedUpdates(_ updates: [Api.Update]) -> [Api.Update] {
} else { } else {
updatesByChannel[peerId]!.append(update) updatesByChannel[peerId]!.append(update)
} }
case let .updateChannelPinnedTopic(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
if updatesByChannel[peerId] == nil {
updatesByChannel[peerId] = [update]
} else {
updatesByChannel[peerId]!.append(update)
}
case let .updateChannelPinnedTopics(_, channelId, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
if updatesByChannel[peerId] == nil {
updatesByChannel[peerId] = [update]
} else {
updatesByChannel[peerId]!.append(update)
}
case let .updateDeleteChannelMessages(channelId, _, _, _): case let .updateDeleteChannelMessages(channelId, _, _, _):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
if updatesByChannel[peerId] == nil { if updatesByChannel[peerId] == nil {
@ -860,6 +889,15 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
channelsToPoll.insert(peerId) channelsToPoll.insert(peerId)
} }
} }
case let .updateChannelPinnedTopics(_, channelId, order):
if let order = order {
updatedState.addUpdatePinnedTopicOrder(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadIds: order.map(Int64.init))
} else {
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
if !channelsToPoll.contains(peerId) {
channelsToPoll.insert(peerId)
}
}
case let .updateDeleteChannelMessages(channelId, messages, pts: pts, ptsCount): case let .updateDeleteChannelMessages(channelId, messages, pts: pts, ptsCount):
let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)) let peerId = PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId))
if let previousState = updatedState.channelStates[peerId] { if let previousState = updatedState.channelStates[peerId] {
@ -1375,8 +1413,9 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
} else { } else {
updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .sync) updatedState.addUpdatePinnedItemIds(groupId: groupId, operation: .sync)
} }
case let .updateChannelPinnedTopic(_, channelId, topicId): case let .updateChannelPinnedTopic(flags, channelId, topicId):
updatedState.addUpdatePinnedTopic(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadId: topicId.flatMap(Int64.init)) let isPinned = (flags & (1 << 0)) != 0
updatedState.addUpdatePinnedTopic(peerId: PeerId(namespace: Namespaces.Peer.CloudChannel, id: PeerId.Id._internalFromInt64Value(channelId)), threadId: Int64(topicId), isPinned: isPinned)
case let .updateReadMessagesContents(messages, _, _): case let .updateReadMessagesContents(messages, _, _):
updatedState.addReadMessagesContents((nil, messages)) updatedState.addReadMessagesContents((nil, messages))
case let .updateChannelReadMessagesContents(_, channelId, topMsgId, messages): case let .updateChannelReadMessagesContents(_, channelId, topMsgId, messages):
@ -2847,7 +2886,7 @@ private func optimizedOperations(_ operations: [AccountStateMutationOperation])
var currentAddScheduledMessages: OptimizeAddMessagesState? var currentAddScheduledMessages: OptimizeAddMessagesState?
for operation in operations { for operation in operations {
switch operation { switch operation {
case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic: case .DeleteMessages, .DeleteMessagesWithGlobalIds, .EditMessage, .UpdateMessagePoll, .UpdateMessageReactions, .UpdateMedia, .MergeApiChats, .MergeApiUsers, .MergePeerPresences, .UpdatePeer, .ReadInbox, .ReadOutbox, .ReadGroupFeedInbox, .ResetReadState, .ResetIncomingReadState, .UpdatePeerChatUnreadMark, .ResetMessageTagSummary, .UpdateNotificationSettings, .UpdateGlobalNotificationSettings, .UpdateSecretChat, .AddSecretMessages, .ReadSecretOutbox, .AddPeerInputActivity, .UpdateCachedPeerData, .UpdatePinnedItemIds, .UpdatePinnedTopic, .UpdatePinnedTopicOrder, .ReadMessageContents, .UpdateMessageImpressionCount, .UpdateMessageForwardsCount, .UpdateInstalledStickerPacks, .UpdateRecentGifs, .UpdateChatInputState, .UpdateCall, .AddCallSignalingData, .UpdateLangPack, .UpdateMinAvailableMessage, .UpdateIsContact, .UpdatePeerChatInclusion, .UpdatePeersNearby, .UpdateTheme, .SyncChatListFilters, .UpdateChatListFilter, .UpdateChatListFilterOrder, .UpdateReadThread, .UpdateMessagesPinned, .UpdateGroupCallParticipants, .UpdateGroupCall, .UpdateAutoremoveTimeout, .UpdateAttachMenuBots, .UpdateAudioTranscription, .UpdateConfig, .UpdateExtendedMedia, .ResetForumTopic:
if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty { if let currentAddMessages = currentAddMessages, !currentAddMessages.messages.isEmpty {
result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location)) result.append(.AddMessages(currentAddMessages.messages, currentAddMessages.location))
} }
@ -3757,12 +3796,18 @@ func replayFinalState(
case .sync: case .sync:
addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId) addSynchronizePinnedChatsOperation(transaction: transaction, groupId: groupId)
} }
case let .UpdatePinnedTopic(peerId, threadId): case let .UpdatePinnedTopic(peerId, threadId, isPinned):
if let threadId = threadId { var currentThreadIds = transaction.getPeerPinnedThreads(peerId: peerId)
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: [threadId]) if isPinned {
if !currentThreadIds.contains(threadId) {
currentThreadIds.insert(threadId, at: 0)
}
} else { } else {
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: []) currentThreadIds.removeAll(where: { $0 == threadId })
} }
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: currentThreadIds)
case let .UpdatePinnedTopicOrder(peerId, threadIds):
transaction.setPeerPinnedThreads(peerId: peerId, threadIds: threadIds)
case let .ReadMessageContents(peerIdAndMessageIds): case let .ReadMessageContents(peerIdAndMessageIds):
let (peerId, messageIds) = peerIdAndMessageIds let (peerId, messageIds) = peerIdAndMessageIds

View File

@ -784,10 +784,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
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: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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)
} }
@ -810,7 +810,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -825,7 +825,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -843,7 +843,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size): case let .photoSize(_, location, w, h, size):
switch location { switch location {
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -853,7 +853,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData())) resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -986,10 +986,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
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: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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)
} }
@ -1013,7 +1013,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1044,7 +1044,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1062,7 +1062,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size): case let .photoSize(_, location, w, h, size):
switch location { switch location {
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -1072,7 +1072,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData())) resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -1265,10 +1265,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
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: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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)
} }
@ -1292,7 +1292,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1323,7 +1323,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1341,7 +1341,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size): case let .photoSize(_, location, w, h, size):
switch location { switch location {
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -1351,7 +1351,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData())) resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -1466,10 +1466,10 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
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: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let image = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudSecretImage, id: file.id), representations: representations, immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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)
} }
@ -1493,7 +1493,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: size), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1524,7 +1524,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if thumb.size != 0 { if thumb.size != 0 {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: thumbW, height: thumbH), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resources.append((resource, thumb.makeData())) resources.append((resource, thumb.makeData()))
} }
let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes) let fileMedia = TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudSecretFile, id: file.id), partialReference: nil, resource: file.resource(key: SecretFileEncryptionKey(aesKey: key.makeData(), aesIv: iv.makeData()), decryptedSize: Int64(size)), previewRepresentations: previewRepresentations, videoThumbnails: [], immediateThumbnailData: nil, mimeType: mimeType, size: Int64(size), attributes: parsedAttributes)
@ -1542,7 +1542,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .photoSize(_, location, w, h, size): case let .photoSize(_, location, w, h, size):
switch location { switch location {
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: size == 0 ? nil : Int64(size), fileReference: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }
@ -1552,7 +1552,7 @@ private func parseMessage(peerId: PeerId, authorId: PeerId, tagLocalIndex: Int32
case let .fileLocation(dcId, volumeId, localId, secret): case let .fileLocation(dcId, volumeId, localId, secret):
let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil) let resource = CloudFileMediaResource(datacenterId: Int(dcId), volumeId: volumeId, localId: localId, secret: secret, size: Int64(bytes.size), fileReference: nil)
resources.append((resource, bytes.makeData())) resources.append((resource, bytes.makeData()))
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case .fileLocationUnavailable: case .fileLocationUnavailable:
break break
} }

View File

@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
public class Serialization: NSObject, MTSerialization { public class Serialization: NSObject, MTSerialization {
public func currentLayer() -> UInt { public func currentLayer() -> UInt {
return 148 return 149
} }
public func parseMessage(_ data: Data!) -> Any! { public func parseMessage(_ data: Data!) -> Any! {

View File

@ -305,12 +305,13 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
public let resource: TelegramMediaResource public let resource: TelegramMediaResource
public let progressiveSizes: [Int32] public let progressiveSizes: [Int32]
public let immediateThumbnailData: Data? public let immediateThumbnailData: Data?
public let hasVideo: Bool
public init(dimensions: PixelDimensions, resource: TelegramMediaResource, progressiveSizes: [Int32], immediateThumbnailData: Data?) { public init(dimensions: PixelDimensions, resource: TelegramMediaResource, progressiveSizes: [Int32], immediateThumbnailData: Data?, hasVideo: Bool) {
self.dimensions = dimensions self.dimensions = dimensions
self.resource = resource self.resource = resource
self.progressiveSizes = progressiveSizes self.progressiveSizes = progressiveSizes
self.immediateThumbnailData = immediateThumbnailData self.immediateThumbnailData = immediateThumbnailData
self.hasVideo = hasVideo
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
@ -318,6 +319,7 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
self.resource = decoder.decodeObjectForKey("r") as? TelegramMediaResource ?? EmptyMediaResource() self.resource = decoder.decodeObjectForKey("r") as? TelegramMediaResource ?? EmptyMediaResource()
self.progressiveSizes = decoder.decodeInt32ArrayForKey("ps") self.progressiveSizes = decoder.decodeInt32ArrayForKey("ps")
self.immediateThumbnailData = decoder.decodeDataForKey("th") self.immediateThumbnailData = decoder.decodeDataForKey("th")
self.hasVideo = decoder.decodeBoolForKey("hv", orElse: false)
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
@ -330,6 +332,7 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
} else { } else {
encoder.encodeNil(forKey: "th") encoder.encodeNil(forKey: "th")
} }
encoder.encodeBool(self.hasVideo, forKey: "hv")
} }
public var description: String { public var description: String {
@ -349,6 +352,9 @@ public final class TelegramMediaImageRepresentation: PostboxCoding, Equatable, C
if self.immediateThumbnailData != other.immediateThumbnailData { if self.immediateThumbnailData != other.immediateThumbnailData {
return false return false
} }
if self.hasVideo != other.hasVideo {
return false
}
return true return true
} }
} }

View File

@ -17,7 +17,7 @@ public struct TelegramMediaInvoiceFlags: OptionSet {
} }
public enum TelegramExtendedMedia: PostboxCoding, Equatable { public enum TelegramExtendedMedia: PostboxCoding, Equatable {
public static func == (lhs: TelegramExtendedMedia, rhs: TelegramExtendedMedia) -> Bool { public static func ==(lhs: TelegramExtendedMedia, rhs: TelegramExtendedMedia) -> Bool {
switch lhs { switch lhs {
case let .preview(lhsDimensions, lhsImmediateThumbnailData, lhsVideoDuration): case let .preview(lhsDimensions, lhsImmediateThumbnailData, lhsVideoDuration):
if case let .preview(rhsDimensions, rhsImmediateThumbnailData, rhsVideoDuration) = rhs, lhsDimensions == rhsDimensions, lhsImmediateThumbnailData == rhsImmediateThumbnailData, lhsVideoDuration == rhsVideoDuration { if case let .preview(rhsDimensions, rhsImmediateThumbnailData, rhsVideoDuration) = rhs, lhsDimensions == rhsDimensions, lhsImmediateThumbnailData == rhsImmediateThumbnailData, lhsVideoDuration == rhsVideoDuration {
@ -88,6 +88,8 @@ public enum TelegramExtendedMedia: PostboxCoding, Equatable {
} }
public final class TelegramMediaInvoice: Media { public final class TelegramMediaInvoice: Media {
public static let lastVersion: Int32 = 1
public var peerIds: [PeerId] = [] public var peerIds: [PeerId] = []
public var id: MediaId? = nil public var id: MediaId? = nil
@ -102,7 +104,9 @@ public final class TelegramMediaInvoice: Media {
public let flags: TelegramMediaInvoiceFlags public let flags: TelegramMediaInvoiceFlags
public let extendedMedia: TelegramExtendedMedia? public let extendedMedia: TelegramExtendedMedia?
public init(title: String, description: String, photo: TelegramMediaWebFile?, receiptMessageId: MessageId?, currency: String, totalAmount: Int64, startParam: String, extendedMedia: TelegramExtendedMedia?, flags: TelegramMediaInvoiceFlags) { public let version: Int32
public init(title: String, description: String, photo: TelegramMediaWebFile?, receiptMessageId: MessageId?, currency: String, totalAmount: Int64, startParam: String, extendedMedia: TelegramExtendedMedia?, flags: TelegramMediaInvoiceFlags, version: Int32) {
self.title = title self.title = title
self.description = description self.description = description
self.photo = photo self.photo = photo
@ -112,6 +116,7 @@ public final class TelegramMediaInvoice: Media {
self.startParam = startParam self.startParam = startParam
self.flags = flags self.flags = flags
self.extendedMedia = extendedMedia self.extendedMedia = extendedMedia
self.version = version
} }
public init(decoder: PostboxDecoder) { public init(decoder: PostboxDecoder) {
@ -129,6 +134,8 @@ public final class TelegramMediaInvoice: Media {
} else { } else {
self.receiptMessageId = nil self.receiptMessageId = nil
} }
self.version = decoder.decodeInt32ForKey("vrs", orElse: 0)
} }
public func encode(_ encoder: PostboxEncoder) { public func encode(_ encoder: PostboxEncoder) {
@ -160,6 +167,8 @@ public final class TelegramMediaInvoice: Media {
encoder.encodeNil(forKey: "r.n") encoder.encodeNil(forKey: "r.n")
encoder.encodeNil(forKey: "r.i") encoder.encodeNil(forKey: "r.i")
} }
encoder.encodeInt32(self.version, forKey: "vrs")
} }
public func isEqual(to other: Media) -> Bool { public func isEqual(to other: Media) -> Bool {
@ -199,6 +208,10 @@ public final class TelegramMediaInvoice: Media {
return false return false
} }
if self.version != other.version {
return false
}
return true return true
} }
@ -216,6 +229,8 @@ public final class TelegramMediaInvoice: Media {
totalAmount: self.totalAmount, totalAmount: self.totalAmount,
startParam: self.startParam, startParam: self.startParam,
extendedMedia: extendedMedia, extendedMedia: extendedMedia,
flags: self.flags) flags: self.flags,
version: self.version
)
} }
} }

View File

@ -57,10 +57,10 @@ public enum RequestWebViewError {
case generic case generic
} }
private func keepWebViewSignal(network: Network, stateManager: AccountStateManager, flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMessageId: MessageId?, sendAs: Api.InputPeer?) -> Signal<Never, KeepWebViewError> { private func keepWebViewSignal(network: Network, stateManager: AccountStateManager, flags: Int32, peer: Api.InputPeer, bot: Api.InputUser, queryId: Int64, replyToMessageId: MessageId?, threadId: Int64?, sendAs: Api.InputPeer?) -> Signal<Never, KeepWebViewError> {
let signal = Signal<Never, KeepWebViewError> { subscriber in let signal = Signal<Never, KeepWebViewError> { subscriber in
let poll = Signal<Never, KeepWebViewError> { subscriber in let poll = Signal<Never, KeepWebViewError> { subscriber in
let signal: Signal<Never, KeepWebViewError> = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyToMsgId: replyToMessageId?.id, sendAs: sendAs)) let signal: Signal<Never, KeepWebViewError> = network.request(Api.functions.messages.prolongWebView(flags: flags, peer: peer, bot: bot, queryId: queryId, replyToMsgId: replyToMessageId?.id, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: sendAs))
|> mapError { _ -> KeepWebViewError in |> mapError { _ -> KeepWebViewError in
return .generic return .generic
} }
@ -99,7 +99,7 @@ private func keepWebViewSignal(network: Network, stateManager: AccountStateManag
return signal return signal
} }
func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?) -> Signal<RequestWebViewResult, RequestWebViewError> { func _internal_requestWebView(postbox: Postbox, network: Network, stateManager: AccountStateManager, peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?, threadId: Int64?) -> Signal<RequestWebViewResult, RequestWebViewError> {
var serializedThemeParams: Api.DataJSON? var serializedThemeParams: Api.DataJSON?
if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) { if let themeParams = themeParams, let data = try? JSONSerialization.data(withJSONObject: themeParams, options: []), let dataString = String(data: data, encoding: .utf8) {
serializedThemeParams = .dataJSON(data: dataString) serializedThemeParams = .dataJSON(data: dataString)
@ -128,17 +128,20 @@ func _internal_requestWebView(postbox: Postbox, network: Network, stateManager:
if fromMenu { if fromMenu {
flags |= (1 << 4) flags |= (1 << 4)
} }
if threadId != nil {
flags |= (1 << 9)
}
// if _ { // if _ {
// flags |= (1 << 13) // flags |= (1 << 13)
// } // }
return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyToMsgId: replyToMsgId, sendAs: nil)) return network.request(Api.functions.messages.requestWebView(flags: flags, peer: inputPeer, bot: inputBot, url: url, startParam: payload, themeParams: serializedThemeParams, platform: botWebViewPlatform, replyToMsgId: replyToMsgId, topMsgId: threadId.flatMap(Int32.init(clamping:)), sendAs: nil))
|> mapError { _ -> RequestWebViewError in |> mapError { _ -> RequestWebViewError in
return .generic return .generic
} }
|> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in |> mapToSignal { result -> Signal<RequestWebViewResult, RequestWebViewError> in
switch result { switch result {
case let .webViewResultUrl(queryId, url): case let .webViewResultUrl(queryId, url):
return .single(RequestWebViewResult(queryId: queryId, url: url, keepAliveSignal: keepWebViewSignal(network: network, stateManager: stateManager, flags: flags, peer: inputPeer, bot: inputBot, queryId: queryId, replyToMessageId: replyToMessageId, sendAs: nil))) return .single(RequestWebViewResult(queryId: queryId, url: url, keepAliveSignal: keepWebViewSignal(network: network, stateManager: stateManager, flags: flags, peer: inputPeer, bot: inputBot, queryId: queryId, replyToMessageId: replyToMessageId, threadId: threadId, sendAs: nil)))
} }
} }
} }

View File

@ -69,7 +69,7 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId:
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, progressiveSizes: [], immediateThumbnailData: nil)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.LocalImage, id: randomId), representations: [TelegramMediaImageRepresentation(dimensions: imageDimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: [])
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []) return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: .standalone(media: tmpImage), replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
} else { } else {
return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: []) return .message(text: caption, attributes: attributes, inlineStickers: [:], mediaReference: nil, replyToMessageId: replyToMessageId, localGroupingKey: nil, correlationId: correlationId, bubbleUpEmojiOrStickersets: [])
@ -85,7 +85,7 @@ func _internal_outgoingMessageWithChatContextResult(to peerId: PeerId, threadId:
if thumbnail.mimeType.hasPrefix("video/") { if thumbnail.mimeType.hasPrefix("video/") {
videoThumbnails.append(TelegramMediaFile.VideoThumbnail(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource)) videoThumbnails.append(TelegramMediaFile.VideoThumbnail(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource))
} else { } else {
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: thumbnail.dimensions ?? PixelDimensions(width: 128, height: 128), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
} }
var fileName = "file" var fileName = "file"

View File

@ -106,8 +106,8 @@ public extension TelegramEngine {
return _internal_requestUpdatePinnedMessage(account: self.account, peerId: peerId, update: update) return _internal_requestUpdatePinnedMessage(account: self.account, peerId: peerId, update: update)
} }
public func requestUnpinAllMessages(peerId: PeerId) -> Signal<Never, UpdatePinnedMessageError> { public func requestUnpinAllMessages(peerId: PeerId, threadId: Int64?) -> Signal<Never, UpdatePinnedMessageError> {
return _internal_requestUnpinAllMessages(account: self.account, peerId: peerId) return _internal_requestUnpinAllMessages(account: self.account, peerId: peerId, threadId: threadId)
} }
public func fetchChannelReplyThreadMessage(messageId: MessageId, atMessageId: MessageId?) -> Signal<ChatReplyThreadMessage, FetchChannelReplyThreadMessageError> { public func fetchChannelReplyThreadMessage(messageId: MessageId, atMessageId: MessageId?) -> Signal<ChatReplyThreadMessage, FetchChannelReplyThreadMessageError> {
@ -382,8 +382,8 @@ public extension TelegramEngine {
return _internal_rateAudioTranscription(postbox: self.account.postbox, network: self.account.network, messageId: messageId, id: id, isGood: isGood) return _internal_rateAudioTranscription(postbox: self.account.postbox, network: self.account.network, messageId: messageId, id: id, isGood: isGood)
} }
public func requestWebView(peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?) -> Signal<RequestWebViewResult, RequestWebViewError> { public func requestWebView(peerId: PeerId, botId: PeerId, url: String?, payload: String?, themeParams: [String: Any]?, fromMenu: Bool, replyToMessageId: MessageId?, threadId: Int64?) -> Signal<RequestWebViewResult, RequestWebViewError> {
return _internal_requestWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, botId: botId, url: url, payload: payload, themeParams: themeParams, fromMenu: fromMenu, replyToMessageId: replyToMessageId) return _internal_requestWebView(postbox: self.account.postbox, network: self.account.network, stateManager: self.account.stateManager, peerId: peerId, botId: botId, url: url, payload: payload, themeParams: themeParams, fromMenu: fromMenu, replyToMessageId: replyToMessageId, threadId: threadId)
} }
public func requestSimpleWebView(botId: PeerId, url: String, themeParams: [String: Any]?) -> Signal<String, RequestSimpleWebViewError> { public func requestSimpleWebView(botId: PeerId, url: String, themeParams: [String: Any]?) -> Signal<String, RequestSimpleWebViewError> {

View File

@ -109,7 +109,7 @@ func _internal_requestUpdatePinnedMessage(account: Account, peerId: PeerId, upda
} }
} }
func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId) -> Signal<Never, UpdatePinnedMessageError> { func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId, threadId: Int64?) -> Signal<Never, UpdatePinnedMessageError> {
return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in return account.postbox.transaction { transaction -> (Peer?, CachedPeerData?) in
return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId)) return (transaction.getPeer(peerId), transaction.getPeerCachedData(peerId: peerId))
} }
@ -147,7 +147,11 @@ func _internal_requestUnpinAllMessages(account: Account, peerId: PeerId) -> Sign
case restart case restart
} }
let request: Signal<Never, InternalError> = account.network.request(Api.functions.messages.unpinAllMessages(peer: inputPeer)) var flags: Int32 = 0
if threadId != nil {
flags |= (1 << 0)
}
let request: Signal<Never, InternalError> = account.network.request(Api.functions.messages.unpinAllMessages(flags: flags, peer: inputPeer, topMsgId: threadId.flatMap(Int32.init(clamping:))))
|> mapError { error -> InternalError in |> mapError { error -> InternalError in
return .error(error.errorDescription) return .error(error.errorDescription)
} }

View File

@ -239,7 +239,7 @@ func _internal_fetchBotPaymentInvoice(postbox: Postbox, network: Network, source
parsedFlags.insert(.shippingAddressRequested) parsedFlags.insert(.shippingAddressRequested)
} }
return TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: 0, startParam: "", extendedMedia: nil, flags: parsedFlags) return TelegramMediaInvoice(title: title, description: description, photo: photo.flatMap(TelegramMediaWebFile.init), receiptMessageId: nil, currency: parsedInvoice.currency, totalAmount: 0, startParam: "", extendedMedia: nil, flags: parsedFlags, version: TelegramMediaInvoice.lastVersion)
} }
} }
|> mapError { _ -> BotPaymentFormRequestError in } |> mapError { _ -> BotPaymentFormRequestError in }
@ -613,7 +613,8 @@ func _internal_requestBotPaymentReceipt(account: Account, messageId: MessageId)
totalAmount: totalAmount, totalAmount: totalAmount,
startParam: "", startParam: "",
extendedMedia: nil, extendedMedia: nil,
flags: [] flags: [],
version: TelegramMediaInvoice.lastVersion
) )
let botPaymentId = PeerId.init(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId)) let botPaymentId = PeerId.init(namespace: Namespaces.Peer.CloudUser, id: PeerId.Id._internalFromInt64Value(botId))

View File

@ -158,9 +158,9 @@ func _internal_updatePeerPhotoInternal(postbox: Postbox, network: Network, state
for size in sizes { for size in sizes {
switch size { switch size {
case let .photoSize(_, w, h, _): case let .photoSize(_, w, h, _):
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSizeProgressive(_, w, h, sizes): case let .photoSizeProgressive(_, w, h, sizes):
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: sizes, immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: CloudPeerPhotoSizeMediaResource(datacenterId: dcId, photoId: id, sizeSpec: w <= 200 ? .small : .fullSize, volumeId: nil, localId: nil), progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false))
default: default:
break break
} }

View File

@ -858,8 +858,28 @@ public extension TelegramEngine {
|> ignoreValues |> ignoreValues
} }
public func setForumChannelTopicPinned(id: EnginePeer.Id, threadId: Int64, isPinned: Bool) -> Signal<Never, SetForumChannelTopicPinnedError> { public func toggleForumChannelTopicPinned(id: EnginePeer.Id, threadId: Int64) -> Signal<Never, SetForumChannelTopicPinnedError> {
return _internal_setForumChannelTopicPinned(account: self.account, id: id, threadId: threadId, isPinned: isPinned) return self.account.postbox.transaction { transaction -> [Int64] in
return transaction.getPeerPinnedThreads(peerId: id)
}
|> castError(SetForumChannelTopicPinnedError.self)
|> mapToSignal { threadIds -> Signal<Never, SetForumChannelTopicPinnedError> in
var threadIds = threadIds
if threadIds.contains(threadId) {
threadIds.removeAll(where: { $0 == threadId })
} else {
if threadIds.count + 1 > 5 {
return .fail(.limitReached(5))
}
threadIds.insert(threadId, at: 0)
}
return _internal_setForumChannelPinnedTopics(account: self.account, id: id, threadIds: threadIds)
}
}
public func setForumChannelPinnedTopics(id: EnginePeer.Id, threadIds: [Int64]) -> Signal<Never, SetForumChannelTopicPinnedError> {
return _internal_setForumChannelPinnedTopics(account: self.account, id: id, threadIds: threadIds)
} }
public func forumChannelTopicNotificationExceptions(id: EnginePeer.Id) -> Signal<[EngineMessageHistoryThread.NotificationException], NoError> { public func forumChannelTopicNotificationExceptions(id: EnginePeer.Id) -> Signal<[EngineMessageHistoryThread.NotificationException], NoError> {

View File

@ -11,13 +11,13 @@ func telegramStickerPackThumbnailRepresentationFromApiSizes(datacenterId: Int32,
switch size { switch size {
case let .photoCachedSize(_, w, h, _): case let .photoCachedSize(_, w, h, _):
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSize(_, w, h, _): case let .photoSize(_, w, h, _):
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
case let .photoSizeProgressive(_, w, h, sizes): case let .photoSizeProgressive(_, w, h, sizes):
let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil) let resource = CloudStickerPackThumbnailMediaResource(datacenterId: datacenterId, thumbVersion: thumbVersion, volumeId: nil, localId: nil)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: w, height: h), resource: resource, progressiveSizes: sizes, immediateThumbnailData: nil, hasVideo: false))
case let .photoPathSize(_, data): case let .photoPathSize(_, data):
immediateThumbnailData = data.makeData() immediateThumbnailData = data.makeData()
case .photoStrippedSize: case .photoStrippedSize:

View File

@ -355,6 +355,15 @@ public extension Message {
} }
return nil return nil
} }
var restrictedContentAttribute: RestrictedContentMessageAttribute? {
for attribute in self.attributes {
if let attribute = attribute as? RestrictedContentMessageAttribute {
return attribute
}
}
return nil
}
} }
public func _internal_parseMediaAttachment(data: Data) -> Media? { public func _internal_parseMediaAttachment(data: Data) -> Media? {

View File

@ -1278,7 +1278,8 @@ public func defaultBuiltinWallpaper(data: BuiltinWallpaperData, colors: [UInt32]
fileReference: Data() fileReference: Data()
), ),
progressiveSizes: [], progressiveSizes: [],
immediateThumbnailData: nil immediateThumbnailData: nil,
hasVideo: false
) )
], ],
videoThumbnails: [], videoThumbnails: [],

View File

@ -684,7 +684,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
let maybeFileId = iconFileId ?? 0 let maybeFileId = iconFileId ?? 0
attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicCreated(".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) attributedString = addAttributesToStringWithRanges(strings.Notification_OverviewTopicCreated(".", title)._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])])
} else { } else {
attributedString = NSAttributedString(string: strings.Notification_TopicCreated, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ForumTopicCreated, font: titleFont, textColor: primaryTextColor)
} }
case let .topicEdited(components): case let .topicEdited(components):
if let isClosed = components.compactMap({ item -> Bool? in if let isClosed = components.compactMap({ item -> Bool? in
@ -712,16 +712,16 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
} }
} else { } else {
if isClosed { if isClosed {
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicClosedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)])
} else { } else {
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicReopenedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder))._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)])
} }
} }
} else { } else {
if isClosed { if isClosed {
attributedString = NSAttributedString(string: strings.Notification_TopicClosed, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ForumTopicClosed, font: titleFont, textColor: primaryTextColor)
} else { } else {
attributedString = NSAttributedString(string: strings.Notification_TopicReopened, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ForumTopicReopened, font: titleFont, textColor: primaryTextColor)
} }
} }
} else if let maybeFileId = components.compactMap({ item -> Int64? in } else if let maybeFileId = components.compactMap({ item -> Int64? in
@ -744,12 +744,12 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
if let info = message.associatedThreadInfo { if let info = message.associatedThreadInfo {
iconColor = info.iconColor iconColor = info.iconColor
} }
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicRenamedIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [ attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicRenamedIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".", title)._tuple, body: bodyAttributes, argumentAttributes: [
0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id),
1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)]) 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])
]) ])
} else { } else {
attributedString = NSAttributedString(string: strings.Notification_TopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ForumTopicRenamed(title).string, font: titleFont, textColor: primaryTextColor)
} }
} else if let title = components.compactMap({ item -> String? in } else if let title = components.compactMap({ item -> String? in
switch item { switch item {
@ -760,9 +760,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
} }
}).first { }).first {
if case let .user(user) = message.author { if case let .user(user) = message.author {
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicRenamedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)]) attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicRenamedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), title)._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id)])
} else { } else {
attributedString = NSAttributedString(string: strings.Notification_TopicRenamed(title).string, font: titleFont, textColor: primaryTextColor) attributedString = NSAttributedString(string: strings.Notification_ForumTopicRenamed(title).string, font: titleFont, textColor: primaryTextColor)
} }
} else if let maybeFileId = components.compactMap({ item -> Int64? in } else if let maybeFileId = components.compactMap({ item -> Int64? in
switch item { switch item {
@ -779,9 +779,9 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
title = info.title title = info.title
} }
if case let .user(user) = message.author { if case let .user(user) = message.author {
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicIconChangedAuthor(EnginePeer.user(user).displayTitle(strings: strings, displayOrder: nameDisplayOrder), ".")._tuple, body: bodyAttributes, argumentAttributes: [0: peerMentionAttributes(primaryTextColor: primaryTextColor, peerId: user.id), 1: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])])
} else { } else {
attributedString = addAttributesToStringWithRanges(strings.Notification_TopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])]) attributedString = addAttributesToStringWithRanges(strings.Notification_ForumTopicIconChanged(".")._tuple, body: bodyAttributes, argumentAttributes: [0: MarkdownAttributeSet(font: titleFont, textColor: primaryTextColor, additionalAttributes: [ChatTextInputAttributes.customEmoji.rawValue: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: maybeFileId, file: nil, topicInfo: maybeFileId == 0 ? EngineMessageHistoryThread.Info(title: title, icon: nil, iconColor: iconColor) : nil)])])
} }
} }
case .unknown: case .unknown:

View File

@ -171,7 +171,7 @@ private final class ChatContextResultPeekNode: ASDisplayNode, PeekControllerCont
imageDimensions = externalReference.content?.dimensions?.cgSize imageDimensions = externalReference.content?.dimensions?.cgSize
if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = imageResource if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = imageResource
, let dimensions = content.dimensions { , let dimensions = content.dimensions {
videoFileReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) videoFileReference = .standalone(media: TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])]))
imageResource = nil imageResource = nil
} }
case let .internalReference(internalReference): case let .internalReference(internalReference):
@ -233,7 +233,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, progressiveSizes: [], immediateThumbnailData: nil) let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: Int32(fittedImageDimensions.width * 2.0), height: Int32(fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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 {

View File

@ -3934,7 +3934,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: true, isSimple: false) let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: true, isSimple: false)
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in
self?.openUrl(url, concealed: true, forceExternal: true) self?.openUrl(url, concealed: true, forceExternal: true)
}, getInputContainerNode: { [weak self] in }, getInputContainerNode: { [weak self] in
if let strongSelf = self, let layout = strongSelf.validLayout, case .compact = layout.metrics.widthClass { if let strongSelf = self, let layout = strongSelf.validLayout, case .compact = layout.metrics.widthClass {
@ -3978,7 +3978,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: false, isSimple: true) let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: url, queryId: nil, payload: nil, buttonText: buttonText, keepAliveSignal: nil, fromMenu: false, isSimple: true)
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in
self?.openUrl(url, concealed: true, forceExternal: true) self?.openUrl(url, concealed: true, forceExternal: true)
}, getNavigationController: { [weak self] in }, getNavigationController: { [weak self] in
return self?.effectiveNavigationController return self?.effectiveNavigationController
@ -3993,7 +3993,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
})) }))
} else { } else {
strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), fromMenu: buttonText == "Menu", replyToMessageId: nil) strongSelf.messageActionCallbackDisposable.set(((strongSelf.context.engine.messages.requestWebView(peerId: peerId, botId: peerId, url: !url.isEmpty ? url : nil, payload: nil, themeParams: generateWebAppThemeParams(strongSelf.presentationData.theme), fromMenu: buttonText == "Menu", replyToMessageId: nil, threadId: strongSelf.chatLocation.threadId)
|> afterDisposed { |> afterDisposed {
updateProgress() updateProgress()
}) })
@ -4002,7 +4002,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
return return
} }
let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, fromMenu: false, isSimple: false) let params = WebAppParameters(peerId: peerId, botId: peerId, botName: botName, url: result.url, queryId: result.queryId, payload: nil, buttonText: buttonText, keepAliveSignal: result.keepAliveSignal, fromMenu: false, isSimple: false)
let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, openUrl: { [weak self] url in let controller = standaloneWebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, threadId: strongSelf.chatLocation.threadId, openUrl: { [weak self] url in
self?.openUrl(url, concealed: true, forceExternal: true) self?.openUrl(url, concealed: true, forceExternal: true)
}, completion: { [weak self] in }, completion: { [weak self] in
self?.chatDisplayNode.historyNode.scrollToEndOfHistory() self?.chatDisplayNode.historyNode.scrollToEndOfHistory()
@ -6132,12 +6132,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
var buttonKeyboardMessage = combinedInitialData.buttonKeyboardMessage
if let buttonKeyboardMessageValue = buttonKeyboardMessage, buttonKeyboardMessageValue.isRestricted(platform: "ios", contentSettings: strongSelf.context.currentContentSettings.with({ $0 })) {
buttonKeyboardMessage = nil
}
strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { updated in strongSelf.updateChatPresentationInterfaceState(animated: false, interactive: false, { updated in
var updated = updated var updated = updated
updated = updated.updatedInterfaceState({ _ in return interfaceState }) updated = updated.updatedInterfaceState({ _ in return interfaceState })
updated = updated.updatedKeyboardButtonsMessage(combinedInitialData.buttonKeyboardMessage) updated = updated.updatedKeyboardButtonsMessage(buttonKeyboardMessage)
updated = updated.updatedPinnedMessageId(pinnedMessageId) updated = updated.updatedPinnedMessageId(pinnedMessageId)
updated = updated.updatedPinnedMessage(pinnedMessage) updated = updated.updatedPinnedMessage(pinnedMessage)
updated = updated.updatedPeerIsBlocked(peerIsBlocked) updated = updated.updatedPeerIsBlocked(peerIsBlocked)
@ -6900,14 +6905,17 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
self.chatDisplayNode.paste = { [weak self] data in self.chatDisplayNode.paste = { [weak self] data in
switch data { switch data {
case let .images(images): case let .images(images):
self?.displayPasteMenu(images) self?.displayPasteMenu(images.map { .image($0) })
case let .video(data): case let .video(data):
self?.enqueueVideoData(data) let tempFilePath = NSTemporaryDirectory() + "\(Int64.random(in: 0...Int64.max)).mp4"
case let .gif(data): let url = NSURL(fileURLWithPath: tempFilePath) as URL
self?.enqueueGifData(data) try? data.write(to: url)
case let .sticker(image, isMemoji): self?.displayPasteMenu([.video(url)])
self?.enqueueStickerImage(image, isMemoji: isMemoji) case let .gif(data):
self?.enqueueGifData(data)
case let .sticker(image, isMemoji):
self?.enqueueStickerImage(image, isMemoji: isMemoji)
} }
} }
self.chatDisplayNode.updateTypingActivity = { [weak self] value in self.chatDisplayNode.updateTypingActivity = { [weak self] value in
@ -12195,7 +12203,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
case let .app(bot, botName, _): case let .app(bot, botName, _):
let params = WebAppParameters(peerId: peer.id, botId: bot.id, botName: botName, url: nil, queryId: nil, payload: botPayload, buttonText: nil, keepAliveSignal: nil, fromMenu: false, isSimple: false) let params = WebAppParameters(peerId: peer.id, botId: bot.id, botName: botName, url: nil, queryId: nil, payload: botPayload, buttonText: nil, keepAliveSignal: nil, fromMenu: false, isSimple: false)
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
let controller = WebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, replyToMessageId: replyMessageId) let controller = WebAppController(context: strongSelf.context, updatedPresentationData: strongSelf.updatedPresentationData, params: params, replyToMessageId: replyMessageId, threadId: strongSelf.chatLocation.threadId)
controller.openUrl = { [weak self] url in controller.openUrl = { [weak self] url in
self?.openUrl(url, concealed: true, forceExternal: true) self?.openUrl(url, concealed: true, forceExternal: true)
} }
@ -12600,7 +12608,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
let mimeType = guessMimeTypeByFileExtension((item.fileName as NSString).pathExtension) let mimeType = guessMimeTypeByFileExtension((item.fileName as NSString).pathExtension)
var previewRepresentations: [TelegramMediaImageRepresentation] = [] var previewRepresentations: [TelegramMediaImageRepresentation] = []
if mimeType.hasPrefix("image/") || mimeType == "application/pdf" { if mimeType.hasPrefix("image/") || mimeType == "application/pdf" {
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 320, height: 320), resource: ICloudFileResource(urlData: item.urlData, thumbnail: true), progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
var attributes: [TelegramMediaFileAttribute] = [] var attributes: [TelegramMediaFileAttribute] = []
attributes.append(.FileName(fileName: item.fileName)) attributes.append(.FileName(fileName: item.fileName))
@ -13746,7 +13754,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
})) }))
} }
private func displayPasteMenu(_ images: [UIImage]) { private func displayPasteMenu(_ subjects: [MediaPickerScreen.Subject.Media]) {
let _ = (self.context.sharedContext.accountManager.transaction { transaction -> GeneratedMediaStoreSettings in let _ = (self.context.sharedContext.accountManager.transaction { transaction -> GeneratedMediaStoreSettings in
let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings)?.get(GeneratedMediaStoreSettings.self) let entry = transaction.getSharedData(ApplicationSpecificSharedDataKeys.generatedMediaStoreSettings)?.get(GeneratedMediaStoreSettings.self)
return entry ?? GeneratedMediaStoreSettings.defaultSettings return entry ?? GeneratedMediaStoreSettings.defaultSettings
@ -13759,7 +13767,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
context: strongSelf.context, context: strongSelf.context,
updatedPresentationData: strongSelf.updatedPresentationData, updatedPresentationData: strongSelf.updatedPresentationData,
peer: EnginePeer(peer), peer: EnginePeer(peer),
subjects: images, subjects: subjects,
presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendMedia, present in presentMediaPicker: { [weak self] subject, saveEditedPhotos, bannedSendMedia, present in
if let strongSelf = self { if let strongSelf = self {
strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendMedia: bannedSendMedia, present: present, updateMediaPickerContext: { _ in }, completion: { [weak self] signals, silentPosting, scheduleTime, getAnimatedTransitionSource, completion in strongSelf.presentMediaPicker(subject: subject, saveEditedPhotos: saveEditedPhotos, bannedSendMedia: bannedSendMedia, present: present, updateMediaPickerContext: { _ in }, completion: { [weak self] signals, silentPosting, scheduleTime, getAnimatedTransitionSource, completion in
@ -16374,7 +16382,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
} }
} }
strongSelf.chatDisplayNode.updateDropInteraction(isActive: false) strongSelf.chatDisplayNode.updateDropInteraction(isActive: false)
strongSelf.displayPasteMenu(images) strongSelf.displayPasteMenu(images.map { .image($0) })
} }
} }
@ -17028,7 +17036,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
switch action { switch action {
case .commit: case .commit:
let _ = (strongSelf.context.engine.messages.requestUnpinAllMessages(peerId: peerId) let _ = (strongSelf.context.engine.messages.requestUnpinAllMessages(peerId: peerId, threadId: strongSelf.chatLocation.threadId)
|> deliverOnMainQueue).start(error: { _ in |> deliverOnMainQueue).start(error: { _ in
}, completed: { }, completed: {
guard let strongSelf = self else { guard let strongSelf = self else {

View File

@ -1396,7 +1396,12 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
forceUpdateAll = true forceUpdateAll = true
} }
let rawTransition = preparedChatHistoryViewTransition(from: previous, to: processedView, reason: reason, reverse: reverse, chatLocation: chatLocation, controllerInteraction: controllerInteraction, scrollPosition: updatedScrollPosition, scrollAnimationCurve: scrollAnimationCurve, initialData: initialData?.initialData, keyboardButtonsMessage: view.topTaggedMessages.first, cachedData: initialData?.cachedData, cachedDataMessages: initialData?.cachedDataMessages, readStateData: initialData?.readStateData, flashIndicators: flashIndicators, updatedMessageSelection: previousSelectedMessages != selectedMessages, messageTransitionNode: messageTransitionNode(), allUpdated: updateAllOnEachVersion || forceUpdateAll) var keyboardButtonsMessage = view.topTaggedMessages.first
if let keyboardButtonsMessageValue = keyboardButtonsMessage, keyboardButtonsMessageValue.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with({ $0 })) {
keyboardButtonsMessage = nil
}
let rawTransition = preparedChatHistoryViewTransition(from: previous, to: processedView, reason: reason, reverse: reverse, chatLocation: chatLocation, controllerInteraction: controllerInteraction, scrollPosition: updatedScrollPosition, scrollAnimationCurve: scrollAnimationCurve, initialData: initialData?.initialData, keyboardButtonsMessage: keyboardButtonsMessage, cachedData: initialData?.cachedData, cachedDataMessages: initialData?.cachedDataMessages, readStateData: initialData?.readStateData, flashIndicators: flashIndicators, updatedMessageSelection: previousSelectedMessages != selectedMessages, messageTransitionNode: messageTransitionNode(), allUpdated: updateAllOnEachVersion || forceUpdateAll)
var mappedTransition = mappedChatHistoryViewListTransition(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, lastHeaderId: lastHeaderId, transition: rawTransition) var mappedTransition = mappedChatHistoryViewListTransition(context: context, chatLocation: chatLocation, associatedData: associatedData, controllerInteraction: controllerInteraction, mode: mode, lastHeaderId: lastHeaderId, transition: rawTransition)
if disableAnimations { if disableAnimations {
@ -2042,6 +2047,9 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
} }
} else if let invoice = media as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case .preview = extendedMedia { } else if let invoice = media as? TelegramMediaInvoice, let extendedMedia = invoice.extendedMedia, case .preview = extendedMedia {
messageIdsWithInactiveExtendedMedia.insert(message.id) messageIdsWithInactiveExtendedMedia.insert(message.id)
if invoice.version != TelegramMediaInvoice.lastVersion {
contentRequiredValidation = true
}
} }
} }
if contentRequiredValidation { if contentRequiredValidation {

View File

@ -181,17 +181,6 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
} }
} }
} }
} else {
if chatPresentationInterfaceState.interfaceState.replyMessageId == nil {
if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
return (currentPanel, nil)
} else {
let panel = ChatRestrictedInputPanelNode()
panel.context = context
panel.interfaceInteraction = interfaceInteraction
return (panel, nil)
}
}
} }
} }
@ -248,6 +237,22 @@ func inputPanelForChatPresentationIntefaceState(_ chatPresentationInterfaceState
} }
} }
} }
if channel.flags.contains(.isForum) {
if let _ = chatPresentationInterfaceState.threadData {
} else {
if chatPresentationInterfaceState.interfaceState.replyMessageId == nil {
if let currentPanel = (currentPanel as? ChatRestrictedInputPanelNode) ?? (currentSecondaryPanel as? ChatRestrictedInputPanelNode) {
return (currentPanel, nil)
} else {
let panel = ChatRestrictedInputPanelNode()
panel.context = context
panel.interfaceInteraction = interfaceInteraction
return (panel, nil)
}
}
}
}
} else if let group = peer as? TelegramGroup { } else if let group = peer as? TelegramGroup {
switch group.membership { switch group.membership {
case .Removed, .Left: case .Removed, .Left:

View File

@ -200,7 +200,7 @@ final class ChatMediaInputStickerPackItemNode: ListViewItemNode {
thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
} }
} }

View File

@ -1077,7 +1077,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
var edited = false var edited = false
var viewCount: Int? = nil var viewCount: Int? = nil
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute, isEmoji { if let attribute = attribute as? EditedMessageAttribute, isEmoji {
edited = !attribute.isHidden edited = !attribute.isHidden
@ -1164,7 +1167,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] {
if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId {
} else if let threadId = item.message.threadId, Int64(replyAttribute.messageId.id) == threadId, let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) {
} else { } else {
replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments(
presentationData: item.presentationData, presentationData: item.presentationData,
@ -2295,7 +2297,21 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.item?.controllerInteraction.cancelInteractiveKeyboardGestures() self.item?.controllerInteraction.cancelInteractiveKeyboardGestures()
case .changed: case .changed:
var translation = recognizer.translation(in: self.view) var translation = recognizer.translation(in: self.view)
translation.x = max(-80.0, min(0.0, translation.x)) func rubberBandingOffset(offset: CGFloat, bandingStart: CGFloat) -> CGFloat {
let bandedOffset = offset - bandingStart
if offset < bandingStart {
return offset
}
let range: CGFloat = 100.0
let coefficient: CGFloat = 0.4
return bandingStart + (1.0 - (1.0 / ((bandedOffset * coefficient / range) + 1.0))) * range
}
if translation.x < 0.0 {
translation.x = max(-180.0, min(0.0, -rubberBandingOffset(offset: abs(translation.x), bandingStart: swipeOffset)))
} else {
translation.x = 0.0
}
if let item = self.item, self.swipeToReplyNode == nil { if let item = self.item, self.swipeToReplyNode == nil {
let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction))
@ -2311,7 +2327,8 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate) self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate)
if let swipeToReplyNode = self.swipeToReplyNode { if let swipeToReplyNode = self.swipeToReplyNode {
swipeToReplyNode.frame = CGRect(origin: CGPoint(x: bounds.size.width + offset, y: floor((self.contentSize.height - 33.0) / 2.0)), size: CGSize(width: 33.0, height: 33.0)) swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
if let (rect, containerSize) = self.absoluteRect { if let (rect, containerSize) = self.absoluteRect {
let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size) let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size)

View File

@ -338,7 +338,10 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: associatedData.accountPeer, message: message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: associatedData.accountPeer, message: message)
if message.isRestricted(platform: "ios", contentSettings: context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in message.attributes { for attribute in message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -1426,7 +1426,6 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} }
} else if let attribute = attribute as? ReplyMessageAttribute { } else if let attribute = attribute as? ReplyMessageAttribute {
if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == attribute.messageId { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == attribute.messageId {
} else if let threadId = firstMessage.threadId, Int64(attribute.messageId.id) == threadId, let channel = firstMessage.peers[firstMessage.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) {
} else { } else {
replyMessage = firstMessage.associatedMessages[attribute.messageId] replyMessage = firstMessage.associatedMessages[attribute.messageId]
} }
@ -1465,6 +1464,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} }
} }
if firstMessage.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
replyMarkup = nil
}
if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil { if let forwardInfo = firstMessage.forwardInfo, forwardInfo.psaType != nil {
inlineBotNameString = nil inlineBotNameString = nil
} }
@ -1759,7 +1762,10 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: message)
if message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in message.attributes { for attribute in message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden
@ -4101,7 +4107,21 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
self.item?.controllerInteraction.cancelInteractiveKeyboardGestures() self.item?.controllerInteraction.cancelInteractiveKeyboardGestures()
case .changed: case .changed:
var translation = recognizer.translation(in: self.view) var translation = recognizer.translation(in: self.view)
translation.x = max(-80.0, min(0.0, translation.x)) func rubberBandingOffset(offset: CGFloat, bandingStart: CGFloat) -> CGFloat {
let bandedOffset = offset - bandingStart
if offset < bandingStart {
return offset
}
let range: CGFloat = 100.0
let coefficient: CGFloat = 0.4
return bandingStart + (1.0 - (1.0 / ((bandedOffset * coefficient / range) + 1.0))) * range
}
if translation.x < 0.0 {
translation.x = max(-180.0, min(0.0, -rubberBandingOffset(offset: abs(translation.x), bandingStart: swipeOffset)))
} else {
translation.x = 0.0
}
if let item = self.item, self.swipeToReplyNode == nil { if let item = self.item, self.swipeToReplyNode == nil {
let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction))
@ -4120,8 +4140,9 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate) self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate)
if let swipeToReplyNode = self.swipeToReplyNode { if let swipeToReplyNode = self.swipeToReplyNode {
swipeToReplyNode.frame = CGRect(origin: CGPoint(x: bounds.size.width + offset, y: floor((self.contentSize.height - 33.0) / 2.0)), size: CGSize(width: 33.0, height: 33.0)) swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
if let (rect, containerSize) = self.absoluteRect { if let (rect, containerSize) = self.absoluteRect {
let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size) let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size)
swipeToReplyNode.updateAbsoluteRect(mappedRect, within: containerSize) swipeToReplyNode.updateAbsoluteRect(mappedRect, within: containerSize)

View File

@ -172,7 +172,10 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -1020,7 +1020,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView, UIGestureRecognizerD
self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate) self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate)
if let swipeToReplyNode = self.swipeToReplyNode { if let swipeToReplyNode = self.swipeToReplyNode {
swipeToReplyNode.frame = CGRect(origin: CGPoint(x: bounds.size.width + offset, y: floor((self.contentSize.height - 33.0) / 2.0)), size: CGSize(width: 33.0, height: 33.0)) swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
if let (rect, containerSize) = self.absoluteRect { if let (rect, containerSize) = self.absoluteRect {
let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size) let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size)

View File

@ -781,7 +781,10 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: arguments.associatedData.accountPeer, message: arguments.topMessage) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: arguments.associatedData.accountPeer, message: arguments.topMessage)
if arguments.topMessage.isRestricted(platform: "ios", contentSettings: arguments.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in arguments.message.attributes { for attribute in arguments.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -463,7 +463,10 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
let sentViaBot = false let sentViaBot = false
var viewCount: Int? = nil var viewCount: Int? = nil
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -1066,7 +1066,7 @@ final class ChatMessageInteractiveMediaNode: ASDisplayNode, GalleryItemTransitio
} else { } else {
var representations: [ImageRepresentationWithReference] = file.previewRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference($0.resource)) }) var representations: [ImageRepresentationWithReference] = file.previewRepresentations.map({ ImageRepresentationWithReference(representation: $0, reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference($0.resource)) })
if file.mimeType == "image/svg+xml" || file.mimeType == "application/x-tgwallpattern" { if file.mimeType == "image/svg+xml" || file.mimeType == "application/x-tgwallpattern" {
representations.append(ImageRepresentationWithReference(representation: .init(dimensions: PixelDimensions(width: 1440, height: 2960), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource))) representations.append(ImageRepresentationWithReference(representation: .init(dimensions: PixelDimensions(width: 1440, height: 2960), resource: file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: AnyMediaReference.message(message: MessageReference(message), media: file).resourceReference(file.resource)))
} }
if ["image/png", "image/svg+xml", "application/x-tgwallpattern"].contains(file.mimeType) { if ["image/png", "image/svg+xml", "application/x-tgwallpattern"].contains(file.mimeType) {
return patternWallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: representations, mode: .screen) return patternWallpaperImage(account: context.account, accountManager: context.sharedContext.accountManager, representations: representations, mode: .screen)

View File

@ -183,7 +183,10 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -218,7 +218,10 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
if case .mosaic = preparePosition { if case .mosaic = preparePosition {

View File

@ -84,9 +84,6 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
private var compact: Bool? private var compact: Bool?
private var validLayout: CGFloat? private var validLayout: CGFloat?
private var animationCache: AnimationCache?
private var multiAnimationRenderer: MultiAnimationRenderer?
override init() { override init() {
self.avatarNode = AvatarNode(font: avatarFont) self.avatarNode = AvatarNode(font: avatarFont)
@ -115,8 +112,6 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
func setupItem(_ item: ChatMessageNotificationItem, compact: Bool) { func setupItem(_ item: ChatMessageNotificationItem, compact: Bool) {
self.item = item self.item = item
self.animationCache = item.context.animationCache
self.compact = compact self.compact = compact
if compact { if compact {
self.avatarNode.font = compactAvatarFont self.avatarNode.font = compactAvatarFont
@ -412,12 +407,12 @@ final class ChatMessageNotificationItemNode: NotificationItemNode {
let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: self.textAttributedText, backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets())) let (textLayout, textApply) = makeTextLayout(TextNodeLayoutArguments(attributedString: self.textAttributedText, backgroundColor: nil, maximumNumberOfLines: 2, truncationType: .end, constrainedSize: CGSize(width: width - leftInset - rightInset, height: CGFloat.greatestFiniteMagnitude), alignment: .left, lineSpacing: 0.0, cutout: nil, insets: UIEdgeInsets()))
let _ = titleApply() let _ = titleApply()
if let item = self.item, let cache = self.animationCache, let renderer = self.multiAnimationRenderer { if let item = self.item {
let theme = item.context.sharedContext.currentPresentationData.with({ $0 }).theme let theme = item.context.sharedContext.currentPresentationData.with({ $0 }).theme
let _ = textApply(TextNodeWithEntities.Arguments( let _ = textApply(TextNodeWithEntities.Arguments(
context: item.context, context: item.context,
cache: cache, cache: item.context.animationCache,
renderer: renderer, renderer: item.context.animationRenderer,
placeholderColor: theme.list.mediaPlaceholderColor, placeholderColor: theme.list.mediaPlaceholderColor,
attemptSynchronous: false attemptSynchronous: false
)) ))

View File

@ -1053,7 +1053,10 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -97,8 +97,6 @@ class ChatMessageReplyInfoNode: ASDisplayNode {
let previousMediaReference = maybeNode?.previousMediaReference let previousMediaReference = maybeNode?.previousMediaReference
return { arguments in return { arguments in
//presentationData, strings, context, type, message, parentMessage, constrainedSize
let fontSize = floor(arguments.presentationData.fontSize.baseDisplaySize * 14.0 / 17.0) let fontSize = floor(arguments.presentationData.fontSize.baseDisplaySize * 14.0 / 17.0)
let titleFont = Font.medium(fontSize) let titleFont = Font.medium(fontSize)
let textFont = Font.regular(fontSize) let textFont = Font.regular(fontSize)
@ -114,7 +112,12 @@ class ChatMessageReplyInfoNode: ASDisplayNode {
} }
} }
let (textString, isMedia, isText) = descriptionStringForMessage(contentSettings: arguments.context.currentContentSettings.with { $0 }, message: EngineMessage(arguments.message), strings: arguments.strings, nameDisplayOrder: arguments.presentationData.nameDisplayOrder, dateTimeFormat: arguments.presentationData.dateTimeFormat, accountPeerId: arguments.context.account.peerId) var (textString, isMedia, isText) = descriptionStringForMessage(contentSettings: arguments.context.currentContentSettings.with { $0 }, message: EngineMessage(arguments.message), strings: arguments.strings, nameDisplayOrder: arguments.presentationData.nameDisplayOrder, dateTimeFormat: arguments.presentationData.dateTimeFormat, accountPeerId: arguments.context.account.peerId)
if let threadId = arguments.parentMessage.threadId, Int64(arguments.message.id.id) == threadId, let channel = arguments.parentMessage.peers[arguments.parentMessage.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum), let threadInfo = arguments.parentMessage.associatedThreadInfo {
titleString = "\(threadInfo.title)"
textString = NSAttributedString()
}
let placeholderColor: UIColor = arguments.message.effectivelyIncoming(arguments.context.account.peerId) ? arguments.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : arguments.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor let placeholderColor: UIColor = arguments.message.effectivelyIncoming(arguments.context.account.peerId) ? arguments.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : arguments.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor
let titleColor: UIColor let titleColor: UIColor

View File

@ -53,7 +53,10 @@ class ChatMessageRestrictedBubbleContentNode: ChatMessageBubbleContentNode {
var viewCount: Int? var viewCount: Int?
var rawText = "" var rawText = ""
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {
edited = !attribute.isHidden edited = !attribute.isHidden

View File

@ -520,7 +520,10 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
var edited = false var edited = false
var viewCount: Int? = nil var viewCount: Int? = nil
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.message)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute, isEmoji { if let attribute = attribute as? EditedMessageAttribute, isEmoji {
edited = !attribute.isHidden edited = !attribute.isHidden
@ -608,7 +611,6 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] { if let replyAttribute = attribute as? ReplyMessageAttribute, let replyMessage = item.message.associatedMessages[replyAttribute.messageId] {
if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId { if case let .replyThread(replyThreadMessage) = item.chatLocation, replyThreadMessage.messageId == replyAttribute.messageId {
} else if let threadId = item.message.threadId, Int64(replyAttribute.messageId.id) == threadId, let channel = item.message.peers[item.message.id.peerId] as? TelegramChannel, channel.flags.contains(.isForum) {
} else { } else {
replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments( replyInfoApply = makeReplyInfoLayout(ChatMessageReplyInfoNode.Arguments(
presentationData: item.presentationData, presentationData: item.presentationData,
@ -1259,7 +1261,21 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
self.item?.controllerInteraction.cancelInteractiveKeyboardGestures() self.item?.controllerInteraction.cancelInteractiveKeyboardGestures()
case .changed: case .changed:
var translation = recognizer.translation(in: self.view) var translation = recognizer.translation(in: self.view)
translation.x = max(-80.0, min(0.0, translation.x)) func rubberBandingOffset(offset: CGFloat, bandingStart: CGFloat) -> CGFloat {
let bandedOffset = offset - bandingStart
if offset < bandingStart {
return offset
}
let range: CGFloat = 100.0
let coefficient: CGFloat = 0.4
return bandingStart + (1.0 - (1.0 / ((bandedOffset * coefficient / range) + 1.0))) * range
}
if translation.x < 0.0 {
translation.x = max(-180.0, min(0.0, -rubberBandingOffset(offset: abs(translation.x), bandingStart: swipeOffset)))
} else {
translation.x = 0.0
}
if let item = self.item, self.swipeToReplyNode == nil { if let item = self.item, self.swipeToReplyNode == nil {
let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction)) let swipeToReplyNode = ChatMessageSwipeToReplyNode(fillColor: selectDateFillStaticColor(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), enableBlur: dateFillNeedsBlur(theme: item.presentationData.theme.theme, wallpaper: item.presentationData.theme.wallpaper), foregroundColor: bubbleVariableColor(variableColor: item.presentationData.theme.theme.chat.message.shareButtonForegroundColor, wallpaper: item.presentationData.theme.wallpaper), backgroundNode: item.controllerInteraction.presentationContext.backgroundNode, action: ChatMessageSwipeToReplyNode.Action(self.currentSwipeAction))
@ -1275,7 +1291,8 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate) self.updateAttachedAvatarNodeOffset(offset: translation.x, transition: .immediate)
if let swipeToReplyNode = self.swipeToReplyNode { if let swipeToReplyNode = self.swipeToReplyNode {
swipeToReplyNode.frame = CGRect(origin: CGPoint(x: bounds.size.width + offset, y: floor((self.contentSize.height - 33.0) / 2.0)), size: CGSize(width: 33.0, height: 33.0)) swipeToReplyNode.bounds = CGRect(origin: .zero, size: CGSize(width: 33.0, height: 33.0))
swipeToReplyNode.position = CGPoint(x: bounds.size.width + offset + 33.0 * 0.5, y: self.contentSize.height / 2.0)
if let (rect, containerSize) = self.absoluteRect { if let (rect, containerSize) = self.absoluteRect {
let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size) let mappedRect = CGRect(origin: CGPoint(x: rect.minX + swipeToReplyNode.frame.minX, y: rect.minY + swipeToReplyNode.frame.minY), size: swipeToReplyNode.frame.size)

View File

@ -178,19 +178,26 @@ final class ChatMessageSwipeToReplyNode: ASDisplayNode {
guard !self.animatedWave else { guard !self.animatedWave else {
return return
} }
self.layer.transform = CATransform3DMakeScale(1.1, 1.1, 1.0)
self.layer.animateScale(from: 1.0, to: 1.1, duration: 0.2, completion: { [weak self] _ in
self?.layer.transform = CATransform3DMakeScale(1.0, 1.0, 1.0)
self?.layer.animateScale(from: 1.1, to: 1.0, duration: 0.15)
})
self.animatedWave = true self.animatedWave = true
var lineWidth = self.progressLayer.lineWidth var lineWidth = self.progressLayer.lineWidth
self.progressLayer.lineWidth = 1.0 self.progressLayer.lineWidth = 0.0
self.progressLayer.animate(from: lineWidth as NSNumber, to: 1.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.2, completion: { [weak self] _ in self.progressLayer.animate(from: lineWidth as NSNumber, to: 0.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3, completion: { _ in
self?.progressLayer.animate(from: 1.0 as NSNumber, to: 0.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.1, removeOnCompletion: false)
}) })
var path = self.progressLayer.path var path = self.progressLayer.path
var targetPath = UIBezierPath(arcCenter: CGPoint(x: self.progressLayer.frame.width / 2.0, y: self.progressLayer.frame.height / 2.0), radius: 35.0, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(-0.5 * .pi + 2.0 * .pi), clockwise: true).cgPath var targetPath = UIBezierPath(arcCenter: CGPoint(x: self.progressLayer.frame.width / 2.0, y: self.progressLayer.frame.height / 2.0), radius: 35.0, startAngle: CGFloat(-0.5 * .pi), endAngle: CGFloat(-0.5 * .pi + 2.0 * .pi), clockwise: true).cgPath
self.progressLayer.path = targetPath self.progressLayer.path = targetPath
self.progressLayer.animate(from: path, to: targetPath, keyPath: "path", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.25) self.progressLayer.animate(from: path, to: targetPath, keyPath: "path", timingFunction: kCAMediaTimingFunctionSpring, duration: 0.3)
self.progressLayer.animateAlpha(from: 1.0, to: 0.0, duration: 0.3)
self.fillLayer.isHidden = false self.fillLayer.isHidden = false
self.fillLayer.path = UIBezierPath(ovalIn: CGRect(origin: .zero, size: size)).cgPath self.fillLayer.path = UIBezierPath(ovalIn: CGRect(origin: .zero, size: size)).cgPath
@ -198,12 +205,12 @@ final class ChatMessageSwipeToReplyNode: ASDisplayNode {
lineWidth = self.fillLayer.lineWidth lineWidth = self.fillLayer.lineWidth
self.fillLayer.lineWidth = 18.0 self.fillLayer.lineWidth = 18.0
self.fillLayer.animate(from: lineWidth as NSNumber, to: 18.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.25) self.fillLayer.animate(from: lineWidth as NSNumber, to: 18.0 as NSNumber, keyPath: "lineWidth", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
path = self.fillLayer.path path = self.fillLayer.path
targetPath = UIBezierPath(ovalIn: CGRect(origin: .zero, size: size).insetBy(dx: 9.0, dy: 9.0)).cgPath targetPath = UIBezierPath(ovalIn: CGRect(origin: .zero, size: size).insetBy(dx: 9.0, dy: 9.0)).cgPath
self.fillLayer.path = targetPath self.fillLayer.path = targetPath
self.fillLayer.animate(from: path, to: targetPath, keyPath: "path", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.25) self.fillLayer.animate(from: path, to: targetPath, keyPath: "path", timingFunction: CAMediaTimingFunctionName.linear.rawValue, duration: 0.3)
} }
func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) { func updateAbsoluteRect(_ rect: CGRect, within containerSize: CGSize) {

View File

@ -157,7 +157,10 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
} }
var viewCount: Int? var viewCount: Int?
var dateReplies = 0 var dateReplies = 0
let dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.topMessage) var dateReactionsAndPeers = mergedMessageReactionsAndPeers(accountPeer: item.associatedData.accountPeer, message: item.topMessage)
if item.message.isRestricted(platform: "ios", contentSettings: item.context.currentContentSettings.with { $0 }) {
dateReactionsAndPeers = ([], [])
}
for attribute in item.message.attributes { for attribute in item.message.attributes {
if let attribute = attribute as? EditedMessageAttribute { if let attribute = attribute as? EditedMessageAttribute {

View File

@ -317,7 +317,7 @@ final class ChatPinnedMessageTitlePanelNode: ChatTitleAccessoryPanelNode {
messageUpdated = true messageUpdated = true
} }
if let message = interfaceState.pinnedMessage { if let message = interfaceState.pinnedMessage, !message.message.isRestricted(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) {
for attribute in message.message.attributes { for attribute in message.message.attributes {
if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), attribute.rows.count == 1, attribute.rows[0].buttons.count == 1 { if let attribute = attribute as? ReplyMarkupMessageAttribute, attribute.flags.contains(.inline), attribute.rows.count == 1, attribute.rows[0].buttons.count == 1 {
actionTitle = attribute.rows[0].buttons[0].title actionTitle = attribute.rows[0].buttons[0].title

View File

@ -329,7 +329,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
if let data = image.jpegData(compressionQuality: 0.6) { if let data = image.jpegData(compressionQuality: 0.6) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource)) uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource))
uploadedVideoAvatar = nil uploadedVideoAvatar = nil
updateState { current in updateState { current in
@ -344,7 +344,7 @@ public func createChannelController(context: AccountContext) -> ViewController {
if let data = image.jpegData(compressionQuality: 0.6) { if let data = image.jpegData(compressionQuality: 0.6) {
let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
updateState { state in updateState { state in
var state = state var state = state
state.avatar = .image(representation, true) state.avatar = .image(representation, true)

View File

@ -594,7 +594,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
if let data = image.jpegData(compressionQuality: 0.6) { if let data = image.jpegData(compressionQuality: 0.6) {
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource)) uploadedAvatar.set(context.engine.peers.uploadedPeerPhoto(resource: resource))
uploadedVideoAvatar = nil uploadedVideoAvatar = nil
updateState { current in updateState { current in
@ -609,7 +609,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
if let data = image.jpegData(compressionQuality: 0.6) { if let data = image.jpegData(compressionQuality: 0.6) {
let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
updateState { state in updateState { state in
var state = state var state = state
state.avatar = .image(representation, true) state.avatar = .image(representation, true)

View File

@ -88,7 +88,8 @@ func paneGifSearchForQuery(context: AccountContext, query: String, offset: Strin
dimensions: dimensions, dimensions: dimensions,
resource: thumbnailResource, resource: thumbnailResource,
progressiveSizes: [], progressiveSizes: [],
immediateThumbnailData: nil immediateThumbnailData: nil,
hasVideo: false
)) ))
} }
} }

View File

@ -352,7 +352,7 @@ final class HorizontalListContextResultsChatInputPanelItemNode: ListViewItemNode
if let stickerFile = stickerFile { if let stickerFile = stickerFile {
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, progressiveSizes: [], immediateThumbnailData: nil) let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(CGSize(width: fittedImageDimensions.width * 2.0, height: fittedImageDimensions.height * 2.0)), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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), synchronousLoad: true) updateImageSignal = chatMessagePhoto(postbox: item.account.postbox, photoReference: .standalone(media: tmpImage), synchronousLoad: true)
} }

View File

@ -176,7 +176,7 @@ func legacyInstantVideoController(theme: PresentationTheme, panelFrame: CGRect,
let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)! let thumbnailImage = TGScaleImageToPixelSize(previewImage, thumbnailSize)!
if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) { if let thumbnailData = thumbnailImage.jpegData(compressionQuality: 0.4) {
context.account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData) context.account.postbox.mediaBox.storeResourceData(resource.id, data: thumbnailData)
previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) previewRepresentations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailSize), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
} }

View File

@ -91,7 +91,9 @@ final class NotificationItemContainerNode: ASDisplayNode {
var contentInsets = UIEdgeInsets(top: inset, left: inset + layout.safeInsets.left, bottom: inset, right: inset + layout.safeInsets.right) var contentInsets = UIEdgeInsets(top: inset, left: inset + layout.safeInsets.left, bottom: inset, right: inset + layout.safeInsets.right)
if let statusBarHeight = layout.statusBarHeight, statusBarHeight >= 39.0 { if let statusBarHeight = layout.statusBarHeight, statusBarHeight >= 39.0 {
if statusBarHeight >= 44.0 { if layout.deviceMetrics.hasDynamicIsland {
contentInsets.top = statusBarHeight
} else if statusBarHeight >= 44.0 {
contentInsets.top += 34.0 contentInsets.top += 34.0
} else { } else {
contentInsets.top += 29.0 contentInsets.top += 29.0

View File

@ -621,6 +621,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
if let components = URLComponents(string: "/?" + query) { if let components = URLComponents(string: "/?" + query) {
var channelId: Int64? var channelId: Int64?
var postId: Int32? var postId: Int32?
var threadId: Int64?
if let queryItems = components.queryItems { if let queryItems = components.queryItems {
for queryItem in queryItems { for queryItem in queryItems {
if let value = queryItem.value { if let value = queryItem.value {
@ -628,12 +629,22 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
channelId = Int64(value) channelId = Int64(value)
} else if queryItem.name == "post" { } else if queryItem.name == "post" {
postId = Int32(value) postId = Int32(value)
} else if queryItem.name == "thread" {
threadId = Int64(value)
} }
} }
} }
} }
if let channelId = channelId, let postId = postId { if let channelId = channelId {
convertedUrl = "https://t.me/c/\(channelId)/\(postId)" if let postId = postId {
if let threadId = threadId {
convertedUrl = "https://t.me/c/\(channelId)/\(threadId)/\(postId)"
} else {
convertedUrl = "https://t.me/c/\(channelId)/\(postId)"
}
} else if let threadId = threadId {
convertedUrl = "https://t.me/c/\(channelId)/\(threadId)"
}
} }
} }
} }
@ -652,6 +663,7 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
var attach: String? var attach: String?
var startAttach: String? var startAttach: String?
var choose: String? var choose: String?
var threadId: Int64?
if let queryItems = components.queryItems { if let queryItems = components.queryItems {
for queryItem in queryItems { for queryItem in queryItems {
if let value = queryItem.value { if let value = queryItem.value {
@ -677,6 +689,8 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
startAttach = value startAttach = value
} else if queryItem.name == "choose" { } else if queryItem.name == "choose" {
choose = value choose = value
} else if queryItem.name == "thread" {
threadId = Int64(value)
} }
} else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) { } else if ["voicechat", "videochat", "livestream"].contains(queryItem.name) {
voiceChat = "" voiceChat = ""
@ -694,8 +708,15 @@ func openExternalUrlImpl(context: AccountContext, urlContext: OpenURLContext, ur
convertedUrl = "https://t.me/+\(phone)" convertedUrl = "https://t.me/+\(phone)"
} else if let domain = domain { } else if let domain = domain {
var result = "https://t.me/\(domain)" var result = "https://t.me/\(domain)"
if let post = post, let postValue = Int(post) { if let threadId = threadId {
result += "/\(postValue)" result += "/\(threadId)"
if let post = post, let postValue = Int(post) {
result += "/\(postValue)"
}
} else {
if let post = post, let postValue = Int(post) {
result += "/\(postValue)"
}
} }
if let start = start { if let start = start {
result += "?start=\(start)" result += "?start=\(start)"

View File

@ -6551,7 +6551,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let resource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data) self.context.account.postbox.mediaBox.storeResourceData(resource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
self.state = self.state.withUpdatingAvatar(.image(representation)) self.state = self.state.withUpdatingAvatar(.image(representation))
if let (layout, navigationHeight) = self.validLayout { if let (layout, navigationHeight) = self.validLayout {
@ -6596,7 +6596,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let photoResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data) self.context.account.postbox.mediaBox.storeResourceData(photoResource.id, data: data)
let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil) let representation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 640, height: 640), resource: photoResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
self.state = self.state.withUpdatingAvatar(.image(representation)) self.state = self.state.withUpdatingAvatar(.image(representation))
if let (layout, navigationHeight) = self.validLayout { if let (layout, navigationHeight) = self.validLayout {

View File

@ -266,7 +266,7 @@ private final class FeaturedPackItemNode: ListViewItemNode {
thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker) thumbnailItem = .animated(item.file.resource, item.file.dimensions ?? PixelDimensions(width: 100, height: 100), item.file.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
} }
} }

View File

@ -103,7 +103,7 @@ final class ThemeUpdateManagerImpl: ThemeUpdateManager {
|> mapToSignal { wallpaper -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in |> mapToSignal { wallpaper -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in
if let wallpaper = wallpaper, case let .file(file) = wallpaper { if let wallpaper = wallpaper, case let .file(file) = wallpaper {
var convertedRepresentations: [ImageRepresentationWithReference] = [] var convertedRepresentations: [ImageRepresentationWithReference] = []
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationThemeReference, PresentationTheme?), NoError> in
guard complete, let fullSizeData = fullSizeData else { guard complete, let fullSizeData = fullSizeData else {

View File

@ -74,7 +74,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me
} }
} }
attributes.append(.ImageSize(size: PixelDimensions(imageDimensions))) attributes.append(.ImageSize(size: PixelDimensions(imageDimensions)))
let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)]).withUpdatedAttributes(attributes) let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)]).withUpdatedAttributes(attributes)
subscriber.putNext(.standalone(media: updatedFile)) subscriber.putNext(.standalone(media: updatedFile))
subscriber.putCompletion() subscriber.putCompletion()
} else { } else {
@ -103,7 +103,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me
let scaledImageSize = CGSize(width: scaledImage.size.width * scaledImage.scale, height: scaledImage.size.height * scaledImage.scale) let scaledImageSize = CGSize(width: scaledImage.size.width * scaledImage.scale, height: scaledImage.size.height * scaledImage.scale)
let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)]) let updatedFile = file.withUpdatedSize(data.size).withUpdatedPreviewRepresentations([TelegramMediaImageRepresentation(dimensions: PixelDimensions(scaledImageSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)])
subscriber.putNext(.standalone(media: updatedFile)) subscriber.putNext(.standalone(media: updatedFile))
subscriber.putCompletion() subscriber.putCompletion()
} else { } else {
@ -159,7 +159,7 @@ public func transformOutgoingMessageMedia(postbox: Postbox, network: Network, me
let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max)) let thumbnailResource = LocalFileMediaResource(fileId: Int64.random(in: Int64.min ... Int64.max))
postbox.mediaBox.storeResourceData(thumbnailResource.id, data: smallestData) postbox.mediaBox.storeResourceData(thumbnailResource.id, data: smallestData)
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(smallestSize), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let updatedImage = TelegramMediaImage(imageId: image.imageId, representations: representations, immediateThumbnailData: image.immediateThumbnailData, reference: image.reference, partialReference: image.partialReference, flags: []) 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))
} }

View File

@ -250,7 +250,7 @@ final class VerticalListContextResultsChatInputPanelItemNode: ListViewItemNode {
if let stickerFile = stickerFile { if let stickerFile = stickerFile {
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, progressiveSizes: [], immediateThumbnailData: nil) let tmpRepresentation = TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 55, height: 55), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)
let tmpImage = TelegramMediaImage(imageId: MediaId(namespace: 0, id: 0), representations: [tmpRepresentation], immediateThumbnailData: nil, reference: nil, partialReference: nil, flags: []) 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))
} }

View File

@ -26,9 +26,9 @@ let package = Package(
.target( .target(
name: "TelegramVoip", name: "TelegramVoip",
dependencies: [ dependencies: [
.productItem(name: "TgVoipWebrtc", package: "TgVoipWebrtc", condition: nil), .product(name: "TgVoipWebrtc", package: "TgVoipWebrtc", condition: nil),
.productItem(name: "SwiftSignalKit", package: "SSignalKit", condition: nil), .product(name: "SwiftSignalKit", package: "SSignalKit", condition: nil),
.productItem(name: "TelegramCore", package: "TelegramCore", condition: nil), .product(name: "TelegramCore", package: "TelegramCore", condition: nil),
], ],
path: "Sources", path: "Sources",
exclude: [ exclude: [

View File

@ -384,7 +384,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
thumbnailItem = .animated(EngineMediaResource(item.file.resource), item.file.dimensions ?? PixelDimensions(width: 512, height: 512), item.file.isVideoSticker) thumbnailItem = .animated(EngineMediaResource(item.file.resource), item.file.dimensions ?? PixelDimensions(width: 512, height: 512), item.file.isVideoSticker)
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: item.file.resource)
} else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource { } else if let dimensions = item.file.dimensions, let resource = chatMessageStickerResource(file: item.file, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource) resourceReference = MediaResourceReference.media(media: .standalone(media: item.file), resource: resource)
} }
} }
@ -668,7 +668,7 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
thumbnailItem = .animated(EngineMediaResource(file.resource)) thumbnailItem = .animated(EngineMediaResource(file.resource))
resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: file.resource) resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: file.resource)
} else if let dimensions = file.dimensions, let resource = chatMessageStickerResource(file: file, small: true) as? TelegramMediaResource { } else if let dimensions = file.dimensions, let resource = chatMessageStickerResource(file: file, small: true) as? TelegramMediaResource {
thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil)) thumbnailItem = .still(TelegramMediaImageRepresentation(dimensions: dimensions, resource: resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: resource) resourceReference = MediaResourceReference.media(media: .standalone(media: file), resource: resource)
} }

View File

@ -949,7 +949,7 @@ final class WallpaperBackgroundNodeImpl: ASDisplayNode, WallpaperBackgroundNode
convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: EngineMediaResource(representation.resource), media: EngineMedia(file.file)))) convertedRepresentations.append(ImageRepresentationWithReference(representation: representation, reference: reference(for: EngineMediaResource(representation.resource), media: EngineMedia(file.file))))
} }
let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000) let dimensions = file.file.dimensions ?? PixelDimensions(width: 2000, height: 4000)
convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: reference(for: EngineMediaResource(file.file.resource), media: EngineMedia(file.file)))) convertedRepresentations.append(ImageRepresentationWithReference(representation: .init(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: reference(for: EngineMediaResource(file.file.resource), media: EngineMedia(file.file))))
let signal = patternWallpaperImage(account: self.context.account, accountManager: self.context.sharedContext.accountManager, representations: convertedRepresentations, mode: .screen, autoFetchFullSize: true) let signal = patternWallpaperImage(account: self.context.account, accountManager: self.context.sharedContext.accountManager, representations: convertedRepresentations, mode: .screen, autoFetchFullSize: true)
self.patternImageDisposable.set((signal self.patternImageDisposable.set((signal
@ -1801,7 +1801,7 @@ final class WallpaperBackgroundNodeMergedImpl: ASDisplayNode, WallpaperBackgroun
gradientSpec = WallpaperGradiendComponentView.Spec(colors: file.settings.colors) gradientSpec = WallpaperGradiendComponentView.Spec(colors: file.settings.colors)
} }
if let dimensions = file.file.dimensions { if let dimensions = file.file.dimensions {
let representation = TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: file.file.immediateThumbnailData) let representation = TelegramMediaImageRepresentation(dimensions: dimensions, resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: file.file.immediateThumbnailData, hasVideo: false)
imageSpec = WallpaperImageComponentView.Spec.image(representation: representation, isPattern: file.isPattern, intensity: CGFloat(file.settings.intensity ?? 100) / 100.0) imageSpec = WallpaperImageComponentView.Spec.image(representation: representation, isPattern: file.isPattern, intensity: CGFloat(file.settings.intensity ?? 100) / 100.0)
} }
} }

View File

@ -1169,7 +1169,7 @@ public func themeImage(account: Account, accountManager: AccountManager<Telegram
|> mapToSignal { wallpaper -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in |> mapToSignal { wallpaper -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in
if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper { if let wallpaper = wallpaper, case let .file(file) = wallpaper.wallpaper {
var convertedRepresentations: [ImageRepresentationWithReference] = [] var convertedRepresentations: [ImageRepresentationWithReference] = []
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in |> mapToSignal { _, fullSizeData, complete -> Signal<(PresentationTheme?, WallpaperImage?, Data?), NoError> in
guard complete, let fullSizeData = fullSizeData else { guard complete, let fullSizeData = fullSizeData else {
@ -1417,7 +1417,7 @@ public func themeIconImage(account: Account, accountManager: AccountManager<Tele
} }
var convertedRepresentations: [ImageRepresentationWithReference] = [] var convertedRepresentations: [ImageRepresentationWithReference] = []
convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource))) convertedRepresentations.append(ImageRepresentationWithReference(representation: TelegramMediaImageRepresentation(dimensions: PixelDimensions(width: 100, height: 100), resource: file.file.resource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false), reference: .wallpaper(wallpaper: .slug(file.slug), resource: file.file.resource)))
return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false) return wallpaperDatas(account: account, accountManager: accountManager, fileReference: .standalone(media: file.file), representations: convertedRepresentations, alwaysShowThumbnailFirst: false, thumbnail: false, onlyFullSize: true, autoFetchFullSize: true, synchronousLoad: false)
|> mapToSignal { thumbnailData, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Bool, Bool, CGFloat, Int32?), NoError> in |> mapToSignal { thumbnailData, fullSizeData, complete -> Signal<((UIColor, UIColor?, [UInt32]), [UIColor], [UIColor], UIImage?, Bool, Bool, CGFloat, Int32?), NoError> in
guard complete, let fullSizeData = fullSizeData else { guard complete, let fullSizeData = fullSizeData else {

View File

@ -260,9 +260,9 @@ func legacyWebSearchItem(account: Account, result: ChatContextResult) -> LegacyW
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(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

View File

@ -37,7 +37,7 @@ struct WebSearchGalleryEntry: Equatable {
switch self.result { switch self.result {
case let .externalReference(externalReference): case let .externalReference(externalReference):
if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = externalReference.thumbnail?.resource, let dimensions = content.dimensions { if let content = externalReference.content, externalReference.type == "gif", let thumbnailResource = externalReference.thumbnail?.resource, let dimensions = content.dimensions {
let fileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])])) let fileReference = FileMediaReference.standalone(media: TelegramMediaFile(fileId: EngineMedia.Id(namespace: Namespaces.Media.LocalFile, id: 0), partialReference: nil, resource: content.resource, previewRepresentations: [TelegramMediaImageRepresentation(dimensions: dimensions, resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false)], videoThumbnails: [], immediateThumbnailData: nil, mimeType: "video/mp4", size: nil, attributes: [.Animated, .Video(duration: 0, size: dimensions, flags: [])]))
return WebSearchVideoGalleryItem(context: context, presentationData: presentationData, index: self.index, result: self.result, content: NativeVideoContent(id: .contextResult(self.result.queryId, self.result.id), fileReference: fileReference, loopVideo: true, enableSound: false, fetchAutomatically: true), controllerInteraction: controllerInteraction) return WebSearchVideoGalleryItem(context: context, presentationData: presentationData, index: self.index, result: self.result, content: NativeVideoContent(id: .contextResult(self.result.queryId, self.result.id), fileReference: fileReference, loopVideo: true, enableSound: false, fetchAutomatically: true), controllerInteraction: controllerInteraction)
} }
case let .internalReference(internalReference): case let .internalReference(internalReference):

View File

@ -130,10 +130,10 @@ final class WebSearchItemNode: GridItemNode {
var representations: [TelegramMediaImageRepresentation] = [] var representations: [TelegramMediaImageRepresentation] = []
if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions { if let thumbnailResource = thumbnailResource, let thumbnailDimensions = thumbnailDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(thumbnailDimensions), resource: thumbnailResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
if let imageResource = imageResource, let imageDimensions = imageDimensions { if let imageResource = imageResource, let imageDimensions = imageDimensions {
representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil)) representations.append(TelegramMediaImageRepresentation(dimensions: PixelDimensions(imageDimensions), resource: imageResource, progressiveSizes: [], immediateThumbnailData: nil, hasVideo: false))
} }
if !representations.isEmpty { if !representations.isEmpty {
let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: []) let tmpImage = TelegramMediaImage(imageId: EngineMedia.Id(namespace: 0, id: 0), representations: representations, immediateThumbnailData: immediateThumbnailData, reference: nil, partialReference: nil, flags: [])

View File

@ -350,7 +350,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
}) })
} }
} else { } else {
let _ = (context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.fromMenu, replyToMessageId: controller.replyToMessageId) let _ = (context.engine.messages.requestWebView(peerId: controller.peerId, botId: controller.botId, url: controller.url, payload: controller.payload, themeParams: generateWebAppThemeParams(presentationData.theme), fromMenu: controller.fromMenu, replyToMessageId: controller.replyToMessageId, threadId: controller.threadId)
|> deliverOnMainQueue).start(next: { [weak self] result in |> deliverOnMainQueue).start(next: { [weak self] result in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
@ -985,6 +985,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
private let isSimple: Bool private let isSimple: Bool
private let keepAliveSignal: Signal<Never, KeepWebViewError>? private let keepAliveSignal: Signal<Never, KeepWebViewError>?
private let replyToMessageId: MessageId? private let replyToMessageId: MessageId?
private let threadId: Int64?
private var presentationData: PresentationData private var presentationData: PresentationData
fileprivate let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? fileprivate let updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)?
@ -994,7 +995,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
public var getNavigationController: () -> NavigationController? = { return nil } public var getNavigationController: () -> NavigationController? = { return nil }
public var completion: () -> Void = {} public var completion: () -> Void = {}
public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, params: WebAppParameters, replyToMessageId: MessageId?) { public init(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, params: WebAppParameters, replyToMessageId: MessageId?, threadId: Int64?) {
self.context = context self.context = context
self.peerId = params.peerId self.peerId = params.peerId
self.botId = params.botId self.botId = params.botId
@ -1007,6 +1008,7 @@ public final class WebAppController: ViewController, AttachmentContainable {
self.isSimple = params.isSimple self.isSimple = params.isSimple
self.keepAliveSignal = params.keepAliveSignal self.keepAliveSignal = params.keepAliveSignal
self.replyToMessageId = replyToMessageId self.replyToMessageId = replyToMessageId
self.threadId = threadId
self.updatedPresentationData = updatedPresentationData self.updatedPresentationData = updatedPresentationData
self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 } self.presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
@ -1285,13 +1287,13 @@ private final class WebAppContextReferenceContentSource: ContextReferenceContent
} }
} }
public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, params: WebAppParameters, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }, getSourceRect: (() -> CGRect?)? = nil) -> ViewController { public func standaloneWebAppController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, params: WebAppParameters, threadId: Int64?, openUrl: @escaping (String) -> Void, getInputContainerNode: @escaping () -> (CGFloat, ASDisplayNode, () -> AttachmentController.InputPanelTransition?)? = { return nil }, completion: @escaping () -> Void = {}, willDismiss: @escaping () -> Void = {}, didDismiss: @escaping () -> Void = {}, getNavigationController: @escaping () -> NavigationController? = { return nil }, getSourceRect: (() -> CGRect?)? = nil) -> ViewController {
let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: params.peerId), buttons: [.standalone], initialButton: .standalone, fromMenu: params.fromMenu, hasTextInput: false, makeEntityInputView: { let controller = AttachmentController(context: context, updatedPresentationData: updatedPresentationData, chatLocation: .peer(id: params.peerId), buttons: [.standalone], initialButton: .standalone, fromMenu: params.fromMenu, hasTextInput: false, makeEntityInputView: {
return nil return nil
}) })
controller.getInputContainerNode = getInputContainerNode controller.getInputContainerNode = getInputContainerNode
controller.requestController = { _, present in controller.requestController = { _, present in
let webAppController = WebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, replyToMessageId: nil) let webAppController = WebAppController(context: context, updatedPresentationData: updatedPresentationData, params: params, replyToMessageId: nil, threadId: threadId)
webAppController.openUrl = openUrl webAppController.openUrl = openUrl
webAppController.completion = completion webAppController.completion = completion
webAppController.getNavigationController = getNavigationController webAppController.getNavigationController = getNavigationController