mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'formatted-date-api'
This commit is contained in:
commit
96bb624b2d
34 changed files with 501 additions and 321 deletions
|
|
@ -117,7 +117,7 @@ final class AuthorizationSequenceSignUpController: ViewController {
|
|||
items.append(.separator)
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Login_Announce_Notify, icon: { theme in
|
||||
if !announceSignUp {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, iconPosition: .left, action: { [weak self] _, a in
|
||||
|
|
@ -128,7 +128,7 @@ final class AuthorizationSequenceSignUpController: ViewController {
|
|||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Login_Announce_DontNotify, icon: { theme in
|
||||
if announceSignUp {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, iconPosition: .left, action: { [weak self] _, a in
|
||||
|
|
|
|||
|
|
@ -3742,7 +3742,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.Chat_ContextViewAsTopics, icon: { theme in
|
||||
if !isViewingAsTopics {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak sourceController] _, a in
|
||||
|
|
@ -3778,7 +3778,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.Chat_ContextViewAsMessages, icon: { theme in
|
||||
if isViewingAsTopics {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak sourceController] _, a in
|
||||
|
|
|
|||
|
|
@ -5587,7 +5587,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
}
|
||||
var items: [ContextMenuItem] = []
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_AllChats, icon: { theme in
|
||||
return scope == .everywhere ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return scope == .everywhere ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { [weak self] _, f in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -5596,7 +5596,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
self.searchScopePromise.set(.everywhere)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_PrivateChats, icon: { theme in
|
||||
return scope == .privateChats ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return scope == .privateChats ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { [weak self] _, f in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -5605,7 +5605,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
self.searchScopePromise.set(.privateChats)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_GroupChats, icon: { theme in
|
||||
return scope == .groups ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return scope == .groups ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { [weak self] _, f in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
@ -5614,7 +5614,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
|||
self.searchScopePromise.set(.groups)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_Search_Messages_Menu_Channels, icon: { theme in
|
||||
return scope == .channels ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return scope == .channels ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { [weak self] _, f in
|
||||
guard let self else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -739,11 +739,7 @@
|
|||
|
||||
bool processLive = false;
|
||||
if (asset.subtypes & TGMediaAssetSubtypePhotoLive) {
|
||||
if (iosMajorVersion() < 9 || (iosMajorVersion() == 9 && iosMinorVersion() < 1)) {
|
||||
processLive = false;
|
||||
} else {
|
||||
processLive = true;
|
||||
}
|
||||
processLive = true;
|
||||
}
|
||||
|
||||
if (processLive)
|
||||
|
|
|
|||
|
|
@ -369,32 +369,7 @@
|
|||
count = MIN(count, _itemsLimit);
|
||||
|
||||
for (NSUInteger i = 0; i < count; i++)
|
||||
{
|
||||
// TGMediaAsset *asset = [fetchResult assetAtIndex:i];
|
||||
//
|
||||
// TGMediaPickerGalleryItem<TGModernGallerySelectableItem, TGModernGalleryEditableItem> *galleryItem = nil;
|
||||
// switch (asset.type)
|
||||
// {
|
||||
// case TGMediaAssetVideoType:
|
||||
// {
|
||||
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case TGMediaAssetGifType:
|
||||
// {
|
||||
// TGCameraCapturedVideo *convertedAsset = [[TGCameraCapturedVideo alloc] initWithAsset:asset livePhoto:false];
|
||||
// galleryItem = [[TGMediaPickerGalleryVideoItem alloc] initWithAsset:convertedAsset];
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// {
|
||||
// galleryItem = [[TGMediaPickerGalleryPhotoItem alloc] initWithAsset:(id<TGMediaEditableItem,TGMediaSelectableItem>)asset];
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
|
||||
{
|
||||
TGMediaPickerGalleryFetchResultItem *galleryItem = [[TGMediaPickerGalleryFetchResultItem alloc] initWithFetchResult:fetchResult index:i];
|
||||
galleryItem.selectionContext = selectionContext;
|
||||
galleryItem.editingContext = editingContext;
|
||||
|
|
|
|||
|
|
@ -401,7 +401,7 @@ public func storageUsageExceptionsScreen(
|
|||
if currentValue == value {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
applyValue(value)
|
||||
|
|
|
|||
|
|
@ -649,6 +649,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[681706865] = { return Api.MessageEntity.parse_messageEntityCode($0) }
|
||||
dict[-925956616] = { return Api.MessageEntity.parse_messageEntityCustomEmoji($0) }
|
||||
dict[1692693954] = { return Api.MessageEntity.parse_messageEntityEmail($0) }
|
||||
dict[-1874147385] = { return Api.MessageEntity.parse_messageEntityFormattedDate($0) }
|
||||
dict[1868782349] = { return Api.MessageEntity.parse_messageEntityHashtag($0) }
|
||||
dict[-2106619040] = { return Api.MessageEntity.parse_messageEntityItalic($0) }
|
||||
dict[-100378723] = { return Api.MessageEntity.parse_messageEntityMention($0) }
|
||||
|
|
@ -1172,7 +1173,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
|
|||
dict[-1094555409] = { return Api.Update.parse_updateNotifySettings($0) }
|
||||
dict[-1955438642] = { return Api.Update.parse_updatePaidReactionPrivacy($0) }
|
||||
dict[-337610926] = { return Api.Update.parse_updatePeerBlocked($0) }
|
||||
dict[1115654513] = { return Api.Update.parse_updatePeerHistoryNoForward($0) }
|
||||
dict[1463202714] = { return Api.Update.parse_updatePeerHistoryNoForwards($0) }
|
||||
dict[-1147422299] = { return Api.Update.parse_updatePeerHistoryTTL($0) }
|
||||
dict[-1263546448] = { return Api.Update.parse_updatePeerLocated($0) }
|
||||
dict[1786671974] = { return Api.Update.parse_updatePeerSettings($0) }
|
||||
|
|
|
|||
|
|
@ -78,6 +78,18 @@ public extension Api {
|
|||
self.length = length
|
||||
}
|
||||
}
|
||||
public class Cons_messageEntityFormattedDate {
|
||||
public var flags: Int32
|
||||
public var offset: Int32
|
||||
public var length: Int32
|
||||
public var date: Int32
|
||||
public init(flags: Int32, offset: Int32, length: Int32, date: Int32) {
|
||||
self.flags = flags
|
||||
self.offset = offset
|
||||
self.length = length
|
||||
self.date = date
|
||||
}
|
||||
}
|
||||
public class Cons_messageEntityHashtag {
|
||||
public var offset: Int32
|
||||
public var length: Int32
|
||||
|
|
@ -189,6 +201,7 @@ public extension Api {
|
|||
case messageEntityCode(Cons_messageEntityCode)
|
||||
case messageEntityCustomEmoji(Cons_messageEntityCustomEmoji)
|
||||
case messageEntityEmail(Cons_messageEntityEmail)
|
||||
case messageEntityFormattedDate(Cons_messageEntityFormattedDate)
|
||||
case messageEntityHashtag(Cons_messageEntityHashtag)
|
||||
case messageEntityItalic(Cons_messageEntityItalic)
|
||||
case messageEntityMention(Cons_messageEntityMention)
|
||||
|
|
@ -270,6 +283,15 @@ public extension Api {
|
|||
serializeInt32(_data.offset, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.length, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageEntityFormattedDate(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(-1874147385)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.offset, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.length, buffer: buffer, boxed: false)
|
||||
serializeInt32(_data.date, buffer: buffer, boxed: false)
|
||||
break
|
||||
case .messageEntityHashtag(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1868782349)
|
||||
|
|
@ -380,6 +402,8 @@ public extension Api {
|
|||
return ("messageEntityCustomEmoji", [("offset", _data.offset as Any), ("length", _data.length as Any), ("documentId", _data.documentId as Any)])
|
||||
case .messageEntityEmail(let _data):
|
||||
return ("messageEntityEmail", [("offset", _data.offset as Any), ("length", _data.length as Any)])
|
||||
case .messageEntityFormattedDate(let _data):
|
||||
return ("messageEntityFormattedDate", [("flags", _data.flags as Any), ("offset", _data.offset as Any), ("length", _data.length as Any), ("date", _data.date as Any)])
|
||||
case .messageEntityHashtag(let _data):
|
||||
return ("messageEntityHashtag", [("offset", _data.offset as Any), ("length", _data.length as Any)])
|
||||
case .messageEntityItalic(let _data):
|
||||
|
|
@ -544,6 +568,26 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageEntityFormattedDate(_ reader: BufferReader) -> MessageEntity? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Int32?
|
||||
_2 = reader.readInt32()
|
||||
var _3: Int32?
|
||||
_3 = reader.readInt32()
|
||||
var _4: Int32?
|
||||
_4 = reader.readInt32()
|
||||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
let _c3 = _3 != nil
|
||||
let _c4 = _4 != nil
|
||||
if _c1 && _c2 && _c3 && _c4 {
|
||||
return Api.MessageEntity.messageEntityFormattedDate(Cons_messageEntityFormattedDate(flags: _1!, offset: _2!, length: _3!, date: _4!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_messageEntityHashtag(_ reader: BufferReader) -> MessageEntity? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
|
|
|
|||
|
|
@ -969,7 +969,7 @@ public extension Api {
|
|||
self.peerId = peerId
|
||||
}
|
||||
}
|
||||
public class Cons_updatePeerHistoryNoForward {
|
||||
public class Cons_updatePeerHistoryNoForwards {
|
||||
public var flags: Int32
|
||||
public var peer: Api.Peer
|
||||
public init(flags: Int32, peer: Api.Peer) {
|
||||
|
|
@ -1539,7 +1539,7 @@ public extension Api {
|
|||
case updateNotifySettings(Cons_updateNotifySettings)
|
||||
case updatePaidReactionPrivacy(Cons_updatePaidReactionPrivacy)
|
||||
case updatePeerBlocked(Cons_updatePeerBlocked)
|
||||
case updatePeerHistoryNoForward(Cons_updatePeerHistoryNoForward)
|
||||
case updatePeerHistoryNoForwards(Cons_updatePeerHistoryNoForwards)
|
||||
case updatePeerHistoryTTL(Cons_updatePeerHistoryTTL)
|
||||
case updatePeerLocated(Cons_updatePeerLocated)
|
||||
case updatePeerSettings(Cons_updatePeerSettings)
|
||||
|
|
@ -2497,9 +2497,9 @@ public extension Api {
|
|||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
_data.peerId.serialize(buffer, true)
|
||||
break
|
||||
case .updatePeerHistoryNoForward(let _data):
|
||||
case .updatePeerHistoryNoForwards(let _data):
|
||||
if boxed {
|
||||
buffer.appendInt32(1115654513)
|
||||
buffer.appendInt32(1463202714)
|
||||
}
|
||||
serializeInt32(_data.flags, buffer: buffer, boxed: false)
|
||||
_data.peer.serialize(buffer, true)
|
||||
|
|
@ -3208,8 +3208,8 @@ public extension Api {
|
|||
return ("updatePaidReactionPrivacy", [("`private`", _data.`private` as Any)])
|
||||
case .updatePeerBlocked(let _data):
|
||||
return ("updatePeerBlocked", [("flags", _data.flags as Any), ("peerId", _data.peerId as Any)])
|
||||
case .updatePeerHistoryNoForward(let _data):
|
||||
return ("updatePeerHistoryNoForward", [("flags", _data.flags as Any), ("peer", _data.peer as Any)])
|
||||
case .updatePeerHistoryNoForwards(let _data):
|
||||
return ("updatePeerHistoryNoForwards", [("flags", _data.flags as Any), ("peer", _data.peer as Any)])
|
||||
case .updatePeerHistoryTTL(let _data):
|
||||
return ("updatePeerHistoryTTL", [("flags", _data.flags as Any), ("peer", _data.peer as Any), ("ttlPeriod", _data.ttlPeriod as Any)])
|
||||
case .updatePeerLocated(let _data):
|
||||
|
|
@ -5176,7 +5176,7 @@ public extension Api {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
public static func parse_updatePeerHistoryNoForward(_ reader: BufferReader) -> Update? {
|
||||
public static func parse_updatePeerHistoryNoForwards(_ reader: BufferReader) -> Update? {
|
||||
var _1: Int32?
|
||||
_1 = reader.readInt32()
|
||||
var _2: Api.Peer?
|
||||
|
|
@ -5186,7 +5186,7 @@ public extension Api {
|
|||
let _c1 = _1 != nil
|
||||
let _c2 = _2 != nil
|
||||
if _c1 && _c2 {
|
||||
return Api.Update.updatePeerHistoryNoForward(Cons_updatePeerHistoryNoForward(flags: _1!, peer: _2!))
|
||||
return Api.Update.updatePeerHistoryNoForwards(Cons_updatePeerHistoryNoForwards(flags: _1!, peer: _2!))
|
||||
}
|
||||
else {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -571,7 +571,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, ASScrollVi
|
|||
if isSelected && value == nil {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}), action: { [weak self] _, f in
|
||||
scheduleTooltip(nil)
|
||||
|
|
|
|||
|
|
@ -398,7 +398,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
|
|||
case let .messageMediaDocument(messageMediaDocumentData):
|
||||
let (flags, document, altDocuments, coverPhoto, videoTimestamp, ttlSeconds) = (messageMediaDocumentData.flags, messageMediaDocumentData.document, messageMediaDocumentData.altDocuments, messageMediaDocumentData.videoCover, messageMediaDocumentData.videoTimestamp, messageMediaDocumentData.ttlSeconds)
|
||||
if let document = document {
|
||||
if let mediaFile = telegramMediaFileFromApiDocument(document, altDocuments: altDocuments, videoCover: coverPhoto) {
|
||||
if let mediaFile = telegramMediaFileFromApiDocument(document, altDocuments: altDocuments, videoCover: coverPhoto, isLivePhoto: (flags & (1 << 11)) != 0) {
|
||||
return (mediaFile, ttlSeconds, (flags & (1 << 3)) != 0, (flags & (1 << 4)) != 0, nil, videoTimestamp)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -785,6 +785,31 @@ func messageTextEntitiesFromApiEntities(_ entities: [Api.MessageEntity]) -> [Mes
|
|||
case let .messageEntityCustomEmoji(messageEntityCustomEmojiData):
|
||||
let (offset, length, documentId) = (messageEntityCustomEmojiData.offset, messageEntityCustomEmojiData.length, messageEntityCustomEmojiData.documentId)
|
||||
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .CustomEmoji(stickerPack: nil, fileId: documentId)))
|
||||
case let .messageEntityFormattedDate(messageEntityFormattedDateData):
|
||||
let (flags, offset, length, date) = (messageEntityFormattedDateData.flags, messageEntityFormattedDateData.offset, messageEntityFormattedDateData.length, messageEntityFormattedDateData.date)
|
||||
let format: MessageTextEntityType.DateTimeFormat
|
||||
if (flags & (1 << 0)) != 0 {
|
||||
format = .relative
|
||||
} else {
|
||||
let timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat
|
||||
if (flags & (1 << 1)) != 0 {
|
||||
timeFormat = .short
|
||||
} else if (flags & (1 << 2)) != 0 {
|
||||
timeFormat = .long
|
||||
} else {
|
||||
timeFormat = .short
|
||||
}
|
||||
let dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat
|
||||
if (flags & (1 << 3)) != 0 {
|
||||
dateFormat = .short
|
||||
} else if (flags & (1 << 4)) != 0 {
|
||||
dateFormat = .long
|
||||
} else {
|
||||
dateFormat = .short
|
||||
}
|
||||
format = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
result.append(MessageTextEntity(range: Int(offset) ..< Int(offset + length), type: .FormattedDate(format: format, date: date)))
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ extension StickerMaskCoords {
|
|||
}
|
||||
}
|
||||
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute]) -> [TelegramMediaFileAttribute] {
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute], isLivePhoto: Bool = false) -> [TelegramMediaFileAttribute] {
|
||||
var result: [TelegramMediaFileAttribute] = []
|
||||
for attribute in attributes {
|
||||
switch attribute {
|
||||
|
|
@ -137,6 +137,9 @@ func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAtt
|
|||
if (flags & (1 << 3)) != 0 {
|
||||
videoFlags.insert(.isSilent)
|
||||
}
|
||||
if isLivePhoto {
|
||||
videoFlags.insert(.isLivePhoto)
|
||||
}
|
||||
result.append(.Video(duration: Double(duration), size: PixelDimensions(width: w, height: h), flags: videoFlags, preloadSize: preloadSize, coverTime: videoStart, videoCodec: videoCodec))
|
||||
case let .documentAttributeAudio(documentAttributeAudioData):
|
||||
let (flags, duration, title, performer, waveform) = (documentAttributeAudioData.flags, documentAttributeAudioData.duration, documentAttributeAudioData.title, documentAttributeAudioData.performer, documentAttributeAudioData.waveform)
|
||||
|
|
@ -192,11 +195,11 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
|
|||
return (immediateThumbnailData, representations)
|
||||
}
|
||||
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil) -> TelegramMediaFile? {
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil, isLivePhoto: Bool = false) -> TelegramMediaFile? {
|
||||
switch document {
|
||||
case let .document(documentData):
|
||||
let (id, accessHash, fileReference, mimeType, size, thumbs, videoThumbs, dcId, attributes) = (documentData.id, documentData.accessHash, documentData.fileReference, documentData.mimeType, documentData.size, documentData.thumbs, documentData.videoThumbs, documentData.dcId, documentData.attributes)
|
||||
var parsedAttributes = telegramMediaFileAttributesFromApiAttributes(attributes)
|
||||
var parsedAttributes = telegramMediaFileAttributesFromApiAttributes(attributes, isLivePhoto: isLivePhoto)
|
||||
var isSticker = false
|
||||
var isAnimated = false
|
||||
for attribute in parsedAttributes {
|
||||
|
|
@ -238,7 +241,7 @@ func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [A
|
|||
alternativeRepresentations = altDocuments.compactMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
}
|
||||
|
||||
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: size, fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, videoCover: videoCover.flatMap(telegramMediaImageFromApiPhoto), immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes, alternativeRepresentations: alternativeRepresentations)
|
||||
return TelegramMediaFile(fileId: MediaId(namespace: Namespaces.Media.CloudFile, id: id), partialReference: nil, resource: CloudDocumentMediaResource(datacenterId: Int(dcId), fileId: id, accessHash: accessHash, size: size, fileReference: fileReference.makeData(), fileName: fileNameFromFileAttributes(parsedAttributes)), previewRepresentations: previewRepresentations, videoThumbnails: videoThumbnails, videoCover: videoCover.flatMap(telegramMediaImageFromApiPhoto), immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes, alternativeRepresentations: alternativeRepresentations)
|
||||
case .documentEmpty:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,52 +10,72 @@ func apiEntitiesFromMessageTextEntities(_ entities: [MessageTextEntity], associa
|
|||
let offset: Int32 = Int32(entity.range.lowerBound)
|
||||
let length: Int32 = Int32(entity.range.upperBound - entity.range.lowerBound)
|
||||
switch entity.type {
|
||||
case .Unknown:
|
||||
break
|
||||
case .Mention:
|
||||
apiEntities.append(.messageEntityMention(.init(offset: offset, length: length)))
|
||||
case .Hashtag:
|
||||
apiEntities.append(.messageEntityHashtag(.init(offset: offset, length: length)))
|
||||
case .BotCommand:
|
||||
apiEntities.append(.messageEntityBotCommand(.init(offset: offset, length: length)))
|
||||
case .Url:
|
||||
apiEntities.append(.messageEntityUrl(.init(offset: offset, length: length)))
|
||||
case .Email:
|
||||
apiEntities.append(.messageEntityEmail(.init(offset: offset, length: length)))
|
||||
case .Bold:
|
||||
apiEntities.append(.messageEntityBold(.init(offset: offset, length: length)))
|
||||
case .Italic:
|
||||
apiEntities.append(.messageEntityItalic(.init(offset: offset, length: length)))
|
||||
case .Code:
|
||||
apiEntities.append(.messageEntityCode(.init(offset: offset, length: length)))
|
||||
case let .Pre(language):
|
||||
apiEntities.append(.messageEntityPre(.init(offset: offset, length: length, language: language ?? "")))
|
||||
case let .TextUrl(url):
|
||||
apiEntities.append(.messageEntityTextUrl(.init(offset: offset, length: length, url: url)))
|
||||
case let .TextMention(peerId):
|
||||
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
|
||||
apiEntities.append(.inputMessageEntityMentionName(.init(offset: offset, length: length, userId: inputUser)))
|
||||
case .Unknown:
|
||||
break
|
||||
case .Mention:
|
||||
apiEntities.append(.messageEntityMention(.init(offset: offset, length: length)))
|
||||
case .Hashtag:
|
||||
apiEntities.append(.messageEntityHashtag(.init(offset: offset, length: length)))
|
||||
case .BotCommand:
|
||||
apiEntities.append(.messageEntityBotCommand(.init(offset: offset, length: length)))
|
||||
case .Url:
|
||||
apiEntities.append(.messageEntityUrl(.init(offset: offset, length: length)))
|
||||
case .Email:
|
||||
apiEntities.append(.messageEntityEmail(.init(offset: offset, length: length)))
|
||||
case .Bold:
|
||||
apiEntities.append(.messageEntityBold(.init(offset: offset, length: length)))
|
||||
case .Italic:
|
||||
apiEntities.append(.messageEntityItalic(.init(offset: offset, length: length)))
|
||||
case .Code:
|
||||
apiEntities.append(.messageEntityCode(.init(offset: offset, length: length)))
|
||||
case let .Pre(language):
|
||||
apiEntities.append(.messageEntityPre(.init(offset: offset, length: length, language: language ?? "")))
|
||||
case let .TextUrl(url):
|
||||
apiEntities.append(.messageEntityTextUrl(.init(offset: offset, length: length, url: url)))
|
||||
case let .TextMention(peerId):
|
||||
if let peer = associatedPeers[peerId], let inputUser = apiInputUser(peer) {
|
||||
apiEntities.append(.inputMessageEntityMentionName(.init(offset: offset, length: length, userId: inputUser)))
|
||||
}
|
||||
case .PhoneNumber:
|
||||
break
|
||||
case .Strikethrough:
|
||||
apiEntities.append(.messageEntityStrike(.init(offset: offset, length: length)))
|
||||
case let .BlockQuote(isCollapsed):
|
||||
var flags: Int32 = 0
|
||||
if isCollapsed {
|
||||
flags |= 1 << 0
|
||||
}
|
||||
apiEntities.append(.messageEntityBlockquote(.init(flags: flags, offset: offset, length: length)))
|
||||
case .Underline:
|
||||
apiEntities.append(.messageEntityUnderline(.init(offset: offset, length: length)))
|
||||
case .BankCard:
|
||||
apiEntities.append(.messageEntityBankCard(.init(offset: offset, length: length)))
|
||||
case .Spoiler:
|
||||
apiEntities.append(.messageEntitySpoiler(.init(offset: offset, length: length)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
apiEntities.append(.messageEntityCustomEmoji(.init(offset: offset, length: length, documentId: fileId)))
|
||||
case let .FormattedDate(format, date):
|
||||
var flags: Int32 = 0
|
||||
switch format {
|
||||
case .relative:
|
||||
flags |= 1 << 0
|
||||
case let .full(timeFormat, dateFormat):
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
flags |= 1 << 1
|
||||
case .long:
|
||||
flags |= 1 << 2
|
||||
}
|
||||
case .PhoneNumber:
|
||||
break
|
||||
case .Strikethrough:
|
||||
apiEntities.append(.messageEntityStrike(.init(offset: offset, length: length)))
|
||||
case let .BlockQuote(isCollapsed):
|
||||
var flags: Int32 = 0
|
||||
if isCollapsed {
|
||||
flags |= 1 << 0
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
flags |= 1 << 3
|
||||
case .long:
|
||||
flags |= 1 << 4
|
||||
}
|
||||
apiEntities.append(.messageEntityBlockquote(.init(flags: flags, offset: offset, length: length)))
|
||||
case .Underline:
|
||||
apiEntities.append(.messageEntityUnderline(.init(offset: offset, length: length)))
|
||||
case .BankCard:
|
||||
apiEntities.append(.messageEntityBankCard(.init(offset: offset, length: length)))
|
||||
case .Spoiler:
|
||||
apiEntities.append(.messageEntitySpoiler(.init(offset: offset, length: length)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
apiEntities.append(.messageEntityCustomEmoji(.init(offset: offset, length: length, documentId: fileId)))
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
apiEntities.append(.messageEntityFormattedDate(.init(flags: flags, offset: offset, length: length, date: date)))
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1169,7 +1169,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||
if let _ = videoCoverPhoto {
|
||||
flags |= 1 << 6
|
||||
}
|
||||
|
||||
|
||||
var ttlSeconds: Int32?
|
||||
var videoTimestamp: Int32?
|
||||
for attribute in attributes {
|
||||
|
|
@ -1213,6 +1213,10 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||
flags |= 1 << 7
|
||||
}
|
||||
|
||||
if file.isLivePhoto {
|
||||
flags |= 1 << 8
|
||||
}
|
||||
|
||||
if ttlSeconds != nil {
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedDocument(.init(flags: flags, file: inputFile, thumb: thumbnailFile, mimeType: file.mimeType, attributes: inputDocumentAttributesFromFileAttributes(file.attributes), stickers: stickers, videoCover: videoCoverPhoto, videoTimestamp: videoTimestamp, ttlSeconds: ttlSeconds)), text), reuploadInfo: nil, cacheReferenceKey: referenceKey)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2010,8 +2010,8 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
|
|||
updatedState.updateStarGiftAuctionMyState(giftId: giftId, state: GiftAuctionContext.State.MyState(apiAuctionUserState: userState))
|
||||
case let .updateEmojiGameInfo(updateEmojiGameInfoData):
|
||||
updatedState.updateEmojiGameInfo(info: EmojiGameInfo(apiEmojiGameInfo: updateEmojiGameInfoData.info))
|
||||
case let .updatePeerHistoryNoForward(updatePeerHistoryNoForwardData):
|
||||
let (flags, peer) = (updatePeerHistoryNoForwardData.flags, updatePeerHistoryNoForwardData.peer)
|
||||
case let .updatePeerHistoryNoForwards(updatePeerHistoryNoForwardsData):
|
||||
let (flags, peer) = (updatePeerHistoryNoForwardsData.flags, updatePeerHistoryNoForwardsData.peer)
|
||||
let peerId = peer.peerId
|
||||
updatedState.updateCachedPeerData(peerId, { current in
|
||||
if let previous = current as? CachedUserData {
|
||||
|
|
|
|||
|
|
@ -822,6 +822,8 @@ private func decryptedEntities73(_ entities: [MessageTextEntity]?) -> [SecretApi
|
|||
break
|
||||
case .CustomEmoji:
|
||||
break
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
@ -875,6 +877,8 @@ private func decryptedEntities101(_ entities: [MessageTextEntity]?) -> [SecretAp
|
|||
break
|
||||
case .CustomEmoji:
|
||||
break
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
@ -928,6 +932,8 @@ private func decryptedEntities144(_ entities: [MessageTextEntity]?) -> [SecretAp
|
|||
result.append(.messageEntitySpoiler(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count)))
|
||||
case let .CustomEmoji(_, fileId):
|
||||
result.append(.messageEntityCustomEmoji(offset: Int32(entity.range.lowerBound), length: Int32(entity.range.count), documentId: fileId))
|
||||
case .FormattedDate:
|
||||
break
|
||||
case .Custom:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,6 +311,7 @@ public struct TelegramMediaVideoFlags: OptionSet {
|
|||
public static let instantRoundVideo = TelegramMediaVideoFlags(rawValue: 1 << 0)
|
||||
public static let supportsStreaming = TelegramMediaVideoFlags(rawValue: 1 << 1)
|
||||
public static let isSilent = TelegramMediaVideoFlags(rawValue: 1 << 3)
|
||||
public static let isLivePhoto = TelegramMediaVideoFlags(rawValue: 1 << 4)
|
||||
}
|
||||
|
||||
public struct StickerMaskCoords: PostboxCoding, Equatable {
|
||||
|
|
@ -1060,6 +1061,15 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
|||
return false
|
||||
}
|
||||
|
||||
public var isLivePhoto: Bool {
|
||||
for attribute in self.attributes {
|
||||
if case .Video(_, _, let flags, _, _, _) = attribute {
|
||||
return flags.contains(.isLivePhoto)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
public var preloadSize: Int32? {
|
||||
for attribute in self.attributes {
|
||||
if case .Video(_, _, _, let preloadSize, _, _) = attribute {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,67 @@ import Postbox
|
|||
public enum MessageTextEntityType: Equatable {
|
||||
public typealias CustomEntityType = Int32
|
||||
|
||||
public enum DateTimeFormat: Equatable {
|
||||
public enum TimeFormat: Equatable {
|
||||
case short
|
||||
case long
|
||||
}
|
||||
|
||||
public enum DateFormat: Equatable {
|
||||
case short
|
||||
case long
|
||||
}
|
||||
|
||||
case relative
|
||||
case full(timeFormat: TimeFormat, dateFormat: DateFormat)
|
||||
|
||||
public init(rawValue: Int32) {
|
||||
if (rawValue & (1 << 0)) != 0 {
|
||||
self = .relative
|
||||
} else {
|
||||
let timeFormat: MessageTextEntityType.DateTimeFormat.TimeFormat
|
||||
if (rawValue & (1 << 1)) != 0 {
|
||||
timeFormat = .short
|
||||
} else if (rawValue & (1 << 2)) != 0 {
|
||||
timeFormat = .long
|
||||
} else {
|
||||
timeFormat = .short
|
||||
}
|
||||
let dateFormat: MessageTextEntityType.DateTimeFormat.DateFormat
|
||||
if (rawValue & (1 << 3)) != 0 {
|
||||
dateFormat = .short
|
||||
} else if (rawValue & (1 << 4)) != 0 {
|
||||
dateFormat = .long
|
||||
} else {
|
||||
dateFormat = .short
|
||||
}
|
||||
self = .full(timeFormat: timeFormat, dateFormat: dateFormat)
|
||||
}
|
||||
}
|
||||
|
||||
public var rawValue: Int32 {
|
||||
var rawValue: Int32 = 0
|
||||
switch self {
|
||||
case .relative:
|
||||
rawValue |= 1 << 0
|
||||
case let .full(timeFormat, dateFormat):
|
||||
switch timeFormat {
|
||||
case .short:
|
||||
rawValue |= 1 << 1
|
||||
case .long:
|
||||
rawValue |= 1 << 2
|
||||
}
|
||||
switch dateFormat {
|
||||
case .short:
|
||||
rawValue |= 1 << 3
|
||||
case .long:
|
||||
rawValue |= 1 << 4
|
||||
}
|
||||
}
|
||||
return rawValue
|
||||
}
|
||||
}
|
||||
|
||||
case Unknown
|
||||
case Mention
|
||||
case Hashtag
|
||||
|
|
@ -23,6 +84,7 @@ public enum MessageTextEntityType: Equatable {
|
|||
case BankCard
|
||||
case Spoiler
|
||||
case CustomEmoji(stickerPack: StickerPackReference?, fileId: Int64)
|
||||
case FormattedDate(format: DateTimeFormat, date: Int32)
|
||||
case Custom(type: CustomEntityType)
|
||||
}
|
||||
|
||||
|
|
@ -39,47 +101,49 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
self.range = Int(decoder.decodeInt32ForKey("start", orElse: 0)) ..< Int(decoder.decodeInt32ForKey("end", orElse: 0))
|
||||
let type: Int32 = decoder.decodeInt32ForKey("_rawValue", orElse: 0)
|
||||
switch type {
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: decoder.decodeOptionalStringForKey("language"))
|
||||
case 10:
|
||||
self.type = .TextUrl(url: decoder.decodeStringForKey("url", orElse: ""))
|
||||
case 11:
|
||||
self.type = .TextMention(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: decoder.decodeBoolForKey("cl", orElse: false))
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
let stickerPack = decoder.decodeObjectForKey("s", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference
|
||||
self.type = .CustomEmoji(stickerPack: stickerPack, fileId: decoder.decodeInt64ForKey("f", orElse: 0))
|
||||
case Int32.max:
|
||||
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
|
||||
default:
|
||||
self.type = .Unknown
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: decoder.decodeOptionalStringForKey("language"))
|
||||
case 10:
|
||||
self.type = .TextUrl(url: decoder.decodeStringForKey("url", orElse: ""))
|
||||
case 11:
|
||||
self.type = .TextMention(peerId: PeerId(decoder.decodeInt64ForKey("peerId", orElse: 0)))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: decoder.decodeBoolForKey("cl", orElse: false))
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
let stickerPack = decoder.decodeObjectForKey("s", decoder: { StickerPackReference(decoder: $0) }) as? StickerPackReference
|
||||
self.type = .CustomEmoji(stickerPack: stickerPack, fileId: decoder.decodeInt64ForKey("f", orElse: 0))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: decoder.decodeInt32ForKey("format", orElse: 0)), date: decoder.decodeInt32ForKey("date", orElse: 0))
|
||||
case Int32.max:
|
||||
self.type = .Custom(type: decoder.decodeInt32ForKey("type", orElse: 0))
|
||||
default:
|
||||
self.type = .Unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -95,49 +159,51 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
self.range = Int(rangeStart) ..< Int(rangeEnd)
|
||||
|
||||
switch type {
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: try? container.decodeIfPresent(String.self, forKey: "language"))
|
||||
case 10:
|
||||
let url = (try? container.decode(String.self, forKey: "url")) ?? ""
|
||||
self.type = .TextUrl(url: url)
|
||||
case 11:
|
||||
let peerId = (try? container.decode(Int64.self, forKey: "peerId")) ?? 0
|
||||
self.type = .TextMention(peerId: PeerId(peerId))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: try container.decodeIfPresent(Bool.self, forKey: "cl") ?? false)
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
self.type = .CustomEmoji(stickerPack: try container.decodeIfPresent(StickerPackReference.self, forKey: "s"), fileId: try container.decode(Int64.self, forKey: "f"))
|
||||
case Int32.max:
|
||||
let customType: Int32 = (try? container.decode(Int32.self, forKey: "type")) ?? 0
|
||||
self.type = .Custom(type: customType)
|
||||
default:
|
||||
self.type = .Unknown
|
||||
case 1:
|
||||
self.type = .Mention
|
||||
case 2:
|
||||
self.type = .Hashtag
|
||||
case 3:
|
||||
self.type = .BotCommand
|
||||
case 4:
|
||||
self.type = .Url
|
||||
case 5:
|
||||
self.type = .Email
|
||||
case 6:
|
||||
self.type = .Bold
|
||||
case 7:
|
||||
self.type = .Italic
|
||||
case 8:
|
||||
self.type = .Code
|
||||
case 9:
|
||||
self.type = .Pre(language: try? container.decodeIfPresent(String.self, forKey: "language"))
|
||||
case 10:
|
||||
let url = (try? container.decode(String.self, forKey: "url")) ?? ""
|
||||
self.type = .TextUrl(url: url)
|
||||
case 11:
|
||||
let peerId = (try? container.decode(Int64.self, forKey: "peerId")) ?? 0
|
||||
self.type = .TextMention(peerId: PeerId(peerId))
|
||||
case 12:
|
||||
self.type = .PhoneNumber
|
||||
case 13:
|
||||
self.type = .Strikethrough
|
||||
case 14:
|
||||
self.type = .BlockQuote(isCollapsed: try container.decodeIfPresent(Bool.self, forKey: "cl") ?? false)
|
||||
case 15:
|
||||
self.type = .Underline
|
||||
case 16:
|
||||
self.type = .BankCard
|
||||
case 17:
|
||||
self.type = .Spoiler
|
||||
case 18:
|
||||
self.type = .CustomEmoji(stickerPack: try container.decodeIfPresent(StickerPackReference.self, forKey: "s"), fileId: try container.decode(Int64.self, forKey: "f"))
|
||||
case 19:
|
||||
self.type = .FormattedDate(format: MessageTextEntityType.DateTimeFormat(rawValue: try container.decode(Int32.self, forKey: "format")), date: try container.decode(Int32.self, forKey: "date"))
|
||||
case Int32.max:
|
||||
let customType: Int32 = (try? container.decode(Int32.self, forKey: "type")) ?? 0
|
||||
self.type = .Custom(type: customType)
|
||||
default:
|
||||
self.type = .Unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -145,61 +211,65 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
encoder.encodeInt32(Int32(self.range.lowerBound), forKey: "start")
|
||||
encoder.encodeInt32(Int32(self.range.upperBound), forKey: "end")
|
||||
switch self.type {
|
||||
case .Unknown:
|
||||
encoder.encodeInt32(0, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
encoder.encodeInt32(1, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
encoder.encodeInt32(2, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
encoder.encodeInt32(3, forKey: "_rawValue")
|
||||
case .Url:
|
||||
encoder.encodeInt32(4, forKey: "_rawValue")
|
||||
case .Email:
|
||||
encoder.encodeInt32(5, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
encoder.encodeInt32(6, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
encoder.encodeInt32(7, forKey: "_rawValue")
|
||||
case .Code:
|
||||
encoder.encodeInt32(8, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
encoder.encodeInt32(9, forKey: "_rawValue")
|
||||
if let language = language {
|
||||
encoder.encodeString(language, forKey: "language")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "language")
|
||||
}
|
||||
case let .TextUrl(url):
|
||||
encoder.encodeInt32(10, forKey: "_rawValue")
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
encoder.encodeInt32(11, forKey: "_rawValue")
|
||||
encoder.encodeInt64(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
encoder.encodeInt32(12, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
encoder.encodeInt32(13, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
encoder.encodeInt32(14, forKey: "_rawValue")
|
||||
encoder.encodeBool(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
encoder.encodeInt32(15, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
encoder.encodeInt32(16, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
encoder.encodeInt32(17, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
encoder.encodeInt32(18, forKey: "_rawValue")
|
||||
if let stickerPack = stickerPack {
|
||||
encoder.encodeObject(stickerPack, forKey: "s")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "s")
|
||||
}
|
||||
encoder.encodeInt64(fileId, forKey: "f")
|
||||
case let .Custom(type):
|
||||
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
|
||||
encoder.encodeInt32(type, forKey: "type")
|
||||
case .Unknown:
|
||||
encoder.encodeInt32(0, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
encoder.encodeInt32(1, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
encoder.encodeInt32(2, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
encoder.encodeInt32(3, forKey: "_rawValue")
|
||||
case .Url:
|
||||
encoder.encodeInt32(4, forKey: "_rawValue")
|
||||
case .Email:
|
||||
encoder.encodeInt32(5, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
encoder.encodeInt32(6, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
encoder.encodeInt32(7, forKey: "_rawValue")
|
||||
case .Code:
|
||||
encoder.encodeInt32(8, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
encoder.encodeInt32(9, forKey: "_rawValue")
|
||||
if let language = language {
|
||||
encoder.encodeString(language, forKey: "language")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "language")
|
||||
}
|
||||
case let .TextUrl(url):
|
||||
encoder.encodeInt32(10, forKey: "_rawValue")
|
||||
encoder.encodeString(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
encoder.encodeInt32(11, forKey: "_rawValue")
|
||||
encoder.encodeInt64(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
encoder.encodeInt32(12, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
encoder.encodeInt32(13, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
encoder.encodeInt32(14, forKey: "_rawValue")
|
||||
encoder.encodeBool(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
encoder.encodeInt32(15, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
encoder.encodeInt32(16, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
encoder.encodeInt32(17, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
encoder.encodeInt32(18, forKey: "_rawValue")
|
||||
if let stickerPack = stickerPack {
|
||||
encoder.encodeObject(stickerPack, forKey: "s")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "s")
|
||||
}
|
||||
encoder.encodeInt64(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
encoder.encodeInt32(19, forKey: "_rawValue")
|
||||
encoder.encodeInt32(format.rawValue, forKey: "format")
|
||||
encoder.encodeInt32(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
encoder.encodeInt32(Int32.max, forKey: "_rawValue")
|
||||
encoder.encodeInt32(type, forKey: "type")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -209,53 +279,57 @@ public struct MessageTextEntity: PostboxCoding, Codable, Equatable {
|
|||
try container.encode(Int32(self.range.lowerBound), forKey: "start")
|
||||
try container.encode(Int32(self.range.upperBound), forKey: "end")
|
||||
switch self.type {
|
||||
case .Unknown:
|
||||
try container.encode(0 as Int32, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
try container.encode(1 as Int32, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
try container.encode(2 as Int32, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
try container.encode(3 as Int32, forKey: "_rawValue")
|
||||
case .Url:
|
||||
try container.encode(4 as Int32, forKey: "_rawValue")
|
||||
case .Email:
|
||||
try container.encode(5 as Int32, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
try container.encode(6 as Int32, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
try container.encode(7 as Int32, forKey: "_rawValue")
|
||||
case .Code:
|
||||
try container.encode(8 as Int32, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
try container.encode(9 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(language, forKey: "language")
|
||||
case let .TextUrl(url):
|
||||
try container.encode(10 as Int32, forKey: "_rawValue")
|
||||
try container.encode(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
try container.encode(11 as Int32, forKey: "_rawValue")
|
||||
try container.encode(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
try container.encode(12 as Int32, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
try container.encode(13 as Int32, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
try container.encode(14 as Int32, forKey: "_rawValue")
|
||||
try container.encode(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
try container.encode(15 as Int32, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
try container.encode(16 as Int32, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
try container.encode(17 as Int32, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
try container.encode(18 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(stickerPack, forKey: "s")
|
||||
try container.encode(fileId, forKey: "f")
|
||||
case let .Custom(type):
|
||||
try container.encode(Int32.max as Int32, forKey: "_rawValue")
|
||||
try container.encode(type as Int32, forKey: "type")
|
||||
case .Unknown:
|
||||
try container.encode(0 as Int32, forKey: "_rawValue")
|
||||
case .Mention:
|
||||
try container.encode(1 as Int32, forKey: "_rawValue")
|
||||
case .Hashtag:
|
||||
try container.encode(2 as Int32, forKey: "_rawValue")
|
||||
case .BotCommand:
|
||||
try container.encode(3 as Int32, forKey: "_rawValue")
|
||||
case .Url:
|
||||
try container.encode(4 as Int32, forKey: "_rawValue")
|
||||
case .Email:
|
||||
try container.encode(5 as Int32, forKey: "_rawValue")
|
||||
case .Bold:
|
||||
try container.encode(6 as Int32, forKey: "_rawValue")
|
||||
case .Italic:
|
||||
try container.encode(7 as Int32, forKey: "_rawValue")
|
||||
case .Code:
|
||||
try container.encode(8 as Int32, forKey: "_rawValue")
|
||||
case let .Pre(language):
|
||||
try container.encode(9 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(language, forKey: "language")
|
||||
case let .TextUrl(url):
|
||||
try container.encode(10 as Int32, forKey: "_rawValue")
|
||||
try container.encode(url, forKey: "url")
|
||||
case let .TextMention(peerId):
|
||||
try container.encode(11 as Int32, forKey: "_rawValue")
|
||||
try container.encode(peerId.toInt64(), forKey: "peerId")
|
||||
case .PhoneNumber:
|
||||
try container.encode(12 as Int32, forKey: "_rawValue")
|
||||
case .Strikethrough:
|
||||
try container.encode(13 as Int32, forKey: "_rawValue")
|
||||
case let .BlockQuote(isCollapsed):
|
||||
try container.encode(14 as Int32, forKey: "_rawValue")
|
||||
try container.encode(isCollapsed, forKey: "cl")
|
||||
case .Underline:
|
||||
try container.encode(15 as Int32, forKey: "_rawValue")
|
||||
case .BankCard:
|
||||
try container.encode(16 as Int32, forKey: "_rawValue")
|
||||
case .Spoiler:
|
||||
try container.encode(17 as Int32, forKey: "_rawValue")
|
||||
case let .CustomEmoji(stickerPack, fileId):
|
||||
try container.encode(18 as Int32, forKey: "_rawValue")
|
||||
try container.encodeIfPresent(stickerPack, forKey: "s")
|
||||
try container.encode(fileId, forKey: "f")
|
||||
case let .FormattedDate(format, date):
|
||||
try container.encode(19 as Int32, forKey: "_rawValue")
|
||||
try container.encode(format.rawValue, forKey: "format")
|
||||
try container.encode(date, forKey: "date")
|
||||
case let .Custom(type):
|
||||
try container.encode(Int32.max as Int32, forKey: "_rawValue")
|
||||
try container.encode(type as Int32, forKey: "type")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3594,6 +3594,8 @@ private func serializeGroupCallMessage(randomId: Int64, text: String, entities:
|
|||
case let .CustomEmoji(_, fileId):
|
||||
entityDict["_"] = "messageEntityCustomEmoji"
|
||||
entityDict["document_id"] = "\(fileId)"
|
||||
case .FormattedDate:
|
||||
return nil
|
||||
case .Custom:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -408,7 +408,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
|
|||
items.append(.action(ContextMenuActionItem(text: title, textLayout: .multiline, textFont: .small, icon: { _ in return nil }, action: emptyAction)))
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Timer_ViewOnce, icon: { theme in
|
||||
return currentValue == viewOnceTimeout ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return currentValue == viewOnceTimeout ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, a in
|
||||
a(.default)
|
||||
|
||||
|
|
@ -419,7 +419,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
|
|||
|
||||
for value in values {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Timer_Seconds(value), icon: { theme in
|
||||
return currentValue == value ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return currentValue == value ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, a in
|
||||
a(.default)
|
||||
|
||||
|
|
@ -428,7 +428,7 @@ public class LegacyMessageInputPanelNode: ASDisplayNode, TGCaptionPanelView {
|
|||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.MediaPicker_Timer_DoNotDelete, icon: { theme in
|
||||
return currentValue == nil ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return currentValue == nil ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, a in
|
||||
a(.default)
|
||||
|
||||
|
|
|
|||
|
|
@ -7286,7 +7286,7 @@ public final class MediaEditorScreenImpl: ViewController, MediaEditorScreen, UID
|
|||
color: theme.contextMenu.primaryColor
|
||||
)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
},
|
||||
action: { [weak self] _, a in
|
||||
|
|
|
|||
|
|
@ -561,7 +561,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, ASScrollVi
|
|||
if isSelected && value == nil {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}), action: { [weak self] _, f in
|
||||
scheduleTooltip(nil)
|
||||
|
|
|
|||
|
|
@ -476,7 +476,7 @@ final class AffiliateProgramSetupScreenComponent: Component {
|
|||
if isSelected {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.actionSheet.primaryTextColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
|
|
|||
|
|
@ -451,7 +451,7 @@ func infoItems(data: PeerInfoScreenData?, context: AccountContext, presentationD
|
|||
if canManageEmojiStatus || data.webAppPermissions?.emojiStatus?.isRequested == true {
|
||||
items[.permissions]!.append(PeerInfoScreenSwitchItem(id: ItemBotPermissionsEmojiStatus, text: presentationData.strings.PeerInfo_Permissions_EmojiStatus, value: canManageEmojiStatus, icon: UIImage(bundleImageName: "Chat/Info/Status"), isLocked: false, toggled: { value in
|
||||
let _ = (context.engine.peers.toggleBotEmojiStatusAccess(peerId: user.id, enabled: value)
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
|> deliverOnMainQueue).startStandalone()
|
||||
|
||||
let _ = updateWebAppPermissionsStateInteractively(context: context, peerId: user.id) { current in
|
||||
return WebAppPermissionsState(location: current?.location, emojiStatus: WebAppPermissionsState.EmojiStatus(isRequested: true))
|
||||
|
|
@ -869,6 +869,7 @@ func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostStatus?, s
|
|||
case peerNote
|
||||
case peerDataSettings
|
||||
case peerVerifySettings
|
||||
case peerPrivacySettings
|
||||
case peerSettings
|
||||
case linkedMonoforum
|
||||
case peerAdditionalSettings
|
||||
|
|
@ -901,6 +902,10 @@ func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostStatus?, s
|
|||
let ItemBotSettings = 13
|
||||
let ItemBotInfo = 14
|
||||
|
||||
let ItemPeerCopyProtectionHeader = 15
|
||||
let ItemPeerCopyProtection = 16
|
||||
let ItemPeerCopyProtectionInfo = 17
|
||||
|
||||
if let botInfo = user.botInfo, botInfo.flags.contains(.canEdit) {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemUsername, label: .text("@\(user.addressName ?? "")"), text: presentationData.strings.PeerInfo_Bot_Username, icon: PresentationResourcesSettings.bot, action: {
|
||||
interaction.editingOpenPublicLinkSetup()
|
||||
|
|
@ -1020,6 +1025,21 @@ func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostStatus?, s
|
|||
items[.peerDataSettings]!.append(PeerInfoScreenCommentItem(id: ItemInfo, text: presentationData.strings.UserInfo_CustomPhotoInfo(compactName).string))
|
||||
}
|
||||
|
||||
if "".isEmpty {
|
||||
var copyProtectionEnabled = false
|
||||
if let cachedData = data.cachedData as? CachedUserData, cachedData.flags.contains(.myCopyProtectionEnabled) {
|
||||
copyProtectionEnabled = true
|
||||
}
|
||||
items[.peerPrivacySettings]!.append(PeerInfoScreenHeaderItem(id: ItemPeerCopyProtectionHeader, text: "FORWARDING FROM THIS CHAT") )
|
||||
items[.peerPrivacySettings]!.append(PeerInfoScreenSwitchItem(id: ItemPeerCopyProtection, text: "Restrict Saving Content", value: copyProtectionEnabled, icon: nil, isLocked: false, toggled: { value in
|
||||
let _ = context.engine.peers.toggleMessageCopyProtection(peerId: user.id, enabled: !copyProtectionEnabled).start()
|
||||
}))
|
||||
|
||||
let peerName = data.peer.flatMap(EnginePeer.init)?.compactDisplayTitle ?? ""
|
||||
let text = copyProtectionEnabled ? "\(peerName) is not able to copy, save and forward content from the chat." : "\(peerName) is able to copy, save and forward content from the chat."
|
||||
items[.peerPrivacySettings]!.append(PeerInfoScreenCommentItem(id: ItemPeerCopyProtectionInfo, text: text, attributedPrefix: nil, useAccentLinkColor: false))
|
||||
}
|
||||
|
||||
if data.isContact {
|
||||
items[.peerSettings]!.append(PeerInfoScreenActionItem(id: ItemDelete, text: presentationData.strings.UserInfo_DeleteContact, color: .destructive, action: {
|
||||
interaction.requestDeleteContact()
|
||||
|
|
|
|||
|
|
@ -172,28 +172,28 @@ extension PeerInfoScreenNode {
|
|||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unlimited, icon: { theme in
|
||||
return filter.contains(.unlimited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.unlimited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unlimited)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.unlimited)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Limited, icon: { theme in
|
||||
return filter.contains(.limitedNonUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.limitedNonUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.limitedNonUpgradable)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.limitedNonUpgradable)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Upgradable, icon: { theme in
|
||||
return filter.contains(.limitedUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.limitedUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.limitedUpgradable)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.limitedUpgradable)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unique, icon: { theme in
|
||||
return filter.contains(.unique) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.unique) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unique)
|
||||
}, longPressAction: { _, f in
|
||||
|
|
@ -204,14 +204,14 @@ extension PeerInfoScreenNode {
|
|||
items.append(.separator)
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Displayed, icon: { theme in
|
||||
return filter.contains(.displayed) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.displayed) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.displayed)
|
||||
}, longPressAction: { _, f in
|
||||
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
|
||||
return filter.contains(.hidden) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.hidden)
|
||||
}, longPressAction: { _, f in
|
||||
|
|
|
|||
|
|
@ -381,28 +381,28 @@ public final class AddGiftsScreen: ViewControllerComponentContainer {
|
|||
}
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unlimited, icon: { theme in
|
||||
return filter.contains(.unlimited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.unlimited) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unlimited)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.unlimited)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Limited, icon: { theme in
|
||||
return filter.contains(.limitedNonUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.limitedNonUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.limitedNonUpgradable)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.limitedNonUpgradable)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Upgradable, icon: { theme in
|
||||
return filter.contains(.limitedUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.limitedUpgradable) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.limitedUpgradable)
|
||||
}, longPressAction: { _, f in
|
||||
switchToFilter(.limitedUpgradable)
|
||||
})))
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Unique, icon: { theme in
|
||||
return filter.contains(.unique) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.unique) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.unique)
|
||||
}, longPressAction: { _, f in
|
||||
|
|
@ -412,14 +412,14 @@ public final class AddGiftsScreen: ViewControllerComponentContainer {
|
|||
items.append(.separator)
|
||||
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Displayed, icon: { theme in
|
||||
return filter.contains(.displayed) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil
|
||||
return filter.contains(.displayed) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.displayed)
|
||||
}, longPressAction: { _, f in
|
||||
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
|
||||
return filter.contains(.hidden) ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage()
|
||||
}, action: { _, f in
|
||||
toggleFilter(.hidden)
|
||||
}, longPressAction: { _, f in
|
||||
|
|
|
|||
|
|
@ -1033,7 +1033,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
|||
let isAdded = gift.collectionIds?.contains(collection.id) ?? false
|
||||
|
||||
subItems.append(.action(ContextMenuActionItem(text: title, entities: entities, entityFiles: entityFiles, enableEntityAnimations: false, icon: { theme in
|
||||
return entities.isEmpty ? generateTintedImage(image: UIImage(bundleImageName: "Peer Info/Gifts/Collection"), color: theme.contextMenu.primaryColor) : (isAdded ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : nil)
|
||||
return entities.isEmpty ? generateTintedImage(image: UIImage(bundleImageName: "Peer Info/Gifts/Collection"), color: theme.contextMenu.primaryColor) : (isAdded ? generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor) : UIImage())
|
||||
}, iconPosition: collection.icon == nil ? .left : .right, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
|
|
|
|||
|
|
@ -488,7 +488,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
if canHideNames {
|
||||
items.append(.action(ContextMenuActionItem(text: uniquePeerIds.count == 1 ? presentationData.strings.Conversation_ForwardOptions_ShowSendersName : presentationData.strings.Conversation_ForwardOptions_ShowSendersNames, icon: { theme in
|
||||
if hideNames {
|
||||
return nil
|
||||
return UIImage()
|
||||
} else {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}
|
||||
|
|
@ -506,7 +506,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
if hideNames {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
self?.interfaceInteraction?.updateForwardOptionsState({ current in
|
||||
|
|
@ -523,7 +523,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
if hasCaptions {
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.Conversation_ForwardOptions_ShowCaption, icon: { theme in
|
||||
if hideCaptions {
|
||||
return nil
|
||||
return UIImage()
|
||||
} else {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}
|
||||
|
|
@ -543,7 +543,7 @@ final class PeerSelectionControllerNode: ASDisplayNode {
|
|||
if hideCaptions {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
self?.interfaceInteraction?.updateForwardOptionsState({ current in
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ final class ShareWithPeersScreenComponent: Component {
|
|||
let isSelected = self.shareToFolders.contains(where: { $0.id == folderPreview.folder.id })
|
||||
items.append(.action(ContextMenuActionItem(text: folderPreview.folder.title, icon: icon, additionalLeftIcon: { theme in
|
||||
if !isSelected {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, iconSource: iconSource, iconPosition: .left, action: { [weak self] c, f in
|
||||
|
|
|
|||
|
|
@ -3241,7 +3241,7 @@ final class StorageUsageScreenComponent: Component {
|
|||
if currentValue == value {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
applyValue(value)
|
||||
|
|
|
|||
|
|
@ -6388,7 +6388,7 @@ public final class StoryItemSetContainerComponent: Component {
|
|||
if isSelected && value == nil {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: .white)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}), action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
|
|
|||
|
|
@ -1397,7 +1397,7 @@ public final class StoryItemSetViewListComponent: Component {
|
|||
return generateTintedImage(image: UIImage(bundleImageName: "Stories/Context Menu/Repost"), color: theme.contextMenu.primaryColor)
|
||||
}, additionalLeftIcon: { theme in
|
||||
if sortMode != .repostsFirst {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
|
|
@ -1416,7 +1416,7 @@ public final class StoryItemSetViewListComponent: Component {
|
|||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Reactions"), color: theme.contextMenu.primaryColor)
|
||||
}, additionalLeftIcon: { theme in
|
||||
if sortMode != .reactionsFirst {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
|
|
@ -1435,7 +1435,7 @@ public final class StoryItemSetViewListComponent: Component {
|
|||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Time"), color: theme.contextMenu.primaryColor)
|
||||
}, additionalLeftIcon: { theme in
|
||||
if sortMode != .recentFirst {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
|
|
|
|||
|
|
@ -1185,7 +1185,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||
if currentValue == 0 {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
applyValue(0)
|
||||
|
|
@ -1208,7 +1208,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
|||
if currentValue == value {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}, action: { _, f in
|
||||
applyValue(value)
|
||||
|
|
|
|||
|
|
@ -1310,7 +1310,7 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
|||
if isSelected && value == nil {
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Check"), color: theme.contextMenu.primaryColor)
|
||||
} else {
|
||||
return nil
|
||||
return UIImage()
|
||||
}
|
||||
}), action: { [weak self] _, f in
|
||||
scheduleTooltip(nil)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue