mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-09 03:20:48 +00:00
Voice Chat fixes
This commit is contained in:
parent
73657fc155
commit
67ac8b10c3
@ -6263,3 +6263,6 @@ Sorry for the inconvenience.";
|
||||
"VoiceChat.CancelSpeakRequest" = "Cancel Request to Speak";
|
||||
|
||||
"VoiceChat.RemovePeerConfirmationChannel" = "Are you sure you want to remove %@ from the channel?";
|
||||
"VoiceChat.RemoveAndBanPeerConfirmation" = "“Do you want to remove %1$@ from the voice chat and ban them in %2$@?";
|
||||
|
||||
"Notification.VoiceChatStartedChannel" = "Voice chat started";
|
||||
|
21
submodules/CameraUI/Sources/CameraModeNode.swift
Normal file
21
submodules/CameraUI/Sources/CameraModeNode.swift
Normal file
@ -0,0 +1,21 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
import SwiftSignalKit
|
||||
|
||||
final class CameraModeNode: ASDisplayNode {
|
||||
enum Mode {
|
||||
case photo
|
||||
case video
|
||||
case scan
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
func update(mode: Mode, transition: ContainedViewLayoutTransition) {
|
||||
|
||||
}
|
||||
}
|
@ -1339,17 +1339,21 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
}
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
self.chatListDisplayNode.containerNode.updateEnableAdjacentFilterLoading(false)
|
||||
|
||||
func dismissAllUndoControllers() {
|
||||
self.forEachController({ controller in
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
controller.dismissWithCommitAction()
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
override public func viewWillDisappear(_ animated: Bool) {
|
||||
super.viewWillDisappear(animated)
|
||||
|
||||
self.chatListDisplayNode.containerNode.updateEnableAdjacentFilterLoading(false)
|
||||
|
||||
self.dismissAllUndoControllers()
|
||||
|
||||
self.featuredFiltersDisposable.set(nil)
|
||||
}
|
||||
|
@ -403,6 +403,8 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||
private let filterBecameEmpty: (ChatListFilter?) -> Void
|
||||
private let filterEmptyAction: (ChatListFilter?) -> Void
|
||||
|
||||
fileprivate var onFilterSwitch: (() -> Void)?
|
||||
|
||||
private var presentationData: PresentationData
|
||||
|
||||
private var itemNodes: [ChatListFilterTabEntryId: ChatListContainerItemNode] = [:]
|
||||
@ -607,6 +609,8 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||
@objc private func panGesture(_ recognizer: UIPanGestureRecognizer) {
|
||||
switch recognizer.state {
|
||||
case .began:
|
||||
self.onFilterSwitch?()
|
||||
|
||||
self.transitionFractionOffset = 0.0
|
||||
if let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, isReorderingFilters, isEditing) = self.validLayout, let itemNode = self.itemNodes[self.selectedId] {
|
||||
for (id, itemNode) in self.itemNodes {
|
||||
@ -792,6 +796,7 @@ final class ChatListContainerNode: ASDisplayNode, UIGestureRecognizerDelegate {
|
||||
guard let (layout, navigationBarHeight, visualNavigationHeight, cleanNavigationBarHeight, isReorderingFilters, isEditing) = self.validLayout else {
|
||||
return
|
||||
}
|
||||
self.onFilterSwitch?()
|
||||
if id != self.selectedId, let index = self.availableFilters.firstIndex(where: { $0.id == id }) {
|
||||
if let itemNode = self.itemNodes[id] {
|
||||
self.selectedId = id
|
||||
@ -1057,6 +1062,12 @@ final class ChatListControllerNode: ASDisplayNode {
|
||||
}
|
||||
strongSelf.emptyListAction?()
|
||||
}
|
||||
|
||||
self.containerNode.onFilterSwitch = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controller?.dismissAllUndoControllers()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
|
@ -142,14 +142,14 @@ private final class DeleteChatPeerActionSheetItemNode: ActionSheetItemNode {
|
||||
text?.0 += "\n\n\(strings.Conversation_AlsoClearCacheTitle)"
|
||||
}
|
||||
case .removeFromGroup:
|
||||
text = strings.VoiceChat_RemovePeerConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder))
|
||||
text = strings.VoiceChat_RemoveAndBanPeerConfirmation(peer.displayTitle(strings: strings, displayOrder: nameOrder), chatPeer.displayTitle(strings: strings, displayOrder: nameOrder))
|
||||
case .removeFromChannel:
|
||||
text = strings.VoiceChat_RemovePeerConfirmationChannel(peer.displayTitle(strings: strings, displayOrder: nameOrder))
|
||||
default:
|
||||
break
|
||||
}
|
||||
if let text = text {
|
||||
var formattedAttributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: textFont, textColor: theme.primaryTextColor))
|
||||
let formattedAttributedText = NSMutableAttributedString(attributedString: NSAttributedString(string: text.0, font: textFont, textColor: theme.primaryTextColor))
|
||||
for (_, range) in text.1 {
|
||||
formattedAttributedText.addAttribute(.font, value: boldFont, range: range)
|
||||
}
|
||||
|
@ -346,7 +346,13 @@ final class JoinLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
}
|
||||
}
|
||||
|
||||
private var animatingOut = false
|
||||
func animateOut(completion: (() -> Void)? = nil) {
|
||||
guard !self.animatingOut else {
|
||||
return
|
||||
}
|
||||
self.animatingOut = true
|
||||
|
||||
if self.contentNode != nil {
|
||||
var dimCompleted = false
|
||||
var offsetCompleted = false
|
||||
@ -354,6 +360,7 @@ final class JoinLinkPreviewControllerNode: ViewControllerTracingNode, UIScrollVi
|
||||
let internalCompletion: () -> Void = { [weak self] in
|
||||
if let strongSelf = self, dimCompleted && offsetCompleted {
|
||||
strongSelf.dismiss?()
|
||||
strongSelf.animatingOut = true
|
||||
}
|
||||
completion?()
|
||||
}
|
||||
|
@ -639,7 +639,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
}
|
||||
}
|
||||
|
||||
var animatingOut = false
|
||||
private var animatingOut = false
|
||||
var outCompletion: (() -> Void)?
|
||||
func animateOut(shared: Bool, completion: @escaping () -> Void) {
|
||||
guard !self.animatingOut else {
|
||||
|
@ -445,6 +445,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
private var markedAsCanBeRemoved = false
|
||||
|
||||
private let wasRemoved = Promise<Bool>(false)
|
||||
private var leaving = false
|
||||
|
||||
private var stateValue: PresentationGroupCallState {
|
||||
didSet {
|
||||
@ -1391,7 +1392,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
}
|
||||
}
|
||||
|
||||
if !participants.contains(where: { $0.peer.id == myPeerId }) {
|
||||
if !participants.contains(where: { $0.peer.id == myPeerId }) && !strongSelf.leaving {
|
||||
if let (myPeer, cachedData) = myPeerAndCachedData {
|
||||
let about: String?
|
||||
if let cachedData = cachedData as? CachedUserData {
|
||||
@ -1444,17 +1445,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
return
|
||||
}
|
||||
let presentationData = strongSelf.accountContext.sharedContext.currentPresentationData.with { $0 }
|
||||
if hasGroupCallOnScreen, let groupCallController = strongSelf.accountContext.sharedContext.currentGroupCallController {
|
||||
var animateInAsReplacement = false
|
||||
groupCallController.forEachController { c in
|
||||
if let c = c as? UndoOverlayController {
|
||||
animateInAsReplacement = true
|
||||
c.dismiss()
|
||||
}
|
||||
return true
|
||||
}
|
||||
groupCallController.present(UndoOverlayController(presentationData: presentationData, content: .voiceChatCanSpeak(text: presentationData.strings.VoiceChat_YouCanNowSpeak), elevatedLayout: false, animateInAsReplacement: animateInAsReplacement, action: { _ in return true }), in: .current)
|
||||
} else {
|
||||
if !hasGroupCallOnScreen {
|
||||
let title: String?
|
||||
if let voiceChatTitle = strongSelf.stateValue.title {
|
||||
title = voiceChatTitle
|
||||
@ -1760,6 +1751,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
||||
}
|
||||
|
||||
public func leave(terminateIfPossible: Bool) -> Signal<Bool, NoError> {
|
||||
self.leaving = true
|
||||
if let callInfo = self.internalState.callInfo, let localSsrc = self.currentLocalSsrc {
|
||||
if terminateIfPossible {
|
||||
self.leaveDisposable.set((stopGroupCall(account: self.account, peerId: self.peerId, callId: callInfo.id, accessHash: callInfo.accessHash)
|
||||
|
@ -1410,7 +1410,17 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode {
|
||||
|
||||
func playRandomAnimation() {
|
||||
if case .hand = self.iconState {
|
||||
if let animationName = ["VoiceHand_1", "VoiceHand_2", "VoiceHand_3", "VoiceHand_4", "VoiceHand_5", "VoiceHand_6", "VoiceHand_7"].randomElement() {
|
||||
var useTiredAnimation = false
|
||||
let val = Float.random(in: 0.0..<1.0)
|
||||
if val <= 0.01 {
|
||||
useTiredAnimation = true
|
||||
}
|
||||
|
||||
let normalAnimations = ["VoiceHand_1", "VoiceHand_2", "VoiceHand_3", "VoiceHand_4", "VoiceHand_7"]
|
||||
let tiredAnimations = ["VoiceHand_5", "VoiceHand_6"]
|
||||
let animations = useTiredAnimation ? tiredAnimations : normalAnimations
|
||||
|
||||
if let animationName = animations.randomElement() {
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local(animationName)))
|
||||
}
|
||||
}
|
||||
|
@ -1270,12 +1270,7 @@ public final class VoiceChatController: ViewController {
|
||||
let actionSheet = ActionSheetController(presentationData: strongSelf.presentationData.withUpdated(theme: strongSelf.darkTheme))
|
||||
var items: [ActionSheetItem] = []
|
||||
|
||||
var action: DeleteChatPeerAction = .removeFromGroup
|
||||
if let chatPeer = chatPeer as? TelegramChannel, case .broadcast = chatPeer.info {
|
||||
action = .removeFromChannel
|
||||
}
|
||||
|
||||
items.append(DeleteChatPeerActionSheetItem(context: strongSelf.context, peer: peer, chatPeer: peer, action: action, strings: strongSelf.presentationData.strings, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder))
|
||||
items.append(DeleteChatPeerActionSheetItem(context: strongSelf.context, peer: peer, chatPeer: chatPeer, action: .removeFromGroup, strings: strongSelf.presentationData.strings, nameDisplayOrder: strongSelf.presentationData.nameDisplayOrder))
|
||||
|
||||
items.append(ActionSheetButtonItem(title: strongSelf.presentationData.strings.VoiceChat_RemovePeerRemove, color: .destructive, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
|
@ -96,9 +96,37 @@ public final class VoiceChatJoinScreen: ViewController {
|
||||
}
|
||||
|> castError(GetCurrentGroupCallError.self)
|
||||
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), signal, cachedGroupCallDisplayAsAvailablePeers(account: context.account, peerId: peerId) |> castError(GetCurrentGroupCallError.self), cachedData).start(next: { [weak self] peerAndCall, availablePeers, cachedData in
|
||||
let currentGroupCallId: Signal<Int64?, GetCurrentGroupCallError>
|
||||
if let callManager = context.sharedContext.callManager {
|
||||
currentGroupCallId = callManager.currentGroupCallSignal
|
||||
|> castError(GetCurrentGroupCallError.self)
|
||||
|> mapToSignal { call -> Signal<Int64?, GetCurrentGroupCallError> in
|
||||
if let call = call {
|
||||
return call.summaryState
|
||||
|> castError(GetCurrentGroupCallError.self)
|
||||
|> map { state -> Int64? in
|
||||
return state?.info?.id
|
||||
}
|
||||
|> filter { id in
|
||||
return id != nil
|
||||
}
|
||||
} else {
|
||||
return .single(nil)
|
||||
}
|
||||
}
|
||||
|> take(1)
|
||||
} else {
|
||||
currentGroupCallId = .single(nil)
|
||||
}
|
||||
|
||||
self.disposable.set(combineLatest(queue: Queue.mainQueue(), signal, cachedGroupCallDisplayAsAvailablePeers(account: context.account, peerId: peerId) |> castError(GetCurrentGroupCallError.self), cachedData, currentGroupCallId).start(next: { [weak self] peerAndCall, availablePeers, cachedData, currentGroupCallId in
|
||||
if let strongSelf = self {
|
||||
if let (peer, call) = peerAndCall {
|
||||
if call.info.id == currentGroupCallId {
|
||||
strongSelf.context.sharedContext.navigateToCurrentCall()
|
||||
return
|
||||
}
|
||||
|
||||
var defaultJoinAsPeerId: PeerId?
|
||||
if let cachedData = cachedData as? CachedChannelData {
|
||||
defaultJoinAsPeerId = cachedData.callJoinPeerId
|
||||
@ -481,13 +509,20 @@ public final class VoiceChatJoinScreen: ViewController {
|
||||
}
|
||||
}
|
||||
|
||||
private var animatingOut = false
|
||||
func animateOut(completion: (() -> Void)? = nil) {
|
||||
guard !self.animatingOut else {
|
||||
return
|
||||
}
|
||||
self.animatingOut = true
|
||||
|
||||
if self.contentNode != nil {
|
||||
var dimCompleted = false
|
||||
var offsetCompleted = false
|
||||
|
||||
let internalCompletion: () -> Void = { [weak self] in
|
||||
if let strongSelf = self, dimCompleted && offsetCompleted {
|
||||
strongSelf.animatingOut = false
|
||||
strongSelf.dismiss?()
|
||||
}
|
||||
completion?()
|
||||
|
@ -243,7 +243,6 @@ private func installRemoteStickerPacks(network: Network, infos: [StickerPackColl
|
||||
}
|
||||
|
||||
private func removeRemoteStickerPacks(network: Network, infos: [StickerPackCollectionInfo]) -> Signal<Void, NoError> {
|
||||
var signals: [Signal<Void, NoError>] = []
|
||||
if infos.count > 0 {
|
||||
if infos.count > 1 {
|
||||
return network.request(Api.functions.messages.toggleStickerSets(flags: 1 << 0, stickersets: infos.map { .inputStickerSetID(id: $0.id.id, accessHash: $0.accessHash) }))
|
||||
@ -267,7 +266,6 @@ private func removeRemoteStickerPacks(network: Network, infos: [StickerPackColle
|
||||
}
|
||||
|
||||
private func archiveRemoteStickerPacks(network: Network, infos: [StickerPackCollectionInfo]) -> Signal<Void, NoError> {
|
||||
var signals: [Signal<Void, NoError>] = []
|
||||
if infos.count > 0 {
|
||||
if infos.count > 1 {
|
||||
return network.request(Api.functions.messages.toggleStickerSets(flags: 1 << 1, stickersets: infos.map { .inputStickerSetID(id: $0.id.id, accessHash: $0.accessHash) }))
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -451,9 +451,14 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
||||
let titleString = strings.Notification_VoiceChatEnded(callDurationString(strings: strings, value: duration)).0
|
||||
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
|
||||
} else {
|
||||
let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)]
|
||||
let titleString = strings.Notification_VoiceChatStarted(authorName)
|
||||
attributedString = addAttributesToStringWithRanges(titleString, body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: attributePeerIds))
|
||||
if message.author?.id.namespace == Namespaces.Peer.CloudChannel {
|
||||
let titleString = strings.Notification_VoiceChatStartedChannel
|
||||
attributedString = NSAttributedString(string: titleString, font: titleFont, textColor: primaryTextColor)
|
||||
} else {
|
||||
let attributePeerIds: [(Int, PeerId?)] = [(0, message.author?.id)]
|
||||
let titleString = strings.Notification_VoiceChatStarted(authorName)
|
||||
attributedString = addAttributesToStringWithRanges(titleString, body: bodyAttributes, argumentAttributes: peerMentionsAttributes(primaryTextColor: primaryTextColor, peerIds: attributePeerIds))
|
||||
}
|
||||
}
|
||||
case let .customText(text, entities):
|
||||
attributedString = stringWithAppliedEntities(text, entities: entities, baseColor: primaryTextColor, linkColor: primaryTextColor, baseFont: titleFont, linkFont: titleBoldFont, boldFont: titleBoldFont, italicFont: titleFont, boldItalicFont: titleBoldFont, fixedFont: titleFont, blockQuoteFont: titleFont, underlineLinks: false)
|
||||
|
File diff suppressed because one or more lines are too long
Binary file not shown.
@ -70,7 +70,7 @@ private class ChatHistoryListSelectionRecognizer: UIPanGestureRecognizer {
|
||||
let dy = v1.y - v2.y
|
||||
return sqrt(dx * dx + dy * dy)
|
||||
}
|
||||
if distance(firstLocation, secondLocation) > 100 {
|
||||
if distance(firstLocation, secondLocation) > 70 {
|
||||
self.state = .failed
|
||||
}
|
||||
}
|
||||
|
@ -1388,6 +1388,15 @@ final class PeerInfoAvatarTransformContainerNode: ASDisplayNode {
|
||||
overrideImage = AvatarNodeImageOverride.none
|
||||
item = nil
|
||||
}
|
||||
|
||||
if let _ = overrideImage {
|
||||
self.containerNode.isGestureEnabled = false
|
||||
} else if peer.profileImageRepresentations.isEmpty {
|
||||
self.containerNode.isGestureEnabled = false
|
||||
} else {
|
||||
self.containerNode.isGestureEnabled = false
|
||||
}
|
||||
|
||||
self.avatarNode.setPeer(context: self.context, theme: theme, peer: peer, overrideImage: overrideImage, synchronousLoad: self.isFirstAvatarLoading, displayDimensions: CGSize(width: avatarSize, height: avatarSize), storeUnrounded: true)
|
||||
self.isFirstAvatarLoading = false
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user