mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '3ac9d2d9a41a9e15912d4aceaeec935b684400f4'
This commit is contained in:
commit
47b0315671
@ -13798,3 +13798,6 @@ Sorry for the inconvenience.";
|
||||
"NameColor.GiftTitle" = "USE A GIFT";
|
||||
"NameColor.GiftInfo" = "Apply your collectible's unique look to your profile.";
|
||||
"NameColor.WearCollectible" = "Wear Collectible";
|
||||
|
||||
"Notification.StarsGift.TransferToChannel" = "%@ transferred a unique collectible to %@";
|
||||
"Notification.StarsGift.TransferToChannelYou" = "You transferred a unique collectible to %@";
|
||||
|
@ -370,7 +370,7 @@ final class BrowserAddressListComponent: Component {
|
||||
if let media = message.media.first(where: { $0 is TelegramMediaWebpage }) as? TelegramMediaWebpage {
|
||||
webPage = media
|
||||
} else {
|
||||
webPage = TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: primaryUrl, displayUrl: "", hash: 0, type: nil, websiteName: "", title: message.text, text: "", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))
|
||||
webPage = TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: primaryUrl, displayUrl: "", hash: 0, type: nil, websiteName: "", title: message.text, text: "", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))
|
||||
}
|
||||
itemMessage = message
|
||||
} else {
|
||||
@ -560,7 +560,7 @@ final class BrowserAddressListComponent: Component {
|
||||
component: AnyComponent(BrowserAddressListItemComponent(
|
||||
context: component.context,
|
||||
theme: component.theme,
|
||||
webPage: TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "https://telegram.org", displayUrl: "https://telegram.org", hash: 0, type: nil, websiteName: "Telegram", title: "Telegram Telegram", text: "Telegram", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))),
|
||||
webPage: TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "https://telegram.org", displayUrl: "https://telegram.org", hash: 0, type: nil, websiteName: "Telegram", title: "Telegram Telegram", text: "Telegram", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))),
|
||||
message: nil,
|
||||
hasNext: true,
|
||||
insets: .zero,
|
||||
|
@ -138,6 +138,7 @@ private func parseJson(_ input: [String: Any], url: String) -> TelegramMediaWebp
|
||||
duration: nil,
|
||||
author: byline,
|
||||
isMediaLargeByDefault: nil,
|
||||
imageIsVideoCover: false,
|
||||
image: nil,
|
||||
file: nil,
|
||||
story: nil,
|
||||
|
@ -1023,7 +1023,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
||||
}
|
||||
self.instantPage = webPage
|
||||
self.instantPageResources = resources
|
||||
let _ = (updatedRemoteWebpage(postbox: self.context.account.postbox, network: self.context.account.network, accountPeerId: self.context.account.peerId, webPage: WebpageReference(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: self._state.url, displayUrl: "", hash: 0, type: nil, websiteName: nil, title: nil, text: nil, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))))
|
||||
let _ = (updatedRemoteWebpage(postbox: self.context.account.postbox, network: self.context.account.network, accountPeerId: self.context.account.peerId, webPage: WebpageReference(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: self._state.url, displayUrl: "", hash: 0, type: nil, websiteName: nil, title: nil, text: nil, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] webPage in
|
||||
guard let self, let webPage, case let .Loaded(result) = webPage.content, let _ = result.instantPage else {
|
||||
return
|
||||
@ -1518,6 +1518,7 @@ final class BrowserWebContent: UIView, BrowserContent, WKNavigationDelegate, WKU
|
||||
duration: nil,
|
||||
author: nil,
|
||||
isMediaLargeByDefault: nil,
|
||||
imageIsVideoCover: false,
|
||||
image: image,
|
||||
file: nil,
|
||||
story: nil,
|
||||
|
@ -5286,7 +5286,7 @@ public final class ChatListSearchShimmerNode: ASDisplayNode {
|
||||
return nil
|
||||
case .links:
|
||||
var media: [EngineMedia] = []
|
||||
media.append(.webpage(TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "https://telegram.org", displayUrl: "https://telegram.org", hash: 0, type: nil, websiteName: "Telegram", title: "Telegram Telegram", text: "Telegram", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))))
|
||||
media.append(.webpage(TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "https://telegram.org", displayUrl: "https://telegram.org", hash: 0, type: nil, websiteName: "Telegram", title: "Telegram Telegram", text: "Telegram", embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: nil, file: nil, story: nil, attributes: [], instantPage: nil)))))
|
||||
let message = EngineMessage(
|
||||
stableId: 0,
|
||||
stableVersion: 0,
|
||||
|
@ -172,8 +172,10 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
||||
}
|
||||
if highlighted {
|
||||
strongSelf.highlightBackgroundNode.alpha = 1.0
|
||||
strongSelf.startTimer()
|
||||
} else {
|
||||
strongSelf.highlightBackgroundNode.alpha = 0.0
|
||||
strongSelf.invalidateTimer()
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,6 +185,25 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
||||
deinit {
|
||||
self.iconDisposable?.dispose()
|
||||
}
|
||||
|
||||
private var timer: SwiftSignalKit.Timer?
|
||||
private func startTimer() {
|
||||
self.invalidateTimer()
|
||||
|
||||
self.timer = SwiftSignalKit.Timer(timeout: 1.0, repeat: false, completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.invalidateTimer()
|
||||
self.longPressed()
|
||||
}, queue: Queue.mainQueue())
|
||||
self.timer?.start()
|
||||
}
|
||||
|
||||
private func invalidateTimer() {
|
||||
self.timer?.invalidate()
|
||||
self.timer = nil
|
||||
}
|
||||
|
||||
public override func didLoad() {
|
||||
super.didLoad()
|
||||
@ -191,6 +212,8 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
||||
}
|
||||
|
||||
@objc private func pressed() {
|
||||
self.invalidateTimer()
|
||||
|
||||
self.item.action?(ContextMenuActionItem.Action(
|
||||
controller: self.getController(),
|
||||
dismissWithResult: { [weak self] result in
|
||||
@ -208,6 +231,26 @@ public final class ContextControllerActionsListActionItemNode: HighlightTracking
|
||||
))
|
||||
}
|
||||
|
||||
private func longPressed() {
|
||||
self.touchesCancelled(nil, with: nil)
|
||||
|
||||
self.item.longPressAction?(ContextMenuActionItem.Action(
|
||||
controller: self.getController(),
|
||||
dismissWithResult: { [weak self] result in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.requestDismiss(result)
|
||||
},
|
||||
updateAction: { [weak self] id, updatedAction in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
strongSelf.requestUpdateAction(id, updatedAction)
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
public func canBeHighlighted() -> Bool {
|
||||
return self.item.action != nil
|
||||
}
|
||||
|
@ -345,7 +345,11 @@ public class DrawingStickerEntityView: DrawingEntityView {
|
||||
} else {
|
||||
imageView = UIImageView()
|
||||
imageView.contentMode = .scaleAspectFit
|
||||
self.addSubview(imageView)
|
||||
if let _ = self.animationNode {
|
||||
self.insertSubview(imageView, at: 0)
|
||||
} else {
|
||||
self.addSubview(imageView)
|
||||
}
|
||||
self.animatedImageView = imageView
|
||||
}
|
||||
imageView.image = image
|
||||
@ -754,11 +758,16 @@ public class DrawingStickerEntityView: DrawingEntityView {
|
||||
|
||||
self.updateAnimationColor()
|
||||
|
||||
if case .message = self.stickerEntity.content, self.animatedImageView == nil {
|
||||
let image = self.isNightTheme ? self.stickerEntity.secondaryRenderImage : self.stickerEntity.renderImage
|
||||
if let image {
|
||||
self.setupWithImage(image)
|
||||
switch self.stickerEntity.content {
|
||||
case .message, .gift:
|
||||
if self.animatedImageView == nil {
|
||||
let image = self.isNightTheme ? self.stickerEntity.secondaryRenderImage : self.stickerEntity.renderImage
|
||||
if let image {
|
||||
self.setupWithImage(image)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
self.updateMirroring(animated: animated)
|
||||
|
@ -77,7 +77,10 @@ private func mediaForMessage(message: Message) -> [(Media, TelegramMediaImage?)]
|
||||
case let .Loaded(content):
|
||||
if let embedUrl = content.embedUrl, !embedUrl.isEmpty {
|
||||
return [(webpage, nil)]
|
||||
} else if let file = content.file {
|
||||
} else if var file = content.file {
|
||||
if content.imageIsVideoCover, let image = content.image {
|
||||
file = file.withUpdatedVideoCover(image)
|
||||
}
|
||||
if let result = galleryMediaForMedia(media: file) {
|
||||
return [(result, content.image)]
|
||||
}
|
||||
|
@ -632,7 +632,7 @@ public func layoutInstantPageBlock(webpage: TelegramMediaWebpage, userLocation:
|
||||
let frame = CGRect(origin: CGPoint(x: floor((boundingWidth - size.width) / 2.0), y: 0.0), size: size)
|
||||
let item: InstantPageItem
|
||||
if let url = url, let coverId = coverId, case let .image(image) = media[coverId] {
|
||||
let loadedContent = TelegramMediaWebpageLoadedContent(url: url, displayUrl: url, hash: 0, type: "video", websiteName: nil, title: nil, text: nil, embedUrl: url, embedType: "video", embedSize: PixelDimensions(size), duration: nil, author: nil, isMediaLargeByDefault: nil, image: image, file: nil, story: nil, attributes: [], instantPage: nil)
|
||||
let loadedContent = TelegramMediaWebpageLoadedContent(url: url, displayUrl: url, hash: 0, type: "video", websiteName: nil, title: nil, text: nil, embedUrl: url, embedType: "video", embedSize: PixelDimensions(size), duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: image, file: nil, story: nil, attributes: [], instantPage: nil)
|
||||
let content = TelegramMediaWebpageContent.Loaded(loadedContent)
|
||||
|
||||
item = InstantPageImageItem(frame: frame, webPage: webpage, media: InstantPageMedia(index: embedIndex, media: .webpage(TelegramMediaWebpage(webpageId: EngineMedia.Id(namespace: Namespaces.Media.LocalWebpage, id: -1), content: content)), url: nil, caption: nil, credit: nil), attributes: [], interactive: true, roundCorners: false, fit: false)
|
||||
|
@ -63,9 +63,12 @@
|
||||
- (void)setFullSizeImage:(UIImage *)image forItem:(id<TGMediaEditableItem>)item;
|
||||
|
||||
- (SSignal *)coverImageSignalForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
- (void)setCoverImage:(UIImage *)image forItem:(id<TGMediaEditableItem>)item;
|
||||
- (void)setCoverImage:(UIImage *)image position:(NSNumber *)position forItem:(id<TGMediaEditableItem>)item;
|
||||
- (UIImage *)coverImageForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
|
||||
- (NSNumber *)coverPositionForItem:(NSObject<TGMediaEditableItem> *)item;
|
||||
- (void)setCoverImage:(UIImage *)image position:(NSNumber *)position forItem:(id<TGMediaEditableItem>)item;
|
||||
|
||||
- (void)setTemporaryRep:(id)rep forItem:(id<TGMediaEditableItem>)item;
|
||||
|
||||
- (SSignal *)fullSizeImageUrlForItem:(id<TGMediaEditableItem>)item;
|
||||
|
@ -34,6 +34,7 @@
|
||||
- (void)prepareForCoverEditing;
|
||||
- (void)returnFromCoverEditing;
|
||||
|
||||
- (NSTimeInterval)currentPosition;
|
||||
- (UIImage *)screenImage;
|
||||
- (UIImage *)transitionImage;
|
||||
- (CGRect)editorTransitionViewRect;
|
||||
|
@ -107,6 +107,7 @@
|
||||
TGMemoryImageCache *_originalThumbnailImageCache;
|
||||
|
||||
TGMemoryImageCache *_coverImageCache;
|
||||
NSMutableDictionary *_coverPositions;
|
||||
|
||||
TGModernCache *_diskCache;
|
||||
NSURL *_fullSizeResultsUrl;
|
||||
@ -171,6 +172,7 @@
|
||||
|
||||
_coverImageCache = [[TGMemoryImageCache alloc] initWithSoftMemoryLimit:[[self class] thumbnailImageSoftMemoryLimit] * 10
|
||||
hardMemoryLimit:[[self class] thumbnailImageHardMemoryLimit] * 10];
|
||||
_coverPositions = [[NSMutableDictionary alloc] init];
|
||||
|
||||
NSString *diskCachePath = [[[LegacyComponentsGlobals provider] dataStoragePath] stringByAppendingPathComponent:[[self class] diskCachePath]];
|
||||
_diskCache = [[TGModernCache alloc] initWithPath:diskCachePath size:[[self class] diskMemoryLimit]];
|
||||
@ -945,7 +947,14 @@
|
||||
return [_coverImageCache imageForKey:itemId attributes:NULL];
|
||||
}
|
||||
|
||||
- (void)setCoverImage:(UIImage *)image forItem:(id<TGMediaEditableItem>)item
|
||||
- (NSNumber *)coverPositionForItem:(NSObject<TGMediaEditableItem> *)item {
|
||||
NSString *itemId = [TGMediaEditingContext _coverImageUriForItemId:item.uniqueIdentifier];
|
||||
if (itemId == nil)
|
||||
return nil;
|
||||
return _coverPositions[itemId];
|
||||
}
|
||||
|
||||
- (void)setCoverImage:(UIImage *)image position:(NSNumber *)position forItem:(id<TGMediaEditableItem>)item
|
||||
{
|
||||
NSString *itemId = [TGMediaEditingContext _coverImageUriForItemId:item.uniqueIdentifier];
|
||||
if (itemId == nil)
|
||||
@ -953,6 +962,7 @@
|
||||
|
||||
[_coverImageCache setImage:image forKey:itemId attributes:NULL];
|
||||
_coverImagePipe.sink([TGMediaImageUpdate imageUpdateWithItem:item representation:image]);
|
||||
[_coverPositions setObject:position forKey:itemId];
|
||||
}
|
||||
|
||||
- (void)setFullSizeImage:(UIImage *)image forItem:(id<TGMediaEditableItem>)item
|
||||
|
@ -931,7 +931,7 @@
|
||||
TGModernGalleryItemView *currentItemView = _currentItemView;
|
||||
if ([currentItemView isKindOfClass:[TGMediaPickerGalleryVideoItemView class]]) {
|
||||
id<TGMediaEditableItem> editableMediaItem = [galleryEditableItem editableMediaItem];
|
||||
[_editingContext setCoverImage:[(TGMediaPickerGalleryVideoItemView *)currentItemView screenImage] forItem:editableMediaItem];
|
||||
[_editingContext setCoverImage:[(TGMediaPickerGalleryVideoItemView *)currentItemView screenImage] position:@([(TGMediaPickerGalleryVideoItemView *)currentItemView currentPosition]) forItem:editableMediaItem];
|
||||
}
|
||||
|
||||
TGDispatchAfter(0.01, dispatch_get_main_queue(), ^{
|
||||
@ -956,7 +956,7 @@
|
||||
__strong TGMediaPickerGalleryInterfaceView *strongSelf = weakSelf;
|
||||
if (strongSelf == nil)
|
||||
return;
|
||||
[strongSelf->_editingContext setCoverImage:cover forItem:editableMediaItem];
|
||||
[strongSelf->_editingContext setCoverImage:cover position:nil forItem:editableMediaItem];
|
||||
[strongSelf coverEditorTransitionOut];
|
||||
});
|
||||
}
|
||||
|
@ -768,6 +768,13 @@
|
||||
_isCoverEditing = true;
|
||||
[self setPlayButtonHidden:true animated:true];
|
||||
[self stop];
|
||||
|
||||
NSNumber *savedPosition = [self.item.editingContext coverPositionForItem:self.item.editableMediaItem];
|
||||
if (savedPosition != nil) {
|
||||
[self _seekToPosition:savedPosition.doubleValue manual:false];
|
||||
[_scrubberView setValue:savedPosition.doubleValue resetPosition:true];
|
||||
[_coverScrubberView setValue:savedPosition.doubleValue resetPosition:true];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)returnFromCoverEditing
|
||||
@ -941,6 +948,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (NSTimeInterval)currentPosition {
|
||||
return _coverScrubberView.value;
|
||||
}
|
||||
|
||||
- (UIImage *)screenImage
|
||||
{
|
||||
if (_videoView != nil)
|
||||
|
@ -74,8 +74,9 @@ func telegramMediaWebpageFromApiWebpage(_ webpage: Api.WebPage) -> TelegramMedia
|
||||
}
|
||||
|
||||
let isMediaLargeByDefault = (flags & (1 << 13)) != 0
|
||||
let imageIsVideoCover = (flags & (1 << 14)) != 0
|
||||
|
||||
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Loaded(TelegramMediaWebpageLoadedContent(url: url, displayUrl: displayUrl, hash: hash, type: type, websiteName: siteName, title: title, text: description, embedUrl: embedUrl, embedType: embedType, embedSize: embedSize, duration: webpageDuration, author: author, isMediaLargeByDefault: isMediaLargeByDefault, image: image, file: file, story: story, attributes: webpageAttributes, instantPage: instantPage)))
|
||||
return TelegramMediaWebpage(webpageId: MediaId(namespace: Namespaces.Media.CloudWebpage, id: id), content: .Loaded(TelegramMediaWebpageLoadedContent(url: url, displayUrl: displayUrl, hash: hash, type: type, websiteName: siteName, title: title, text: description, embedUrl: embedUrl, embedType: embedType, embedSize: embedSize, duration: webpageDuration, author: author, isMediaLargeByDefault: isMediaLargeByDefault, imageIsVideoCover: imageIsVideoCover, image: image, file: file, story: story, attributes: webpageAttributes, instantPage: instantPage)))
|
||||
case .webPageEmpty:
|
||||
return nil
|
||||
}
|
||||
|
@ -179,6 +179,11 @@ private func findMediaResource(media: Media, previousMedia: Media?, resource: Me
|
||||
if areResourcesEqual(file.resource, resource) {
|
||||
return file.resource
|
||||
} else {
|
||||
if let videoCover = file.videoCover {
|
||||
if let resource = findMediaResource(media: videoCover, previousMedia: previousMedia, resource: resource) {
|
||||
return resource
|
||||
}
|
||||
}
|
||||
for representation in file.previewRepresentations {
|
||||
if areResourcesEqual(representation.resource, resource) {
|
||||
return representation.resource
|
||||
|
@ -922,6 +922,10 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
||||
public func withUpdatedAttributes(_ attributes: [TelegramMediaFileAttribute]) -> TelegramMediaFile {
|
||||
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: self.resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, videoCover: self.videoCover, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: self.size, attributes: attributes, alternativeRepresentations: self.alternativeRepresentations)
|
||||
}
|
||||
|
||||
public func withUpdatedVideoCover(_ videoCover: TelegramMediaImage?) -> TelegramMediaFile {
|
||||
return TelegramMediaFile(fileId: self.fileId, partialReference: self.partialReference, resource: self.resource, previewRepresentations: self.previewRepresentations, videoThumbnails: self.videoThumbnails, videoCover: videoCover, immediateThumbnailData: self.immediateThumbnailData, mimeType: self.mimeType, size: self.size, attributes: self.attributes, alternativeRepresentations: self.alternativeRepresentations)
|
||||
}
|
||||
}
|
||||
|
||||
public func ==(lhs: TelegramMediaFile, rhs: TelegramMediaFile) -> Bool {
|
||||
|
@ -171,6 +171,7 @@ public final class TelegramMediaWebpageLoadedContent: PostboxCoding, Equatable {
|
||||
public let duration: Int?
|
||||
public let author: String?
|
||||
public let isMediaLargeByDefault: Bool?
|
||||
public let imageIsVideoCover: Bool
|
||||
|
||||
public let image: TelegramMediaImage?
|
||||
public let file: TelegramMediaFile?
|
||||
@ -192,6 +193,7 @@ public final class TelegramMediaWebpageLoadedContent: PostboxCoding, Equatable {
|
||||
duration: Int?,
|
||||
author: String?,
|
||||
isMediaLargeByDefault: Bool?,
|
||||
imageIsVideoCover: Bool,
|
||||
image: TelegramMediaImage?,
|
||||
file: TelegramMediaFile?,
|
||||
story: TelegramMediaStory?,
|
||||
@ -211,6 +213,7 @@ public final class TelegramMediaWebpageLoadedContent: PostboxCoding, Equatable {
|
||||
self.duration = duration
|
||||
self.author = author
|
||||
self.isMediaLargeByDefault = isMediaLargeByDefault
|
||||
self.imageIsVideoCover = imageIsVideoCover
|
||||
self.image = image
|
||||
self.file = file
|
||||
self.story = story
|
||||
@ -240,6 +243,7 @@ public final class TelegramMediaWebpageLoadedContent: PostboxCoding, Equatable {
|
||||
}
|
||||
self.author = decoder.decodeOptionalStringForKey("au")
|
||||
self.isMediaLargeByDefault = decoder.decodeOptionalBoolForKey("lbd")
|
||||
self.imageIsVideoCover = decoder.decodeBoolForKey("isvc", orElse: false)
|
||||
|
||||
if let image = decoder.decodeObjectForKey("im") as? TelegramMediaImage {
|
||||
self.image = image
|
||||
@ -331,6 +335,7 @@ public final class TelegramMediaWebpageLoadedContent: PostboxCoding, Equatable {
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "lbd")
|
||||
}
|
||||
encoder.encodeBool(self.imageIsVideoCover, forKey: "isvc")
|
||||
if let image = self.image {
|
||||
encoder.encodeObject(image, forKey: "im")
|
||||
} else {
|
||||
@ -377,6 +382,10 @@ public func ==(lhs: TelegramMediaWebpageLoadedContent, rhs: TelegramMediaWebpage
|
||||
return false
|
||||
}
|
||||
|
||||
if lhs.imageIsVideoCover != rhs.imageIsVideoCover {
|
||||
return false
|
||||
}
|
||||
|
||||
if let lhsImage = lhs.image, let rhsImage = rhs.image {
|
||||
if !lhsImage.isEqual(to: rhsImage) {
|
||||
return false
|
||||
|
@ -115,6 +115,7 @@ public func webpagePreviewWithProgress(account: Account, urls: [String], webpage
|
||||
duration: nil,
|
||||
author: nil,
|
||||
isMediaLargeByDefault: true,
|
||||
imageIsVideoCover: false,
|
||||
image: image,
|
||||
file: nil,
|
||||
story: nil,
|
||||
@ -247,6 +248,7 @@ public func actualizedWebpage(account: Account, webpage: TelegramMediaWebpage) -
|
||||
duration: content.duration,
|
||||
author: content.author,
|
||||
isMediaLargeByDefault: content.isMediaLargeByDefault,
|
||||
imageIsVideoCover: content.imageIsVideoCover,
|
||||
image: content.image,
|
||||
file: content.file,
|
||||
story: content.story,
|
||||
|
@ -1113,7 +1113,7 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Sent(authorName, starsPrice)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
}
|
||||
case let .starGiftUnique(gift, isUpgrade, _, _, _, _, _, _, senderId, _):
|
||||
case let .starGiftUnique(gift, isUpgrade, _, _, _, _, _, peerId, senderId, _):
|
||||
if case let .unique(gift) = gift {
|
||||
if !forAdditionalServiceMessage && !"".isEmpty {
|
||||
attributedString = NSAttributedString(string: "\(gift.title) #\(gift.number)", font: titleFont, textColor: primaryTextColor)
|
||||
@ -1138,10 +1138,25 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
} else if message.author?.id == accountPeerId {
|
||||
attributedString = NSAttributedString(string: strings.Notification_StarsGift_TransferYou, font: titleFont, textColor: primaryTextColor)
|
||||
} else if let senderId, let peer = message.peers[senderId] {
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
peerIds = [(0, senderId)]
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Transfer(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
if let peerId, let targetPeer = message.peers[peerId] {
|
||||
if senderId == accountPeerId {
|
||||
peerName = EnginePeer(targetPeer).compactDisplayTitle
|
||||
peerIds = [(0, peerId)]
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_TransferToChannelYou(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
} else {
|
||||
let senderPeerName = EnginePeer(targetPeer).compactDisplayTitle
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
peerIds = [(0, senderId), (1, peerId)]
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_TransferToChannel(senderPeerName, peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
} else {
|
||||
peerName = EnginePeer(peer).compactDisplayTitle
|
||||
peerIds = [(0, senderId)]
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Transfer(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
}
|
||||
} else {
|
||||
let attributes = peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: peerIds)
|
||||
attributedString = addAttributesToStringWithRanges(strings.Notification_StarsGift_Transfer(peerName)._tuple, body: bodyAttributes, argumentAttributes: attributes)
|
||||
|
@ -360,7 +360,9 @@ public final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
contentMediaAutomaticDownload = .prefetch
|
||||
}
|
||||
|
||||
if file.isAnimated {
|
||||
if let _ = file.videoCover {
|
||||
contentMediaAutomaticPlayback = false
|
||||
} else if file.isAnimated {
|
||||
contentMediaAutomaticPlayback = context.sharedContext.energyUsageSettings.autoplayGif
|
||||
} else if file.isVideo && context.sharedContext.energyUsageSettings.autoplayVideo {
|
||||
var willDownloadOrLocal = false
|
||||
|
@ -344,7 +344,11 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
|
||||
}
|
||||
}
|
||||
default:
|
||||
if let file = mainMedia as? TelegramMediaFile, webpage.type != "telegram_theme" {
|
||||
if var file = mainMedia as? TelegramMediaFile, webpage.type != "telegram_theme" {
|
||||
if webpage.imageIsVideoCover, let image = webpage.image {
|
||||
file = file.withUpdatedVideoCover(image)
|
||||
}
|
||||
|
||||
if let embedUrl = webpage.embedUrl, !embedUrl.isEmpty {
|
||||
if automaticPlayback {
|
||||
mediaAndFlags = ([file], [.preferMediaBeforeText])
|
||||
@ -689,7 +693,10 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
|
||||
if let image = content.image {
|
||||
mediaList.append(image)
|
||||
}
|
||||
if let file = content.file {
|
||||
if var file = content.file {
|
||||
if content.imageIsVideoCover, let image = content.image {
|
||||
file = file.withUpdatedVideoCover(image)
|
||||
}
|
||||
mediaList.append(file)
|
||||
}
|
||||
updatedMedia = mediaList
|
||||
@ -698,7 +705,10 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
|
||||
if let image = content.image {
|
||||
mediaList.append(image)
|
||||
}
|
||||
if let file = content.file {
|
||||
if var file = content.file {
|
||||
if content.imageIsVideoCover, let image = content.image {
|
||||
file = file.withUpdatedVideoCover(image)
|
||||
}
|
||||
mediaList.append(file)
|
||||
}
|
||||
updatedMedia = mediaList
|
||||
|
@ -31,8 +31,13 @@ extension MediaEditorScreenImpl {
|
||||
let filteredEntities = self.node.entitiesView.entities.filter { entity in
|
||||
if entity is DrawingMediaEntity {
|
||||
return false
|
||||
} else if let entity = entity as? DrawingStickerEntity, case .message = entity.content {
|
||||
return false
|
||||
} else if let entity = entity as? DrawingStickerEntity {
|
||||
switch entity.content {
|
||||
case .message, .gift:
|
||||
return false
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
@ -46,6 +51,8 @@ extension MediaEditorScreenImpl {
|
||||
return false
|
||||
} else if case .message = subject, !filteredValues.hasChanges && filteredEntities.isEmpty && caption.string.isEmpty {
|
||||
return false
|
||||
} else if case .gift = subject, !filteredValues.hasChanges && filteredEntities.isEmpty && caption.string.isEmpty {
|
||||
return false
|
||||
} else if case .empty = subject, !self.node.hasAnyChanges && !self.node.drawingView.internalState.canUndo {
|
||||
return false
|
||||
} else if case .videoCollage = subject {
|
||||
|
@ -3151,9 +3151,15 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
||||
var effectiveSubject = subject
|
||||
if case let .draft(draft, _ ) = subject {
|
||||
for entity in draft.values.entities {
|
||||
if case let .sticker(sticker) = entity, case let .message(ids, _, _, _, _) = sticker.content {
|
||||
effectiveSubject = .message(ids)
|
||||
break
|
||||
if case let .sticker(sticker) = entity {
|
||||
switch sticker.content {
|
||||
case let .message(ids, _, _, _, _):
|
||||
effectiveSubject = .message(ids)
|
||||
case let .gift(gift, _):
|
||||
effectiveSubject = .gift(gift)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3173,11 +3179,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
||||
case .image, .video:
|
||||
isSavingAvailable = !controller.isEmbeddedEditor
|
||||
isFromCamera = true
|
||||
case .draft:
|
||||
isSavingAvailable = true
|
||||
case .message:
|
||||
isSavingAvailable = true
|
||||
case .gift:
|
||||
case .draft, .message,. gift:
|
||||
isSavingAvailable = true
|
||||
default:
|
||||
isSavingAvailable = false
|
||||
@ -3454,11 +3456,14 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
||||
let renderer = DrawingMessageRenderer(context: self.context, messages: messages, parentView: self.view, isGift: isGift, wallpaperDayColor: wallpaperColors.0, wallpaperNightColor: wallpaperColors.1)
|
||||
renderer.render(completion: { result in
|
||||
if case .draft = subject, let existingEntityView = self.entitiesView.getView(where: { entityView in
|
||||
if let stickerEntityView = entityView as? DrawingStickerEntityView, case .message = (stickerEntityView.entity as! DrawingStickerEntity).content {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
if let stickerEntityView = entityView as? DrawingStickerEntityView {
|
||||
if case .message = (stickerEntityView.entity as! DrawingStickerEntity).content {
|
||||
return true
|
||||
} else if case .gift = (stickerEntityView.entity as! DrawingStickerEntity).content {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}) as? DrawingStickerEntityView {
|
||||
existingEntityView.isNightTheme = isNightTheme
|
||||
let messageEntity = existingEntityView.entity as! DrawingStickerEntity
|
||||
@ -6416,7 +6421,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
||||
}
|
||||
|
||||
fileprivate func checkPostingAvailability() {
|
||||
guard self.postingAvailabilityDisposable == nil else {
|
||||
guard self.postingAvailabilityDisposable == nil && !self.isEditingStory else {
|
||||
return
|
||||
}
|
||||
self.postingAvailabilityDisposable = (self.postingAvailabilityPromise.get()
|
||||
|
@ -10972,7 +10972,20 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}
|
||||
|
||||
let switchToFilter: (ProfileGiftsContext.Filters) -> Void = { [weak giftsContext] value in
|
||||
giftsContext?.updateFilter(value)
|
||||
var updatedFilter = filter
|
||||
updatedFilter.remove(.unlimited)
|
||||
updatedFilter.remove(.limited)
|
||||
updatedFilter.remove(.unique)
|
||||
updatedFilter.insert(value)
|
||||
giftsContext?.updateFilter(updatedFilter)
|
||||
}
|
||||
|
||||
let switchToVisiblityFilter: (ProfileGiftsContext.Filters) -> Void = { [weak giftsContext] value in
|
||||
var updatedFilter = filter
|
||||
updatedFilter.remove(.hidden)
|
||||
updatedFilter.remove(.displayed)
|
||||
updatedFilter.insert(value)
|
||||
giftsContext?.updateFilter(updatedFilter)
|
||||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unlimited, icon: { theme in
|
||||
@ -11005,14 +11018,14 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
||||
}, action: { _, f in
|
||||
toggleFilter(.displayed)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.displayed)
|
||||
switchToVisiblityFilter(.displayed)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Hidden, icon: { theme in
|
||||
return filter.contains(.hidden) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
}, action: { _, f in
|
||||
toggleFilter(.hidden)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.hidden)
|
||||
switchToVisiblityFilter(.hidden)
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -237,7 +237,7 @@ final class PeerNameColorChatPreviewItemNode: ListViewItemNode {
|
||||
|
||||
var media: [Media] = []
|
||||
if let (site, title, text) = messageItem.linkPreview, params.width > 320.0 {
|
||||
media.append(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "", displayUrl: "", hash: 0, type: nil, websiteName: site, title: title, text: text, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))))
|
||||
media.append(TelegramMediaWebpage(webpageId: MediaId(namespace: 0, id: 0), content: .Loaded(TelegramMediaWebpageLoadedContent(url: "", displayUrl: "", hash: 0, type: nil, websiteName: site, title: title, text: text, embedUrl: nil, embedType: nil, embedSize: nil, duration: nil, author: nil, isMediaLargeByDefault: nil, imageIsVideoCover: false, image: nil, file: nil, story: nil, attributes: [], instantPage: nil))))
|
||||
}
|
||||
|
||||
let message = Message(stableId: 1, stableVersion: 0, id: MessageId(peerId: peerId, namespace: 0, id: 1), globallyUniqueId: nil, groupingKey: nil, groupInfo: nil, threadId: nil, timestamp: 66000, flags: messageItem.outgoing ? [] : [.Incoming], tags: [], globalTags: [], localTags: [], customTags: [], forwardInfo: nil, author: peers[authorPeerId], text: messageItem.text, attributes: messageItem.reply != nil ? [ReplyMessageAttribute(messageId: replyMessageId, threadMessageId: nil, quote: nil, isQuote: false)] : [], media: media, peers: peers, associatedMessages: messages, associatedMessageIds: [], associatedMedia: [:], associatedThreadInfo: nil, associatedStories: [:])
|
||||
|
@ -487,7 +487,6 @@ final class UserAppearanceScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let navigationController: NavigationController? = self.environment?.controller()?.navigationController as? NavigationController
|
||||
|
||||
|
@ -586,11 +586,15 @@ public final class StoryPeerListComponent: Component {
|
||||
var titleIconSize: CGSize?
|
||||
if let peerStatus = component.titlePeerStatus {
|
||||
let statusContent: EmojiStatusComponent.Content
|
||||
var particleColor: UIColor?
|
||||
switch peerStatus {
|
||||
case .premium:
|
||||
statusContent = .premium(color: component.theme.list.itemAccentColor)
|
||||
case let .emoji(emoji):
|
||||
statusContent = .animation(content: .customEmoji(fileId: emoji.fileId), size: CGSize(width: 44.0, height: 44.0), placeholderColor: component.theme.list.mediaPlaceholderColor, themeColor: component.theme.list.itemAccentColor, loopMode: .count(2))
|
||||
if let color = emoji.color {
|
||||
particleColor = UIColor(rgb: UInt32(bitPattern: color))
|
||||
}
|
||||
}
|
||||
|
||||
var animateStatusTransition = false
|
||||
@ -618,6 +622,7 @@ public final class StoryPeerListComponent: Component {
|
||||
animationCache: component.context.animationCache,
|
||||
animationRenderer: component.context.animationRenderer,
|
||||
content: statusContent,
|
||||
particleColor: particleColor,
|
||||
isVisibleForAnimations: true,
|
||||
action: { [weak self] in
|
||||
guard let self, let component = self.component, let titleIconView = self.titleIconView?.view else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user