Various improvements

This commit is contained in:
Ilya Laktyushin 2025-01-28 21:57:30 +04:00
parent 681b5c9d3a
commit 2a7d1938d7
18 changed files with 114 additions and 15 deletions

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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
}

View File

@ -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)

View File

@ -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;

View File

@ -34,6 +34,7 @@
- (void)prepareForCoverEditing;
- (void)returnFromCoverEditing;
- (NSTimeInterval)currentPosition;
- (UIImage *)screenImage;
- (UIImage *)transitionImage;
- (CGRect)editorTransitionViewRect;

View File

@ -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

View File

@ -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];
});
}

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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,

View File

@ -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)
})))
}

View File

@ -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: [:])

View File

@ -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

View File

@ -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 {