From 53da3e1e46ee39e97a05f03dd82366e6edf69a21 Mon Sep 17 00:00:00 2001 From: Ilya Laktyushin Date: Thu, 8 Apr 2021 00:29:24 +0300 Subject: [PATCH] Voice Chat Fixes --- .../Resources/VoiceCancelReminder.tgs | Bin 0 -> 2395 bytes .../Resources/VoiceCancelReminderToMute.tgs | Bin 0 -> 2834 bytes .../VoiceCancelReminderToRaiseHand.tgs | Bin 0 -> 3729 bytes .../Telegram-iOS/Resources/VoiceHandOff.tgs | Bin 1379 -> 0 bytes .../Telegram-iOS/Resources/VoiceHandOff2.tgs | Bin 1296 -> 0 bytes .../Telegram-iOS/Resources/VoiceHandOn.tgs | Bin 1371 -> 0 bytes .../Resources/VoiceMuteToRaiseHand.tgs | Bin 0 -> 5710 bytes .../Resources/VoiceRaiseHandToMute.tgs | Bin 0 -> 4893 bytes .../Resources/VoiceSetReminder.tgs | Bin 0 -> 2366 bytes .../Resources/VoiceSetReminderToMute.tgs | Bin 0 -> 3408 bytes .../Resources/VoiceSetReminderToRaiseHand.tgs | Bin 0 -> 4341 bytes .../Resources/VoiceUnmuteToRaiseHand.tgs | Bin 0 -> 4698 bytes .../Sources/PresentationCallManager.swift | 6 ++- .../SyncCore/Sources/CachedChannelData.swift | 10 ++-- .../Sources/TelegramBaseController.swift | 2 +- .../GroupCallNavigationAccessoryPanel.swift | 4 +- .../Sources/PresentationGroupCall.swift | 30 +++++++++--- .../Sources/VoiceChatActionButton.swift | 45 +++++++++++++----- .../Sources/VoiceChatController.swift | 31 +++++++----- .../Sources/VoiceChatJoinScreen.swift | 4 +- .../Sources/VoiceChatTimerNode.swift | 2 +- .../TelegramCore/Sources/GroupCalls.swift | 41 ++++++++++------ .../State/AccountStateManagementUtils.swift | 8 ++-- .../Sources/UpdateCachedPeerData.swift | 4 +- .../TelegramUI/Sources/ChatController.swift | 4 +- .../Sources/PeerInfo/PeerInfoScreen.swift | 10 ++-- .../Sources/UndoOverlayController.swift | 2 + 27 files changed, 133 insertions(+), 70 deletions(-) create mode 100644 Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceCancelReminderToMute.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs delete mode 100644 Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs delete mode 100644 Telegram/Telegram-iOS/Resources/VoiceHandOff2.tgs delete mode 100644 Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceSetReminderToMute.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs create mode 100644 Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs diff --git a/Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs b/Telegram/Telegram-iOS/Resources/VoiceCancelReminder.tgs new file mode 100644 index 0000000000000000000000000000000000000000..7e5b7f873c5b20b22fbf35e56891b41ac939883a GIT binary patch literal 2395 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 k9zVnOc)}aIlo=T(NL09yZt04vXChyVZp literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceCancelReminderToRaiseHand.tgs new file mode 100644 index 0000000000000000000000000000000000000000..a221fafc74d5aa2d2250dd8279b9eb1072ca9469 GIT binary patch literal 3729 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 literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs b/Telegram/Telegram-iOS/Resources/VoiceHandOff.tgs deleted file mode 100644 index 3e20f033957762f744a1673d64d2035b70b5b896..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1379 zcmV-p1)TaHiwFpSB}-rc16FToV`WHTZe&kpW-e-TZ*BnXTFs6dMG$@!tIso|{+}7& zKtQ;G2;#D`(6H-`&H7K{NyuttDS{(BK@RW=3j!e_vCm+?5mnVazxKjL$tET{iZU}@ zRbAax-SvI$POjK9He@C;QOW{#p0lCl0h_Ma5MIlbYktRug2Q{_--|i)`7~RceRh8S zwSazSXJ^zQTd&8(nhj4z0h?u);~c-QD)n>$ZxOKKk`1+Y^LbWG28jeGt1KTc3N};$ zTjykV0o||I5+4~kxbPF0K8Fvn30U6Jl^PD3RZDZiBc9km@qmw~`KySTxS`60>xt0BM=>`!PG^n`Jidy;2P z5{gI~lF|n#PTBB0o2|#2IzmeE_T~0w`}gkq-4DAL16;280;C^&^x?;Yug0gvG9Ns~ z$q&N8qkQ>v1qPF|%9RhNn6qv|c%7-SR|uCWisOns$DG2vE-`tdP2g6Nq>)m}YdC5O zmqVB35seDoj1z&Nv1rRflTe_T)A(do2LAK**WHWlAKO2-*AV_sgY92+CU!p_&c!Fw zSuxHb8DHkp`N3SQ3r5LqZH|EcjOyv!vTgN->Zz%UluVq`fO2+90nEOoaON{Am2c)` zT}8G14FdTc!nr;i#G^c0O{S+1#p5DhUW^Z~DQ?kjo%~0E++H3QBD7U$sN0Iu-kzEm zon9R3gh^Xxhcu?zv?XVd3!b4Z_`C1#+q~(WpKuK9cfQ+}Fs{9!lTkxsT*`>_uoFCXiQr zfIQUrt^GHARXs5IlH_ROEG&Fk`a&1zp-B|o^=pL&1j7@g87;8IsRe6`4H@aUF;@^L z8kK46S_&Jn^8I4;Vv;%u;1XtPQ*?lComa4tKxSzj5incghKZ~JtJu;vY*WyPZj#bS zTZ?ImHBBRqq=Gi2B=v31sV&QCTKG)>UTLB#N|dfzaU^05b5uf6?kv}sQG+cUM+Z2J z>SS|t56pX*ZLok|k!{`tIY-uZ_e@>q@1DJ2iA|tzyT7j#hScHtOTIn+Qv1Kzk-Z8U z{5aT4rvN@8FmRMl|Wmza0k+y!VHgx6c52{{+L11^PP&7p%^N%2V>V0sSN`g18fdpb>9tisPN0{tIh`m|Sv>`!PH^n`U*2a*?F z62(GUlF|=QoU-A0KHrSDO@x%<-Rs@;?(hBg`yckN1~II@Sc3F}k3Rf(@YVRVTor?- zxcNaecv7sMufbq)R=Wz}lnd5Rh-@-74vN@kisHCrFEOXEuM14xXv_Ucl2mA|gGQpJ z^f~ld9?`1c&3X|CT8Fkewh0Z21+7nJRp3AGe%-&?{jvLVcLm}9G}!&sWMcp0@mzc| zotNVRlJR9RT^!BDreu`t&gJ0rXVh%xhHGoKR8MV{(8_tG1?Bvd0+@eG;VkAHbA=c~IM3%YD+q*0ja&x(}Fri!^nxITmr6AOgdShG}M7ib{^q44M{<`!PR> zx`t8XA?o>VgMI=>6lo9pM%WA;XydJdIO@uyW=fkN`e#@LC#3RBBUFY5p7`jr2~q=l z6q!TEQp5@t%~TVe0KnG5Xs>SB)*hmc<928;&nCFjELEU_D*#a_;hdv|B`86ckUIz` zHMJ6k)|hH)H_FjHFyY;!Ki;=T^nWMlAD~~oJLuP4=*O?-2Lt_9a%+SGT@CzLp^i$_ znWP2(B&~#f25>?p2?rubt$j}z;I_}hFZf%|B2 zi2DisLKo=aHuzsLkaS2uCiakxBLH_CC}GmpUg?^kGE4nP(`Q0p0GXl}>skz9V%TYt zc}#cQdj%T>jFmMJK}X{PzQ>j!B{4Q(S8O2ZgZl7+F9G*;C% z6X*rOD{WLm0hoG}0_`HV=vY(k5@|4_7Du>_;kb-`q?{x8{Z>#}X|O>r|W#cow>tAc$IK z;4BGTQx?zvg}9@tvjmoO#Md^oPA&_KO^RC1Nz?8t(s zrl`zudUiV2t~{#kWv6is;r~CFw*T*W@gvjT2h+Au_@3K3P%rXg=Kn`ywEYJqH~0WI G82|v%*o5u? diff --git a/Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs b/Telegram/Telegram-iOS/Resources/VoiceHandOn.tgs deleted file mode 100644 index f0db083d4f85b3e25417c305cfa8b6cd6beb4d5a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1371 zcmV-h1*G~PiwFpUB}-rc16FToV`WHTZe&kxE^2dcZUF6C&2A($5Pp@B&)t^)yL)aR zV7Y-<#AP*yCYjv~nLqXPE*nK7t>6exzyV$%AP^D~d4|awQB`*T&IGaw*@V!F((U?j z*;RJc*LHHwUa>K=-13Y??0Lb)PDE_BW@C7*)}H*DjirG1Nq8?8(C6cPdHl%|IvpP$ zlXkw@Ov?=$Kbu5so}Wz%Y@gTS*%IC|V&xedn_%P9ygV7D3XH7tV!ABZSVwGAklrbD zKW8g^56gW@Eere z7LBY(V{?+Pr`}z3kG&|srCCV~@>_VnL6L#0Uor}XxJSp<^$?OQccv=>#)9K+g#Vy*;lYdB%>(j%5hptWyeO+?8>qC>E(bGen zFld|nki^!T{3lxJOIq;@Sn*4U5v@AI-P5Zz%Qe-Rqp({-ctchmh-N=6CVK@EHU*Mo z2_xL8d8%9Uux^eF7%Y7~{1?mJUIq%vGTF*LN%eZO>+#dyC}G~h*PIZLlqV&)?y=(5=22SvqYEYOZp3+DpI`m7>icOoE4<;kUU4{nGthWj}3MzhPYP(SWQ$GxM7PJyaZCC=3 z$R2LQ88^;Famo`z(@40|K*QQ+ffj;jRZY_YaDr8usOG6QHI;Cg7?`7$NTu8f6B%wT zQaFx@a2Vaerv7Hx!@Qe3_i^!ty?hK(*y#8`{|vTGXhW;+f!Uylk1AfnLCaAKO`wIY zYm+-b-ot2v3G|j|a~p6L*MT#4u6FzW(F=C3jWjOMV}&q;j(}h4-Qkzs|7J(@DrxYC zfnFwqx+-D$xRA2JFF`dHN@jyyQN`%(;;vn@fz$8!`&TG--g@~W*EHx}Za?Y5tY73e@fkPHoI4)!PIGu1MlBW8{ zo*P%};pj3PU52B}fH4Ec-2W-V9=Ih_!!6kWH3QTPP&3?;4Yy-KJ!cCg8p$Mxijp*6AUh4AWT3>W-nabkj-vADbo?)S@VHBuf zq$`OlQ6F|HwYc3^RIYhht8Z}4650}&RtN)SC)@%CM%+>ZW3KDaf8#{c|I@!5PBeFc d2<>8g$FKn6MP8ixe}0;5{{qzO9spk@005@Vos$3n diff --git a/Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceMuteToRaiseHand.tgs new file mode 100644 index 0000000000000000000000000000000000000000..2617414f3fb53afc93bafa6decb436c704117f27 GIT binary patch literal 5710 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 A(EtDd literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs b/Telegram/Telegram-iOS/Resources/VoiceRaiseHandToMute.tgs new file mode 100644 index 0000000000000000000000000000000000000000..44a88db65eab2fed8a5d4aafa1e3dba14cc79cea GIT binary patch literal 4893 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 P7a#r~RP4Vy`Dy?F+9au> literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs b/Telegram/Telegram-iOS/Resources/VoiceSetReminder.tgs new file mode 100644 index 0000000000000000000000000000000000000000..02f6cffa5e4b8396a2823b209cb7ebcecc076c6b GIT binary patch literal 2366 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
TI(_ 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 literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceSetReminderToRaiseHand.tgs new file mode 100644 index 0000000000000000000000000000000000000000..98da6a6ac4c324ef6e21965ce10ac07e2ff30274 GIT binary patch literal 4341 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 literal 0 HcmV?d00001 diff --git a/Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs b/Telegram/Telegram-iOS/Resources/VoiceUnmuteToRaiseHand.tgs new file mode 100644 index 0000000000000000000000000000000000000000..8f79ae293d2428f465dbacf5bfb692bd5708cbcb GIT binary patch literal 4698 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 { get } var reconnectedAsEvents: Signal { get } + func toggleScheduledSubscription(_ subscribe: Bool) func schedule(timestamp: Int32) func startScheduled() diff --git a/submodules/SyncCore/Sources/CachedChannelData.swift b/submodules/SyncCore/Sources/CachedChannelData.swift index dff76b59aa..5b994dc253 100644 --- a/submodules/SyncCore/Sources/CachedChannelData.swift +++ b/submodules/SyncCore/Sources/CachedChannelData.swift @@ -160,20 +160,20 @@ public final class CachedChannelData: CachedPeerData { public var accessHash: Int64 public var title: String? public var scheduleTimestamp: Int32? - public var subscribed: Bool + public var subscribedToScheduled: Bool public init( id: Int64, accessHash: Int64, title: String?, scheduleTimestamp: Int32?, - subscribed: Bool + subscribedToScheduled: Bool ) { self.id = id self.accessHash = accessHash self.title = title self.scheduleTimestamp = scheduleTimestamp - self.subscribed = subscribed + self.subscribedToScheduled = subscribedToScheduled } public init(decoder: PostboxDecoder) { @@ -181,7 +181,7 @@ public final class CachedChannelData: CachedPeerData { self.accessHash = decoder.decodeInt64ForKey("accessHash", orElse: 0) self.title = decoder.decodeOptionalStringForKey("title") self.scheduleTimestamp = decoder.decodeOptionalInt32ForKey("scheduleTimestamp") - self.subscribed = decoder.decodeBoolForKey("subscribed", orElse: false) + self.subscribedToScheduled = decoder.decodeBoolForKey("subscribed", orElse: false) } public func encode(_ encoder: PostboxEncoder) { @@ -197,7 +197,7 @@ public final class CachedChannelData: CachedPeerData { } else { encoder.encodeNil(forKey: "scheduleTimestamp") } - encoder.encodeBool(self.subscribed, forKey: "subscribed") + encoder.encodeBool(self.subscribedToScheduled, forKey: "subscribed") } } diff --git a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift index 18b8202cc9..95bfc3281d 100644 --- a/submodules/TelegramBaseController/Sources/TelegramBaseController.swift +++ b/submodules/TelegramBaseController/Sources/TelegramBaseController.swift @@ -406,7 +406,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder { strongSelf.joinGroupCall( peerId: groupCallPanelData.peerId, invite: nil, - activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribed: false) + activeCall: CachedChannelData.ActiveCall(id: groupCallPanelData.info.id, accessHash: groupCallPanelData.info.accessHash, title: groupCallPanelData.info.title, scheduleTimestamp: groupCallPanelData.info.scheduleTimestamp, subscribedToScheduled: groupCallPanelData.info.subscribedToScheduled) ) }) if let navigationBar = self.navigationBar { diff --git a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift b/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift index c26f008d51..d8d1414981 100644 --- a/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift +++ b/submodules/TelegramCallsUI/Sources/GroupCallNavigationAccessoryPanel.swift @@ -505,7 +505,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { transition.updateFrame(node: self.avatarsNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((size.width - avatarsSize.width) / 2.0), y: floor((size.height - avatarsSize.height) / 2.0)), size: avatarsSize)) } - var joinText = self.strings.VoiceChat_PanelJoin.uppercased() + var joinText = self.strings.VoiceChat_PanelJoin var title = self.strings.VoiceChat_Title var text = self.currentText var isScheduled = false @@ -554,7 +554,7 @@ public final class GroupCallNavigationAccessoryPanel: ASDisplayNode { self.updateJoinButton() } - self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText, font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor) + self.joinButtonTitleNode.attributedText = NSAttributedString(string: joinText.uppercased(), font: Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers]), textColor: self.theme.chat.inputPanel.actionControlForegroundColor) let joinButtonTitleSize = self.joinButtonTitleNode.updateLayout(CGSize(width: 150.0, height: .greatestFiniteMagnitude)) let joinButtonSize = CGSize(width: joinButtonTitleSize.width + 20.0, height: 28.0) diff --git a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift index 165b4b35e9..1ace64c919 100644 --- a/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift +++ b/submodules/TelegramCallsUI/Sources/PresentationGroupCall.swift @@ -78,6 +78,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext { streamDcId: nil, title: call.title, scheduleTimestamp: call.scheduleTimestamp, + subscribedToScheduled: call.subscribedToScheduled, recordingStartTimestamp: nil, sortAscending: true ), @@ -121,7 +122,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext { } return GroupCallPanelData( peerId: peerId, - info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, recordingStartTimestamp: nil, sortAscending: state.sortAscending), + info: GroupCallInfo(id: call.id, accessHash: call.accessHash, participantCount: state.totalCount, clientParams: nil, streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, subscribedToScheduled: state.subscribedToScheduled, recordingStartTimestamp: nil, sortAscending: state.sortAscending), topParticipants: topParticipants, participantCount: state.totalCount, activeSpeakers: activeSpeakers, @@ -206,7 +207,7 @@ public final class AccountGroupCallContextCacheImpl: AccountGroupCallContextCach } private extension PresentationGroupCallState { - static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?) -> PresentationGroupCallState { + static func initialValue(myPeerId: PeerId, title: String?, scheduleTimestamp: Int32?, subscribedToScheduled: Bool) -> PresentationGroupCallState { return PresentationGroupCallState( myPeerId: myPeerId, networkState: .connecting, @@ -217,7 +218,8 @@ private extension PresentationGroupCallState { recordingStartTimestamp: nil, title: title, raisedHand: false, - scheduleTimestamp: scheduleTimestamp + scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled ) } } @@ -511,6 +513,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { private let joinDisposable = MetaDisposable() private let requestDisposable = MetaDisposable() private let startDisposable = MetaDisposable() + private let subscribeDisposable = MetaDisposable() private var groupCallParticipantUpdatesDisposable: Disposable? private let networkStateDisposable = MetaDisposable() @@ -579,7 +582,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.joinAsPeerId = joinAsPeerId ?? accountContext.account.peerId self.schedulePending = initialCall == nil - self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp) + self.stateValue = PresentationGroupCallState.initialValue(myPeerId: self.joinAsPeerId, title: initialCall?.title, scheduleTimestamp: initialCall?.scheduleTimestamp, subscribedToScheduled: initialCall?.subscribedToScheduled ?? false) self.statePromise = ValuePromise(self.stateValue) self.temporaryJoinTimestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970) @@ -734,7 +737,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { addedParticipants.append((ssrc, participantUpdate.jsonParams)) } } - case let .call(isTerminated, _, _, _): + case let .call(isTerminated, _, _, _, _): if isTerminated { strongSelf.markAsCanBeRemoved() } @@ -767,7 +770,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { }) if let initialCall = initialCall, let temporaryParticipantsContext = (self.accountContext.cachedGroupCallContexts as? AccountGroupCallContextCacheImpl)?.impl.syncWith({ impl in - impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribed: initialCall.subscribed)) + impl.get(account: accountContext.account, peerId: peerId, call: CachedChannelData.ActiveCall(id: initialCall.id, accessHash: initialCall.accessHash, title: initialCall.title, scheduleTimestamp: initialCall.scheduleTimestamp, subscribedToScheduled: initialCall.subscribedToScheduled)) }) { self.switchToTemporaryParticipantsContext(sourceContext: temporaryParticipantsContext.context.participantsContext, oldMyPeerId: self.joinAsPeerId) } else { @@ -824,6 +827,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.joinDisposable.dispose() self.requestDisposable.dispose() self.startDisposable.dispose() + self.subscribeDisposable.dispose() self.groupCallParticipantUpdatesDisposable?.dispose() self.leaveDisposable.dispose() self.isMutedDisposable.dispose() @@ -1666,6 +1670,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { streamDcId: nil, title: state.title, scheduleTimestamp: state.scheduleTimestamp, + subscribedToScheduled: false, recordingStartTimestamp: state.recordingStartTimestamp, sortAscending: state.sortAscending )))) @@ -1987,6 +1992,17 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { self.callContext?.setIsNoiseSuppressionEnabled(isNoiseSuppressionEnabled) } + public func toggleScheduledSubscription(_ subscribe: Bool) { + guard case let .active(callInfo) = self.internalState, callInfo.scheduleTimestamp != nil else { + return + } + + self.stateValue.subscribedToScheduled = subscribe + + self.subscribeDisposable.set((toggleScheduledGroupCallSubscription(account: self.account, peerId: self.peerId, callId: callInfo.id, accessHash: callInfo.accessHash, subscribe: subscribe) + |> deliverOnMainQueue).start()) + } + public func schedule(timestamp: Int32) { guard self.schedulePending else { return @@ -2270,7 +2286,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall { } if let value = value { - strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribed: false) + strongSelf.initialCall = CachedChannelData.ActiveCall(id: value.id, accessHash: value.accessHash, title: value.title, scheduleTimestamp: nil, subscribedToScheduled: false) strongSelf.updateSessionState(internalState: .active(value), audioSessionControl: strongSelf.audioSessionControl) } else { diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift index 754bcc7d2c..9432a2fea2 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatActionButton.swift @@ -607,11 +607,11 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.maskProgressLayer.lineCap = .round self.maskProgressLayer.path = path - let circleFrame = CGRect(origin: CGPoint(x: (358 - buttonSize.width) / 2.0, y: (358 - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + let circleFrame = CGRect(origin: CGPoint(x: (areaSize.width - buttonSize.width) / 2.0, y: (areaSize.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath - self.maskCircleLayer.fillColor = white.cgColor self.maskCircleLayer.path = largerCirclePath + self.maskCircleLayer.fillColor = white.cgColor self.maskCircleLayer.isHidden = true updateInHierarchy = { [weak self] value in @@ -971,6 +971,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { CATransaction.commit() } + private var maskIsCircle = true private func setupButtonAnimation() { CATransaction.begin() CATransaction.setDisableActions(true) @@ -982,6 +983,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { let path = UIBezierPath(roundedRect: CGRect(x: 0.0, y: floor((self.bounds.height - buttonHeight) / 2.0), width: self.bounds.width, height: buttonHeight), cornerRadius: 10.0).cgPath self.maskCircleLayer.path = path + self.maskIsCircle = false CATransaction.commit() @@ -1001,6 +1003,7 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { let previousPath = self.maskCircleLayer.path self.maskCircleLayer.path = largerCirclePath + self.maskIsCircle = true self.maskCircleLayer.animateSpring(from: previousPath as AnyObject, to: largerCirclePath as AnyObject, keyPath: "path", duration: 0.42, initialVelocity: 0.0, damping: 104.0) @@ -1144,9 +1147,13 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.updateAnimations() } + var previousSize: CGSize? override func layout() { super.layout() + let sizeUpdated = self.previousSize != self.bounds.size + self.previousSize = self.bounds.size + let bounds = CGRect(x: (self.bounds.width - areaSize.width) / 2.0, y: (self.bounds.height - areaSize.height) / 2.0, width: areaSize.width, height: areaSize.height) let center = bounds.center @@ -1159,7 +1166,17 @@ private final class VoiceChatActionButtonBackgroundNode: ASDisplayNode { self.growingForegroundCircleLayer.position = center self.growingForegroundCircleLayer.bounds = self.foregroundCircleLayer.bounds self.maskCircleLayer.frame = self.bounds -// circleFrame.insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + + if sizeUpdated && self.maskIsCircle { + CATransaction.begin() + CATransaction.setDisableActions(true) + let circleFrame = CGRect(origin: CGPoint(x: (self.bounds.width - buttonSize.width) / 2.0, y: (self.bounds.height - buttonSize.height) / 2.0), size: buttonSize).insetBy(dx: -progressLineWidth / 2.0, dy: -progressLineWidth / 2.0) + let largerCirclePath = UIBezierPath(roundedRect: CGRect(x: circleFrame.minX, y: circleFrame.minY, width: circleFrame.width, height: circleFrame.height), cornerRadius: circleFrame.width / 2.0).cgPath + + self.maskCircleLayer.path = largerCirclePath + CATransaction.commit() + } + self.maskProgressLayer.frame = circleFrame.insetBy(dx: -3.0, dy: -3.0) self.foregroundView.frame = self.bounds self.foregroundGradientLayer.frame = self.bounds @@ -1543,22 +1560,22 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .subscribe: switch state { case .unsubscribe: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminder"))) case .mute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand"))) default: break } case .unsubscribe: switch state { case .subscribe: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminder"))) case .mute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceStart"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand"))) default: break } @@ -1574,7 +1591,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .mute: self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff2"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmuteToRaiseHand"))) default: break } @@ -1585,7 +1602,11 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .unmute: self.trackTo(item: ManagedAnimationItem(source: .local("VoiceUnmute"))) case .hand: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOff"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceMuteToRaiseHand"))) + case .subscribe: + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceSetReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001)) + case .unsubscribe: + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceCancelReminderToRaiseHand"), frames: .range(startFrame: 0, endFrame: 0), duration: 0.001)) case .empty: self.alpha = 0.0 default: @@ -1594,7 +1615,7 @@ final class VoiceChatActionButtonIconNode: ManagedAnimationNode { case .hand: switch state { case .mute, .unmute: - self.trackTo(item: ManagedAnimationItem(source: .local("VoiceHandOn"))) + self.trackTo(item: ManagedAnimationItem(source: .local("VoiceRaiseHandToMute"))) default: break } diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift index a758f3ebb6..2c25d44ef6 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatController.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatController.swift @@ -2438,8 +2438,12 @@ public final class VoiceChatController: ViewController { @objc func dimTapGesture(_ recognizer: UITapGestureRecognizer) { if case .ended = recognizer.state { - self.controller?.dismiss(closing: false) - self.controller?.dismissAllTooltips() + if self.isScheduling { + self.dismissScheduled() + } else { + self.controller?.dismiss(closing: false) + self.controller?.dismissAllTooltips() + } } } @@ -2594,7 +2598,7 @@ public final class VoiceChatController: ViewController { self.call.startScheduled() self.transitionToCall() } else { - + self.call.toggleScheduledSubscription(!callState.subscribedToScheduled) } } default: @@ -2670,8 +2674,6 @@ public final class VoiceChatController: ViewController { |> deliverOnMainQueue).start(next: { [weak self] inviteLinks in if let inviteLinks = inviteLinks { self?.presentShare(inviteLinks) - } else { - self?.presentShare(GroupCallInviteLinks(listenerLink: "a", speakerLink: nil)) } }) return @@ -3199,16 +3201,20 @@ public final class VoiceChatController: ViewController { let actionButtonSubtitle: String var actionButtonEnabled = true if let callState = self.callState, !self.isScheduling { - var isScheduled = callState.scheduleTimestamp != nil - if isScheduled { + if callState.scheduleTimestamp != nil { self.ignoreNextConnecting = true if callState.canManageCall { actionButtonState = .scheduled(state: .start) actionButtonTitle = self.presentationData.strings.VoiceChat_StartNow actionButtonSubtitle = "" } else { - actionButtonState = .scheduled(state: .subscribe) - actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder + if callState.subscribedToScheduled { + actionButtonState = .scheduled(state: .unsubscribe) + actionButtonTitle = self.presentationData.strings.VoiceChat_CancelReminder + } else { + actionButtonState = .scheduled(state: .subscribe) + actionButtonTitle = self.presentationData.strings.VoiceChat_SetReminder + } actionButtonSubtitle = "" } } else { @@ -3681,6 +3687,7 @@ public final class VoiceChatController: ViewController { @objc func panGesture(_ recognizer: UIPanGestureRecognizer) { let contentOffset = self.listNode.visibleContentOffset() + let isScheduling = self.isScheduling || self.callState?.scheduleTimestamp != nil switch recognizer.state { case .began: let topInset: CGFloat @@ -3696,7 +3703,7 @@ public final class VoiceChatController: ViewController { self.controller?.dismissAllTooltips() case .changed: var translation = recognizer.translation(in: self.contentContainer.view).y - if (self.isScheduling || self.callState?.scheduleTimestamp != nil) && translation < 0.0 { + if isScheduling && translation < 0.0 { return } var topInset: CGFloat = 0.0 @@ -3802,7 +3809,7 @@ public final class VoiceChatController: ViewController { self.controller?.dismiss(closing: false, manual: true) } dismissing = true - } else if !self.isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) { + } else if !isScheduling && (velocity.y < -300.0 || offset < topInset / 2.0) { if velocity.y > -1500.0 && !self.isFullscreen { DispatchQueue.main.async { self.listNode.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous, .LowLatency], scrollToItem: ListViewScrollToItem(index: 0, position: .top(0.0), animated: true, curve: .Default(duration: nil), directionHint: .Up), updateSizeAndInsets: nil, stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in }) @@ -3819,7 +3826,7 @@ public final class VoiceChatController: ViewController { self.updateFloatingHeaderOffset(offset: self.currentContentOffset ?? 0.0, transition: .animated(duration: 0.3, curve: .easeInOut), completion: { self.animatingExpansion = false }) - } else if !self.isScheduling { + } else if !isScheduling { self.updateIsFullscreen(false) self.animatingExpansion = true self.listNode.scroller.setContentOffset(CGPoint(), animated: false) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift b/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift index 2b0c01617f..a0f81d690a 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatJoinScreen.swift @@ -144,8 +144,8 @@ public final class VoiceChatJoinScreen: ViewController { } else if let cachedData = cachedData as? CachedGroupData { defaultJoinAsPeerId = cachedData.callJoinPeerId } - - let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribed: false) + + let activeCall = CachedChannelData.ActiveCall(id: call.info.id, accessHash: call.info.accessHash, title: call.info.title, scheduleTimestamp: call.info.scheduleTimestamp, subscribedToScheduled: call.info.subscribedToScheduled) if availablePeers.count > 0 && defaultJoinAsPeerId == nil { strongSelf.dismiss() strongSelf.join(activeCall) diff --git a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift index fe3a71af12..fd2d504c53 100644 --- a/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift +++ b/submodules/TelegramCallsUI/Sources/VoiceChatTimerNode.swift @@ -136,7 +136,7 @@ final class VoiceChatTimerNode: ASDisplayNode { self.subtitleNode.attributedText = NSAttributedString(string: subtitle, font: Font.with(size: 21.0, design: .round, weight: .semibold, traits: []), textColor: .white) let subtitleSize = self.subtitleNode.updateLayout(size) - self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: timerSize.width, height: subtitleSize.height) + self.subtitleNode.frame = CGRect(x: floor((size.width - subtitleSize.width) / 2.0), y: 164.0, width: subtitleSize.width, height: subtitleSize.height) self.foregroundView.frame = CGRect(origin: CGPoint(), size: size) } diff --git a/submodules/TelegramCore/Sources/GroupCalls.swift b/submodules/TelegramCore/Sources/GroupCalls.swift index 11ef176bec..5a81c3ad33 100644 --- a/submodules/TelegramCore/Sources/GroupCalls.swift +++ b/submodules/TelegramCore/Sources/GroupCalls.swift @@ -12,6 +12,7 @@ public struct GroupCallInfo: Equatable { public var streamDcId: Int32? public var title: String? public var scheduleTimestamp: Int32? + public var subscribedToScheduled: Bool public var recordingStartTimestamp: Int32? public var sortAscending: Bool @@ -23,6 +24,7 @@ public struct GroupCallInfo: Equatable { streamDcId: Int32?, title: String?, scheduleTimestamp: Int32?, + subscribedToScheduled: Bool, recordingStartTimestamp: Int32?, sortAscending: Bool ) { @@ -33,6 +35,7 @@ public struct GroupCallInfo: Equatable { self.streamDcId = streamDcId self.title = title self.scheduleTimestamp = scheduleTimestamp + self.subscribedToScheduled = subscribedToScheduled self.recordingStartTimestamp = recordingStartTimestamp self.sortAscending = sortAscending } @@ -62,6 +65,7 @@ extension GroupCallInfo { streamDcId: streamDcId, title: title, scheduleTimestamp: scheduleDate, + subscribedToScheduled: (flags & (1 << 8)) != 0, recordingStartTimestamp: recordStartDate, sortAscending: (flags & (1 << 6)) != 0 ) @@ -214,9 +218,9 @@ public func createGroupCall(account: Account, peerId: PeerId, title: String?, sc return account.postbox.transaction { transaction -> GroupCallInfo in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else { return cachedData } @@ -259,9 +263,9 @@ public func startScheduledGroupCall(account: Account, peerId: PeerId, callId: In return account.postbox.transaction { transaction -> GroupCallInfo in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else { return cachedData } @@ -303,9 +307,9 @@ public func toggleScheduledGroupCallSubscription(account: Account, peerId: PeerI return account.postbox.transaction { transaction in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribed: subscribe)) + return cachedData.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: callInfo.id, accessHash: callInfo.accessHash, title: callInfo.title, scheduleTimestamp: callInfo.scheduleTimestamp, subscribedToScheduled: callInfo.subscribedToScheduled)) } else { return cachedData } @@ -361,19 +365,19 @@ public enum GetGroupCallParticipantsError { } public func getGroupCallParticipants(account: Account, callId: Int64, accessHash: Int64, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal { - let sortAscendingValue: Signal<(Bool, Int32?), GetGroupCallParticipantsError> + let sortAscendingValue: Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError> if let sortAscending = sortAscending { - sortAscendingValue = .single((sortAscending, nil)) + sortAscendingValue = .single((sortAscending, nil, false)) } else { sortAscendingValue = getCurrentGroupCall(account: account, callId: callId, accessHash: accessHash) |> mapError { _ -> GetGroupCallParticipantsError in return .generic } - |> mapToSignal { result -> Signal<(Bool, Int32?), GetGroupCallParticipantsError> in + |> mapToSignal { result -> Signal<(Bool, Int32?, Bool), GetGroupCallParticipantsError> in guard let result = result else { return .fail(.generic) } - return .single((result.info.sortAscending, result.info.scheduleTimestamp)) + return .single((result.info.sortAscending, result.info.scheduleTimestamp, result.info.subscribedToScheduled)) } } @@ -391,7 +395,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash let version: Int32 let nextParticipantsFetchOffset: String? - let (sortAscendingValue, scheduleTimestamp) = sortAscendingAndScheduleTimestamp + let (sortAscendingValue, scheduleTimestamp, subscribedToScheduled) = sortAscendingAndScheduleTimestamp switch result { case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion): @@ -480,6 +484,7 @@ public func getGroupCallParticipants(account: Account, callId: Int64, accessHash recordingStartTimestamp: nil, title: nil, scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled, totalCount: totalCount, version: version ) @@ -656,9 +661,9 @@ public func joinGroupCall(account: Account, peerId: PeerId, joinAs: PeerId?, cal return account.postbox.transaction { transaction -> JoinGroupCallResult in transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, cachedData -> CachedPeerData? in if let cachedData = cachedData as? CachedChannelData { - return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else if let cachedData = cachedData as? CachedGroupData { - return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribed: false)) + return cachedData.withUpdatedCallJoinPeerId(joinAs).withUpdatedActiveCall(CachedChannelData.ActiveCall(id: parsedCall.id, accessHash: parsedCall.accessHash, title: parsedCall.title, scheduleTimestamp: nil, subscribedToScheduled: false)) } else { return cachedData } @@ -999,6 +1004,7 @@ public final class GroupCallParticipantsContext { public var recordingStartTimestamp: Int32? public var title: String? public var scheduleTimestamp: Int32? + public var subscribedToScheduled: Bool public var totalCount: Int public var version: Int32 @@ -1111,7 +1117,7 @@ public final class GroupCallParticipantsContext { } case state(update: StateUpdate) - case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?) + case call(isTerminated: Bool, defaultParticipantsAreMuted: State.DefaultParticipantsAreMuted, title: String?, recordingStartTimestamp: Int32?, scheduleTimestamp: Int32?) } public final class MemberEvent { @@ -1301,6 +1307,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, title: strongSelf.stateValue.state.title, scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp, + subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled, totalCount: strongSelf.stateValue.state.totalCount, version: strongSelf.stateValue.state.version ), @@ -1356,11 +1363,12 @@ public final class GroupCallParticipantsContext { for update in updates { if case let .state(update) = update { stateUpdates.append(update) - } else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp) = update { + } else if case let .call(_, defaultParticipantsAreMuted, title, recordingStartTimestamp, scheduleTimestamp) = update { var state = self.stateValue.state state.defaultParticipantsAreMuted = defaultParticipantsAreMuted state.recordingStartTimestamp = recordingStartTimestamp state.title = title + state.scheduleTimestamp = scheduleTimestamp self.stateValue.state = state } @@ -1434,6 +1442,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, title: strongSelf.stateValue.state.title, scheduleTimestamp: strongSelf.stateValue.state.scheduleTimestamp, + subscribedToScheduled: strongSelf.stateValue.state.subscribedToScheduled, totalCount: strongSelf.stateValue.state.totalCount, version: strongSelf.stateValue.state.version ), @@ -1650,6 +1659,7 @@ public final class GroupCallParticipantsContext { let recordingStartTimestamp = strongSelf.stateValue.state.recordingStartTimestamp let title = strongSelf.stateValue.state.title let scheduleTimestamp = strongSelf.stateValue.state.scheduleTimestamp + let subscribedToScheduled = strongSelf.stateValue.state.subscribedToScheduled updatedParticipants.sort(by: { GroupCallParticipantsContext.Participant.compare(lhs: $0, rhs: $1, sortAscending: strongSelf.stateValue.state.sortAscending) }) @@ -1664,6 +1674,7 @@ public final class GroupCallParticipantsContext { recordingStartTimestamp: recordingStartTimestamp, title: title, scheduleTimestamp: scheduleTimestamp, + subscribedToScheduled: subscribedToScheduled, totalCount: updatedTotalCount, version: update.version ), diff --git a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift index 5cac66545f..e57096a47b 100644 --- a/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift +++ b/submodules/TelegramCore/Sources/State/AccountStateManagementUtils.swift @@ -2982,9 +2982,9 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP if let info = GroupCallInfo(call) { transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in if let current = current as? CachedChannelData { - return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) } else if let current = current as? CachedGroupData { - return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + return current.withUpdatedActiveCall(CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) } else { return current } @@ -2997,7 +2997,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP let defaultParticipantsAreMuted = GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: isMuted, canChange: canChange) updatedGroupCallParticipants.append(( info.id, - .call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate) + .call(isTerminated: false, defaultParticipantsAreMuted: defaultParticipantsAreMuted, title: title, recordingStartTimestamp: recordStartDate, scheduleTimestamp: scheduleDate) )) default: break @@ -3006,7 +3006,7 @@ func replayFinalState(accountManager: AccountManager, postbox: Postbox, accountP case let .groupCallDiscarded(callId, _, _): updatedGroupCallParticipants.append(( callId, - .call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil) + .call(isTerminated: true, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), title: nil, recordingStartTimestamp: nil, scheduleTimestamp: nil) )) transaction.updatePeerCachedData(peerIds: Set([peerId]), update: { _, current in diff --git a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift index 7ebfa241a6..7e0c426020 100644 --- a/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift +++ b/submodules/TelegramCore/Sources/UpdateCachedPeerData.swift @@ -306,7 +306,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId if let inputCall = chatFull.call { switch inputCall { case let .inputGroupCall(id, accessHash): - updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false) + updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false) } } @@ -516,7 +516,7 @@ public func fetchAndUpdateCachedPeerData(accountPeerId: PeerId, peerId rawPeerId if let inputCall = inputCall { switch inputCall { case let .inputGroupCall(id, accessHash): - updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribed: previous.activeCall?.subscribed ?? false) + updatedActiveCall = CachedChannelData.ActiveCall(id: id, accessHash: accessHash, title: previous.activeCall?.title, scheduleTimestamp: previous.activeCall?.scheduleTimestamp, subscribedToScheduled: previous.activeCall?.subscribedToScheduled ?? false) } } diff --git a/submodules/TelegramUI/Sources/ChatController.swift b/submodules/TelegramUI/Sources/ChatController.swift index 1934261113..184f0b6782 100644 --- a/submodules/TelegramUI/Sources/ChatController.swift +++ b/submodules/TelegramUI/Sources/ChatController.swift @@ -535,7 +535,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G } case .groupPhoneCall, .inviteToGroupPhoneCall: if let activeCall = strongSelf.presentationInterfaceState.activeGroupCallInfo?.activeCall { - strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribed: activeCall.subscribed)) + strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: activeCall.id, accessHash: activeCall.accessHash, title: activeCall.title, scheduleTimestamp: activeCall.scheduleTimestamp, subscribedToScheduled: activeCall.subscribedToScheduled)) } else { var canManageGroupCalls = false if let channel = strongSelf.presentationInterfaceState.renderedPeer?.chatMainPeer as? TelegramChannel { @@ -569,7 +569,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G guard let strongSelf = self else { return } - strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribed: false)) + strongSelf.joinGroupCall(peerId: message.id.peerId, invite: nil, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: info.scheduleTimestamp, subscribedToScheduled: info.subscribedToScheduled)) }, error: { [weak self] error in dismissStatus?() diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 681eabb22d..9d3a467201 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4020,7 +4020,7 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD } strongSelf.context.joinGroupCall(peerId: peerId, invite: nil, requestJoinAsPeerId: { result in result(joinAsPeerId) - }, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribed: false)) + }, activeCall: CachedChannelData.ActiveCall(id: info.id, accessHash: info.accessHash, title: info.title, scheduleTimestamp: nil, subscribedToScheduled: false)) }, error: { [weak self] error in guard let strongSelf = self else { return @@ -4199,7 +4199,9 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD |> deliverOnMainQueue).start(completed: { [weak self] in if let strongSelf = self, let peer = strongSelf.data?.peer { let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 } - strongSelf.controller?.present(UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root)) + let controller = UndoOverlayController(presentationData: presentationData, content: .info(text: presentationData.strings.Conversation_DeletedFromContacts(peer.displayTitle(strings: strongSelf.presentationData.strings, displayOrder: strongSelf.presentationData.nameDisplayOrder)).0), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }) + controller.keepOnParentDismissal = true + strongSelf.controller?.present(controller, in: .window(.root)) strongSelf.controller?.dismiss() } @@ -6642,12 +6644,12 @@ public final class PeerInfoScreenImpl: ViewController, PeerInfoScreen { private func dismissAllTooltips() { self.window?.forEachController({ controller in - if let controller = controller as? UndoOverlayController { + if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal { controller.dismissWithCommitAction() } }) self.forEachController({ controller in - if let controller = controller as? UndoOverlayController { + if let controller = controller as? UndoOverlayController, !controller.keepOnParentDismissal { controller.dismissWithCommitAction() } return true diff --git a/submodules/UndoUI/Sources/UndoOverlayController.swift b/submodules/UndoUI/Sources/UndoOverlayController.swift index bf84710a72..05ef86b7f0 100644 --- a/submodules/UndoUI/Sources/UndoOverlayController.swift +++ b/submodules/UndoUI/Sources/UndoOverlayController.swift @@ -56,6 +56,8 @@ public final class UndoOverlayController: ViewController { private var didPlayPresentationAnimation = false private var dismissed = false + public var keepOnParentDismissal = false + public init(presentationData: PresentationData, content: UndoOverlayContent, elevatedLayout: Bool, animateInAsReplacement: Bool = false, action: @escaping (UndoOverlayAction) -> Bool) { self.presentationData = presentationData self.content = content