From e98d60353d121e1358bf394e69efe1c19c01f656 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Mon, 29 Nov 2021 01:52:12 +0400 Subject: [PATCH] Various Fixes --- .../RecentSessionScreen.swift | 60 +++++++----- .../Sources/State/PendingMessageManager.swift | 6 +- .../TelegramUI/Sources/ChatController.swift | 4 +- .../Sources/ChatMessageBubbleItemNode.swift | 4 +- .../Sources/PeerInfo/PeerInfoData.swift | 97 ++++++++++--------- .../Sources/PeerInfo/PeerInfoScreen.swift | 59 ++++------- .../PeerSelectionTextInputPanelNode.swift | 7 +- 7 files changed, 124 insertions(+), 113 deletions(-) diff --git a/submodules/SettingsUI/Sources/Privacy and Security/RecentSessionScreen.swift b/submodules/SettingsUI/Sources/Privacy and Security/RecentSessionScreen.swift index 9139af6d9b..4617e7e5f5 100644 --- a/submodules/SettingsUI/Sources/Privacy and Security/RecentSessionScreen.swift +++ b/submodules/SettingsUI/Sources/Privacy and Security/RecentSessionScreen.swift @@ -211,6 +211,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.wrappingScrollNode = ASScrollNode() self.wrappingScrollNode.view.alwaysBounceVertical = true self.wrappingScrollNode.view.delaysContentTouches = false + self.wrappingScrollNode.view.showsVerticalScrollIndicator = false self.wrappingScrollNode.view.canCancelContentTouches = true self.dimNode = ASDisplayNode() @@ -269,6 +270,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.terminateButton = SolidRoundedButtonNode(theme: SolidRoundedButtonTheme(backgroundColor: self.presentationData.theme.list.itemBlocksBackgroundColor, foregroundColor: self.presentationData.theme.list.itemDestructiveColor), font: .regular, height: 44.0, cornerRadius: 11.0, gloss: false) var hasSecretChats = false + var hasIncomingCalls = false let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) let title: String @@ -341,8 +343,11 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.secretChatsSwitchNode.isOn = session.flags.contains(.acceptsSecretChats) self.incomingCallsSwitchNode.isOn = session.flags.contains(.acceptsIncomingCalls) - if !session.flags.contains(.passwordPending) && ![2040, 2496].contains(session.apiId) { - hasSecretChats = true + if !session.flags.contains(.passwordPending) { + hasIncomingCalls = true + if ![2040, 2496].contains(session.apiId) { + hasSecretChats = true + } } case let .website(website, peer): self.terminateButton.title = self.presentationData.strings.AuthSessions_View_Logout @@ -399,7 +404,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.locationTitleNode.attributedText = NSAttributedString(string: self.presentationData.strings.AuthSessions_View_Location, font: Font.regular(17.0), textColor: textColor) self.locationValueNode.attributedText = NSAttributedString(string: location, font: Font.regular(17.0), textColor: secondaryTextColor) self.locationInfoNode.attributedText = NSAttributedString(string: self.presentationData.strings.AuthSessions_View_LocationInfo, font: Font.regular(13.0), textColor: secondaryTextColor) - self.locationInfoNode.maximumNumberOfLines = 3 + self.locationInfoNode.maximumNumberOfLines = 4 self.acceptBackgroundNode = ASDisplayNode() self.acceptBackgroundNode.clipsToBounds = true @@ -454,26 +459,28 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.animationNode.flatMap { self.contentContainerNode.addSubnode($0) } self.avatarNode.flatMap { self.contentContainerNode.addSubnode($0) } - self.contentContainerNode.addSubnode(self.acceptBackgroundNode) - self.contentContainerNode.addSubnode(self.acceptHeaderNode) - if hasSecretChats { - self.contentContainerNode.addSubnode(self.secretChatsTitleNode) - self.contentContainerNode.addSubnode(self.secretChatsSwitchNode) - - self.secretChatsSwitchNode.valueUpdated = { [weak self] value in - if let strongSelf = self { - strongSelf.updateAcceptSecretChats?(value) + if hasIncomingCalls { + self.contentContainerNode.addSubnode(self.acceptBackgroundNode) + self.contentContainerNode.addSubnode(self.acceptHeaderNode) + if hasSecretChats { + self.contentContainerNode.addSubnode(self.secretChatsTitleNode) + self.contentContainerNode.addSubnode(self.secretChatsSwitchNode) + + self.secretChatsSwitchNode.valueUpdated = { [weak self] value in + if let strongSelf = self { + strongSelf.updateAcceptSecretChats?(value) + } } + + self.contentContainerNode.addSubnode(self.acceptSeparatorNode) } + self.contentContainerNode.addSubnode(self.incomingCallsTitleNode) + self.contentContainerNode.addSubnode(self.incomingCallsSwitchNode) - self.contentContainerNode.addSubnode(self.acceptSeparatorNode) - } - self.contentContainerNode.addSubnode(self.incomingCallsTitleNode) - self.contentContainerNode.addSubnode(self.incomingCallsSwitchNode) - - self.incomingCallsSwitchNode.valueUpdated = { [weak self] value in - if let strongSelf = self { - strongSelf.updateAcceptIncomingCalls?(value) + self.incomingCallsSwitchNode.valueUpdated = { [weak self] value in + if let strongSelf = self { + strongSelf.updateAcceptIncomingCalls?(value) + } } } @@ -779,7 +786,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe } transition.updateFrame(node: self.acceptBackgroundNode, frame: secretFrame) - let secretChatsHeaderTextSize = self.acceptHeaderNode.updateLayout(CGSize(width: secretFrame.width - inset * 2.0 - locationTitleTextSize.width - 10.0, height: fieldItemHeight)) + let secretChatsHeaderTextSize = self.acceptHeaderNode.updateLayout(CGSize(width: secretFrame.width - inset * 2.0, height: fieldItemHeight)) let secretChatsHeaderTextFrame = CGRect(origin: CGPoint(x: secretFrame.minX + inset, y: secretFrame.minY - secretChatsHeaderTextSize.height - 6.0), size: secretChatsHeaderTextSize) transition.updateFrame(node: self.acceptHeaderNode, frame: secretChatsHeaderTextFrame) @@ -813,7 +820,9 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe self.incomingCallsSwitchNode.frame = CGRect(origin: CGPoint(x: fieldFrame.maxX - switchSize.width - inset, y: secretFrame.maxY - fieldItemHeight + floorToScreenPixels((fieldItemHeight - switchSize.height) / 2.0)), size: switchSize) } - contentHeight += secretFrame.maxY - locationInfoTextFrame.maxY + if let _ = self.acceptBackgroundNode.supernode { + contentHeight += secretFrame.maxY - locationInfoTextFrame.maxY + } contentHeight += 40.0 let isCurrent: Bool @@ -823,7 +832,7 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe isCurrent = false } - if isCurrent || (layout.size.width > layout.size.height && layout.metrics.widthClass == .compact) { + if isCurrent { contentHeight -= 68.0 self.terminateButton.isHidden = true } else { @@ -831,9 +840,12 @@ private class RecentSessionScreenNode: ViewControllerTracingNode, UIScrollViewDe } let sideInset = floor((layout.size.width - width) / 2.0) - let contentContainerFrame = CGRect(origin: CGPoint(x: sideInset, y: layout.size.height - contentHeight), size: CGSize(width: width, height: contentHeight)) + let scrollContentHeight = max(layout.size.height, contentHeight) + let contentContainerFrame = CGRect(origin: CGPoint(x: sideInset, y: max(layout.statusBarHeight ?? 20.0, layout.size.height - contentHeight)), size: CGSize(width: width, height: contentHeight)) let contentFrame = contentContainerFrame + self.wrappingScrollNode.view.contentSize = CGSize(width: layout.size.width, height: scrollContentHeight) + var backgroundFrame = CGRect(origin: CGPoint(x: contentFrame.minX, y: contentFrame.minY), size: CGSize(width: width, height: contentFrame.height + 2000.0)) if backgroundFrame.minY < contentFrame.minY { backgroundFrame.origin.y = contentFrame.minY diff --git a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift index cba4a35efc..5450e5743b 100644 --- a/submodules/TelegramCore/Sources/State/PendingMessageManager.swift +++ b/submodules/TelegramCore/Sources/State/PendingMessageManager.swift @@ -369,8 +369,10 @@ public final class PendingMessageManager { guard let messageContext = strongSelf.messageContexts[message.id] else { continue } - - messageContext.activityType = uploadActivityTypeForMessage(message) + + if message.author?.id == strongSelf.accountPeerId { + messageContext.activityType = uploadActivityTypeForMessage(message) + } messageContext.threadId = message.threadId strongSelf.collectUploadingInfo(messageContext: messageContext, message: message) } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index f5cdbeb5fd..3b413b7fdc 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -10905,7 +10905,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } } if let sendAsPeerId = self.presentationInterfaceState.currentSendAsPeerId { - attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) + if attributes.first(where: { $0 is SendAsMessageAttribute }) == nil { + attributes.append(SendAsMessageAttribute(peerId: sendAsPeerId)) + } } return attributes } diff --git a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift index c85b7d6dfe..3c91d78eb3 100644 --- a/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift +++ b/submodules/TelegramUI/Sources/ChatMessageBubbleItemNode.swift @@ -949,6 +949,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode var effectiveAuthor: Peer? var ignoreForward = false var displayAuthorInfo: Bool + var ignoreNameHiding = false let avatarInset: CGFloat var hasAvatar = false @@ -995,6 +996,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode if let author = firstMessage.author, author is TelegramChannel, !incoming { allowAuthor = true + ignoreNameHiding = true } displayAuthorInfo = !mergedTop.merged && allowAuthor && peerId.isGroupOrChannel && effectiveAuthor != nil @@ -1370,7 +1372,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode initialDisplayHeader = false } else { if inlineBotNameString == nil && (ignoreForward || firstMessage.forwardInfo == nil) && replyMessage == nil { - if let first = contentPropertiesAndLayouts.first, first.1.hidesSimpleAuthorHeader { + if let first = contentPropertiesAndLayouts.first, first.1.hidesSimpleAuthorHeader && !ignoreNameHiding { if let author = firstMessage.author as? TelegramChannel, case .group = author.info, author.id == firstMessage.id.peerId, !incoming { } else { initialDisplayHeader = false diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift index f1e990b930..99e314e444 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoData.swift @@ -1042,43 +1042,33 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro result.append(.more) } } else if let channel = peer as? TelegramChannel { - var displayLeave = !channel.flags.contains(.isCreator) - var canViewStats = false - var hasDiscussion = false - var hasVoiceChat = false - var displayMore = true - var canStartVoiceChat = false - if let cachedChannelData = cachedData as? CachedChannelData { - canViewStats = cachedChannelData.flags.contains(.canViewStats) - } - if channel.flags.contains(.hasVoiceChat) { - hasVoiceChat = true - } - if channel.flags.contains(.isCreator) { - displayMore = true - } + let hasVoiceChat = channel.flags.contains(.hasVoiceChat) + let canStartVoiceChat = !hasVoiceChat && (channel.flags.contains(.isCreator) || channel.hasPermission(.manageCalls)) + let canManage = channel.flags.contains(.isCreator) || channel.adminRights != nil + + let hasDiscussion: Bool switch channel.info { - case let .broadcast(info): - if !channel.flags.contains(.isCreator) { - displayLeave = true - } - if info.flags.contains(.hasDiscussionGroup) { - hasDiscussion = true - } - case .group: - if channel.flags.contains(.hasVoiceChat) { - hasVoiceChat = true - } - } - if !hasVoiceChat && (channel.flags.contains(.isCreator) || channel.hasPermission(.manageCalls)) { - canStartVoiceChat = true + case let .broadcast(info): + hasDiscussion = info.flags.contains(.hasDiscussionGroup) + case .group: + hasDiscussion = false } + + let canLeave: Bool switch channel.participationStatus { case .member: - break + canLeave = true default: - displayLeave = false + canLeave = false } + + let canViewStats: Bool + if let cachedChannelData = cachedData as? CachedChannelData { + canViewStats = cachedChannelData.flags.contains(.canViewStats) + } else { + canViewStats = false + } + if hasVoiceChat || canStartVoiceChat { result.append(.voiceChat) } @@ -1086,42 +1076,57 @@ func peerInfoHeaderButtons(peer: Peer?, cachedData: CachedPeerData?, isOpenedFro if hasDiscussion { result.append(.discussion) } - if isExpanded && hasDiscussion { - } else { - result.append(.search) - } - if displayLeave && result.count < 4 { + result.append(.search) + if canLeave { result.append(.leave) } + var canReport = true if channel.isVerified || channel.adminRights != nil || channel.flags.contains(.isCreator) { canReport = false } - if !canReport && !canViewStats { - displayMore = false - } - if displayMore { + + var hasMore = false + if canReport || canViewStats { + hasMore = true result.append(.more) } - } else if let group = peer as? TelegramGroup { - var hasVoiceChat = false - var canStartVoiceChat = false - if group.flags.contains(.hasVoiceChat) { - hasVoiceChat = true + if hasDiscussion && isExpanded && result.count >= 5 { + result.removeAll(where: { $0 == .search }) + if !hasMore { + hasMore = true + result.append(.more) + } } + + if canLeave && isExpanded && (canManage || result.count >= 5) { + result.removeAll(where: { $0 == .leave }) + if !hasMore { + hasMore = true + result.append(.more) + } + } + } else if let group = peer as? TelegramGroup { + let hasVoiceChat = group.flags.contains(.hasVoiceChat) + let canStartVoiceChat: Bool + if !hasVoiceChat { if case .creator = group.role { canStartVoiceChat = true } else if case let .admin(rights, _) = group.role, rights.rights.contains(.canManageCalls) { canStartVoiceChat = true + } else { + canStartVoiceChat = false } + } else { + canStartVoiceChat = false } - result.append(.mute) if hasVoiceChat || canStartVoiceChat { result.append(.voiceChat) } + result.append(.mute) result.append(.search) result.append(.more) } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 0fb3942751..f9042e2600 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -1119,8 +1119,11 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr let ItemDiscussionGroup = 3 let ItemSignMessages = 4 let ItemSignMessagesHelp = 5 + let ItemDeleteChannel = 5 - if channel.flags.contains(.isCreator) { + let isCreator = channel.flags.contains(.isCreator) + + if isCreator { let linkText: String if let _ = channel.username { linkText = presentationData.strings.Channel_Setup_TypePublic @@ -1132,7 +1135,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr })) } - if (channel.flags.contains(.isCreator) && (channel.username?.isEmpty ?? true)) || (!channel.flags.contains(.isCreator) && channel.adminRights?.rights.contains(.canInviteUsers) == true) { + if (isCreator && (channel.username?.isEmpty ?? true)) || (!channel.flags.contains(.isCreator) && channel.adminRights?.rights.contains(.canInviteUsers) == true) { let invitesText: String if let count = data.invitations?.count, count > 0 { invitesText = "\(count)" @@ -1144,7 +1147,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr })) } - if channel.flags.contains(.isCreator) || (channel.adminRights?.rights.contains(.canChangeInfo) == true) { + if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) { let discussionGroupTitle: String if let _ = data.cachedData as? CachedChannelData { if let peer = data.linkedDiscussionPeer { @@ -1165,7 +1168,7 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr })) } - if channel.flags.contains(.isCreator) || (channel.adminRights != nil && channel.hasPermission(.sendMessages)) { + if isCreator || (channel.adminRights != nil && channel.hasPermission(.sendMessages)) { let messagesShouldHaveSignatures: Bool switch channel.info { case let .broadcast(info): @@ -1178,6 +1181,12 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr })) items[.peerSettings]!.append(PeerInfoScreenCommentItem(id: ItemSignMessagesHelp, text: presentationData.strings.Channel_SignMessages_Help)) } + + if isCreator { + items[.peerActions]!.append(PeerInfoScreenActionItem(id: ItemDeleteChannel, text: presentationData.strings.ChannelInfo_DeleteChannel, color: .destructive, icon: nil, alignment: .natural, action: { + interaction.openDeletePeer() + })) + } case .group: let ItemUsername = 101 let ItemInviteLinks = 102 @@ -3702,56 +3711,30 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate switch channel.info { case .broadcast: - if channel.flags.contains(.isCreator) { + if case .member = channel.participationStatus, !headerButtons.contains(.leave) { if !items.isEmpty { items.append(.separator) } - items.append(.action(ContextMenuActionItem(text: presentationData.strings.ChannelInfo_DeleteChannel, textColor: .destructive, icon: { theme in - generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Channel_LeaveChannel, textColor: .destructive, icon: { theme in + generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Logout"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in f(.dismissWithoutContent) - self?.openDeletePeer() + self?.openLeavePeer() }))) - } else { - if case .member = channel.participationStatus, !headerButtons.contains(.leave) { - if !items.isEmpty { - items.append(.separator) - } - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Channel_LeaveChannel, textColor: .destructive, icon: { theme in - generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Logout"), color: theme.contextMenu.destructiveColor) - }, action: { [weak self] _, f in - f(.dismissWithoutContent) - - self?.openLeavePeer() - }))) - } } case .group: - if channel.flags.contains(.isCreator) { + if case .member = channel.participationStatus, !headerButtons.contains(.leave) { if !items.isEmpty { items.append(.separator) } - items.append(.action(ContextMenuActionItem(text: presentationData.strings.ChannelInfo_DeleteGroup, textColor: .destructive, icon: { theme in - generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) + items.append(.action(ContextMenuActionItem(text: presentationData.strings.Group_LeaveGroup, textColor: .destructive, icon: { theme in + generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Logout"), color: theme.contextMenu.destructiveColor) }, action: { [weak self] _, f in f(.dismissWithoutContent) - self?.openDeletePeer() + self?.openLeavePeer() }))) - } else { - if case .member = channel.participationStatus, !headerButtons.contains(.leave) { - if !items.isEmpty { - items.append(.separator) - } - items.append(.action(ContextMenuActionItem(text: presentationData.strings.Group_LeaveGroup, textColor: .destructive, icon: { theme in - generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Logout"), color: theme.contextMenu.destructiveColor) - }, action: { [weak self] _, f in - f(.dismissWithoutContent) - - self?.openLeavePeer() - }))) - } } } } else if let group = peer as? TelegramGroup { diff --git a/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift b/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift index 6475fb6c97..d9b2d34536 100644 --- a/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift +++ b/submodules/TelegramUI/Sources/PeerSelectionTextInputPanelNode.swift @@ -196,7 +196,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A self.loadTextInputNode() } - if let textInputNode = self.textInputNode, let _ = self.presentationInterfaceState { + if let textInputNode = self.textInputNode, let _ = self.presentationInterfaceState, !self.skipUpdate { self.updatingInputState = true var textColor: UIColor = .black @@ -693,6 +693,7 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A return false } + private var skipUpdate = false @objc func editableTextNodeDidUpdateText(_ editableTextNode: ASEditableTextNode) { if let textInputNode = self.textInputNode, let presentationInterfaceState = self.presentationInterfaceState { let baseFontSize = max(minInputFontSize, presentationInterfaceState.fontSize.baseDisplaySize) @@ -701,6 +702,8 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A let inputTextState = self.inputTextState + self.skipUpdate = true + self.interfaceInteraction?.updateTextInputStateAndMode({ _, inputMode in return (inputTextState, inputMode) }) self.interfaceInteraction?.updateInputLanguage({ _ in return textInputNode.textInputMode.primaryLanguage }) if self.isCaption, let presentationInterfaceState = self.presentationInterfaceState { @@ -712,6 +715,8 @@ class PeerSelectionTextInputPanelNode: ChatInputPanelNode, TGCaptionPanelView, A self.updateTextNodeText(animated: true) self.updateCounterTextNode(transition: .immediate) + + self.skipUpdate = false } }