Voice Chat Fixes

This commit is contained in:
Ilya Laktyushin 2021-03-15 02:20:52 +04:00
parent e53c6edf2e
commit ee50e2fa8d
4 changed files with 108 additions and 23 deletions

View File

@ -413,6 +413,7 @@ public final class VoiceChatController: ViewController {
var canManageCall: Bool
var volume: Int32?
var raisedHand: Bool
var displayRaisedHandStatus: Bool
var stableId: PeerId {
return self.peer.id
@ -455,6 +456,9 @@ public final class VoiceChatController: ViewController {
if lhs.raisedHand != rhs.raisedHand {
return false
}
if lhs.displayRaisedHandStatus != rhs.displayRaisedHandStatus {
return false
}
return true
}
@ -584,7 +588,11 @@ public final class VoiceChatController: ViewController {
text = .text(presentationData.strings.VoiceChat_StatusInvited, .generic)
icon = .invite(true)
case .raisedHand:
text = .text(presentationData.strings.VoiceChat_StatusWantsToSpeak, .accent)
if let about = peerEntry.about, !about.isEmpty && !peerEntry.displayRaisedHandStatus {
text = .text(about, .generic)
} else {
text = .text(presentationData.strings.VoiceChat_StatusWantsToSpeak, .accent)
}
icon = .wantsToSpeak
}
@ -713,6 +721,15 @@ public final class VoiceChatController: ViewController {
private let displayAsPeersPromise = Promise<[FoundPeer]>([])
private let inviteLinksPromise = Promise<GroupCallInviteLinks?>(nil)
private var raisedHandDisplayDisposables: [PeerId: Disposable] = [:]
private var displayedRaisedHands = Set<PeerId>() {
didSet {
self.displayedRaisedHandsPromise.set(self.displayedRaisedHands)
}
}
private let displayedRaisedHandsPromise = ValuePromise<Set<PeerId>>(Set())
private var currentDominantSpeakerWithVideo: (PeerId, UInt32)?
init(controller: VoiceChatController, sharedContext: SharedAccountContext, call: PresentationGroupCall) {
@ -2921,16 +2938,40 @@ public final class VoiceChatController: ViewController {
if member.hasRaiseHand && !(member.muteState?.canUnmute ?? false) {
memberState = .raisedHand
memberMuteState = member.muteState
} else if member.peer.id == self.callState?.myPeerId {
if muteState == nil {
memberState = speakingPeers.contains(member.peer.id) ? .speaking : .listening
} else {
memberState = .listening
memberMuteState = member.muteState
if self.raisedHandDisplayDisposables[member.peer.id] == nil {
var displayedRaisedHands = self.displayedRaisedHands
displayedRaisedHands.insert(member.peer.id)
self.displayedRaisedHands = displayedRaisedHands
let signal: Signal<Never, NoError> = Signal.complete() |> delay(3.0, queue: Queue.mainQueue())
self.raisedHandDisplayDisposables[member.peer.id] = signal.start(completed: { [weak self] in
if let strongSelf = self {
var displayedRaisedHands = strongSelf.displayedRaisedHands
displayedRaisedHands.remove(member.peer.id)
strongSelf.displayedRaisedHands = displayedRaisedHands
strongSelf.updateMembers(muteState: strongSelf.effectiveMuteState, callMembers: strongSelf.currentCallMembers ?? ([], nil), invitedPeers: strongSelf.currentInvitedPeers ?? [], speakingPeers: strongSelf.currentSpeakingPeers ?? Set())
}
})
}
} else {
memberState = speakingPeers.contains(member.peer.id) ? .speaking : .listening
memberMuteState = member.muteState
if member.peer.id == self.callState?.myPeerId {
if muteState == nil {
memberState = speakingPeers.contains(member.peer.id) ? .speaking : .listening
} else {
memberState = .listening
memberMuteState = member.muteState
}
} else {
memberState = speakingPeers.contains(member.peer.id) ? .speaking : .listening
memberMuteState = member.muteState
}
if let disposable = self.raisedHandDisplayDisposables[member.peer.id] {
disposable.dispose()
self.raisedHandDisplayDisposables[member.peer.id] = nil
}
}
entries.append(.peer(PeerEntry(
@ -2944,7 +2985,8 @@ public final class VoiceChatController: ViewController {
muteState: memberMuteState,
canManageCall: self.callState?.canManageCall ?? false,
volume: member.volume,
raisedHand: member.raiseHandRating != nil
raisedHand: member.raiseHandRating != nil,
displayRaisedHandStatus: self.displayedRaisedHands.contains(member.peer.id)
)))
index += 1
}
@ -2966,7 +3008,8 @@ public final class VoiceChatController: ViewController {
muteState: nil,
canManageCall: false,
volume: nil,
raisedHand: false
raisedHand: false,
displayRaisedHandStatus: false
)))
index += 1
}

View File

@ -334,6 +334,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
var titleAttributedString: NSAttributedString?
var statusAttributedString: NSAttributedString?
var expandedStatusAttributedString: NSAttributedString?
let rightInset: CGFloat = params.rightInset
@ -403,6 +404,23 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
case .none:
break
}
if let expandedText = item.expandedText, case let .text(text, textColor) = expandedText {
let textColorValue: UIColor
switch textColor {
case .generic:
textColorValue = item.presentationData.theme.list.itemSecondaryTextColor
case .accent:
textColorValue = item.presentationData.theme.list.itemAccentColor
case .constructive:
textColorValue = UIColor(rgb: 0x34c759)
case .destructive:
textColorValue = UIColor(rgb: 0xff3b30)
}
expandedStatusAttributedString = NSAttributedString(string: text, font: statusFont, textColor: textColorValue)
} else {
expandedStatusAttributedString = statusAttributedString
}
let leftInset: CGFloat = 65.0 + params.leftInset
let verticalInset: CGFloat = 8.0
@ -429,7 +447,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 12.0 - rightInset - 30.0 - titleIconsWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (statusLayout, statusApply) = makeStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - rightInset - 30.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (expandedStatusLayout, expandedStatusApply) = makeExpandedStatusLayout(TextNodeLayoutArguments(attributedString: statusAttributedString, backgroundColor: nil, maximumNumberOfLines: 4, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - rightInset - 30.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (expandedStatusLayout, expandedStatusApply) = makeExpandedStatusLayout(TextNodeLayoutArguments(attributedString: expandedStatusAttributedString, backgroundColor: nil, maximumNumberOfLines: 4, truncationType: .end, constrainedSize: CGSize(width: params.width - leftInset - 8.0 - rightInset - 30.0, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let insets = UIEdgeInsets()
@ -799,7 +817,7 @@ class VoiceChatParticipantItemNode: ItemListRevealOptionsItemNode {
let animationSize = CGSize(width: 36.0, height: 36.0)
strongSelf.iconNode?.frame = CGRect(origin: CGPoint(), size: animationSize)
strongSelf.animationNode?.frame = CGRect(origin: CGPoint(), size: animationSize)
strongSelf.raiseHandNode?.frame = CGRect(origin: CGPoint(), size: animationSize).insetBy(dx: -6.0, dy: -6.0)
strongSelf.raiseHandNode?.frame = CGRect(origin: CGPoint(), size: animationSize).insetBy(dx: -6.0, dy: -6.0).offsetBy(dx: -2.0, dy: 0.0)
strongSelf.actionButtonNode.frame = CGRect(x: params.width - animationSize.width - 6.0 - params.rightInset + actionOffset, y: floor((layout.contentSize.height - animationSize.height) / 2.0) + 1.0, width: animationSize.width, height: animationSize.height)

View File

@ -562,8 +562,10 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
}
storeMessageTextInPasteboard(message.text, entities: messageEntities)
let content: UndoOverlayContent = .copy(text: chatPresentationInterfaceState.strings.Conversation_MessageCopied)
controllerInteraction.displayUndo(content)
Queue.mainQueue().after(0.2, {
let content: UndoOverlayContent = .copy(text: chatPresentationInterfaceState.strings.Conversation_MessageCopied)
controllerInteraction.displayUndo(content)
})
}
if resourceAvailable {
for media in message.media {
@ -577,8 +579,11 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
copyTextWithEntities()
} else {
UIPasteboard.general.image = image
let content: UndoOverlayContent = .copy(text: chatPresentationInterfaceState.strings.Conversation_ImageCopied)
controllerInteraction.displayUndo(content)
Queue.mainQueue().after(0.2, {
let content: UndoOverlayContent = .copy(text: chatPresentationInterfaceState.strings.Conversation_ImageCopied)
controllerInteraction.displayUndo(content)
})
}
} else {
copyTextWithEntities()
@ -804,12 +809,13 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
warnAboutPrivate = true
}
}
if warnAboutPrivate {
controllerInteraction.displayUndo(.linkCopied(text: presentationData.strings.Conversation_PrivateMessageLinkCopiedLong))
} else {
controllerInteraction.displayUndo(.linkCopied(text: presentationData.strings.Conversation_LinkCopied))
}
Queue.mainQueue().after(0.2, {
if warnAboutPrivate {
controllerInteraction.displayUndo(.linkCopied(text: presentationData.strings.Conversation_PrivateMessageLinkCopiedLong))
} else {
controllerInteraction.displayUndo(.linkCopied(text: presentationData.strings.Conversation_LinkCopied))
}
})
}
})
f(.default)

View File

@ -2911,6 +2911,24 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
currentCall = cachedData.activeCall
}
var previousCallsPrivate: Bool?
var currentCallsPrivate: Bool?
var previousVideoCallsAvailable: Bool? = true
var currentVideoCallsAvailable: Bool?
if let previousCachedData = previousData?.cachedData as? CachedUserData, let cachedData = data.cachedData as? CachedUserData {
previousCallsPrivate = previousCachedData.callsPrivate ?? false
currentCallsPrivate = cachedData.callsPrivate
previousVideoCallsAvailable = previousCachedData.videoCallsAvailable ?? true
currentVideoCallsAvailable = cachedData.videoCallsAvailable
}
if previousCallsPrivate != currentCallsPrivate || previousVideoCallsAvailable != currentVideoCallsAvailable {
infoUpdated = true
}
if (previousCall == nil) != (currentCall == nil) {
infoUpdated = true
}