mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 09:20:08 +00:00
CarPlay & Siri fixes
Silent posting fixes
This commit is contained in:
parent
b6fa9a7006
commit
659d360a65
@ -294,8 +294,18 @@ class IntentHandler: INExtension, INSendMessageIntentHandling, INSearchForMessag
|
|||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
|> mapToSignal { account -> Signal<[INMessage], IntentHandlingError> in
|
|> mapToSignal { account -> Signal<[INMessage], IntentHandlingError> in
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.now))
|
account.shouldBeServiceTaskMaster.set(.single(.now))
|
||||||
|
|
||||||
|
let completedUpdating: Signal<Bool, IntentHandlingError> = (.single(true) |> then(account.stateManager.isUpdating))
|
||||||
|
|> introduceError(IntentHandlingError.self)
|
||||||
|
|> filter { !$0 }
|
||||||
|
|> take(1)
|
||||||
|
|> timeout(3.0, queue: Queue.mainQueue(), alternate: .fail(.generic))
|
||||||
|
|
||||||
|
return completedUpdating
|
||||||
|
|> mapToSignal { value -> Signal<[INMessage], IntentHandlingError> in
|
||||||
return unreadMessages(account: account)
|
return unreadMessages(account: account)
|
||||||
|> introduceError(IntentHandlingError.self)
|
|> introduceError(IntentHandlingError.self)
|
||||||
|
}
|
||||||
|> afterDisposed {
|
|> afterDisposed {
|
||||||
account.shouldBeServiceTaskMaster.set(.single(.never))
|
account.shouldBeServiceTaskMaster.set(.single(.never))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,8 +14,10 @@ func unreadMessages(account: Account) -> Signal<[INMessage], NoError> {
|
|||||||
for entry in view.0.entries {
|
for entry in view.0.entries {
|
||||||
if case let .MessageEntry(index, _, readState, notificationSettings, _, _, _, _) = entry {
|
if case let .MessageEntry(index, _, readState, notificationSettings, _, _, _, _) = entry {
|
||||||
var hasUnread = false
|
var hasUnread = false
|
||||||
|
var fixedCombinedReadStates: MessageHistoryViewReadState?
|
||||||
if let readState = readState {
|
if let readState = readState {
|
||||||
hasUnread = readState.count != 0
|
hasUnread = readState.count != 0
|
||||||
|
fixedCombinedReadStates = .peer([index.messageIndex.id.peerId: readState])
|
||||||
}
|
}
|
||||||
var isMuted = false
|
var isMuted = false
|
||||||
if let notificationSettings = notificationSettings as? TelegramPeerNotificationSettings {
|
if let notificationSettings = notificationSettings as? TelegramPeerNotificationSettings {
|
||||||
@ -25,12 +27,17 @@ func unreadMessages(account: Account) -> Signal<[INMessage], NoError> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isMuted && hasUnread {
|
if !isMuted && hasUnread {
|
||||||
signals.append(account.postbox.aroundMessageHistoryViewForLocation(.peer(index.messageIndex.id.peerId), anchor: .upperBound, count: 10, fixedCombinedReadStates: nil, topTaggedMessageIdNamespaces: Set(), tagMask: nil, orderStatistics: .combinedLocation)
|
signals.append(account.postbox.aroundMessageHistoryViewForLocation(.peer(index.messageIndex.id.peerId), anchor: .upperBound, count: 10, fixedCombinedReadStates: fixedCombinedReadStates, topTaggedMessageIdNamespaces: Set(), tagMask: nil, orderStatistics: .combinedLocation)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|> map { view -> [INMessage] in
|
|> map { view -> [INMessage] in
|
||||||
var messages: [INMessage] = []
|
var messages: [INMessage] = []
|
||||||
for entry in view.0.entries {
|
for entry in view.0.entries {
|
||||||
if !entry.isRead {
|
var isRead = true
|
||||||
|
if let readState = readState {
|
||||||
|
isRead = readState.isIncomingMessageIndexRead(entry.message.index)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !isRead {
|
||||||
if let message = messageWithTelegramMessage(entry.message, account: account) {
|
if let message = messageWithTelegramMessage(entry.message, account: account) {
|
||||||
messages.append(message)
|
messages.append(message)
|
||||||
}
|
}
|
||||||
@ -150,7 +157,8 @@ private func messageWithTelegramMessage(_ telegramMessage: Message, account: Acc
|
|||||||
personHandle = INPersonHandle(value: user.phone ?? "", type: .phoneNumber)
|
personHandle = INPersonHandle(value: user.phone ?? "", type: .phoneNumber)
|
||||||
}
|
}
|
||||||
|
|
||||||
let sender = INPerson(personHandle: personHandle, nameComponents: nil, displayName: user.displayTitle, image: nil, contactIdentifier: nil, customIdentifier: "tg\(user.id.toInt64())")
|
let personIdentifier = "tg\(user.id.toInt64())"
|
||||||
|
let sender = INPerson(personHandle: personHandle, nameComponents: nil, displayName: user.displayTitle, image: nil, contactIdentifier: personIdentifier, customIdentifier: personIdentifier)
|
||||||
let date = Date(timeIntervalSince1970: TimeInterval(telegramMessage.timestamp))
|
let date = Date(timeIntervalSince1970: TimeInterval(telegramMessage.timestamp))
|
||||||
|
|
||||||
let message: INMessage
|
let message: INMessage
|
||||||
|
|||||||
@ -1183,7 +1183,7 @@ public class Account {
|
|||||||
|
|
||||||
self.networkTypeValue.set(currentNetworkType())
|
self.networkTypeValue.set(currentNetworkType())
|
||||||
|
|
||||||
let serviceTasksMasterBecomeMaster = shouldBeServiceTaskMaster.get()
|
let serviceTasksMasterBecomeMaster = self.shouldBeServiceTaskMaster.get()
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|> deliverOn(self.serviceQueue)
|
|> deliverOn(self.serviceQueue)
|
||||||
|
|
||||||
@ -1193,7 +1193,7 @@ public class Account {
|
|||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
let shouldBeMaster = combineLatest(shouldBeServiceTaskMaster.get(), postbox.isMasterClient())
|
let shouldBeMaster = combineLatest(self.shouldBeServiceTaskMaster.get(), postbox.isMasterClient())
|
||||||
|> map { [weak self] shouldBeMaster, isMaster -> Bool in
|
|> map { [weak self] shouldBeMaster, isMaster -> Bool in
|
||||||
if shouldBeMaster == .always && !isMaster {
|
if shouldBeMaster == .always && !isMaster {
|
||||||
self?.postbox.becomeMasterClient()
|
self?.postbox.becomeMasterClient()
|
||||||
|
|||||||
@ -16,7 +16,7 @@ public enum EnqueueMessageGrouping {
|
|||||||
|
|
||||||
public enum EnqueueMessage {
|
public enum EnqueueMessage {
|
||||||
case message(text: String, attributes: [MessageAttribute], mediaReference: AnyMediaReference?, replyToMessageId: MessageId?, localGroupingKey: Int64?)
|
case message(text: String, attributes: [MessageAttribute], mediaReference: AnyMediaReference?, replyToMessageId: MessageId?, localGroupingKey: Int64?)
|
||||||
case forward(source: MessageId, grouping: EnqueueMessageGrouping)
|
case forward(source: MessageId, grouping: EnqueueMessageGrouping, attributes: [MessageAttribute])
|
||||||
|
|
||||||
public func withUpdatedReplyToMessageId(_ replyToMessageId: MessageId?) -> EnqueueMessage {
|
public func withUpdatedReplyToMessageId(_ replyToMessageId: MessageId?) -> EnqueueMessage {
|
||||||
switch self {
|
switch self {
|
||||||
@ -31,8 +31,8 @@ public enum EnqueueMessage {
|
|||||||
switch self {
|
switch self {
|
||||||
case let .message(text, attributes, mediaReference, replyToMessageId, localGroupingKey):
|
case let .message(text, attributes, mediaReference, replyToMessageId, localGroupingKey):
|
||||||
return .message(text: text, attributes: f(attributes), mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey)
|
return .message(text: text, attributes: f(attributes), mediaReference: mediaReference, replyToMessageId: replyToMessageId, localGroupingKey: localGroupingKey)
|
||||||
case .forward:
|
case let .forward(source, grouping, attributes):
|
||||||
return self
|
return .forward(source: source, grouping: grouping, attributes: f(attributes))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -97,6 +97,8 @@ private func filterMessageAttributesForForwardedMessage(_ attributes: [MessageAt
|
|||||||
return true
|
return true
|
||||||
case _ as InlineBotMessageAttribute:
|
case _ as InlineBotMessageAttribute:
|
||||||
return true
|
return true
|
||||||
|
case _ as NotificationInfoMessageAttribute:
|
||||||
|
return true
|
||||||
default:
|
default:
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -246,10 +248,10 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if canBeForwarded {
|
if canBeForwarded {
|
||||||
updatedMessages.append((true, .forward(source: replyToMessageId, grouping: .none)))
|
updatedMessages.append((true, .forward(source: replyToMessageId, grouping: .none, attributes: [])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case let .forward(sourceId, _):
|
case let .forward(sourceId, _, _):
|
||||||
if let sourceMessage = forwardedMessageToBeReuploaded(transaction: transaction, id: sourceId) {
|
if let sourceMessage = forwardedMessageToBeReuploaded(transaction: transaction, id: sourceId) {
|
||||||
var mediaReference: AnyMediaReference?
|
var mediaReference: AnyMediaReference?
|
||||||
if sourceMessage.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
if sourceMessage.id.peerId.namespace == Namespaces.Peer.SecretChat {
|
||||||
@ -383,7 +385,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||||||
}
|
}
|
||||||
|
|
||||||
storeMessages.append(StoreMessage(peerId: peerId, namespace: Namespaces.Message.Local, globallyUniqueId: randomId, groupingKey: localGroupingKey, timestamp: timestamp, flags: flags, tags: tags, globalTags: globalTags, localTags: localTags, forwardInfo: nil, authorId: authorId, text: text, attributes: attributes, media: mediaList))
|
storeMessages.append(StoreMessage(peerId: peerId, namespace: Namespaces.Message.Local, globallyUniqueId: randomId, groupingKey: localGroupingKey, timestamp: timestamp, flags: flags, tags: tags, globalTags: globalTags, localTags: localTags, forwardInfo: nil, authorId: authorId, text: text, attributes: attributes, media: mediaList))
|
||||||
case let .forward(source, grouping):
|
case let .forward(source, grouping, requestedAttributes):
|
||||||
let sourceMessage = transaction.getMessage(source)
|
let sourceMessage = transaction.getMessage(source)
|
||||||
if let sourceMessage = sourceMessage, let author = sourceMessage.author ?? sourceMessage.peers[sourceMessage.id.peerId] {
|
if let sourceMessage = sourceMessage, let author = sourceMessage.author ?? sourceMessage.peers[sourceMessage.id.peerId] {
|
||||||
if let peer = peer as? TelegramSecretChat {
|
if let peer = peer as? TelegramSecretChat {
|
||||||
@ -407,6 +409,7 @@ func enqueueMessages(transaction: Transaction, account: Account, peerId: PeerId,
|
|||||||
attributes.append(SourceReferenceMessageAttribute(messageId: sourceMessage.id))
|
attributes.append(SourceReferenceMessageAttribute(messageId: sourceMessage.id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attributes.append(contentsOf: filterMessageAttributesForForwardedMessage(requestedAttributes))
|
||||||
attributes.append(contentsOf: filterMessageAttributesForForwardedMessage(sourceMessage.attributes))
|
attributes.append(contentsOf: filterMessageAttributesForForwardedMessage(sourceMessage.attributes))
|
||||||
|
|
||||||
var sourceReplyMarkup: ReplyMarkupMessageAttribute? = nil
|
var sourceReplyMarkup: ReplyMarkupMessageAttribute? = nil
|
||||||
|
|||||||
@ -901,8 +901,19 @@ public final class PendingMessageManager {
|
|||||||
|
|
||||||
var flags: Int32 = 0
|
var flags: Int32 = 0
|
||||||
|
|
||||||
|
if case .forward = content.content {
|
||||||
|
|
||||||
|
} else {
|
||||||
flags |= (1 << 7)
|
flags |= (1 << 7)
|
||||||
|
|
||||||
|
if let _ = replyMessageId {
|
||||||
|
flags |= Int32(1 << 0)
|
||||||
|
}
|
||||||
|
if let _ = messageEntities {
|
||||||
|
flags |= Int32(1 << 3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for attribute in message.attributes {
|
for attribute in message.attributes {
|
||||||
if let replyAttribute = attribute as? ReplyMessageAttribute {
|
if let replyAttribute = attribute as? ReplyMessageAttribute {
|
||||||
replyMessageId = replyAttribute.messageId.id
|
replyMessageId = replyAttribute.messageId.id
|
||||||
@ -923,13 +934,6 @@ public final class PendingMessageManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let _ = replyMessageId {
|
|
||||||
flags |= Int32(1 << 0)
|
|
||||||
}
|
|
||||||
if let _ = messageEntities {
|
|
||||||
flags |= Int32(1 << 3)
|
|
||||||
}
|
|
||||||
|
|
||||||
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messageId)
|
let dependencyTag = PendingMessageRequestDependencyTag(messageId: messageId)
|
||||||
|
|
||||||
let sendMessageRequest: Signal<NetworkRequestResult<Api.Updates>, MTRpcError>
|
let sendMessageRequest: Signal<NetworkRequestResult<Api.Updates>, MTRpcError>
|
||||||
@ -941,7 +945,7 @@ public final class PendingMessageManager {
|
|||||||
|> map(NetworkRequestResult.result)
|
|> map(NetworkRequestResult.result)
|
||||||
case let .forward(sourceInfo):
|
case let .forward(sourceInfo):
|
||||||
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
if let forwardSourceInfoAttribute = forwardSourceInfoAttribute, let sourcePeer = transaction.getPeer(forwardSourceInfoAttribute.messageId.peerId), let sourceInputPeer = apiInputPeer(sourcePeer) {
|
||||||
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: 0, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer), tag: dependencyTag)
|
sendMessageRequest = network.request(Api.functions.messages.forwardMessages(flags: flags, fromPeer: sourceInputPeer, id: [sourceInfo.messageId.id], randomId: [uniqueId], toPeer: inputPeer), tag: dependencyTag)
|
||||||
|> map(NetworkRequestResult.result)
|
|> map(NetworkRequestResult.result)
|
||||||
} else {
|
} else {
|
||||||
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
sendMessageRequest = .fail(MTRpcError(errorCode: 400, errorDescription: "internal"))
|
||||||
|
|||||||
@ -16,8 +16,9 @@ private final class ChannelAdminControllerArguments {
|
|||||||
let updateFocusedOnRank: (Bool) -> Void
|
let updateFocusedOnRank: (Bool) -> Void
|
||||||
let dismissAdmin: () -> Void
|
let dismissAdmin: () -> Void
|
||||||
let dismissInput: () -> Void
|
let dismissInput: () -> Void
|
||||||
|
let animateError: () -> Void
|
||||||
|
|
||||||
init(account: Account, toggleRight: @escaping (TelegramChatAdminRightsFlags, TelegramChatAdminRightsFlags) -> Void, transferOwnership: @escaping () -> Void, updateRank: @escaping (String, String) -> Void, updateFocusedOnRank: @escaping (Bool) -> Void, dismissAdmin: @escaping () -> Void, dismissInput: @escaping () -> Void) {
|
init(account: Account, toggleRight: @escaping (TelegramChatAdminRightsFlags, TelegramChatAdminRightsFlags) -> Void, transferOwnership: @escaping () -> Void, updateRank: @escaping (String, String) -> Void, updateFocusedOnRank: @escaping (Bool) -> Void, dismissAdmin: @escaping () -> Void, dismissInput: @escaping () -> Void, animateError: @escaping () -> Void) {
|
||||||
self.account = account
|
self.account = account
|
||||||
self.toggleRight = toggleRight
|
self.toggleRight = toggleRight
|
||||||
self.transferOwnership = transferOwnership
|
self.transferOwnership = transferOwnership
|
||||||
@ -25,6 +26,7 @@ private final class ChannelAdminControllerArguments {
|
|||||||
self.updateFocusedOnRank = updateFocusedOnRank
|
self.updateFocusedOnRank = updateFocusedOnRank
|
||||||
self.dismissAdmin = dismissAdmin
|
self.dismissAdmin = dismissAdmin
|
||||||
self.dismissInput = dismissInput
|
self.dismissInput = dismissInput
|
||||||
|
self.animateError = animateError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +370,11 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
|
|||||||
return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearButton: enabled, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
|
return ItemListSingleLineInputItem(theme: theme, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearButton: enabled, enabled: enabled, tag: ChannelAdminEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
|
||||||
arguments.updateRank(text, updatedText)
|
arguments.updateRank(text, updatedText)
|
||||||
}, shouldUpdateText: { text in
|
}, shouldUpdateText: { text in
|
||||||
return !text.containsEmoji
|
if text.containsEmoji {
|
||||||
|
arguments.animateError()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
}, updatedFocus: { focus in
|
}, updatedFocus: { focus in
|
||||||
arguments.updateFocusedOnRank(focus)
|
arguments.updateFocusedOnRank(focus)
|
||||||
}, action: {
|
}, action: {
|
||||||
@ -827,6 +833,8 @@ public func channelAdminController(context: AccountContext, peerId: PeerId, admi
|
|||||||
presentControllerImpl?(actionSheet, nil)
|
presentControllerImpl?(actionSheet, nil)
|
||||||
}, dismissInput: {
|
}, dismissInput: {
|
||||||
dismissInputImpl?()
|
dismissInputImpl?()
|
||||||
|
}, animateError: {
|
||||||
|
errorImpl?()
|
||||||
})
|
})
|
||||||
|
|
||||||
let combinedView = context.account.postbox.combinedView(keys: [.peer(peerId: peerId, components: .all), .peer(peerId: adminId, components: .all)])
|
let combinedView = context.account.postbox.combinedView(keys: [.peer(peerId: peerId, components: .all), .peer(peerId: adminId, components: .all)])
|
||||||
|
|||||||
@ -5818,7 +5818,7 @@ public final class ChatController: TelegramController, GalleryHiddenMediaTarget,
|
|||||||
strongController.dismiss()
|
strongController.dismiss()
|
||||||
} else if peerId == strongSelf.context.account.peerId {
|
} else if peerId == strongSelf.context.account.peerId {
|
||||||
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
|
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
|
||||||
return .forward(source: id, grouping: .auto)
|
return .forward(source: id, grouping: .auto, attributes: [])
|
||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(next: { messageIds in
|
|> deliverOnMainQueue).start(next: { messageIds in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
@ -2062,7 +2062,7 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
|
|
||||||
if let forwardMessageIds = self.chatPresentationInterfaceState.interfaceState.forwardMessageIds {
|
if let forwardMessageIds = self.chatPresentationInterfaceState.interfaceState.forwardMessageIds {
|
||||||
for id in forwardMessageIds {
|
for id in forwardMessageIds {
|
||||||
messages.append(.forward(source: id, grouping: .auto))
|
messages.append(.forward(source: id, grouping: .auto, attributes: []))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -74,6 +74,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||||||
if let shareButtonNode = strongSelf.shareButtonNode, shareButtonNode.frame.contains(point) {
|
if let shareButtonNode = strongSelf.shareButtonNode, shareButtonNode.frame.contains(point) {
|
||||||
return .fail
|
return .fail
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strongSelf.telegramFile == nil {
|
||||||
|
if strongSelf.animationNode.frame.contains(point) {
|
||||||
|
return .waitForDoubleTap
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return .waitForSingleTap
|
return .waitForSingleTap
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ import Foundation
|
|||||||
import UIKit
|
import UIKit
|
||||||
import Display
|
import Display
|
||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
|
import SwiftSignalKit
|
||||||
import TelegramPresentationData
|
import TelegramPresentationData
|
||||||
|
|
||||||
final class ChatSendMessageActionSheetController: ViewController {
|
final class ChatSendMessageActionSheetController: ViewController {
|
||||||
@ -14,6 +15,8 @@ final class ChatSendMessageActionSheetController: ViewController {
|
|||||||
private let sendButtonFrame: CGRect
|
private let sendButtonFrame: CGRect
|
||||||
private let textInputNode: EditableTextNode
|
private let textInputNode: EditableTextNode
|
||||||
|
|
||||||
|
private var presentationDataDisposable: Disposable?
|
||||||
|
|
||||||
private var didPlayPresentationAnimation = false
|
private var didPlayPresentationAnimation = false
|
||||||
|
|
||||||
private let hapticFeedback = HapticFeedback()
|
private let hapticFeedback = HapticFeedback()
|
||||||
@ -26,6 +29,13 @@ final class ChatSendMessageActionSheetController: ViewController {
|
|||||||
|
|
||||||
super.init(navigationBarPresentationData: nil)
|
super.init(navigationBarPresentationData: nil)
|
||||||
|
|
||||||
|
self.presentationDataDisposable = (context.sharedContext.presentationData
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] presentationData in
|
||||||
|
if let strongSelf = self {
|
||||||
|
strongSelf.controllerNode.updatePresentationData(presentationData)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
self.statusBar.statusBarStyle = .Hide
|
self.statusBar.statusBarStyle = .Hide
|
||||||
self.statusBar.ignoreInCall = true
|
self.statusBar.ignoreInCall = true
|
||||||
}
|
}
|
||||||
@ -34,6 +44,10 @@ final class ChatSendMessageActionSheetController: ViewController {
|
|||||||
fatalError("init(coder:) has not been implemented")
|
fatalError("init(coder:) has not been implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
self.presentationDataDisposable?.dispose()
|
||||||
|
}
|
||||||
|
|
||||||
override func loadDisplayNode() {
|
override func loadDisplayNode() {
|
||||||
self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, sendButtonFrame: self.sendButtonFrame, textInputNode: self.textInputNode, send: { [weak self] in
|
self.displayNode = ChatSendMessageActionSheetControllerNode(context: self.context, sendButtonFrame: self.sendButtonFrame, textInputNode: self.textInputNode, send: { [weak self] in
|
||||||
self?.controllerInteraction?.sendCurrentMessage(false)
|
self?.controllerInteraction?.sendCurrentMessage(false)
|
||||||
|
|||||||
@ -82,7 +82,7 @@ private final class ActionSheetItemNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode, UIScrollViewDelegate {
|
||||||
private let presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private let sendButtonFrame: CGRect
|
private let sendButtonFrame: CGRect
|
||||||
private let textFieldFrame: CGRect
|
private let textFieldFrame: CGRect
|
||||||
private let textInputNode: EditableTextNode
|
private let textInputNode: EditableTextNode
|
||||||
@ -141,7 +141,6 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
self.sendButtonNode = HighlightableButtonNode()
|
self.sendButtonNode = HighlightableButtonNode()
|
||||||
self.sendButtonNode.imageNode.displayWithoutProcessing = false
|
self.sendButtonNode.imageNode.displayWithoutProcessing = false
|
||||||
self.sendButtonNode.imageNode.displaysAsynchronously = false
|
self.sendButtonNode.imageNode.displaysAsynchronously = false
|
||||||
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
|
||||||
|
|
||||||
self.messageClipNode = ASDisplayNode()
|
self.messageClipNode = ASDisplayNode()
|
||||||
self.messageClipNode.clipsToBounds = true
|
self.messageClipNode.clipsToBounds = true
|
||||||
@ -229,6 +228,35 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func updatePresentationData(_ presentationData: PresentationData) {
|
||||||
|
self.presentationData = presentationData
|
||||||
|
|
||||||
|
if self.presentationData.theme.chatList.searchBarKeyboardColor == .dark {
|
||||||
|
self.effectView.effect = UIBlurEffect(style: .dark)
|
||||||
|
} else {
|
||||||
|
self.effectView.effect = UIBlurEffect(style: .light)
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.presentationData.theme.chatList.searchBarKeyboardColor == .light {
|
||||||
|
self.dimNode.backgroundColor = UIColor(white: 0.0, alpha: 0.04)
|
||||||
|
} else {
|
||||||
|
self.dimNode.backgroundColor = presentationData.theme.chatList.backgroundColor.withAlphaComponent(0.2)
|
||||||
|
}
|
||||||
|
|
||||||
|
self.contentContainerNode.backgroundColor = self.presentationData.theme.actionSheet.opaqueItemBackgroundColor
|
||||||
|
self.textCoverNode.backgroundColor = self.presentationData.theme.chat.inputPanel.inputBackgroundColor
|
||||||
|
self.buttonCoverNode.backgroundColor = self.presentationData.theme.chat.inputPanel.panelBackgroundColor
|
||||||
|
self.sendButtonNode.setImage(PresentationResourcesChat.chatInputPanelSendButtonImage(self.presentationData.theme), for: [])
|
||||||
|
|
||||||
|
if let toAttributedText = self.textInputNode.attributedText?.mutableCopy() as? NSMutableAttributedString {
|
||||||
|
toAttributedText.addAttribute(NSAttributedStringKey.foregroundColor, value: self.presentationData.theme.chat.message.outgoing.primaryTextColor, range: NSMakeRange(0, (toAttributedText.string as NSString).length))
|
||||||
|
self.toMessageTextNode.attributedText = toAttributedText
|
||||||
|
}
|
||||||
|
|
||||||
|
let graphics = PresentationResourcesChat.principalGraphics(self.presentationData.theme, wallpaper: self.presentationData.chatWallpaper)
|
||||||
|
self.messageBackgroundNode.image = graphics.chatMessageBackgroundOutgoingImage
|
||||||
|
}
|
||||||
|
|
||||||
func animateIn() {
|
func animateIn() {
|
||||||
UIView.animate(withDuration: 0.4, animations: {
|
UIView.animate(withDuration: 0.4, animations: {
|
||||||
if #available(iOS 9.0, *) {
|
if #available(iOS 9.0, *) {
|
||||||
@ -270,7 +298,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
self.toMessageTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, removeOnCompletion: false)
|
self.toMessageTextNode.layer.animateAlpha(from: 0.0, to: 1.0, duration: 0.3, removeOnCompletion: false)
|
||||||
|
|
||||||
if let layout = self.validLayout {
|
if let layout = self.validLayout {
|
||||||
let duration = 0.6
|
let duration = 0.4
|
||||||
|
|
||||||
self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear)
|
self.sendButtonNode.layer.animateScale(from: 0.75, to: 1.0, duration: 0.2, timingFunction: kCAMediaTimingFunctionLinear)
|
||||||
self.sendButtonNode.layer.animatePosition(from: self.sendButtonFrame.center, to: self.sendButtonNode.position, duration: duration, timingFunction: kCAMediaTimingFunctionSpring)
|
self.sendButtonNode.layer.animatePosition(from: self.sendButtonFrame.center, to: self.sendButtonNode.position, duration: duration, timingFunction: kCAMediaTimingFunctionSpring)
|
||||||
@ -349,7 +377,7 @@ final class ChatSendMessageActionSheetControllerNode: ViewControllerTracingNode,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let layout = self.validLayout {
|
if let layout = self.validLayout {
|
||||||
let duration = 0.6
|
let duration = 0.4
|
||||||
|
|
||||||
self.sendButtonNode.layer.animatePosition(from: self.sendButtonNode.position, to: self.sendButtonFrame.center, duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
|
self.sendButtonNode.layer.animatePosition(from: self.sendButtonNode.position, to: self.sendButtonFrame.center, duration: duration, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
|
||||||
completedButton = true
|
completedButton = true
|
||||||
|
|||||||
@ -57,6 +57,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
case resetBiometricsData(PresentationTheme)
|
case resetBiometricsData(PresentationTheme)
|
||||||
case optimizeDatabase(PresentationTheme)
|
case optimizeDatabase(PresentationTheme)
|
||||||
case photoPreview(PresentationTheme, Bool)
|
case photoPreview(PresentationTheme, Bool)
|
||||||
|
case playAnimatedEmojiOnce(PresentationTheme, Bool)
|
||||||
case exportTheme(PresentationTheme)
|
case exportTheme(PresentationTheme)
|
||||||
case versionInfo(PresentationTheme)
|
case versionInfo(PresentationTheme)
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
return DebugControllerSection.logging.rawValue
|
return DebugControllerSection.logging.rawValue
|
||||||
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
case .enableRaiseToSpeak, .keepChatNavigationStack, .skipReadHistory, .crashOnSlowQueries:
|
||||||
return DebugControllerSection.experiments.rawValue
|
return DebugControllerSection.experiments.rawValue
|
||||||
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .exportTheme:
|
case .clearTips, .reimport, .resetData, .resetDatabase, .resetHoles, .resetBiometricsData, .optimizeDatabase, .photoPreview, .playAnimatedEmojiOnce, .exportTheme:
|
||||||
return DebugControllerSection.experiments.rawValue
|
return DebugControllerSection.experiments.rawValue
|
||||||
case .versionInfo:
|
case .versionInfo:
|
||||||
return DebugControllerSection.info.rawValue
|
return DebugControllerSection.info.rawValue
|
||||||
@ -119,10 +120,12 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
return 18
|
return 18
|
||||||
case .photoPreview:
|
case .photoPreview:
|
||||||
return 19
|
return 19
|
||||||
case .exportTheme:
|
case .playAnimatedEmojiOnce:
|
||||||
return 20
|
return 20
|
||||||
case .versionInfo:
|
case .exportTheme:
|
||||||
return 21
|
return 21
|
||||||
|
case .versionInfo:
|
||||||
|
return 22
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -469,6 +472,16 @@ private enum DebugControllerEntry: ItemListNodeEntry {
|
|||||||
})
|
})
|
||||||
}).start()
|
}).start()
|
||||||
})
|
})
|
||||||
|
case let .playAnimatedEmojiOnce(theme, value):
|
||||||
|
return ItemListSwitchItem(theme: theme, title: "Play Emoji Once", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||||
|
let _ = arguments.sharedContext.accountManager.transaction ({ transaction in
|
||||||
|
transaction.updateSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings, { settings in
|
||||||
|
var settings = settings as? ExperimentalUISettings ?? ExperimentalUISettings.defaultSettings
|
||||||
|
settings.playAnimatedEmojiOnce = value
|
||||||
|
return settings
|
||||||
|
})
|
||||||
|
}).start()
|
||||||
|
})
|
||||||
case let .exportTheme(theme):
|
case let .exportTheme(theme):
|
||||||
return ItemListActionItem(theme: theme, title: "Export Theme", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
return ItemListActionItem(theme: theme, title: "Export Theme", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
guard let context = arguments.context else {
|
guard let context = arguments.context else {
|
||||||
@ -536,6 +549,7 @@ private func debugControllerEntries(presentationData: PresentationData, loggingS
|
|||||||
entries.append(.resetHoles(presentationData.theme))
|
entries.append(.resetHoles(presentationData.theme))
|
||||||
entries.append(.optimizeDatabase(presentationData.theme))
|
entries.append(.optimizeDatabase(presentationData.theme))
|
||||||
entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos))
|
entries.append(.photoPreview(presentationData.theme, experimentalSettings.chatListPhotos))
|
||||||
|
entries.append(.playAnimatedEmojiOnce(presentationData.theme, experimentalSettings.playAnimatedEmojiOnce))
|
||||||
|
|
||||||
entries.append(.versionInfo(presentationData.theme))
|
entries.append(.versionInfo(presentationData.theme))
|
||||||
|
|
||||||
|
|||||||
@ -654,7 +654,7 @@ public class PeerMediaCollectionController: TelegramController {
|
|||||||
|
|
||||||
if peerId == strongSelf.context.account.peerId {
|
if peerId == strongSelf.context.account.peerId {
|
||||||
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
|
let _ = (enqueueMessages(account: strongSelf.context.account, peerId: peerId, messages: messageIds.map { id -> EnqueueMessage in
|
||||||
return .forward(source: id, grouping: .auto)
|
return .forward(source: id, grouping: .auto, attributes: [])
|
||||||
})
|
})
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|
|> deliverOnMainQueue).start(next: { [weak self] messageIds in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
@ -425,7 +425,7 @@ public final class ShareController: ViewController {
|
|||||||
messagesToEnqueue.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil))
|
messagesToEnqueue.append(.message(text: text, attributes: [], mediaReference: nil, replyToMessageId: nil, localGroupingKey: nil))
|
||||||
}
|
}
|
||||||
for message in messages {
|
for message in messages {
|
||||||
messagesToEnqueue.append(.forward(source: message.id, grouping: .auto))
|
messagesToEnqueue.append(.forward(source: message.id, grouping: .auto, attributes: []))
|
||||||
}
|
}
|
||||||
let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messagesToEnqueue).start()
|
let _ = enqueueMessages(account: strongSelf.currentAccount, peerId: peerId, messages: messagesToEnqueue).start()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -212,7 +212,7 @@ final class WatchSendMessageHandler: WatchRequestHandler {
|
|||||||
} else if let args = subscription as? TGBridgeSendForwardedMessageSubscription {
|
} else if let args = subscription as? TGBridgeSendForwardedMessageSubscription {
|
||||||
let peerId = makePeerIdFromBridgeIdentifier(args.targetPeerId)
|
let peerId = makePeerIdFromBridgeIdentifier(args.targetPeerId)
|
||||||
if let forwardPeerId = makePeerIdFromBridgeIdentifier(args.peerId) {
|
if let forwardPeerId = makePeerIdFromBridgeIdentifier(args.peerId) {
|
||||||
messageSignal = .single((.forward(source: MessageId(peerId: forwardPeerId, namespace: Namespaces.Message.Cloud, id: args.messageId), grouping: .none), peerId))
|
messageSignal = .single((.forward(source: MessageId(peerId: forwardPeerId, namespace: Namespaces.Message.Cloud, id: args.messageId), grouping: .none, attributes: []), peerId))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -7,16 +7,18 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||||||
public var skipReadHistory: Bool
|
public var skipReadHistory: Bool
|
||||||
public var crashOnLongQueries: Bool
|
public var crashOnLongQueries: Bool
|
||||||
public var chatListPhotos: Bool
|
public var chatListPhotos: Bool
|
||||||
|
public var playAnimatedEmojiOnce: Bool
|
||||||
|
|
||||||
public static var defaultSettings: ExperimentalUISettings {
|
public static var defaultSettings: ExperimentalUISettings {
|
||||||
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false)
|
return ExperimentalUISettings(keepChatNavigationStack: false, skipReadHistory: false, crashOnLongQueries: false, chatListPhotos: false, playAnimatedEmojiOnce: false)
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool) {
|
public init(keepChatNavigationStack: Bool, skipReadHistory: Bool, crashOnLongQueries: Bool, chatListPhotos: Bool, playAnimatedEmojiOnce: Bool) {
|
||||||
self.keepChatNavigationStack = keepChatNavigationStack
|
self.keepChatNavigationStack = keepChatNavigationStack
|
||||||
self.skipReadHistory = skipReadHistory
|
self.skipReadHistory = skipReadHistory
|
||||||
self.crashOnLongQueries = crashOnLongQueries
|
self.crashOnLongQueries = crashOnLongQueries
|
||||||
self.chatListPhotos = chatListPhotos
|
self.chatListPhotos = chatListPhotos
|
||||||
|
self.playAnimatedEmojiOnce = playAnimatedEmojiOnce
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(decoder: PostboxDecoder) {
|
public init(decoder: PostboxDecoder) {
|
||||||
@ -24,6 +26,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||||||
self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0
|
self.skipReadHistory = decoder.decodeInt32ForKey("skipReadHistory", orElse: 0) != 0
|
||||||
self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0
|
self.crashOnLongQueries = decoder.decodeInt32ForKey("crashOnLongQueries", orElse: 0) != 0
|
||||||
self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0
|
self.chatListPhotos = decoder.decodeInt32ForKey("chatListPhotos", orElse: 0) != 0
|
||||||
|
self.playAnimatedEmojiOnce = decoder.decodeInt32ForKey("playAnimatedEmojiOnce", orElse: 0) != 0
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(_ encoder: PostboxEncoder) {
|
public func encode(_ encoder: PostboxEncoder) {
|
||||||
@ -31,6 +34,7 @@ public struct ExperimentalUISettings: Equatable, PreferencesEntry {
|
|||||||
encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory")
|
encoder.encodeInt32(self.skipReadHistory ? 1 : 0, forKey: "skipReadHistory")
|
||||||
encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries")
|
encoder.encodeInt32(self.crashOnLongQueries ? 1 : 0, forKey: "crashOnLongQueries")
|
||||||
encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos")
|
encoder.encodeInt32(self.chatListPhotos ? 1 : 0, forKey: "chatListPhotos")
|
||||||
|
encoder.encodeInt32(self.playAnimatedEmojiOnce ? 1 : 0, forKey: "playAnimatedEmojiOnce")
|
||||||
}
|
}
|
||||||
|
|
||||||
public func isEqual(to: PreferencesEntry) -> Bool {
|
public func isEqual(to: PreferencesEntry) -> Bool {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user