mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge commit '249e58fca0'
This commit is contained in:
commit
68e26d20aa
23 changed files with 113 additions and 81 deletions
|
|
@ -15973,3 +15973,6 @@ Error: %8$@";
|
|||
"Month.NomOctober" = "October";
|
||||
"Month.NomNovember" = "November";
|
||||
"Month.NomDecember" = "December";
|
||||
|
||||
"ChannelMessages.LinkTitle" = "LINK TO DIRECT MESSAGES";
|
||||
"Chat.ContactChannel" = "CONTACT CHANNEL";
|
||||
|
|
|
|||
|
|
@ -195,9 +195,14 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
|
|||
break
|
||||
}
|
||||
}
|
||||
case _ as TelegramMediaImage:
|
||||
case let imageMedia as TelegramMediaImage:
|
||||
if message.text.isEmpty {
|
||||
messageText = strings.Message_Photo
|
||||
if imageMedia.flags.contains(.isLivePhoto) {
|
||||
//TODO:localize
|
||||
messageText = "Live Photo"
|
||||
} else {
|
||||
messageText = strings.Message_Photo
|
||||
}
|
||||
} else if enableMediaEmoji {
|
||||
messageText = "🖼 \(messageText)"
|
||||
}
|
||||
|
|
@ -255,21 +260,12 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
|
|||
break inner
|
||||
} else {
|
||||
if message.text.isEmpty {
|
||||
if flags.contains(.isLivePhoto) {
|
||||
//TODO:localize
|
||||
messageText = "Live Photo"
|
||||
} else {
|
||||
messageText = strings.Message_Video
|
||||
}
|
||||
messageText = strings.Message_Video
|
||||
processed = true
|
||||
} else {
|
||||
if enableMediaEmoji {
|
||||
if !fileMedia.isAnimated {
|
||||
if flags.contains(.isLivePhoto) {
|
||||
messageText = "🖼 \(messageText)"
|
||||
} else {
|
||||
messageText = "📹 \(messageText)"
|
||||
}
|
||||
messageText = "📹 \(messageText)"
|
||||
}
|
||||
}
|
||||
processed = true
|
||||
|
|
|
|||
|
|
@ -897,10 +897,7 @@ public func legacyAssetPickerEnqueueMessages(context: AccountContext, account: A
|
|||
fileAttributes.append(.Animated)
|
||||
}
|
||||
if !asFile {
|
||||
var flags: TelegramMediaVideoFlags = [.supportsStreaming]
|
||||
if isLivePhoto {
|
||||
flags.insert(.isLivePhoto)
|
||||
}
|
||||
let flags: TelegramMediaVideoFlags = [.supportsStreaming]
|
||||
fileAttributes.append(.Video(duration: finalDuration, size: PixelDimensions(finalDimensions), flags: flags, preloadSize: nil, coverTime: nil, videoCodec: nil))
|
||||
if let adjustments = adjustments {
|
||||
if adjustments.sendAsGif {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
case groupPrivacy(PresentationTheme, String, String)
|
||||
case groupPrivacyFooter
|
||||
case voiceMessagePrivacy(PresentationTheme, String, String, Bool)
|
||||
case messagePrivacy(PresentationTheme, GlobalPrivacySettings.NonContactChatsPrivacy, Bool)
|
||||
case messagePrivacy(PresentationTheme, String, Bool)
|
||||
case bioPrivacy(PresentationTheme, String, String)
|
||||
case birthdayPrivacy(PresentationTheme, String, String)
|
||||
case savedMusicPrivacy(PresentationTheme, String, String)
|
||||
|
|
@ -454,20 +454,7 @@ private enum PrivacyAndSecurityEntry: ItemListNodeEntry {
|
|||
arguments.openVoiceMessagePrivacy()
|
||||
})
|
||||
case let .messagePrivacy(theme, value, hasPremium):
|
||||
let label: String
|
||||
var effectiveValue = value
|
||||
if !hasPremium {
|
||||
effectiveValue = .everybody
|
||||
}
|
||||
switch effectiveValue {
|
||||
case .everybody:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValueEveryone
|
||||
case .requirePremium:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValueContactsAndPremium
|
||||
case .paidMessages:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValuePaid
|
||||
}
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: presentationData.strings.Settings_Privacy_Messages, titleIcon: hasPremium ? PresentationResourcesItemList.premiumIcon(theme) : nil, label: label, sectionId: self.section, style: .blocks, action: {
|
||||
return ItemListDisclosureItem(presentationData: presentationData, systemStyle: .glass, title: presentationData.strings.Settings_Privacy_Messages, titleIcon: hasPremium ? PresentationResourcesItemList.premiumIcon(theme) : nil, label: value, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.openMessagePrivacy()
|
||||
})
|
||||
case let .bioPrivacy(_, text, value):
|
||||
|
|
@ -639,7 +626,8 @@ private func privacyAndSecurityControllerEntries(
|
|||
isPremiumDisabled: Bool,
|
||||
isPremium: Bool,
|
||||
loginEmail: String?,
|
||||
accountPeer: EnginePeer?
|
||||
accountPeer: EnginePeer?,
|
||||
appConfiguration: AppConfiguration
|
||||
) -> [PrivacyAndSecurityEntry] {
|
||||
var entries: [PrivacyAndSecurityEntry] = []
|
||||
|
||||
|
|
@ -729,7 +717,21 @@ private func privacyAndSecurityControllerEntries(
|
|||
entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.voiceCalls)))
|
||||
if !isPremiumDisabled || isPremium {
|
||||
entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, stringForSelectiveSettings(strings: presentationData.strings, settings: isPremium ? privacySettings.voiceMessages : .enableEveryone(disableFor: [:])), isPremium))
|
||||
entries.append(.messagePrivacy(presentationData.theme, privacySettings.globalSettings.nonContactChatsPrivacy, isPremium))
|
||||
var effectiveValue = privacySettings.globalSettings.nonContactChatsPrivacy
|
||||
if let data = appConfiguration.data, let setting = data["new_noncontact_peers_require_premium_without_ownpremium"] as? Bool, setting {
|
||||
} else if !isPremium {
|
||||
effectiveValue = .everybody
|
||||
}
|
||||
let label: String
|
||||
switch effectiveValue {
|
||||
case .everybody:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValueEveryone
|
||||
case .requirePremium:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValueContactsAndPremium
|
||||
case .paidMessages:
|
||||
label = presentationData.strings.Settings_Privacy_Messages_ValuePaid
|
||||
}
|
||||
entries.append(.messagePrivacy(presentationData.theme, label, isPremium))
|
||||
}
|
||||
entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.PrivacySettings_InviteItem, stringForSelectiveSettings(strings: presentationData.strings, settings: privacySettings.groupInvitations)))
|
||||
entries.append(.groupPrivacyFooter)
|
||||
|
|
@ -745,6 +747,7 @@ private func privacyAndSecurityControllerEntries(
|
|||
entries.append(.voiceCallPrivacy(presentationData.theme, presentationData.strings.Privacy_Calls, presentationData.strings.Channel_NotificationLoading))
|
||||
if !isPremiumDisabled || isPremium {
|
||||
entries.append(.voiceMessagePrivacy(presentationData.theme, presentationData.strings.Privacy_VoiceMessages, presentationData.strings.Channel_NotificationLoading, isPremium))
|
||||
entries.append(.messagePrivacy(presentationData.theme, presentationData.strings.Channel_NotificationLoading, isPremium))
|
||||
}
|
||||
entries.append(.groupPrivacy(presentationData.theme, presentationData.strings.Privacy_GroupsAndChannels, presentationData.strings.Channel_NotificationLoading))
|
||||
entries.append(.groupPrivacyFooter)
|
||||
|
|
@ -1553,7 +1556,7 @@ public func privacyAndSecurityController(
|
|||
let isPremium = accountPeer?.isPremium ?? false
|
||||
let isPremiumDisabled = PremiumConfiguration.with(appConfiguration: context.currentAppConfiguration.with { $0 }).isPremiumDisabled
|
||||
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, hasPasskeys: passkeys.0, displayPasskeys: displayPasskeys, canAutoarchive: canAutoarchive, isPremiumDisabled: isPremiumDisabled, isPremium: isPremium, loginEmail: loginEmail, accountPeer: accountPeer), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: privacyAndSecurityControllerEntries(presentationData: presentationData, state: state, privacySettings: privacySettings, accessChallengeData: accessChallengeData.data, blockedPeerCount: blockedPeersState.totalCount, activeWebsitesCount: activeWebsitesState.sessions.count, hasTwoStepAuth: twoStepAuth.0, twoStepAuthData: twoStepAuth.1, hasPasskeys: passkeys.0, displayPasskeys: displayPasskeys, canAutoarchive: canAutoarchive, isPremiumDisabled: isPremiumDisabled, isPremium: isPremium, loginEmail: loginEmail, accountPeer: accountPeer, appConfiguration: appConfiguration), style: .blocks, ensureVisibleItemTag: focusOnItemTag, animateChanges: false)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ include "MediaId.fbs";
|
|||
include "TelegramMediaImageRepresentation.fbs";
|
||||
include "StickerPackReference.fbs";
|
||||
include "PartialMediaReference.fbs";
|
||||
include "TelegramMediaFile.fbs";
|
||||
|
||||
namespace TelegramCore;
|
||||
|
||||
|
|
@ -46,6 +47,7 @@ table TelegramMediaImage {
|
|||
reference:TelegramMediaImageReference (id: 5);
|
||||
partialReference:PartialMediaReference (id: 6);
|
||||
flags:int32 (id: 7);
|
||||
video:TelegramMediaFile (id: 8);
|
||||
}
|
||||
|
||||
root_type TelegramMediaImage;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ extension BotInfo {
|
|||
switch apiBotInfo {
|
||||
case let .botInfo(botInfoData):
|
||||
let (_, _, description, descriptionPhoto, descriptionDocument, apiCommands, apiMenuButton, privacyPolicyUrl, appSettings, verifierSettings) = (botInfoData.flags, botInfoData.userId, botInfoData.description, botInfoData.descriptionPhoto, botInfoData.descriptionDocument, botInfoData.commands, botInfoData.menuButton, botInfoData.privacyPolicyUrl, botInfoData.appSettings, botInfoData.verifierSettings)
|
||||
let photo: TelegramMediaImage? = descriptionPhoto.flatMap(telegramMediaImageFromApiPhoto)
|
||||
let photo: TelegramMediaImage? = descriptionPhoto.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
let video: TelegramMediaFile? = descriptionDocument.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: []) }
|
||||
var commands: [BotCommand] = []
|
||||
if let apiCommands = apiCommands {
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ func textMediaAndExpirationTimerFromApiMedia(_ media: Api.MessageMedia?, _ peerI
|
|||
case let .messageMediaPhoto(messageMediaPhotoData):
|
||||
let (flags, photo, ttlSeconds) = (messageMediaPhotoData.flags, messageMediaPhotoData.photo, messageMediaPhotoData.ttlSeconds)
|
||||
if let photo = photo {
|
||||
if let mediaImage = telegramMediaImageFromApiPhoto(photo) {
|
||||
if let mediaImage = telegramMediaImageFromApiPhoto(photo, video: messageMediaPhotoData.video) {
|
||||
return (mediaImage, ttlSeconds, nil, (flags & (1 << 3)) != 0, nil, nil)
|
||||
}
|
||||
} else {
|
||||
|
|
@ -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, isLivePhoto: (flags & (1 << 11)) != 0) {
|
||||
if let mediaFile = telegramMediaFileFromApiDocument(document, altDocuments: altDocuments, videoCover: coverPhoto) {
|
||||
return (mediaFile, ttlSeconds, (flags & (1 << 3)) != 0, (flags & (1 << 4)) != 0, nil, videoTimestamp)
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ extension StickerMaskCoords {
|
|||
}
|
||||
}
|
||||
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute], isLivePhoto: Bool = false) -> [TelegramMediaFileAttribute] {
|
||||
func telegramMediaFileAttributesFromApiAttributes(_ attributes: [Api.DocumentAttribute]) -> [TelegramMediaFileAttribute] {
|
||||
var result: [TelegramMediaFileAttribute] = []
|
||||
for attribute in attributes {
|
||||
switch attribute {
|
||||
|
|
@ -137,9 +137,6 @@ 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)
|
||||
|
|
@ -195,11 +192,11 @@ func telegramMediaFileThumbnailRepresentationsFromApiSizes(datacenterId: Int32,
|
|||
return (immediateThumbnailData, representations)
|
||||
}
|
||||
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil, isLivePhoto: Bool = false) -> TelegramMediaFile? {
|
||||
func telegramMediaFileFromApiDocument(_ document: Api.Document, altDocuments: [Api.Document]?, videoCover: Api.Photo? = nil) -> 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, isLivePhoto: isLivePhoto)
|
||||
var parsedAttributes = telegramMediaFileAttributesFromApiAttributes(attributes)
|
||||
var isSticker = false
|
||||
var isAnimated = false
|
||||
for attribute in parsedAttributes {
|
||||
|
|
@ -241,7 +238,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($0) }), immediateThumbnailData: immediateThumbnail, mimeType: mimeType, size: size, attributes: parsedAttributes, alternativeRepresentations: alternativeRepresentations)
|
||||
case .documentEmpty:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ func telegramMediaImageRepresentationsFromApiSizes(datacenterId: Int32, photoId:
|
|||
return (immediateThumbnailData, representations)
|
||||
}
|
||||
|
||||
func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
|
||||
func telegramMediaImageFromApiPhoto(_ photo: Api.Photo, video: Api.Document? = nil) -> TelegramMediaImage? {
|
||||
switch photo {
|
||||
case let .photo(photoData):
|
||||
let (flags, id, accessHash, fileReference, sizes, videoSizes, dcId) = (photoData.flags, photoData.id, photoData.accessHash, photoData.fileReference, photoData.sizes, photoData.videoSizes, photoData.dcId)
|
||||
|
|
@ -67,8 +67,7 @@ func telegramMediaImageFromApiPhoto(_ photo: Api.Photo) -> TelegramMediaImage? {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudImage, id: id), representations: representations, videoRepresentations: videoRepresentations, immediateThumbnailData: immediateThumbnailData, emojiMarkup: emojiMarkup, reference: .cloud(imageId: id, accessHash: accessHash, fileReference: fileReference.makeData()), partialReference: nil, flags: imageFlags)
|
||||
return TelegramMediaImage(imageId: MediaId(namespace: Namespaces.Media.CloudImage, id: id), representations: representations, videoRepresentations: videoRepresentations, immediateThumbnailData: immediateThumbnailData, emojiMarkup: emojiMarkup, reference: .cloud(imageId: id, accessHash: accessHash, fileReference: fileReference.makeData()), partialReference: nil, flags: imageFlags, video: video.flatMap { telegramMediaFileFromApiDocument($0, altDocuments: nil) })
|
||||
case .photoEmpty:
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -683,10 +683,10 @@ if "".isEmpty {
|
|||
|> mapToSignal { inputPeer -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
||||
if let inputPeer = inputPeer {
|
||||
if autoclearMessageAttribute != nil {
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds)), text), reuploadInfo: nil, cacheReferenceKey: nil)))
|
||||
return .single(.content(PendingMessageUploadedContentAndReuploadInfo(content: .media(.inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds, video: nil)), text), reuploadInfo: nil, cacheReferenceKey: nil)))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds))))
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds, video: nil))))
|
||||
|> mapError { _ -> PendingMessageUploadError in return .generic }
|
||||
|> mapToSignal { result -> Signal<PendingMessageUploadedContentResult, PendingMessageUploadError> in
|
||||
switch result {
|
||||
|
|
@ -857,7 +857,7 @@ private func uploadedVideoCover(network: Network, postbox: Postbox, resourceRefe
|
|||
case .progress:
|
||||
return .complete()
|
||||
case let .inputFile(file):
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: file, stickers: [], ttlSeconds: nil))))
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: file, stickers: [], ttlSeconds: nil, video: nil))))
|
||||
|> mapError { _ -> PendingMessageUploadError in return .generic }
|
||||
|> map { uploadResult in
|
||||
switch uploadResult {
|
||||
|
|
@ -1219,11 +1219,7 @@ private func uploadedMediaFileContent(network: Network, postbox: Postbox, auxili
|
|||
if videoTimestamp != nil {
|
||||
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)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -767,7 +767,7 @@ private func uploadedImage(account: Account, data: Data) -> Signal<UploadMediaEv
|
|||
switch next {
|
||||
case let .inputFile(inputFileData):
|
||||
let inputFile = inputFileData
|
||||
return .result(Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil)))
|
||||
return .result(Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil, video: nil)))
|
||||
case .inputSecretFile:
|
||||
preconditionFailure()
|
||||
case let .progress(progress):
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public func standaloneUploadedImage(postbox: Postbox, network: Network, peerId:
|
|||
|> mapError { _ -> StandaloneUploadMediaError in }
|
||||
|> mapToSignal { inputPeer -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
|
||||
if let inputPeer = inputPeer {
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil))))
|
||||
return network.request(Api.functions.messages.uploadMedia(flags: 0, businessConnectionId: nil, peer: inputPeer, media: Api.InputMedia.inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil, video: nil))))
|
||||
|> mapError { _ -> StandaloneUploadMediaError in return .generic }
|
||||
|> mapToSignal { media -> Signal<StandaloneUploadMediaEvent, StandaloneUploadMediaError> in
|
||||
switch media {
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ public class BoxedMessage: NSObject {
|
|||
|
||||
public class Serialization: NSObject, MTSerialization {
|
||||
public func currentLayer() -> UInt {
|
||||
return 223
|
||||
return 224
|
||||
}
|
||||
|
||||
public func parseMessage(_ data: Data!) -> Any! {
|
||||
|
|
|
|||
|
|
@ -750,7 +750,7 @@ extension Api.InputMedia {
|
|||
if let _ = stickers {
|
||||
flags |= (1 << 0)
|
||||
}
|
||||
return .inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds))
|
||||
return .inputMediaUploadedPhoto(.init(flags: flags, file: file, stickers: stickers, ttlSeconds: ttlSeconds, video: nil))
|
||||
default:
|
||||
return self
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,7 +311,6 @@ 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 {
|
||||
|
|
@ -1062,11 +1061,6 @@ public final class TelegramMediaFile: Media, Equatable, Codable {
|
|||
}
|
||||
|
||||
public var isLivePhoto: Bool {
|
||||
for attribute in self.attributes {
|
||||
if case .Video(_, _, let flags, _, _, _) = attribute {
|
||||
return flags.contains(.isLivePhoto)
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ public struct TelegramMediaImageFlags: OptionSet {
|
|||
}
|
||||
|
||||
public static let hasStickers = TelegramMediaImageFlags(rawValue: 1 << 0)
|
||||
public static let isLivePhoto = TelegramMediaImageFlags(rawValue: 1 << 1)
|
||||
}
|
||||
|
||||
public enum TelegramMediaImageDecodingError: Error {
|
||||
|
|
@ -282,12 +283,13 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
public let partialReference: PartialMediaReference?
|
||||
public let peerIds: [PeerId] = []
|
||||
public let flags: TelegramMediaImageFlags
|
||||
public let video: TelegramMediaFile?
|
||||
|
||||
public var id: MediaId? {
|
||||
return self.imageId
|
||||
}
|
||||
|
||||
public init(imageId: MediaId, representations: [TelegramMediaImageRepresentation], videoRepresentations: [TelegramMediaImage.VideoRepresentation] = [], immediateThumbnailData: Data?, emojiMarkup: TelegramMediaImage.EmojiMarkup? = nil, reference: TelegramMediaImageReference?, partialReference: PartialMediaReference?, flags: TelegramMediaImageFlags) {
|
||||
public init(imageId: MediaId, representations: [TelegramMediaImageRepresentation], videoRepresentations: [TelegramMediaImage.VideoRepresentation] = [], immediateThumbnailData: Data?, emojiMarkup: TelegramMediaImage.EmojiMarkup? = nil, reference: TelegramMediaImageReference?, partialReference: PartialMediaReference?, flags: TelegramMediaImageFlags, video: TelegramMediaFile? = nil) {
|
||||
self.imageId = imageId
|
||||
self.representations = representations
|
||||
self.videoRepresentations = videoRepresentations
|
||||
|
|
@ -296,6 +298,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
self.reference = reference
|
||||
self.partialReference = partialReference
|
||||
self.flags = flags
|
||||
self.video = video
|
||||
}
|
||||
|
||||
public init(decoder: PostboxDecoder) {
|
||||
|
|
@ -307,6 +310,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
self.reference = decoder.decodeObjectForKey("rf", decoder: { TelegramMediaImageReference(decoder: $0) }) as? TelegramMediaImageReference
|
||||
self.partialReference = decoder.decodeAnyObjectForKey("prf", decoder: { PartialMediaReference(decoder: $0) }) as? PartialMediaReference
|
||||
self.flags = TelegramMediaImageFlags(rawValue: decoder.decodeInt32ForKey("fl", orElse: 0))
|
||||
self.video = decoder.decodeObjectForKey("vid", decoder: { TelegramMediaFile(decoder: $0) }) as? TelegramMediaFile
|
||||
}
|
||||
|
||||
public func encode(_ encoder: PostboxEncoder) {
|
||||
|
|
@ -336,6 +340,11 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
encoder.encodeNil(forKey: "prf")
|
||||
}
|
||||
encoder.encodeInt32(self.flags.rawValue, forKey: "fl")
|
||||
if let video = self.video {
|
||||
encoder.encodeObject(video, forKey: "vid")
|
||||
} else {
|
||||
encoder.encodeNil(forKey: "vid")
|
||||
}
|
||||
}
|
||||
|
||||
public required init(from decoder: Decoder) throws {
|
||||
|
|
@ -353,6 +362,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
self.reference = object.reference
|
||||
self.partialReference = object.partialReference
|
||||
self.flags = object.flags
|
||||
self.video = object.video
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
|
@ -376,6 +386,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
self.reference = try flatBuffersObject.reference.flatMap { try TelegramMediaImageReference(flatBuffersObject: $0) }
|
||||
self.partialReference = try flatBuffersObject.partialReference.flatMap { try PartialMediaReference(flatBuffersObject: $0) }
|
||||
self.flags = TelegramMediaImageFlags(rawValue: flatBuffersObject.flags)
|
||||
self.video = try flatBuffersObject.video.flatMap { try TelegramMediaFile(flatBuffersObject: $0) }
|
||||
}
|
||||
|
||||
public func encodeToFlatBuffers(builder: inout FlatBufferBuilder) -> Offset {
|
||||
|
|
@ -393,6 +404,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
let emojiMarkupOffset = self.emojiMarkup.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
let referenceOffset = self.reference.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
let partialReferenceOffset = self.partialReference.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
let videoOffset = self.video.flatMap { $0.encodeToFlatBuffers(builder: &builder) }
|
||||
|
||||
let start = TelegramCore_TelegramMediaImage.startTelegramMediaImage(&builder)
|
||||
|
||||
|
|
@ -412,6 +424,9 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
TelegramCore_TelegramMediaImage.add(partialReference: partialReferenceOffset, &builder)
|
||||
}
|
||||
TelegramCore_TelegramMediaImage.add(flags: self.flags.rawValue, &builder)
|
||||
if let videoOffset {
|
||||
TelegramCore_TelegramMediaImage.add(video: videoOffset, &builder)
|
||||
}
|
||||
|
||||
return TelegramCore_TelegramMediaImage.endTelegramMediaImage(&builder, start: start)
|
||||
}
|
||||
|
|
@ -466,6 +481,9 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
if other.flags != self.flags {
|
||||
return false
|
||||
}
|
||||
if other.video != self.video {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -494,6 +512,9 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
if self.flags != other.flags {
|
||||
return false
|
||||
}
|
||||
if self.video != other.video {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -504,7 +525,7 @@ public final class TelegramMediaImage: Media, Equatable, Codable {
|
|||
}
|
||||
|
||||
public func withUpdatedPartialReference(_ partialReference: PartialMediaReference?) -> TelegramMediaImage {
|
||||
return TelegramMediaImage(imageId: self.imageId, representations: self.representations, videoRepresentations: self.videoRepresentations, immediateThumbnailData: self.immediateThumbnailData, reference: self.reference, partialReference: partialReference, flags: self.flags)
|
||||
return TelegramMediaImage(imageId: self.imageId, representations: self.representations, videoRepresentations: self.videoRepresentations, immediateThumbnailData: self.immediateThumbnailData, reference: self.reference, partialReference: partialReference, flags: self.flags, video: self.video)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -140,7 +140,7 @@ public extension TelegramEngine {
|
|||
case let .inputFile(inputFile):
|
||||
switch type {
|
||||
case .photo:
|
||||
inputMedia = .inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil))
|
||||
inputMedia = .inputMediaUploadedPhoto(.init(flags: 0, file: inputFile, stickers: nil, ttlSeconds: nil, video: nil))
|
||||
case .file, .video, .sticker, .voice:
|
||||
var attributes: [Api.DocumentAttribute] = []
|
||||
attributes.append(.documentAttributeFilename(.init(fileName: fileName)))
|
||||
|
|
|
|||
|
|
@ -599,12 +599,12 @@ public extension TelegramEngine {
|
|||
return EngineMessageReactionListContext(account: self.account, message: message, readStats: readStats, reaction: reaction)
|
||||
}
|
||||
|
||||
public func translate(text: String, toLang: String, entities: [MessageTextEntity] = []) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
return _internal_translate(network: self.account.network, text: text, toLang: toLang, entities: entities)
|
||||
public func translate(text: String, toLang: String, entities: [MessageTextEntity] = [], tone: TranslationTone = .neutral) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
return _internal_translate(network: self.account.network, text: text, toLang: toLang, entities: entities, tone: tone)
|
||||
}
|
||||
|
||||
public func translate(texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
return _internal_translateTexts(network: self.account.network, texts: texts, toLang: toLang)
|
||||
public func translate(texts: [(String, [MessageTextEntity])], toLang: String, tone: TranslationTone = .neutral) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
return _internal_translateTexts(network: self.account.network, texts: texts, toLang: toLang, tone: tone)
|
||||
}
|
||||
|
||||
public func translateMessages(messageIds: [EngineMessage.Id], fromLang: String?, toLang: String, enableLocalIfPossible: Bool) -> Signal<Never, TranslationError> {
|
||||
|
|
|
|||
|
|
@ -14,11 +14,21 @@ public enum TranslationError {
|
|||
case tryAlternative
|
||||
}
|
||||
|
||||
func _internal_translate(network: Network, text: String, toLang: String, entities: [MessageTextEntity] = []) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
public enum TranslationTone: String {
|
||||
case neutral
|
||||
case casual
|
||||
case formal
|
||||
}
|
||||
|
||||
func _internal_translate(network: Network, text: String, toLang: String, entities: [MessageTextEntity] = [], tone: TranslationTone = .neutral) -> Signal<(String, [MessageTextEntity])?, TranslationError> {
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 1)
|
||||
|
||||
if tone != .neutral {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(.init(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())))], toLang: toLang))
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(.init(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())))], toLang: toLang, tone: tone.rawValue))
|
||||
|> mapError { error -> TranslationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .limitExceeded
|
||||
|
|
@ -50,16 +60,20 @@ func _internal_translate(network: Network, text: String, toLang: String, entitie
|
|||
}
|
||||
}
|
||||
|
||||
func _internal_translateTexts(network: Network, texts: [(String, [MessageTextEntity])], toLang: String) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
func _internal_translateTexts(network: Network, texts: [(String, [MessageTextEntity])], toLang: String, tone: TranslationTone = .neutral) -> Signal<[(String, [MessageTextEntity])], TranslationError> {
|
||||
var flags: Int32 = 0
|
||||
flags |= (1 << 1)
|
||||
|
||||
if tone != .neutral {
|
||||
flags |= (1 << 2)
|
||||
}
|
||||
|
||||
var apiTexts: [Api.TextWithEntities] = []
|
||||
for text in texts {
|
||||
apiTexts.append(.textWithEntities(.init(text: text.0, entities: apiEntitiesFromMessageTextEntities(text.1, associatedPeers: SimpleDictionary()))))
|
||||
}
|
||||
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: apiTexts, toLang: toLang))
|
||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: apiTexts, toLang: toLang, tone: tone.rawValue))
|
||||
|> mapError { error -> TranslationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
return .limitExceeded
|
||||
|
|
@ -191,7 +205,7 @@ private func _internal_translateMessagesByPeerId(account: Account, peerId: Engin
|
|||
}
|
||||
}
|
||||
} else {
|
||||
msgs = account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: toLang))
|
||||
msgs = account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: toLang, tone: nil))
|
||||
|> map(Optional.init)
|
||||
|> mapError { error -> TranslationError in
|
||||
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ func _internal_updateChannelAdminRights(account: Account, peerId: PeerId, adminI
|
|||
if let _ = rank {
|
||||
flags = (1 << 0)
|
||||
}
|
||||
return account.network.request(Api.functions.channels.editAdmin(flags: flags, channel: inputChannel, userId: inputUser, adminRights: rights?.apiAdminRights ?? .chatAdminRights(Api.ChatAdminRights.Cons_chatAdminRights(flags: 0)), rank: rank ?? ""))
|
||||
return account.network.request(Api.functions.channels.editAdmin(flags: flags, channel: inputChannel, userId: inputUser, adminRights: rights?.apiAdminRights ?? .chatAdminRights(Api.ChatAdminRights.Cons_chatAdminRights(flags: 0)), rank: rank))
|
||||
|> map { [$0] }
|
||||
|> `catch` { error -> Signal<[Api.Updates], UpdateChannelAdminRightsError> in
|
||||
if error.errorDescription == "USER_NOT_PARTICIPANT" {
|
||||
|
|
|
|||
|
|
@ -548,7 +548,7 @@ func _internal_fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPee
|
|||
}
|
||||
}
|
||||
|
||||
let photo: TelegramMediaImage? = chatFullChatPhoto.flatMap(telegramMediaImageFromApiPhoto)
|
||||
let photo: TelegramMediaImage? = chatFullChatPhoto.flatMap { telegramMediaImageFromApiPhoto($0) }
|
||||
|
||||
let exportedInvitation = chatFullExportedInvite.flatMap { ExportedInvitation(apiExportedInvite: $0) }
|
||||
let pinnedMessageId = chatFullPinnedMsgId.flatMap({ MessageId(peerId: peerId, namespace: Namespaces.Message.Cloud, id: $0) })
|
||||
|
|
|
|||
|
|
@ -513,6 +513,8 @@ public final class ChatMessageWebpageBubbleContentNode: ChatMessageBubbleContent
|
|||
actionTitle = hasEnded ? item.presentationData.strings.Chat_Auction_ViewResults : item.presentationData.strings.Chat_Auction_Join
|
||||
actionIcon = !hasEnded ? .bid : nil
|
||||
}
|
||||
case "telegram_channel_direct":
|
||||
actionTitle = item.presentationData.strings.Chat_ContactChannel
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
|
|
|||
|
|
@ -539,12 +539,20 @@ final class PostSuggestionsSettingsScreenComponent: Component {
|
|||
}
|
||||
)
|
||||
)))
|
||||
|
||||
let linkSectionSize = self.linkSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
style: .glass,
|
||||
header: nil,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: environment.strings.ChannelMessages_LinkTitle.uppercased(),
|
||||
font: Font.regular(13.0),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
footer: nil,
|
||||
items: linkSectionItems
|
||||
)),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue