diff --git a/TelegramUI/ChannelMembersController.swift b/TelegramUI/ChannelMembersController.swift index 34a7af8128..ff949c1e5e 100644 --- a/TelegramUI/ChannelMembersController.swift +++ b/TelegramUI/ChannelMembersController.swift @@ -11,8 +11,8 @@ private final class ChannelMembersControllerArguments { let setPeerIdWithRevealedOptions: (PeerId?, PeerId?) -> Void let removePeer: (PeerId) -> Void let openPeer: (Peer) -> Void - let inviteViaLink:()->Void - init(account: Account, addMember: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (Peer) -> Void, inviteViaLink:@escaping()->Void) { + let inviteViaLink: ()->Void + init(account: Account, addMember: @escaping () -> Void, setPeerIdWithRevealedOptions: @escaping (PeerId?, PeerId?) -> Void, removePeer: @escaping (PeerId) -> Void, openPeer: @escaping (Peer) -> Void, inviteViaLink: @escaping()->Void) { self.account = account self.addMember = addMember self.setPeerIdWithRevealedOptions = setPeerIdWithRevealedOptions @@ -246,7 +246,6 @@ private func ChannelMembersControllerEntries(account: Account, presentationData: var entries: [ChannelMembersEntry] = [] if let participants = participants { - var canAddMember: Bool = false if let peer = view.peers[view.peerId] as? TelegramChannel { canAddMember = peer.hasAdminRights(.canInviteUsers) @@ -254,7 +253,9 @@ private func ChannelMembersControllerEntries(account: Account, presentationData: if canAddMember { entries.append(.addMember(presentationData.theme, presentationData.strings.Channel_Members_AddMembers)) - entries.append(.inviteLink(presentationData.theme, presentationData.strings.Channel_Members_InviteLink)) + if let peer = view.peers[view.peerId] as? TelegramChannel, peer.addressName == nil { + entries.append(.inviteLink(presentationData.theme, presentationData.strings.Channel_Members_InviteLink)) + } entries.append(.addMemberInfo(presentationData.theme, presentationData.strings.Channel_Members_AddMembersHelp)) } diff --git a/TelegramUI/ChatListItem.swift b/TelegramUI/ChatListItem.swift index 1850ed581a..2cb3d5ea10 100644 --- a/TelegramUI/ChatListItem.swift +++ b/TelegramUI/ChatListItem.swift @@ -572,7 +572,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode { } if let message = message, message.author?.id == account.peerId && !hasDraft { - if message.flags.isSending { + if message.flags.isSending && !message.isSentOrAcknowledged { statusImage = PresentationResourcesChatList.pendingImage(item.presentationData.theme) } else { if let combinedReadState = combinedReadState, combinedReadState.isOutgoingMessageIndexRead(MessageIndex(message)) { diff --git a/TelegramUI/ChatMessageAttachedContentNode.swift b/TelegramUI/ChatMessageAttachedContentNode.swift index f65e626916..2d3fab4be0 100644 --- a/TelegramUI/ChatMessageAttachedContentNode.swift +++ b/TelegramUI/ChatMessageAttachedContentNode.swift @@ -400,7 +400,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } else { if message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if message.flags.isSending { + } else if message.flags.isSending && !message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: messageRead)) @@ -482,7 +482,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode { } else { statusType = .BubbleOutgoing(.Failed) } - } else if message.flags.isSending { + } else if message.flags.isSending && !message.isSentOrAcknowledged { if imageMode { statusType = .ImageOutgoing(.Sending) } else { diff --git a/TelegramUI/ChatMessageBubbleItemNode.swift b/TelegramUI/ChatMessageBubbleItemNode.swift index fa3f4c429f..e7ca1ffc83 100644 --- a/TelegramUI/ChatMessageBubbleItemNode.swift +++ b/TelegramUI/ChatMessageBubbleItemNode.swift @@ -697,7 +697,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView { } else { if message.flags.contains(.Failed) { statusType = .ImageOutgoing(.Failed) - } else if message.flags.isSending { + } else if message.flags.isSending && !message.isSentOrAcknowledged { statusType = .ImageOutgoing(.Sending) } else { statusType = .ImageOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageContactBubbleContentNode.swift b/TelegramUI/ChatMessageContactBubbleContentNode.swift index ceb1071bfa..ad7585b2f5 100644 --- a/TelegramUI/ChatMessageContactBubbleContentNode.swift +++ b/TelegramUI/ChatMessageContactBubbleContentNode.swift @@ -161,7 +161,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode { } else { if item.message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageFileBubbleContentNode.swift b/TelegramUI/ChatMessageFileBubbleContentNode.swift index 7a96904e50..bc0d3b9bf6 100644 --- a/TelegramUI/ChatMessageFileBubbleContentNode.swift +++ b/TelegramUI/ChatMessageFileBubbleContentNode.swift @@ -48,7 +48,7 @@ class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode { } else { if item.message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift b/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift index eefe7aa4cd..1d8491b638 100644 --- a/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift +++ b/TelegramUI/ChatMessageInteractiveInstantVideoNode.swift @@ -208,7 +208,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { case .free: if item.message.flags.contains(.Failed) { statusType = .FreeOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .FreeOutgoing(.Sending) } else { statusType = .FreeOutgoing(.Sent(read: item.read)) @@ -216,7 +216,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode { case .bubble: if item.message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageItem.swift b/TelegramUI/ChatMessageItem.swift index 46bfeb87ba..06abdb8875 100644 --- a/TelegramUI/ChatMessageItem.swift +++ b/TelegramUI/ChatMessageItem.swift @@ -435,7 +435,7 @@ public final class ChatMessageItem: ListViewItem, CustomStringConvertible { apply(animation) if let nodeValue = node() as? ChatMessageItemView { nodeValue.updateSelectionState(animated: false) - nodeValue.updateHighlightedState(animated: false) + nodeValue.updateHighlightedState(animated: false) } }) } diff --git a/TelegramUI/ChatMessageMapBubbleContentNode.swift b/TelegramUI/ChatMessageMapBubbleContentNode.swift index 62778f0e50..235a42bf80 100644 --- a/TelegramUI/ChatMessageMapBubbleContentNode.swift +++ b/TelegramUI/ChatMessageMapBubbleContentNode.swift @@ -199,7 +199,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { } else { if item.message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: item.read)) @@ -211,7 +211,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode { } else { if item.message.flags.contains(.Failed) { statusType = .ImageOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .ImageOutgoing(.Sending) } else { statusType = .ImageOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageMediaBubbleContentNode.swift b/TelegramUI/ChatMessageMediaBubbleContentNode.swift index 1217f5abef..961a3d12dd 100644 --- a/TelegramUI/ChatMessageMediaBubbleContentNode.swift +++ b/TelegramUI/ChatMessageMediaBubbleContentNode.swift @@ -129,7 +129,7 @@ class ChatMessageMediaBubbleContentNode: ChatMessageBubbleContentNode { } else { if item.message.flags.contains(.Failed) { statusType = .ImageOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .ImageOutgoing(.Sending) } else { statusType = .ImageOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageStickerItemNode.swift b/TelegramUI/ChatMessageStickerItemNode.swift index 2c23168158..91897e98e7 100644 --- a/TelegramUI/ChatMessageStickerItemNode.swift +++ b/TelegramUI/ChatMessageStickerItemNode.swift @@ -201,7 +201,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView { } else { if item.message.flags.contains(.Failed) { statusType = .FreeOutgoing(.Failed) - } else if item.message.flags.isSending { + } else if item.message.flags.isSending && !item.message.isSentOrAcknowledged { statusType = .FreeOutgoing(.Sending) } else { statusType = .FreeOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/ChatMessageTextBubbleContentNode.swift b/TelegramUI/ChatMessageTextBubbleContentNode.swift index 9aee6d5f2a..d3a7f48999 100644 --- a/TelegramUI/ChatMessageTextBubbleContentNode.swift +++ b/TelegramUI/ChatMessageTextBubbleContentNode.swift @@ -97,7 +97,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode { } else { if message.flags.contains(.Failed) { statusType = .BubbleOutgoing(.Failed) - } else if message.flags.isSending { + } else if message.flags.isSending && !message.isSentOrAcknowledged { statusType = .BubbleOutgoing(.Sending) } else { statusType = .BubbleOutgoing(.Sent(read: item.read)) diff --git a/TelegramUI/GroupInfoController.swift b/TelegramUI/GroupInfoController.swift index 6dfac7a5a4..299858cb84 100644 --- a/TelegramUI/GroupInfoController.swift +++ b/TelegramUI/GroupInfoController.swift @@ -751,8 +751,13 @@ private func groupInfoEntries(account: Account, presentationData: PresentationDa } if let editingState = state.editingState { - if let group = view.peers[view.peerId] as? TelegramGroup, case .creator = group.role { - entries.append(.adminManagement(presentationData.theme, presentationData.strings.GroupInfo_ChatAdmins)) + if let group = view.peers[view.peerId] as? TelegramGroup { + if case .creator = group.role { + entries.append(.adminManagement(presentationData.theme, presentationData.strings.GroupInfo_ChatAdmins)) + } + + entries.append(GroupInfoEntry.notifications(presentationData.theme, presentationData.strings.GroupInfo_Notifications, notificationsText)) + entries.append(GroupInfoEntry.notificationSound(presentationData.theme, presentationData.strings.GroupInfo_Sound, localizedPeerNotificationSoundString(strings: presentationData.strings, sound: peerNotificationSettings.messageSound, default: globalNotificationSettings.effective.groupChats.sound))) } else if let cachedChannelData = view.cachedData as? CachedChannelData { if isCreator { entries.append(GroupInfoEntry.groupTypeSetup(presentationData.theme, presentationData.strings.GroupInfo_GroupType, isPublic ? presentationData.strings.Channel_Setup_TypePublic : presentationData.strings.Channel_Setup_TypePrivate)) diff --git a/TelegramUI/LegacyCamera.swift b/TelegramUI/LegacyCamera.swift index 8b437294ab..38ef31734c 100644 --- a/TelegramUI/LegacyCamera.swift +++ b/TelegramUI/LegacyCamera.swift @@ -24,6 +24,26 @@ func presentedLegacyCamera(account: Account, peer: Peer, cameraView: TGAttachmen controller = TGCameraController() } + if #available(iOSApplicationExtension 10.0, *) { + } else { + controller.customPresentOverlayController = { [weak legacyController] overlayController in + guard let legacyController = legacyController, let overlayController = overlayController else { + return + } + + let presentationData = account.telegramApplicationContext.currentPresentationData.with { $0 } + let overlayLegacyController = LegacyController(presentation: .custom, theme: presentationData.theme) + overlayLegacyController.supportedOrientations = ViewControllerSupportedOrientations(regularSize: .portrait, compactSize: .portrait) + overlayLegacyController.statusBar.statusBarStyle = .Hide + overlayLegacyController.bind(controller: overlayController) + overlayController.customDismissSelf = { [weak overlayLegacyController] in + overlayLegacyController?.dismiss() + } + + legacyController.present(overlayLegacyController, in: .window(.root)) + } + } + controller.isImportant = true controller.shouldStoreCapturedAssets = saveCapturedPhotos && !isSecretChat controller.allowCaptions = true diff --git a/TelegramUI/ManagedAudioSession.swift b/TelegramUI/ManagedAudioSession.swift index 7e3dfb05ee..f0f35957fa 100644 --- a/TelegramUI/ManagedAudioSession.swift +++ b/TelegramUI/ManagedAudioSession.swift @@ -615,6 +615,7 @@ public final class ManagedAudioSession { } private func setupOutputMode(_ outputMode: AudioSessionOutputMode, type: ManagedAudioSessionType) throws { + print("ManagedAudioSession setup \(outputMode) for \(type)") var resetToBuiltin = false switch outputMode { case .system: @@ -625,6 +626,16 @@ public final class ManagedAudioSession { resetToBuiltin = true case .speaker: try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker) + if type == .voiceCall { + if let routes = AVAudioSession.sharedInstance().availableInputs { + for route in routes { + if route.portType == AVAudioSessionPortBuiltInMic { + let _ = try? AVAudioSession.sharedInstance().setPreferredInput(route) + break + } + } + } + } case .headphones: break case let .port(port): diff --git a/TelegramUI/NetworkStatusTitleView.swift b/TelegramUI/NetworkStatusTitleView.swift index 885ab77f5a..7af8a99cd5 100644 --- a/TelegramUI/NetworkStatusTitleView.swift +++ b/TelegramUI/NetworkStatusTitleView.swift @@ -161,6 +161,9 @@ final class NetworkStatusTitleView: UIView, NavigationBarTitleView, NavigationBa alignedTitleWidth -= 20.0 proxyPadding += 39.0 } + if !self.lockView.isHidden { + maxTitleWidth -= 10.0 + } let titleSize = self.titleNode.updateLayout(CGSize(width: max(1.0, maxTitleWidth), height: size.height)) diff --git a/TelegramUI/PresenceStrings.swift b/TelegramUI/PresenceStrings.swift index d42dcbdd92..6d3a355691 100644 --- a/TelegramUI/PresenceStrings.swift +++ b/TelegramUI/PresenceStrings.swift @@ -89,7 +89,7 @@ func stringForUserPresence(strings: PresentationStrings, day: RelativeTimestampF case .today: dayString = strings.LastSeen_AtDate(strings.Time_TodayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0).0 case .yesterday: - dayString = strings.LastSeen_AtDate(strings.Time_YesterdayAt(stringForShortTimestamp(hours: hours, minutes: minutes, dateTimeFormat: dateTimeFormat)).0).0 + dayString = strings.LastSeen_YesterdayAt(stringForShortTimestamp(hours: hours, minutes: minutes, timeFormat: timeFormat)).0 } return dayString } @@ -281,7 +281,8 @@ func stringAndActivityForUserPresence(strings: PresentationStrings, dateTimeForm if dayDifference == 0 || dayDifference == -1 { let day: RelativeTimestampFormatDay if dayDifference == 0 { - day = .today + let minutes = difference / (60 * 60) + return (strings.LastSeen_HoursAgo(minutes), false) } else { day = .yesterday } diff --git a/TelegramUI/PresentationCall.swift b/TelegramUI/PresentationCall.swift index 9ca4a38fe1..87c50303b0 100644 --- a/TelegramUI/PresentationCall.swift +++ b/TelegramUI/PresentationCall.swift @@ -29,7 +29,6 @@ private final class PresentationCallToneRenderer { self.queue = queue self.tone = tone - let data = presentationCallToneData(tone) var controlImpl: ((MediaPlayerAudioSessionCustomControl) -> Disposable)? @@ -52,18 +51,28 @@ private final class PresentationCallToneRenderer { let toneDataOffset = Atomic(value: 0) - let toneDataMaxOffset: Int? - if let loopCount = tone.loopCount { - toneDataMaxOffset = (data?.count ?? 0) * loopCount - } else { - toneDataMaxOffset = nil - } + let toneData = Atomic(value: nil) self.toneRenderer.beginRequestingFrames(queue: DispatchQueue.global(), takeFrame: { + var data = toneData.with { $0 } + if data == nil { + data = presentationCallToneData(tone) + if data != nil { + let _ = toneData.swap(data) + } + } + guard let toneData = data else { return .finished } + let toneDataMaxOffset: Int? + if let loopCount = tone.loopCount { + toneDataMaxOffset = (data?.count ?? 0) * loopCount + } else { + toneDataMaxOffset = nil + } + let frameSize = 44100 var takeOffset: Int? diff --git a/TelegramUI/SecureIdDocumentFormControllerNode.swift b/TelegramUI/SecureIdDocumentFormControllerNode.swift index 62afebdf6d..1816b1ff0a 100644 --- a/TelegramUI/SecureIdDocumentFormControllerNode.swift +++ b/TelegramUI/SecureIdDocumentFormControllerNode.swift @@ -2189,6 +2189,9 @@ final class SecureIdDocumentFormControllerNode: FormControllerNode