mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-07 01:10:09 +00:00
Various fixes
This commit is contained in:
parent
b44f3d62eb
commit
b074831fd3
@ -552,6 +552,7 @@ public protocol SharedAccountContext: class {
|
|||||||
func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController
|
func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController
|
||||||
func makePrivacyAndSecurityController(context: AccountContext) -> ViewController
|
func makePrivacyAndSecurityController(context: AccountContext) -> ViewController
|
||||||
func navigateToChatController(_ params: NavigateToChatControllerParams)
|
func navigateToChatController(_ params: NavigateToChatControllerParams)
|
||||||
|
func openLocationScreen(context: AccountContext, messageId: MessageId, navigationController: NavigationController)
|
||||||
func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void)
|
func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void)
|
||||||
func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messageIds: Set<MessageId>) -> Signal<ChatAvailableMessageActions, NoError>
|
func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messageIds: Set<MessageId>) -> Signal<ChatAvailableMessageActions, NoError>
|
||||||
func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messageIds: Set<MessageId>, messages: [MessageId: Message], peers: [PeerId: Peer]) -> Signal<ChatAvailableMessageActions, NoError>
|
func chatAvailableMessageActions(postbox: Postbox, accountPeerId: PeerId, messageIds: Set<MessageId>, messages: [MessageId: Message], peers: [PeerId: Peer]) -> Signal<ChatAvailableMessageActions, NoError>
|
||||||
|
|||||||
@ -43,7 +43,7 @@ class LocationPinAnnotation: NSObject, MKAnnotation {
|
|||||||
let peer: Peer?
|
let peer: Peer?
|
||||||
let message: Message?
|
let message: Message?
|
||||||
let forcedSelection: Bool
|
let forcedSelection: Bool
|
||||||
var heading: Int32? {
|
var heading: Double? {
|
||||||
willSet {
|
willSet {
|
||||||
self.willChangeValue(forKey: "heading")
|
self.willChangeValue(forKey: "heading")
|
||||||
}
|
}
|
||||||
@ -78,7 +78,7 @@ class LocationPinAnnotation: NSObject, MKAnnotation {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
init(context: AccountContext, theme: PresentationTheme, message: Message, selfPeer: Peer?, heading: Int32?) {
|
init(context: AccountContext, theme: PresentationTheme, message: Message, selfPeer: Peer?, heading: Double?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.location = nil
|
self.location = nil
|
||||||
|
|||||||
@ -17,11 +17,11 @@ import DeviceAccess
|
|||||||
|
|
||||||
public class LocationViewParams {
|
public class LocationViewParams {
|
||||||
let sendLiveLocation: (TelegramMediaMap) -> Void
|
let sendLiveLocation: (TelegramMediaMap) -> Void
|
||||||
let stopLiveLocation: () -> Void
|
let stopLiveLocation: (MessageId?) -> Void
|
||||||
let openUrl: (String) -> Void
|
let openUrl: (String) -> Void
|
||||||
let openPeer: (Peer) -> Void
|
let openPeer: (Peer) -> Void
|
||||||
|
|
||||||
public init(sendLiveLocation: @escaping (TelegramMediaMap) -> Void, stopLiveLocation: @escaping () -> Void, openUrl: @escaping (String) -> Void, openPeer: @escaping (Peer) -> Void) {
|
public init(sendLiveLocation: @escaping (TelegramMediaMap) -> Void, stopLiveLocation: @escaping (MessageId?) -> Void, openUrl: @escaping (String) -> Void, openPeer: @escaping (Peer) -> Void) {
|
||||||
self.sendLiveLocation = sendLiveLocation
|
self.sendLiveLocation = sendLiveLocation
|
||||||
self.stopLiveLocation = stopLiveLocation
|
self.stopLiveLocation = stopLiveLocation
|
||||||
self.openUrl = openUrl
|
self.openUrl = openUrl
|
||||||
@ -72,7 +72,7 @@ public final class LocationViewController: ViewController {
|
|||||||
return self.displayNode as! LocationViewControllerNode
|
return self.displayNode as! LocationViewControllerNode
|
||||||
}
|
}
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private var subject: Message
|
public var subject: Message
|
||||||
private var presentationData: PresentationData
|
private var presentationData: PresentationData
|
||||||
private var presentationDataDisposable: Disposable?
|
private var presentationDataDisposable: Disposable?
|
||||||
|
|
||||||
@ -286,7 +286,7 @@ public final class LocationViewController: ViewController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, stopLiveLocation: { [weak self] in
|
}, stopLiveLocation: { [weak self] in
|
||||||
params.stopLiveLocation()
|
params.stopLiveLocation(nil)
|
||||||
self?.dismiss()
|
self?.dismiss()
|
||||||
}, updateRightBarButton: { [weak self] action in
|
}, updateRightBarButton: { [weak self] action in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
@ -318,6 +318,10 @@ public final class LocationViewController: ViewController {
|
|||||||
self.presentationDataDisposable?.dispose()
|
self.presentationDataDisposable?.dispose()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func goToUserLocation(visibleRadius: Double? = nil) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
override public func loadDisplayNode() {
|
||||||
super.loadDisplayNode()
|
super.loadDisplayNode()
|
||||||
guard let interaction = self.interaction else {
|
guard let interaction = self.interaction else {
|
||||||
|
|||||||
@ -42,7 +42,7 @@ private struct LocationViewTransaction {
|
|||||||
private enum LocationViewEntryId: Hashable {
|
private enum LocationViewEntryId: Hashable {
|
||||||
case info
|
case info
|
||||||
case toggleLiveLocation
|
case toggleLiveLocation
|
||||||
case liveLocation(PeerId)
|
case liveLocation(UInt32)
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum LocationViewEntry: Comparable, Identifiable {
|
private enum LocationViewEntry: Comparable, Identifiable {
|
||||||
@ -57,11 +57,7 @@ private enum LocationViewEntry: Comparable, Identifiable {
|
|||||||
case .toggleLiveLocation:
|
case .toggleLiveLocation:
|
||||||
return .toggleLiveLocation
|
return .toggleLiveLocation
|
||||||
case let .liveLocation(_, message, _, _):
|
case let .liveLocation(_, message, _, _):
|
||||||
if let author = message.author {
|
return .liveLocation(message.stableId)
|
||||||
return .liveLocation(author.id)
|
|
||||||
} else {
|
|
||||||
return .liveLocation(message.id.peerId)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -379,7 +375,7 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
|||||||
|
|
||||||
var effectiveSubject: Message?
|
var effectiveSubject: Message?
|
||||||
for message in effectiveLiveLocations {
|
for message in effectiveLiveLocations {
|
||||||
if message.id.peerId == subject.id.peerId {
|
if message.id == subject.id {
|
||||||
effectiveSubject = message
|
effectiveSubject = message
|
||||||
} else {
|
} else {
|
||||||
sortedLiveLocations.append(message)
|
sortedLiveLocations.append(message)
|
||||||
@ -408,9 +404,9 @@ final class LocationViewControllerNode: ViewControllerTracingNode, CLLocationMan
|
|||||||
entries.append(.liveLocation(presentationData.theme, message, distance, index))
|
entries.append(.liveLocation(presentationData.theme, message, distance, index))
|
||||||
|
|
||||||
if message.localTags.contains(.OutgoingLiveLocation), let selfPeer = selfPeer {
|
if message.localTags.contains(.OutgoingLiveLocation), let selfPeer = selfPeer {
|
||||||
userAnnotation = LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer, heading: nil)
|
userAnnotation = LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer, heading: location.heading)
|
||||||
} else {
|
} else {
|
||||||
annotations.append(LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: nil, heading: nil))
|
annotations.append(LocationPinAnnotation(context: context, theme: presentationData.theme, message: message, selfPeer: selfPeer, heading: location.heading))
|
||||||
}
|
}
|
||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,6 +25,7 @@ public enum RequestEditMessageError {
|
|||||||
case generic
|
case generic
|
||||||
case restricted
|
case restricted
|
||||||
case textTooLong
|
case textTooLong
|
||||||
|
case invalidGrouping
|
||||||
}
|
}
|
||||||
|
|
||||||
public func requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
public func requestEditMessage(account: Account, messageId: MessageId, text: String, media: RequestEditMessageMedia, entities: TextEntitiesMessageAttribute? = nil, disableUrlPreview: Bool = false, scheduleTime: Int32? = nil) -> Signal<RequestEditMessageResult, RequestEditMessageError> {
|
||||||
@ -176,6 +177,8 @@ private func requestEditMessageInternal(postbox: Postbox, network: Network, stat
|
|||||||
return .invalidReference
|
return .invalidReference
|
||||||
} else if error.errorDescription.hasSuffix("_TOO_LONG") {
|
} else if error.errorDescription.hasSuffix("_TOO_LONG") {
|
||||||
return .error(.textTooLong)
|
return .error(.textTooLong)
|
||||||
|
} else if error.errorDescription.hasPrefix("MEDIA_GROUPED_INVALID") {
|
||||||
|
return .error(.invalidGrouping)
|
||||||
} else if error.errorDescription.hasPrefix("CHAT_SEND_") && error.errorDescription.hasSuffix("_FORBIDDEN") {
|
} else if error.errorDescription.hasPrefix("CHAT_SEND_") && error.errorDescription.hasSuffix("_FORBIDDEN") {
|
||||||
return .error(.restricted)
|
return .error(.restricted)
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -359,8 +359,19 @@ final class AuthorizedApplicationContext {
|
|||||||
|
|
||||||
strongSelf.notificationController.removeItemsWithGroupingKey(firstMessage.id.peerId)
|
strongSelf.notificationController.removeItemsWithGroupingKey(firstMessage.id.peerId)
|
||||||
|
|
||||||
|
var processed = false
|
||||||
|
for media in firstMessage.media {
|
||||||
|
if let action = media as? TelegramMediaAction, case let .geoProximityReached(distance) = action.action {
|
||||||
|
strongSelf.context.sharedContext.openLocationScreen(context: strongSelf.context, messageId: firstMessage.id, navigationController: strongSelf.rootController)
|
||||||
|
processed = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !processed {
|
||||||
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId)))
|
strongSelf.context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: strongSelf.rootController, context: strongSelf.context, chatLocation: .peer(firstMessage.id.peerId)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return false
|
return false
|
||||||
}, expandAction: { expandData in
|
}, expandAction: { expandData in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
|
|||||||
@ -5824,7 +5824,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
|
|
||||||
let text: String
|
let text: String
|
||||||
switch error {
|
switch error {
|
||||||
case .generic, .textTooLong:
|
case .generic, .textTooLong, .invalidGrouping:
|
||||||
text = strongSelf.presentationData.strings.Channel_EditMessageErrorGeneric
|
text = strongSelf.presentationData.strings.Channel_EditMessageErrorGeneric
|
||||||
case .restricted:
|
case .restricted:
|
||||||
text = strongSelf.presentationData.strings.Group_ErrorSendRestrictedMedia
|
text = strongSelf.presentationData.strings.Group_ErrorSendRestrictedMedia
|
||||||
@ -7149,17 +7149,18 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
|
let replyMessageId = strongSelf.presentationInterfaceState.interfaceState.replyMessageId
|
||||||
|
|
||||||
var groupingKey: Int64?
|
var groupingKey: Int64?
|
||||||
var allItemsAreSame = true
|
var fileTypes: (music: Bool, other: Bool) = (false, false)
|
||||||
for item in results {
|
for item in results {
|
||||||
if let item = item {
|
if let item = item {
|
||||||
let pathExtension = (item.fileName as NSString).pathExtension.lowercased()
|
let pathExtension = (item.fileName as NSString).pathExtension.lowercased()
|
||||||
if !["mp3", "m4a"].contains(pathExtension) {
|
if ["mp3", "m4a"].contains(pathExtension) {
|
||||||
allItemsAreSame = false
|
fileTypes.music = true
|
||||||
|
} else {
|
||||||
|
fileTypes.other = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
allItemsAreSame = true
|
if fileTypes.music != fileTypes.other {
|
||||||
if allItemsAreSame {
|
|
||||||
groupingKey = arc4random64()
|
groupingKey = arc4random64()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -222,9 +222,13 @@ func messageMediaEditingOptions(message: Message) -> MessageMediaEditingOptions
|
|||||||
case let .Audio(audio):
|
case let .Audio(audio):
|
||||||
if audio.isVoice {
|
if audio.isVoice {
|
||||||
return []
|
return []
|
||||||
|
} else {
|
||||||
|
if let _ = message.groupingKey {
|
||||||
|
return []
|
||||||
} else {
|
} else {
|
||||||
options.formUnion([.imageOrVideo, .file])
|
options.formUnion([.imageOrVideo, .file])
|
||||||
}
|
}
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3019,9 +3019,14 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
|
|
||||||
var tapMessage: Message? = item.content.firstMessage
|
var tapMessage: Message? = item.content.firstMessage
|
||||||
var selectAll = true
|
var selectAll = true
|
||||||
|
var hasFiles = false
|
||||||
loop: for contentNode in self.contentNodes {
|
loop: for contentNode in self.contentNodes {
|
||||||
let convertedLocation = self.view.convert(location, to: contentNode.view)
|
let convertedLocation = self.view.convert(location, to: contentNode.view)
|
||||||
|
|
||||||
|
if contentNode is ChatMessageFileBubbleContentNode {
|
||||||
|
hasFiles = true
|
||||||
|
}
|
||||||
|
|
||||||
let convertedNodeFrame = contentNode.view.convert(contentNode.bounds, to: self.view)
|
let convertedNodeFrame = contentNode.view.convert(contentNode.bounds, to: self.view)
|
||||||
if !convertedNodeFrame.contains(location) {
|
if !convertedNodeFrame.contains(location) {
|
||||||
continue loop
|
continue loop
|
||||||
@ -3029,6 +3034,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
|||||||
selectAll = false
|
selectAll = false
|
||||||
} else if contentNode is ChatMessageFileBubbleContentNode {
|
} else if contentNode is ChatMessageFileBubbleContentNode {
|
||||||
selectAll = false
|
selectAll = false
|
||||||
|
} else if contentNode is ChatMessageTextBubbleContentNode, hasFiles {
|
||||||
|
selectAll = false
|
||||||
}
|
}
|
||||||
tapMessage = contentNode.item?.message
|
tapMessage = contentNode.item?.message
|
||||||
let tapAction = contentNode.tapActionAtPoint(convertedLocation, gesture: gesture, isEstimating: false)
|
let tapAction = contentNode.tapActionAtPoint(convertedLocation, gesture: gesture, isEstimating: false)
|
||||||
|
|||||||
@ -982,7 +982,7 @@ final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
|||||||
cutoutNode.removeFromSupernode()
|
cutoutNode.removeFromSupernode()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let statusNode = self.statusNode {
|
} else if let statusNode = self.statusNode, (self.iconNode?.isHidden ?? true) {
|
||||||
if let _ = self.cutoutNode {
|
if let _ = self.cutoutNode {
|
||||||
} else {
|
} else {
|
||||||
let cutoutNode = ASImageNode()
|
let cutoutNode = ASImageNode()
|
||||||
|
|||||||
@ -69,8 +69,8 @@ func openChatMessageImpl(_ params: OpenChatMessageParams) -> Bool {
|
|||||||
let controllerParams = LocationViewParams(sendLiveLocation: { location in
|
let controllerParams = LocationViewParams(sendLiveLocation: { location in
|
||||||
let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil)
|
let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil)
|
||||||
params.enqueueMessage(outMessage)
|
params.enqueueMessage(outMessage)
|
||||||
}, stopLiveLocation: {
|
}, stopLiveLocation: { messageId in
|
||||||
params.context.liveLocationManager?.cancelLiveLocation(peerId: params.message.id.peerId)
|
params.context.liveLocationManager?.cancelLiveLocation(peerId: messageId?.peerId ?? params.message.id.peerId)
|
||||||
}, openUrl: params.openUrl, openPeer: { peer in
|
}, openUrl: params.openUrl, openPeer: { peer in
|
||||||
params.openPeer(peer, .info)
|
params.openPeer(peer, .info)
|
||||||
})
|
})
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import LocalMediaResources
|
|||||||
import OverlayStatusController
|
import OverlayStatusController
|
||||||
import AlertUI
|
import AlertUI
|
||||||
import PresentationDataUtils
|
import PresentationDataUtils
|
||||||
|
import LocationUI
|
||||||
|
|
||||||
private enum CallStatusText: Equatable {
|
private enum CallStatusText: Equatable {
|
||||||
case none
|
case none
|
||||||
@ -1080,6 +1081,41 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
|||||||
navigateToChatControllerImpl(params)
|
navigateToChatControllerImpl(params)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func openLocationScreen(context: AccountContext, messageId: MessageId, navigationController: NavigationController) {
|
||||||
|
var found = false
|
||||||
|
for controller in navigationController.viewControllers.reversed() {
|
||||||
|
if let controller = controller as? LocationViewController, controller.subject.id.peerId == messageId.peerId {
|
||||||
|
controller.goToUserLocation(visibleRadius: nil)
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !found {
|
||||||
|
let controllerParams = LocationViewParams(sendLiveLocation: { location in
|
||||||
|
let outMessage: EnqueueMessage = .message(text: "", attributes: [], mediaReference: .standalone(media: location), replyToMessageId: nil, localGroupingKey: nil)
|
||||||
|
// params.enqueueMessage(outMessage)
|
||||||
|
}, stopLiveLocation: { messageId in
|
||||||
|
if let messageId = messageId {
|
||||||
|
context.liveLocationManager?.cancelLiveLocation(peerId: messageId.peerId)
|
||||||
|
}
|
||||||
|
}, openUrl: { _ in }, openPeer: { peer in
|
||||||
|
// params.openPeer(peer, .info)
|
||||||
|
})
|
||||||
|
|
||||||
|
let _ = ((context.account.postbox.transaction { transaction -> Message? in
|
||||||
|
return transaction.getMessage(messageId)
|
||||||
|
}) |> deliverOnMainQueue).start(next: { message in
|
||||||
|
guard let message = message else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let controller = LocationViewController(context: context, subject: message, params: controllerParams)
|
||||||
|
controller.navigationPresentation = .modal
|
||||||
|
navigationController.pushViewController(controller)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public func resolveUrl(account: Account, url: String) -> Signal<ResolvedUrl, NoError> {
|
public func resolveUrl(account: Account, url: String) -> Signal<ResolvedUrl, NoError> {
|
||||||
return resolveUrlImpl(account: account, url: url)
|
return resolveUrlImpl(account: account, url: url)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user