Various improvements

This commit is contained in:
Ilya Laktyushin 2025-09-26 01:30:15 +04:00
parent 85f8bde398
commit 7dfd3b1d87
17 changed files with 167 additions and 88 deletions

View File

@ -222,6 +222,7 @@ public struct PresentationGroupCallState: Equatable {
public var adminIds: Set<EnginePeer.Id> public var adminIds: Set<EnginePeer.Id>
public var muteState: GroupCallParticipantsContext.Participant.MuteState? public var muteState: GroupCallParticipantsContext.Participant.MuteState?
public var defaultParticipantMuteState: DefaultParticipantMuteState? public var defaultParticipantMuteState: DefaultParticipantMuteState?
public var messagesAreEnabled: Bool
public var recordingStartTimestamp: Int32? public var recordingStartTimestamp: Int32?
public var title: String? public var title: String?
public var raisedHand: Bool public var raisedHand: Bool
@ -238,6 +239,7 @@ public struct PresentationGroupCallState: Equatable {
adminIds: Set<EnginePeer.Id>, adminIds: Set<EnginePeer.Id>,
muteState: GroupCallParticipantsContext.Participant.MuteState?, muteState: GroupCallParticipantsContext.Participant.MuteState?,
defaultParticipantMuteState: DefaultParticipantMuteState?, defaultParticipantMuteState: DefaultParticipantMuteState?,
messagesAreEnabled: Bool,
recordingStartTimestamp: Int32?, recordingStartTimestamp: Int32?,
title: String?, title: String?,
raisedHand: Bool, raisedHand: Bool,
@ -253,6 +255,7 @@ public struct PresentationGroupCallState: Equatable {
self.adminIds = adminIds self.adminIds = adminIds
self.muteState = muteState self.muteState = muteState
self.defaultParticipantMuteState = defaultParticipantMuteState self.defaultParticipantMuteState = defaultParticipantMuteState
self.messagesAreEnabled = messagesAreEnabled
self.recordingStartTimestamp = recordingStartTimestamp self.recordingStartTimestamp = recordingStartTimestamp
self.title = title self.title = title
self.raisedHand = raisedHand self.raisedHand = raisedHand

View File

@ -453,7 +453,7 @@ final class ChatListContainerItemNode: ASDisplayNode {
let edgeEffectHeight: CGFloat = insets.bottom let edgeEffectHeight: CGFloat = insets.bottom
let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - edgeEffectHeight), size: CGSize(width: size.width, height: edgeEffectHeight)) let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: size.height - edgeEffectHeight), size: CGSize(width: size.width, height: edgeEffectHeight))
transition.updateFrame(view: self.edgeEffectView, frame: edgeEffectFrame) transition.updateFrame(view: self.edgeEffectView, frame: edgeEffectFrame)
self.edgeEffectView.update(content: self.presentationData.theme.list.plainBackgroundColor, isInverted: false, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, containerSize: size, transition: ComponentTransition(transition)) self.edgeEffectView.update(content: self.presentationData.theme.list.plainBackgroundColor, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, transition: ComponentTransition(transition))
} }
func updateScrollingOffset(navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition) { func updateScrollingOffset(navigationHeight: CGFloat, offset: CGFloat, transition: ContainedViewLayoutTransition) {

View File

@ -293,7 +293,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-207944868] = { return Api.FileHash.parse_fileHash($0) } dict[-207944868] = { return Api.FileHash.parse_fileHash($0) }
dict[-11252123] = { return Api.Folder.parse_folder($0) } dict[-11252123] = { return Api.Folder.parse_folder($0) }
dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) } dict[-373643672] = { return Api.FolderPeer.parse_folderPeer($0) }
dict[1903173033] = { return Api.ForumTopic.parse_forumTopic($0) } dict[-838922550] = { return Api.ForumTopic.parse_forumTopic($0) }
dict[37687451] = { return Api.ForumTopic.parse_forumTopicDeleted($0) } dict[37687451] = { return Api.ForumTopic.parse_forumTopicDeleted($0) }
dict[-394605632] = { return Api.FoundStory.parse_foundStory($0) } dict[-394605632] = { return Api.FoundStory.parse_foundStory($0) }
dict[-1107729093] = { return Api.Game.parse_game($0) } dict[-1107729093] = { return Api.Game.parse_game($0) }
@ -1111,7 +1111,7 @@ fileprivate let parsers: [Int32 : (BufferReader) -> Any?] = {
dict[-1535694705] = { return Api.Update.parse_updateGroupCallChainBlocks($0) } dict[-1535694705] = { return Api.Update.parse_updateGroupCallChainBlocks($0) }
dict[192428418] = { return Api.Update.parse_updateGroupCallConnection($0) } dict[192428418] = { return Api.Update.parse_updateGroupCallConnection($0) }
dict[-917002394] = { return Api.Update.parse_updateGroupCallEncryptedMessage($0) } dict[-917002394] = { return Api.Update.parse_updateGroupCallEncryptedMessage($0) }
dict[-1761933248] = { return Api.Update.parse_updateGroupCallMessage($0) } dict[2026050784] = { return Api.Update.parse_updateGroupCallMessage($0) }
dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) } dict[-219423922] = { return Api.Update.parse_updateGroupCallParticipants($0) }
dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) } dict[1763610706] = { return Api.Update.parse_updateInlineBotCallbackQuery($0) }
dict[1442983757] = { return Api.Update.parse_updateLangPack($0) } dict[1442983757] = { return Api.Update.parse_updateLangPack($0) }

View File

@ -608,7 +608,7 @@ public extension Api {
case updateGroupCallChainBlocks(call: Api.InputGroupCall, subChainId: Int32, blocks: [Buffer], nextOffset: Int32) case updateGroupCallChainBlocks(call: Api.InputGroupCall, subChainId: Int32, blocks: [Buffer], nextOffset: Int32)
case updateGroupCallConnection(flags: Int32, params: Api.DataJSON) case updateGroupCallConnection(flags: Int32, params: Api.DataJSON)
case updateGroupCallEncryptedMessage(call: Api.InputGroupCall, fromId: Api.Peer, encryptedMessage: Buffer) case updateGroupCallEncryptedMessage(call: Api.InputGroupCall, fromId: Api.Peer, encryptedMessage: Buffer)
case updateGroupCallMessage(call: Api.InputGroupCall, fromId: Api.Peer, message: Api.TextWithEntities) case updateGroupCallMessage(call: Api.InputGroupCall, fromId: Api.Peer, randomId: Int64, message: Api.TextWithEntities)
case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32) case updateGroupCallParticipants(call: Api.InputGroupCall, participants: [Api.GroupCallParticipant], version: Int32)
case updateInlineBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, msgId: Api.InputBotInlineMessageID, chatInstance: Int64, data: Buffer?, gameShortName: String?) case updateInlineBotCallbackQuery(flags: Int32, queryId: Int64, userId: Int64, msgId: Api.InputBotInlineMessageID, chatInstance: Int64, data: Buffer?, gameShortName: String?)
case updateLangPack(difference: Api.LangPackDifference) case updateLangPack(difference: Api.LangPackDifference)
@ -1307,12 +1307,13 @@ public extension Api {
fromId.serialize(buffer, true) fromId.serialize(buffer, true)
serializeBytes(encryptedMessage, buffer: buffer, boxed: false) serializeBytes(encryptedMessage, buffer: buffer, boxed: false)
break break
case .updateGroupCallMessage(let call, let fromId, let message): case .updateGroupCallMessage(let call, let fromId, let randomId, let message):
if boxed { if boxed {
buffer.appendInt32(-1761933248) buffer.appendInt32(2026050784)
} }
call.serialize(buffer, true) call.serialize(buffer, true)
fromId.serialize(buffer, true) fromId.serialize(buffer, true)
serializeInt64(randomId, buffer: buffer, boxed: false)
message.serialize(buffer, true) message.serialize(buffer, true)
break break
case .updateGroupCallParticipants(let call, let participants, let version): case .updateGroupCallParticipants(let call, let participants, let version):
@ -2117,8 +2118,8 @@ public extension Api {
return ("updateGroupCallConnection", [("flags", flags as Any), ("params", params as Any)]) return ("updateGroupCallConnection", [("flags", flags as Any), ("params", params as Any)])
case .updateGroupCallEncryptedMessage(let call, let fromId, let encryptedMessage): case .updateGroupCallEncryptedMessage(let call, let fromId, let encryptedMessage):
return ("updateGroupCallEncryptedMessage", [("call", call as Any), ("fromId", fromId as Any), ("encryptedMessage", encryptedMessage as Any)]) return ("updateGroupCallEncryptedMessage", [("call", call as Any), ("fromId", fromId as Any), ("encryptedMessage", encryptedMessage as Any)])
case .updateGroupCallMessage(let call, let fromId, let message): case .updateGroupCallMessage(let call, let fromId, let randomId, let message):
return ("updateGroupCallMessage", [("call", call as Any), ("fromId", fromId as Any), ("message", message as Any)]) return ("updateGroupCallMessage", [("call", call as Any), ("fromId", fromId as Any), ("randomId", randomId as Any), ("message", message as Any)])
case .updateGroupCallParticipants(let call, let participants, let version): case .updateGroupCallParticipants(let call, let participants, let version):
return ("updateGroupCallParticipants", [("call", call as Any), ("participants", participants as Any), ("version", version as Any)]) return ("updateGroupCallParticipants", [("call", call as Any), ("participants", participants as Any), ("version", version as Any)])
case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName): case .updateInlineBotCallbackQuery(let flags, let queryId, let userId, let msgId, let chatInstance, let data, let gameShortName):
@ -3598,15 +3599,18 @@ public extension Api {
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_2 = Api.parse(reader, signature: signature) as? Api.Peer _2 = Api.parse(reader, signature: signature) as? Api.Peer
} }
var _3: Api.TextWithEntities? var _3: Int64?
_3 = reader.readInt64()
var _4: Api.TextWithEntities?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_3 = Api.parse(reader, signature: signature) as? Api.TextWithEntities _4 = Api.parse(reader, signature: signature) as? Api.TextWithEntities
} }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
if _c1 && _c2 && _c3 { let _c4 = _4 != nil
return Api.Update.updateGroupCallMessage(call: _1!, fromId: _2!, message: _3!) if _c1 && _c2 && _c3 && _c4 {
return Api.Update.updateGroupCallMessage(call: _1!, fromId: _2!, randomId: _3!, message: _4!)
} }
else { else {
return nil return nil

View File

@ -10829,12 +10829,13 @@ public extension Api.functions.phone {
} }
} }
public extension Api.functions.phone { public extension Api.functions.phone {
static func sendGroupCallMessage(call: Api.InputGroupCall, message: Api.TextWithEntities) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) { static func sendGroupCallMessage(call: Api.InputGroupCall, randomId: Int64, message: Api.TextWithEntities) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Bool>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(-614432696) buffer.appendInt32(-2021052396)
call.serialize(buffer, true) call.serialize(buffer, true)
serializeInt64(randomId, buffer: buffer, boxed: false)
message.serialize(buffer, true) message.serialize(buffer, true)
return (FunctionDescription(name: "phone.sendGroupCallMessage", parameters: [("call", String(describing: call)), ("message", String(describing: message))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in return (FunctionDescription(name: "phone.sendGroupCallMessage", parameters: [("call", String(describing: call)), ("randomId", String(describing: randomId)), ("message", String(describing: message))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Bool? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Bool? var result: Api.Bool?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
@ -10912,13 +10913,14 @@ public extension Api.functions.phone {
} }
} }
public extension Api.functions.phone { public extension Api.functions.phone {
static func toggleGroupCallSettings(flags: Int32, call: Api.InputGroupCall, joinMuted: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) { static func toggleGroupCallSettings(flags: Int32, call: Api.InputGroupCall, joinMuted: Api.Bool?, messagesEnabled: Api.Bool?) -> (FunctionDescription, Buffer, DeserializeFunctionResponse<Api.Updates>) {
let buffer = Buffer() let buffer = Buffer()
buffer.appendInt32(1958458429) buffer.appendInt32(-378390524)
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
call.serialize(buffer, true) call.serialize(buffer, true)
if Int(flags) & Int(1 << 0) != 0 {joinMuted!.serialize(buffer, true)} if Int(flags) & Int(1 << 0) != 0 {joinMuted!.serialize(buffer, true)}
return (FunctionDescription(name: "phone.toggleGroupCallSettings", parameters: [("flags", String(describing: flags)), ("call", String(describing: call)), ("joinMuted", String(describing: joinMuted))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in if Int(flags) & Int(1 << 2) != 0 {messagesEnabled!.serialize(buffer, true)}
return (FunctionDescription(name: "phone.toggleGroupCallSettings", parameters: [("flags", String(describing: flags)), ("call", String(describing: call)), ("joinMuted", String(describing: joinMuted)), ("messagesEnabled", String(describing: messagesEnabled))]), buffer, DeserializeFunctionResponse { (buffer: Buffer) -> Api.Updates? in
let reader = BufferReader(buffer) let reader = BufferReader(buffer)
var result: Api.Updates? var result: Api.Updates?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {

View File

@ -824,18 +824,19 @@ public extension Api {
} }
public extension Api { public extension Api {
indirect enum ForumTopic: TypeConstructorDescription { indirect enum ForumTopic: TypeConstructorDescription {
case forumTopic(flags: Int32, id: Int32, date: Int32, title: String, iconColor: Int32, iconEmojiId: Int64?, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, unreadMentionsCount: Int32, unreadReactionsCount: Int32, fromId: Api.Peer, notifySettings: Api.PeerNotifySettings, draft: Api.DraftMessage?) case forumTopic(flags: Int32, id: Int32, date: Int32, peer: Api.Peer, title: String, iconColor: Int32, iconEmojiId: Int64?, topMessage: Int32, readInboxMaxId: Int32, readOutboxMaxId: Int32, unreadCount: Int32, unreadMentionsCount: Int32, unreadReactionsCount: Int32, fromId: Api.Peer, notifySettings: Api.PeerNotifySettings, draft: Api.DraftMessage?)
case forumTopicDeleted(id: Int32) case forumTopicDeleted(id: Int32)
public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) { public func serialize(_ buffer: Buffer, _ boxed: Swift.Bool) {
switch self { switch self {
case .forumTopic(let flags, let id, let date, let title, let iconColor, let iconEmojiId, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let unreadReactionsCount, let fromId, let notifySettings, let draft): case .forumTopic(let flags, let id, let date, let peer, let title, let iconColor, let iconEmojiId, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let unreadReactionsCount, let fromId, let notifySettings, let draft):
if boxed { if boxed {
buffer.appendInt32(1903173033) buffer.appendInt32(-838922550)
} }
serializeInt32(flags, buffer: buffer, boxed: false) serializeInt32(flags, buffer: buffer, boxed: false)
serializeInt32(id, buffer: buffer, boxed: false) serializeInt32(id, buffer: buffer, boxed: false)
serializeInt32(date, buffer: buffer, boxed: false) serializeInt32(date, buffer: buffer, boxed: false)
peer.serialize(buffer, true)
serializeString(title, buffer: buffer, boxed: false) serializeString(title, buffer: buffer, boxed: false)
serializeInt32(iconColor, buffer: buffer, boxed: false) serializeInt32(iconColor, buffer: buffer, boxed: false)
if Int(flags) & Int(1 << 0) != 0 {serializeInt64(iconEmojiId!, buffer: buffer, boxed: false)} if Int(flags) & Int(1 << 0) != 0 {serializeInt64(iconEmojiId!, buffer: buffer, boxed: false)}
@ -860,8 +861,8 @@ public extension Api {
public func descriptionFields() -> (String, [(String, Any)]) { public func descriptionFields() -> (String, [(String, Any)]) {
switch self { switch self {
case .forumTopic(let flags, let id, let date, let title, let iconColor, let iconEmojiId, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let unreadReactionsCount, let fromId, let notifySettings, let draft): case .forumTopic(let flags, let id, let date, let peer, let title, let iconColor, let iconEmojiId, let topMessage, let readInboxMaxId, let readOutboxMaxId, let unreadCount, let unreadMentionsCount, let unreadReactionsCount, let fromId, let notifySettings, let draft):
return ("forumTopic", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("title", title as Any), ("iconColor", iconColor as Any), ("iconEmojiId", iconEmojiId as Any), ("topMessage", topMessage as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("unreadMentionsCount", unreadMentionsCount as Any), ("unreadReactionsCount", unreadReactionsCount as Any), ("fromId", fromId as Any), ("notifySettings", notifySettings as Any), ("draft", draft as Any)]) return ("forumTopic", [("flags", flags as Any), ("id", id as Any), ("date", date as Any), ("peer", peer as Any), ("title", title as Any), ("iconColor", iconColor as Any), ("iconEmojiId", iconEmojiId as Any), ("topMessage", topMessage as Any), ("readInboxMaxId", readInboxMaxId as Any), ("readOutboxMaxId", readOutboxMaxId as Any), ("unreadCount", unreadCount as Any), ("unreadMentionsCount", unreadMentionsCount as Any), ("unreadReactionsCount", unreadReactionsCount as Any), ("fromId", fromId as Any), ("notifySettings", notifySettings as Any), ("draft", draft as Any)])
case .forumTopicDeleted(let id): case .forumTopicDeleted(let id):
return ("forumTopicDeleted", [("id", id as Any)]) return ("forumTopicDeleted", [("id", id as Any)])
} }
@ -874,14 +875,16 @@ public extension Api {
_2 = reader.readInt32() _2 = reader.readInt32()
var _3: Int32? var _3: Int32?
_3 = reader.readInt32() _3 = reader.readInt32()
var _4: String? var _4: Api.Peer?
_4 = parseString(reader) if let signature = reader.readInt32() {
var _5: Int32? _4 = Api.parse(reader, signature: signature) as? Api.Peer
_5 = reader.readInt32() }
var _6: Int64? var _5: String?
if Int(_1!) & Int(1 << 0) != 0 {_6 = reader.readInt64() } _5 = parseString(reader)
var _7: Int32? var _6: Int32?
_7 = reader.readInt32() _6 = reader.readInt32()
var _7: Int64?
if Int(_1!) & Int(1 << 0) != 0 {_7 = reader.readInt64() }
var _8: Int32? var _8: Int32?
_8 = reader.readInt32() _8 = reader.readInt32()
var _9: Int32? var _9: Int32?
@ -892,25 +895,27 @@ public extension Api {
_11 = reader.readInt32() _11 = reader.readInt32()
var _12: Int32? var _12: Int32?
_12 = reader.readInt32() _12 = reader.readInt32()
var _13: Api.Peer? var _13: Int32?
_13 = reader.readInt32()
var _14: Api.Peer?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_13 = Api.parse(reader, signature: signature) as? Api.Peer _14 = Api.parse(reader, signature: signature) as? Api.Peer
} }
var _14: Api.PeerNotifySettings? var _15: Api.PeerNotifySettings?
if let signature = reader.readInt32() { if let signature = reader.readInt32() {
_14 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings _15 = Api.parse(reader, signature: signature) as? Api.PeerNotifySettings
} }
var _15: Api.DraftMessage? var _16: Api.DraftMessage?
if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() { if Int(_1!) & Int(1 << 4) != 0 {if let signature = reader.readInt32() {
_15 = Api.parse(reader, signature: signature) as? Api.DraftMessage _16 = Api.parse(reader, signature: signature) as? Api.DraftMessage
} } } }
let _c1 = _1 != nil let _c1 = _1 != nil
let _c2 = _2 != nil let _c2 = _2 != nil
let _c3 = _3 != nil let _c3 = _3 != nil
let _c4 = _4 != nil let _c4 = _4 != nil
let _c5 = _5 != nil let _c5 = _5 != nil
let _c6 = (Int(_1!) & Int(1 << 0) == 0) || _6 != nil let _c6 = _6 != nil
let _c7 = _7 != nil let _c7 = (Int(_1!) & Int(1 << 0) == 0) || _7 != nil
let _c8 = _8 != nil let _c8 = _8 != nil
let _c9 = _9 != nil let _c9 = _9 != nil
let _c10 = _10 != nil let _c10 = _10 != nil
@ -918,9 +923,10 @@ public extension Api {
let _c12 = _12 != nil let _c12 = _12 != nil
let _c13 = _13 != nil let _c13 = _13 != nil
let _c14 = _14 != nil let _c14 = _14 != nil
let _c15 = (Int(_1!) & Int(1 << 4) == 0) || _15 != nil let _c15 = _15 != nil
if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 { let _c16 = (Int(_1!) & Int(1 << 4) == 0) || _16 != nil
return Api.ForumTopic.forumTopic(flags: _1!, id: _2!, date: _3!, title: _4!, iconColor: _5!, iconEmojiId: _6, topMessage: _7!, readInboxMaxId: _8!, readOutboxMaxId: _9!, unreadCount: _10!, unreadMentionsCount: _11!, unreadReactionsCount: _12!, fromId: _13!, notifySettings: _14!, draft: _15) if _c1 && _c2 && _c3 && _c4 && _c5 && _c6 && _c7 && _c8 && _c9 && _c10 && _c11 && _c12 && _c13 && _c14 && _c15 && _c16 {
return Api.ForumTopic.forumTopic(flags: _1!, id: _2!, date: _3!, peer: _4!, title: _5!, iconColor: _6!, iconEmojiId: _7, topMessage: _8!, readInboxMaxId: _9!, readOutboxMaxId: _10!, unreadCount: _11!, unreadMentionsCount: _12!, unreadReactionsCount: _13!, fromId: _14!, notifySettings: _15!, draft: _16)
} }
else { else {
return nil return nil

View File

@ -96,6 +96,7 @@ public final class AccountGroupCallContextImpl: AccountGroupCallContext {
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
sortAscending: state.sortAscending, sortAscending: state.sortAscending,
defaultParticipantsAreMuted: state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: state.defaultParticipantsAreMuted,
messagesAreEnabled: state.messagesAreEnabled,
isVideoEnabled: state.isVideoEnabled, isVideoEnabled: state.isVideoEnabled,
unmutedVideoLimit: state.unmutedVideoLimit, unmutedVideoLimit: state.unmutedVideoLimit,
isStream: state.isStream, isStream: state.isStream,

View File

@ -72,7 +72,7 @@ final class MessageItemComponent: Component {
self.background = GlassBackgroundView() self.background = GlassBackgroundView()
self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 10.0)) self.avatarNode = AvatarNode(font: avatarPlaceholderFont(size: 12.0))
self.text = ComponentView() self.text = ComponentView()

View File

@ -28,6 +28,7 @@ private extension PresentationGroupCallState {
adminIds: Set(), adminIds: Set(),
muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false), muteState: GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: false),
defaultParticipantMuteState: nil, defaultParticipantMuteState: nil,
messagesAreEnabled: true,
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
title: title, title: title,
raisedHand: false, raisedHand: false,
@ -1537,6 +1538,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
adminIds: Set(), adminIds: Set(),
isCreator: false, isCreator: false,
defaultParticipantsAreMuted: callInfo.defaultParticipantsAreMuted ?? GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: self.stateValue.defaultParticipantMuteState == .muted, canChange: true), defaultParticipantsAreMuted: callInfo.defaultParticipantsAreMuted ?? GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: self.stateValue.defaultParticipantMuteState == .muted, canChange: true),
messagesAreEnabled: callInfo.messagesAreEnabled ?? GroupCallParticipantsContext.State.MessagesAreEnabled(isEnabled: self.stateValue.messagesAreEnabled, canChange: true),
sortAscending: true, sortAscending: true,
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
title: self.stateValue.title, title: self.stateValue.title,
@ -1657,6 +1659,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
sortAscending: true, sortAscending: true,
defaultParticipantsAreMuted: callInfo.defaultParticipantsAreMuted ?? state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: callInfo.defaultParticipantsAreMuted ?? state.defaultParticipantsAreMuted,
messagesAreEnabled: callInfo.messagesAreEnabled ?? state.messagesAreEnabled,
isVideoEnabled: callInfo.isVideoEnabled, isVideoEnabled: callInfo.isVideoEnabled,
unmutedVideoLimit: callInfo.unmutedVideoLimit, unmutedVideoLimit: callInfo.unmutedVideoLimit,
isStream: callInfo.isStream, isStream: callInfo.isStream,
@ -1674,6 +1677,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
recordingStartTimestamp: state.recordingStartTimestamp, recordingStartTimestamp: state.recordingStartTimestamp,
sortAscending: state.sortAscending, sortAscending: state.sortAscending,
defaultParticipantsAreMuted: state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: state.defaultParticipantsAreMuted,
messagesAreEnabled: state.messagesAreEnabled,
isVideoEnabled: state.isVideoEnabled, isVideoEnabled: state.isVideoEnabled,
unmutedVideoLimit: state.unmutedVideoLimit, unmutedVideoLimit: state.unmutedVideoLimit,
isStream: callInfo.isStream, isStream: callInfo.isStream,
@ -2628,6 +2632,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
recordingStartTimestamp: state.recordingStartTimestamp, recordingStartTimestamp: state.recordingStartTimestamp,
sortAscending: state.sortAscending, sortAscending: state.sortAscending,
defaultParticipantsAreMuted: state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: state.defaultParticipantsAreMuted,
messagesAreEnabled: state.messagesAreEnabled,
isVideoEnabled: state.isVideoEnabled, isVideoEnabled: state.isVideoEnabled,
unmutedVideoLimit: state.unmutedVideoLimit, unmutedVideoLimit: state.unmutedVideoLimit,
isStream: callInfo.isStream, isStream: callInfo.isStream,
@ -3994,7 +3999,7 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
public func sendMessage(text: String, entities: [MessageTextEntity]) { public func sendMessage(text: String, entities: [MessageTextEntity]) {
if let messagesContext = self.messagesContext { if let messagesContext = self.messagesContext {
messagesContext.send(text: text, entities: entities) messagesContext.send(fromId: self.joinAsPeerId, text: text, entities: entities)
} }
} }
} }

View File

@ -1181,6 +1181,7 @@ final class VideoChatScreenComponent: Component {
adminIds: Set([accountPeerId, conferenceSourcePeerId]), adminIds: Set([accountPeerId, conferenceSourcePeerId]),
muteState: isMuted ? GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: true) : nil, muteState: isMuted ? GroupCallParticipantsContext.Participant.MuteState(canUnmute: true, mutedByYou: true) : nil,
defaultParticipantMuteState: nil, defaultParticipantMuteState: nil,
messagesAreEnabled: true,
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
title: nil, title: nil,
raisedHand: false, raisedHand: false,

View File

@ -118,7 +118,7 @@ enum AccountStateMutationOperation {
case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32) case UpdateGroupCallParticipants(id: Int64, accessHash: Int64, participants: [Api.GroupCallParticipant], version: Int32)
case UpdateGroupCall(peerId: PeerId?, call: Api.GroupCall) case UpdateGroupCall(peerId: PeerId?, call: Api.GroupCall)
case UpdateGroupCallChainBlocks(id: Int64, accessHash: Int64, subChainId: Int32, blocks: [Data], nextOffset: Int32) case UpdateGroupCallChainBlocks(id: Int64, accessHash: Int64, subChainId: Int32, blocks: [Data], nextOffset: Int32)
case UpdateGroupCallMessage(id: Int64, authorId: PeerId, text: Api.TextWithEntities) case UpdateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities)
case UpdateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) case UpdateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data)
case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?) case UpdateAutoremoveTimeout(peer: Api.Peer, value: CachedPeerAutoremoveTimeout.Value?)
case UpdateAttachMenuBots case UpdateAttachMenuBots
@ -411,8 +411,8 @@ struct AccountMutableState {
self.addOperation(.UpdateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks, nextOffset: nextOffset)) self.addOperation(.UpdateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks, nextOffset: nextOffset))
} }
mutating func updateGroupCallMessage(id: Int64, authorId: PeerId, text: Api.TextWithEntities) { mutating func updateGroupCallMessage(id: Int64, authorId: PeerId, randomId: Int64, text: Api.TextWithEntities) {
self.addOperation(.UpdateGroupCallMessage(id: id, authorId: authorId, text: text)) self.addOperation(.UpdateGroupCallMessage(id: id, authorId: authorId, randomId: randomId, text: text))
} }
mutating func updateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) { mutating func updateGroupCallOpaqueMessage(id: Int64, authorId: PeerId, data: Data) {

View File

@ -991,8 +991,9 @@ func _internal_requestMessageHistoryThreads(accountPeerId: PeerId, postbox: Post
for topic in topics { for topic in topics {
switch topic { switch topic {
case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): case let .forumTopic(flags, id, date, peer, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft):
let _ = draft let _ = draft
let _ = peer
if (flags & (1 << 3)) != 0 { if (flags & (1 << 3)) != 0 {
pinnedIds.append(Int64(id)) pinnedIds.append(Int64(id))
@ -1198,7 +1199,7 @@ func _internal_forumChannelTopicNotificationExceptions(account: Account, id: Eng
case let .forumTopics(_, _, topics, _, _, _, _): case let .forumTopics(_, _, topics, _, _, _, _):
for topic in topics { for topic in topics {
switch topic { switch topic {
case let .forumTopic(_, id, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(_, id, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
infoMapping[Int64(id)] = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor) infoMapping[Int64(id)] = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor)
case .forumTopicDeleted: case .forumTopicDeleted:
break break

View File

@ -1684,9 +1684,9 @@ private func finalStateWithUpdatesAndServerTime(accountPeerId: PeerId, postbox:
if case let .inputGroupCall(id, accessHash) = call { if case let .inputGroupCall(id, accessHash) = call {
updatedState.updateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks.map { $0.makeData() }, nextOffset: nextOffset) updatedState.updateGroupCallChainBlocks(id: id, accessHash: accessHash, subChainId: subChainId, blocks: blocks.map { $0.makeData() }, nextOffset: nextOffset)
} }
case let .updateGroupCallMessage(call, fromId, message): case let .updateGroupCallMessage(call, fromId, randomId, message):
if case let .inputGroupCall(id, _) = call { if case let .inputGroupCall(id, _) = call {
updatedState.updateGroupCallMessage(id: id, authorId: fromId.peerId, text: message) updatedState.updateGroupCallMessage(id: id, authorId: fromId.peerId, randomId: randomId, text: message)
} }
case let .updateGroupCallEncryptedMessage(call, fromId, encryptedMessage): case let .updateGroupCallEncryptedMessage(call, fromId, encryptedMessage):
if case let .inputGroupCall(id, _) = call { if case let .inputGroupCall(id, _) = call {
@ -2122,7 +2122,8 @@ func resolveForumThreads(accountPeerId: PeerId, postbox: Postbox, source: FetchM
switch topic { switch topic {
case let .forum(topic): case let .forum(topic):
switch topic { switch topic {
case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): case let .forumTopic(flags, id, date, peer, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft):
let _ = peer
let _ = draft let _ = draft
state.operations.append(.ResetForumTopic( state.operations.append(.ResetForumTopic(
@ -2286,7 +2287,8 @@ func resolveForumThreads(accountPeerId: PeerId, postbox: Postbox, source: FetchM
switch item { switch item {
case let .forum(topic): case let .forum(topic):
switch topic { switch topic {
case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): case let .forumTopic(flags, id, date, peer, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft):
let _ = peer
let _ = draft let _ = draft
let data = MessageHistoryThreadData( let data = MessageHistoryThreadData(
@ -2452,7 +2454,8 @@ func resolveForumThreads(accountPeerId: PeerId, postbox: Postbox, source: FetchM
switch item { switch item {
case let .forum(topic): case let .forum(topic):
switch topic { switch topic {
case let .forumTopic(flags, id, date, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft): case let .forumTopic(flags, id, date, peer, title, iconColor, iconEmojiId, topMessage, readInboxMaxId, readOutboxMaxId, unreadCount, unreadMentionsCount, unreadReactionsCount, fromId, notifySettings, draft):
let _ = peer
let _ = draft let _ = draft
fetchedChatList.threadInfos[PeerAndBoundThreadId(peerId: peerId, threadId: Int64(id))] = StoreMessageHistoryThreadData( fetchedChatList.threadInfos[PeerAndBoundThreadId(peerId: peerId, threadId: Int64(id))] = StoreMessageHistoryThreadData(
@ -4877,10 +4880,10 @@ func replayFinalState(
callId, callId,
.state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version)) .state(update: GroupCallParticipantsContext.Update.StateUpdate(participants: participants, version: version))
)) ))
case let .UpdateGroupCallMessage(callId, authorId, text): case let .UpdateGroupCallMessage(callId, authorId, randomId, text):
switch text { switch text {
case let .textWithEntities(text, entities): case let .textWithEntities(text, entities):
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newPlaintextMessage(authorId: authorId, text: text, entities: messageTextEntitiesFromApiEntities(entities)))) groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newPlaintextMessage(authorId: authorId, randomId: randomId, text: text, entities: messageTextEntitiesFromApiEntities(entities))))
} }
case let .UpdateGroupCallOpaqueMessage(callId, authorId, data): case let .UpdateGroupCallOpaqueMessage(callId, authorId, data):
groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newOpaqueMessage(authorId: authorId, data: data))) groupCallMessageUpdates.append(GroupCallMessageUpdate(callId: callId, update: .newOpaqueMessage(authorId: authorId, data: data)))

View File

@ -94,6 +94,7 @@ public struct GroupCallInfo: Equatable {
public var recordingStartTimestamp: Int32? public var recordingStartTimestamp: Int32?
public var sortAscending: Bool public var sortAscending: Bool
public var defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted? public var defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?
public var messagesAreEnabled: GroupCallParticipantsContext.State.MessagesAreEnabled?
public var isVideoEnabled: Bool public var isVideoEnabled: Bool
public var unmutedVideoLimit: Int public var unmutedVideoLimit: Int
public var isStream: Bool public var isStream: Bool
@ -110,6 +111,7 @@ public struct GroupCallInfo: Equatable {
recordingStartTimestamp: Int32?, recordingStartTimestamp: Int32?,
sortAscending: Bool, sortAscending: Bool,
defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?, defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?,
messagesAreEnabled: GroupCallParticipantsContext.State.MessagesAreEnabled?,
isVideoEnabled: Bool, isVideoEnabled: Bool,
unmutedVideoLimit: Int, unmutedVideoLimit: Int,
isStream: Bool, isStream: Bool,
@ -125,6 +127,7 @@ public struct GroupCallInfo: Equatable {
self.recordingStartTimestamp = recordingStartTimestamp self.recordingStartTimestamp = recordingStartTimestamp
self.sortAscending = sortAscending self.sortAscending = sortAscending
self.defaultParticipantsAreMuted = defaultParticipantsAreMuted self.defaultParticipantsAreMuted = defaultParticipantsAreMuted
self.messagesAreEnabled = messagesAreEnabled
self.isVideoEnabled = isVideoEnabled self.isVideoEnabled = isVideoEnabled
self.unmutedVideoLimit = unmutedVideoLimit self.unmutedVideoLimit = unmutedVideoLimit
self.isStream = isStream self.isStream = isStream
@ -152,6 +155,7 @@ extension GroupCallInfo {
recordingStartTimestamp: recordStartDate, recordingStartTimestamp: recordStartDate,
sortAscending: (flags & (1 << 6)) != 0, sortAscending: (flags & (1 << 6)) != 0,
defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: (flags & (1 << 1)) != 0, canChange: (flags & (1 << 2)) != 0), defaultParticipantsAreMuted: GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: (flags & (1 << 1)) != 0, canChange: (flags & (1 << 2)) != 0),
messagesAreEnabled: GroupCallParticipantsContext.State.MessagesAreEnabled(isEnabled: (flags & (1 << 17)) != 0, canChange: (flags & (1 << 18)) != 0),
isVideoEnabled: (flags & (1 << 9)) != 0, isVideoEnabled: (flags & (1 << 9)) != 0,
unmutedVideoLimit: Int(unmutedVideoLimit), unmutedVideoLimit: Int(unmutedVideoLimit),
isStream: (flags & (1 << 12)) != 0, isStream: (flags & (1 << 12)) != 0,
@ -506,17 +510,17 @@ public enum GetGroupCallParticipantsError {
func _internal_getGroupCallParticipants(account: Account, reference: InternalGroupCallReference, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> { func _internal_getGroupCallParticipants(account: Account, reference: InternalGroupCallReference, offset: String, ssrcs: [UInt32], limit: Int32, sortAscending: Bool?) -> Signal<GroupCallParticipantsContext.State, GetGroupCallParticipantsError> {
let accountPeerId = account.peerId let accountPeerId = account.peerId
let sortAscendingValue: Signal<(Bool, Int32?, Bool, GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?, Bool, Int, Bool, Bool), GetGroupCallParticipantsError> let sortAscendingValue: Signal<(Bool, Int32?, Bool, GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?, GroupCallParticipantsContext.State.MessagesAreEnabled?, Bool, Int, Bool, Bool), GetGroupCallParticipantsError>
sortAscendingValue = _internal_getCurrentGroupCall(account: account, reference: reference) sortAscendingValue = _internal_getCurrentGroupCall(account: account, reference: reference)
|> mapError { _ -> GetGroupCallParticipantsError in |> mapError { _ -> GetGroupCallParticipantsError in
return .generic return .generic
} }
|> mapToSignal { result -> Signal<(Bool, Int32?, Bool, GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?, Bool, Int, Bool, Bool), GetGroupCallParticipantsError> in |> mapToSignal { result -> Signal<(Bool, Int32?, Bool, GroupCallParticipantsContext.State.DefaultParticipantsAreMuted?, GroupCallParticipantsContext.State.MessagesAreEnabled?, Bool, Int, Bool, Bool), GetGroupCallParticipantsError> in
guard let result = result else { guard let result = result else {
return .fail(.generic) return .fail(.generic)
} }
return .single((sortAscending ?? result.info.sortAscending, result.info.scheduleTimestamp, result.info.subscribedToScheduled, result.info.defaultParticipantsAreMuted, result.info.isVideoEnabled, result.info.unmutedVideoLimit, result.info.isStream, result.info.isCreator)) return .single((sortAscending ?? result.info.sortAscending, result.info.scheduleTimestamp, result.info.subscribedToScheduled, result.info.defaultParticipantsAreMuted, result.info.messagesAreEnabled, result.info.isVideoEnabled, result.info.unmutedVideoLimit, result.info.isStream, result.info.isCreator))
} }
return combineLatest( return combineLatest(
@ -533,7 +537,7 @@ func _internal_getGroupCallParticipants(account: Account, reference: InternalGro
let version: Int32 let version: Int32
let nextParticipantsFetchOffset: String? let nextParticipantsFetchOffset: String?
let (sortAscendingValue, scheduleTimestamp, subscribedToScheduled, defaultParticipantsAreMuted, isVideoEnabled, unmutedVideoLimit, isStream, isCreator) = sortAscendingAndScheduleTimestamp let (sortAscendingValue, scheduleTimestamp, subscribedToScheduled, defaultParticipantsAreMuted, messagesAreEnabled, isVideoEnabled, unmutedVideoLimit, isStream, isCreator) = sortAscendingAndScheduleTimestamp
switch result { switch result {
case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion): case let .groupParticipants(count, participants, nextOffset, chats, users, apiVersion):
@ -560,6 +564,7 @@ func _internal_getGroupCallParticipants(account: Account, reference: InternalGro
adminIds: Set(), adminIds: Set(),
isCreator: isCreator, isCreator: isCreator,
defaultParticipantsAreMuted: defaultParticipantsAreMuted ?? GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false), defaultParticipantsAreMuted: defaultParticipantsAreMuted ?? GroupCallParticipantsContext.State.DefaultParticipantsAreMuted(isMuted: false, canChange: false),
messagesAreEnabled: messagesAreEnabled ?? GroupCallParticipantsContext.State.MessagesAreEnabled(isEnabled: true, canChange: false),
sortAscending: sortAscendingValue, sortAscending: sortAscendingValue,
recordingStartTimestamp: nil, recordingStartTimestamp: nil,
title: nil, title: nil,
@ -1374,11 +1379,22 @@ public final class GroupCallParticipantsContext {
} }
} }
public struct MessagesAreEnabled: Equatable {
public var isEnabled: Bool
public var canChange: Bool
public init(isEnabled: Bool, canChange: Bool) {
self.isEnabled = isEnabled
self.canChange = canChange
}
}
public var participants: [Participant] public var participants: [Participant]
public var nextParticipantsFetchOffset: String? public var nextParticipantsFetchOffset: String?
public var adminIds: Set<PeerId> public var adminIds: Set<PeerId>
public var isCreator: Bool public var isCreator: Bool
public var defaultParticipantsAreMuted: DefaultParticipantsAreMuted public var defaultParticipantsAreMuted: DefaultParticipantsAreMuted
public var messagesAreEnabled: MessagesAreEnabled
public var sortAscending: Bool public var sortAscending: Bool
public var recordingStartTimestamp: Int32? public var recordingStartTimestamp: Int32?
public var title: String? public var title: String?
@ -1416,6 +1432,7 @@ public final class GroupCallParticipantsContext {
adminIds: Set<PeerId>, adminIds: Set<PeerId>,
isCreator: Bool, isCreator: Bool,
defaultParticipantsAreMuted: DefaultParticipantsAreMuted, defaultParticipantsAreMuted: DefaultParticipantsAreMuted,
messagesAreEnabled: MessagesAreEnabled,
sortAscending: Bool, sortAscending: Bool,
recordingStartTimestamp: Int32?, recordingStartTimestamp: Int32?,
title: String?, title: String?,
@ -1432,6 +1449,7 @@ public final class GroupCallParticipantsContext {
self.adminIds = adminIds self.adminIds = adminIds
self.isCreator = isCreator self.isCreator = isCreator
self.defaultParticipantsAreMuted = defaultParticipantsAreMuted self.defaultParticipantsAreMuted = defaultParticipantsAreMuted
self.messagesAreEnabled = messagesAreEnabled
self.sortAscending = sortAscending self.sortAscending = sortAscending
self.recordingStartTimestamp = recordingStartTimestamp self.recordingStartTimestamp = recordingStartTimestamp
self.title = title self.title = title
@ -1708,6 +1726,7 @@ public final class GroupCallParticipantsContext {
private let updateDefaultMuteDisposable = MetaDisposable() private let updateDefaultMuteDisposable = MetaDisposable()
private let resetInviteLinksDisposable = MetaDisposable() private let resetInviteLinksDisposable = MetaDisposable()
private let updateShouldBeRecordingDisposable = MetaDisposable() private let updateShouldBeRecordingDisposable = MetaDisposable()
private let updateMessagesEnabledDisposable = MetaDisposable()
private let subscribeDisposable = MetaDisposable() private let subscribeDisposable = MetaDisposable()
private var localVideoIsMuted: Bool? = nil private var localVideoIsMuted: Bool? = nil
@ -1801,6 +1820,7 @@ public final class GroupCallParticipantsContext {
adminIds: strongSelf.stateValue.state.adminIds, adminIds: strongSelf.stateValue.state.adminIds,
isCreator: strongSelf.stateValue.state.isCreator, isCreator: strongSelf.stateValue.state.isCreator,
defaultParticipantsAreMuted: strongSelf.stateValue.state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: strongSelf.stateValue.state.defaultParticipantsAreMuted,
messagesAreEnabled: strongSelf.stateValue.state.messagesAreEnabled,
sortAscending: strongSelf.stateValue.state.sortAscending, sortAscending: strongSelf.stateValue.state.sortAscending,
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
title: strongSelf.stateValue.state.title, title: strongSelf.stateValue.state.title,
@ -1916,6 +1936,7 @@ public final class GroupCallParticipantsContext {
self.activitiesDisposable?.dispose() self.activitiesDisposable?.dispose()
self.updateDefaultMuteDisposable.dispose() self.updateDefaultMuteDisposable.dispose()
self.updateShouldBeRecordingDisposable.dispose() self.updateShouldBeRecordingDisposable.dispose()
self.updateMessagesEnabledDisposable.dispose()
self.activityRankResetTimer?.invalidate() self.activityRankResetTimer?.invalidate()
self.resetInviteLinksDisposable.dispose() self.resetInviteLinksDisposable.dispose()
self.subscribeDisposable.dispose() self.subscribeDisposable.dispose()
@ -2029,6 +2050,7 @@ public final class GroupCallParticipantsContext {
adminIds: strongSelf.stateValue.state.adminIds, adminIds: strongSelf.stateValue.state.adminIds,
isCreator: strongSelf.stateValue.state.isCreator, isCreator: strongSelf.stateValue.state.isCreator,
defaultParticipantsAreMuted: strongSelf.stateValue.state.defaultParticipantsAreMuted, defaultParticipantsAreMuted: strongSelf.stateValue.state.defaultParticipantsAreMuted,
messagesAreEnabled: strongSelf.stateValue.state.messagesAreEnabled,
sortAscending: strongSelf.stateValue.state.sortAscending, sortAscending: strongSelf.stateValue.state.sortAscending,
recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp, recordingStartTimestamp: strongSelf.stateValue.state.recordingStartTimestamp,
title: strongSelf.stateValue.state.title, title: strongSelf.stateValue.state.title,
@ -2273,6 +2295,7 @@ public final class GroupCallParticipantsContext {
adminIds: adminIds, adminIds: adminIds,
isCreator: isCreator, isCreator: isCreator,
defaultParticipantsAreMuted: defaultParticipantsAreMuted, defaultParticipantsAreMuted: defaultParticipantsAreMuted,
messagesAreEnabled: strongSelf.stateValue.state.messagesAreEnabled,
sortAscending: strongSelf.stateValue.state.sortAscending, sortAscending: strongSelf.stateValue.state.sortAscending,
recordingStartTimestamp: recordingStartTimestamp, recordingStartTimestamp: recordingStartTimestamp,
title: title, title: title,
@ -2550,7 +2573,22 @@ public final class GroupCallParticipantsContext {
} }
self.stateValue.state.defaultParticipantsAreMuted.isMuted = isMuted self.stateValue.state.defaultParticipantsAreMuted.isMuted = isMuted
self.updateDefaultMuteDisposable.set((self.account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 0, call: self.reference.apiInputGroupCall, joinMuted: isMuted ? .boolTrue : .boolFalse)) self.updateDefaultMuteDisposable.set((self.account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 0, call: self.reference.apiInputGroupCall, joinMuted: isMuted ? .boolTrue : .boolFalse, messagesEnabled: nil))
|> deliverOnMainQueue).start(next: { [weak self] updates in
guard let strongSelf = self else {
return
}
strongSelf.account.stateManager.addUpdates(updates)
}))
}
public func updateMessagesEnabled(isEnabled: Bool) {
if isEnabled == self.stateValue.state.messagesAreEnabled.isEnabled {
return
}
self.stateValue.state.messagesAreEnabled.isEnabled = isEnabled
self.updateDefaultMuteDisposable.set((self.account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 2, call: self.reference.apiInputGroupCall, joinMuted: nil, messagesEnabled: isEnabled ? .boolTrue : .boolFalse))
|> deliverOnMainQueue).start(next: { [weak self] updates in |> deliverOnMainQueue).start(next: { [weak self] updates in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
@ -2560,7 +2598,7 @@ public final class GroupCallParticipantsContext {
} }
public func resetInviteLinks() { public func resetInviteLinks() {
self.resetInviteLinksDisposable.set((self.account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 1, call: self.reference.apiInputGroupCall, joinMuted: nil)) self.resetInviteLinksDisposable.set((self.account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 1, call: self.reference.apiInputGroupCall, joinMuted: nil, messagesEnabled: nil))
|> deliverOnMainQueue).start(next: { [weak self] updates in |> deliverOnMainQueue).start(next: { [weak self] updates in
guard let strongSelf = self else { guard let strongSelf = self else {
return return
@ -3251,7 +3289,7 @@ public enum RevokeConferenceInviteLinkError {
} }
func _internal_revokeConferenceInviteLink(account: Account, reference: InternalGroupCallReference, link: String) -> Signal<GroupCallInviteLinks, RevokeConferenceInviteLinkError> { func _internal_revokeConferenceInviteLink(account: Account, reference: InternalGroupCallReference, link: String) -> Signal<GroupCallInviteLinks, RevokeConferenceInviteLinkError> {
return account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 1, call: reference.apiInputGroupCall, joinMuted: .boolFalse)) return account.network.request(Api.functions.phone.toggleGroupCallSettings(flags: 1 << 1, call: reference.apiInputGroupCall, joinMuted: .boolFalse, messagesEnabled: nil))
|> mapError { _ -> RevokeConferenceInviteLinkError in |> mapError { _ -> RevokeConferenceInviteLinkError in
return .generic return .generic
} }
@ -3376,7 +3414,7 @@ func _internal_refreshInlineGroupCall(account: Account, messageId: MessageId) ->
struct GroupCallMessageUpdate { struct GroupCallMessageUpdate {
enum Update { enum Update {
case newPlaintextMessage(authorId: PeerId, text: String, entities: [MessageTextEntity]) case newPlaintextMessage(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity])
case newOpaqueMessage(authorId: PeerId, data: Data) case newOpaqueMessage(authorId: PeerId, data: Data)
} }
@ -3462,6 +3500,8 @@ public final class GroupCallMessagesContext {
var updatesDisposable: Disposable? var updatesDisposable: Disposable?
let sendMessageDisposables = DisposableSet() let sendMessageDisposables = DisposableSet()
var processedIds = Set<Int64>()
private var messageLifeTimer: SwiftSignalKit.Timer? private var messageLifeTimer: SwiftSignalKit.Timer?
init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32) { init(queue: Queue, account: Account, callId: Int64, reference: InternalGroupCallReference, e2eContext: ConferenceCallE2EContext?, messageLifetime: Int32) {
@ -3481,16 +3521,16 @@ public final class GroupCallMessagesContext {
return return
} }
let currentTime = Int32(CFAbsoluteTimeGetCurrent()) let currentTime = Int32(CFAbsoluteTimeGetCurrent())
var addedMessages: [(authorId: PeerId, text: String, entities: [MessageTextEntity])] = [] var addedMessages: [(authorId: PeerId, randomId: Int64, text: String, entities: [MessageTextEntity])] = []
var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = [] var addedOpaqueMessages: [(authorId: PeerId, data: Data)] = []
for update in updates { for update in updates {
if update.callId != self.callId { if update.callId != self.callId {
continue continue
} }
switch update.update { switch update.update {
case let .newPlaintextMessage(authorId, text, entities): case let .newPlaintextMessage(authorId, randomId, text, entities):
if authorId != self.account.peerId { if authorId != self.account.peerId {
addedMessages.append((authorId, text, entities)) addedMessages.append((authorId, randomId, text, entities))
} }
case let .newOpaqueMessage(authorId, data): case let .newOpaqueMessage(authorId, data):
if authorId != self.account.peerId { if authorId != self.account.peerId {
@ -3544,13 +3584,11 @@ public final class GroupCallMessagesContext {
} }
} else { } else {
for addedMessage in addedMessages { for addedMessage in addedMessages {
if addedMessage.authorId == account.peerId { if self.processedIds.contains(addedMessage.randomId) {
continue continue
} }
let messageId = self.nextId
self.nextId += 1
messages.append(Message( messages.append(Message(
id: messageId, id: addedMessage.randomId,
author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init), author: transaction.getPeer(addedMessage.authorId).flatMap(EnginePeer.init),
text: addedMessage.text, text: addedMessage.text,
entities: addedMessage.entities, entities: addedMessage.entities,
@ -3565,6 +3603,9 @@ public final class GroupCallMessagesContext {
guard let self else { guard let self else {
return return
} }
for message in messages {
self.processedIds.insert(message.id)
}
var state = self.state var state = self.state
state.messages.append(contentsOf: messages) state.messages.append(contentsOf: messages)
self.state = state self.state = state
@ -3595,15 +3636,15 @@ public final class GroupCallMessagesContext {
} }
} }
func send(text: String, entities: [MessageTextEntity]) { func send(fromId: EnginePeer.Id, text: String, entities: [MessageTextEntity]) {
let accountPeerId = self.account.peerId
let _ = (self.account.postbox.transaction { transaction -> Peer? in let _ = (self.account.postbox.transaction { transaction -> Peer? in
return transaction.getPeer(accountPeerId) return transaction.getPeer(fromId)
} }
|> deliverOn(self.queue)).startStandalone(next: { [weak self] accountPeer in |> deliverOn(self.queue)).startStandalone(next: { [weak self] fromPeer in
guard let self else { guard let self else {
return return
} }
let currentTime = Int32(CFAbsoluteTimeGetCurrent()) let currentTime = Int32(CFAbsoluteTimeGetCurrent())
let messageId = self.nextId let messageId = self.nextId
@ -3612,7 +3653,7 @@ public final class GroupCallMessagesContext {
var state = self.state var state = self.state
state.messages.append(Message( state.messages.append(Message(
id: messageId, id: messageId,
author: accountPeer.flatMap(EnginePeer.init), author: fromPeer.flatMap(EnginePeer.init),
text: text, text: text,
entities: entities, entities: entities,
date: currentTime, date: currentTime,
@ -3620,6 +3661,8 @@ public final class GroupCallMessagesContext {
)) ))
self.state = state self.state = state
self.processedIds.insert(messageId)
if let e2eContext = self.e2eContext { if let e2eContext = self.e2eContext {
let buffer = Buffer() let buffer = Buffer()
Api.TextWithEntities.textWithEntities(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())).serialize(buffer, true) Api.TextWithEntities.textWithEntities(text: text, entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())).serialize(buffer, true)
@ -3637,8 +3680,11 @@ public final class GroupCallMessagesContext {
)).startStrict()) )).startStrict())
} }
} else { } else {
var randomId: Int64 = 0
arc4random_buf(&randomId, 8)
self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallMessage( self.sendMessageDisposables.add(self.account.network.request(Api.functions.phone.sendGroupCallMessage(
call: self.reference.apiInputGroupCall, call: self.reference.apiInputGroupCall,
randomId: randomId,
message: .textWithEntities( message: .textWithEntities(
text: text, text: text,
entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary()) entities: apiEntitiesFromMessageTextEntities(entities, associatedPeers: SimpleDictionary())
@ -3666,9 +3712,9 @@ public final class GroupCallMessagesContext {
}) })
} }
public func send(text: String, entities: [MessageTextEntity]) { public func send(fromId: EnginePeer.Id, text: String, entities: [MessageTextEntity]) {
self.impl.with { impl in self.impl.with { impl in
impl.send(text: text, entities: entities) impl.send(fromId: fromId, text: text, entities: entities)
} }
} }
} }

View File

@ -328,14 +328,14 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
action = .changeUsernames(prev: prevValue, new: newValue) action = .changeUsernames(prev: prevValue, new: newValue)
case let .channelAdminLogEventActionCreateTopic(topic): case let .channelAdminLogEventActionCreateTopic(topic):
switch topic { switch topic {
case let .forumTopic(_, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(_, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
action = .createTopic(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor)) action = .createTopic(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor))
case .forumTopicDeleted: case .forumTopicDeleted:
action = .createTopic(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0)) action = .createTopic(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0))
} }
case let .channelAdminLogEventActionDeleteTopic(topic): case let .channelAdminLogEventActionDeleteTopic(topic):
switch topic { switch topic {
case let .forumTopic(_, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(_, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
action = .deleteTopic(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor)) action = .deleteTopic(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor))
case .forumTopicDeleted: case .forumTopicDeleted:
action = .deleteTopic(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0)) action = .deleteTopic(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0))
@ -343,7 +343,7 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
case let .channelAdminLogEventActionEditTopic(prevTopic, newTopic): case let .channelAdminLogEventActionEditTopic(prevTopic, newTopic):
let prevInfo: AdminLogEventAction.ForumTopicInfo let prevInfo: AdminLogEventAction.ForumTopicInfo
switch prevTopic { switch prevTopic {
case let .forumTopic(flags, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(flags, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
prevInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor), isClosed: (flags & (1 << 2)) != 0, isHidden: (flags & (1 << 6)) != 0) prevInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor), isClosed: (flags & (1 << 2)) != 0, isHidden: (flags & (1 << 6)) != 0)
case .forumTopicDeleted: case .forumTopicDeleted:
prevInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0), isClosed: false, isHidden: false) prevInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0), isClosed: false, isHidden: false)
@ -351,7 +351,7 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
let newInfo: AdminLogEventAction.ForumTopicInfo let newInfo: AdminLogEventAction.ForumTopicInfo
switch newTopic { switch newTopic {
case let .forumTopic(flags, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(flags, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
newInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor), isClosed: (flags & (1 << 2)) != 0, isHidden: (flags & (1 << 6)) != 0) newInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor), isClosed: (flags & (1 << 2)) != 0, isHidden: (flags & (1 << 6)) != 0)
case .forumTopicDeleted: case .forumTopicDeleted:
newInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0), isClosed: false, isHidden: false) newInfo = AdminLogEventAction.ForumTopicInfo(info: EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0), isClosed: false, isHidden: false)
@ -361,7 +361,7 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
case let .channelAdminLogEventActionPinTopic(_, prevTopic, newTopic): case let .channelAdminLogEventActionPinTopic(_, prevTopic, newTopic):
let prevInfo: EngineMessageHistoryThread.Info? let prevInfo: EngineMessageHistoryThread.Info?
switch prevTopic { switch prevTopic {
case let .forumTopic(_, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(_, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
prevInfo = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor) prevInfo = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor)
case .forumTopicDeleted: case .forumTopicDeleted:
prevInfo = EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0) prevInfo = EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0)
@ -371,7 +371,7 @@ func channelAdminLogEvents(accountPeerId: PeerId, postbox: Postbox, network: Net
let newInfo: EngineMessageHistoryThread.Info? let newInfo: EngineMessageHistoryThread.Info?
switch newTopic { switch newTopic {
case let .forumTopic(_, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _): case let .forumTopic(_, _, _, _, title, iconColor, iconEmojiId, _, _, _, _, _, _, _, _, _):
newInfo = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor) newInfo = EngineMessageHistoryThread.Info(title: title, icon: iconEmojiId, iconColor: iconColor)
case .forumTopicDeleted: case .forumTopicDeleted:
newInfo = EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0) newInfo = EngineMessageHistoryThread.Info(title: "", icon: nil, iconColor: 0)

View File

@ -26,14 +26,21 @@ public final class EdgeEffectView: UIView {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
public func update(content: UIColor, isInverted: Bool, rect: CGRect, edge: Edge, edgeSize: CGFloat, containerSize: CGSize, transition: ComponentTransition) { public func update(content: UIColor, alpha: CGFloat = 0.65, rect: CGRect, edge: Edge, edgeSize: CGFloat, transition: ComponentTransition) {
self.contentView.backgroundColor = content self.contentView.backgroundColor = content
switch edge {
case .top:
self.contentMaskView.transform = CGAffineTransformMakeScale(1.0, -1.0)
case .bottom:
self.contentMaskView.transform = .identity
}
transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(), size: rect.size)) transition.setFrame(view: self.contentView, frame: CGRect(origin: CGPoint(), size: rect.size))
transition.setFrame(view: self.contentMaskView, frame: CGRect(origin: CGPoint(), size: rect.size)) transition.setFrame(view: self.contentMaskView, frame: CGRect(origin: CGPoint(), size: rect.size))
if self.contentMaskView.image?.size.height != edgeSize { if self.contentMaskView.image?.size.height != edgeSize {
let baseGradientAlpha: CGFloat = 0.65 let baseGradientAlpha: CGFloat = alpha
let numSteps = 8 let numSteps = 8
let firstStep = 1 let firstStep = 1
let firstLocation = 0.0 let firstLocation = 0.0

View File

@ -1808,7 +1808,7 @@ final class UserAppearanceScreenComponent: Component {
let edgeEffectHeight: CGFloat = availableSize.height - buttonY + 24.0 let edgeEffectHeight: CGFloat = availableSize.height - buttonY + 24.0
let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - edgeEffectHeight), size: CGSize(width: availableSize.width, height: edgeEffectHeight)) let edgeEffectFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - edgeEffectHeight), size: CGSize(width: availableSize.width, height: edgeEffectHeight))
transition.setFrame(view: self.edgeEffectView, frame: edgeEffectFrame) transition.setFrame(view: self.edgeEffectView, frame: edgeEffectFrame)
self.edgeEffectView.update(content: environment.theme.list.blocksBackgroundColor, isInverted: false, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, containerSize: availableSize, transition: transition) self.edgeEffectView.update(content: environment.theme.list.blocksBackgroundColor, rect: edgeEffectFrame, edge: .bottom, edgeSize: edgeEffectFrame.height, transition: transition)
let previousBounds = self.scrollView.bounds let previousBounds = self.scrollView.bounds
let contentSize = CGSize(width: availableSize.width, height: contentHeight) let contentSize = CGSize(width: availableSize.width, height: contentHeight)