mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Refactoring
This commit is contained in:
parent
5eb4bbeaae
commit
dfad27f9e8
@ -78,7 +78,7 @@ private enum ChannelAdminEntryStableId: Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private enum ChannelAdminEntry: ItemListNodeEntry {
|
private enum ChannelAdminEntry: ItemListNodeEntry {
|
||||||
case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, TelegramUserPresence?)
|
case info(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, EnginePeer, EnginePeer.Presence?)
|
||||||
case rankTitle(PresentationTheme, String, Int32?, Int32)
|
case rankTitle(PresentationTheme, String, Int32?, Int32)
|
||||||
case rank(PresentationTheme, PresentationStrings, String, String, Bool)
|
case rank(PresentationTheme, PresentationStrings, String, String, Bool)
|
||||||
case rankInfo(PresentationTheme, String, Bool)
|
case rankInfo(PresentationTheme, String, Bool)
|
||||||
@ -144,7 +144,7 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
|
|||||||
if lhsDateTimeFormat != rhsDateTimeFormat {
|
if lhsDateTimeFormat != rhsDateTimeFormat {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !arePeersEqual(lhsPeer, rhsPeer) {
|
if lhsPeer != rhsPeer {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if lhsPresence != rhsPresence {
|
if lhsPresence != rhsPresence {
|
||||||
@ -309,7 +309,7 @@ private enum ChannelAdminEntry: ItemListNodeEntry {
|
|||||||
let arguments = arguments as! ChannelAdminControllerArguments
|
let arguments = arguments as! ChannelAdminControllerArguments
|
||||||
switch self {
|
switch self {
|
||||||
case let .info(_, _, dateTimeFormat, peer, presence):
|
case let .info(_, _, dateTimeFormat, peer, presence):
|
||||||
return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: EnginePeer(peer), presence: presence.flatMap(EnginePeer.Presence.init), memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in
|
return ItemListAvatarAndNameInfoItem(accountContext: arguments.context, presentationData: presentationData, dateTimeFormat: dateTimeFormat, mode: .generic, peer: peer, presence: presence, memberCount: nil, state: ItemListAvatarAndNameInfoItemState(), sectionId: self.section, style: .blocks(withTopInset: true, withExtendedBottomInset: false), editingNameUpdated: { _ in
|
||||||
}, avatarTapped: {
|
}, avatarTapped: {
|
||||||
})
|
})
|
||||||
case let .rankTitle(_, text, count, limit):
|
case let .rankTitle(_, text, count, limit):
|
||||||
@ -534,11 +534,11 @@ private func areAllAdminRightsEnabled(_ flags: TelegramChatAdminRightsFlags, gro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func channelAdminControllerEntries(presentationData: PresentationData, state: ChannelAdminControllerState, accountPeerId: PeerId, channelView: PeerView, adminView: PeerView, initialParticipant: ChannelParticipant?, invite: Bool, canEdit: Bool) -> [ChannelAdminEntry] {
|
private func channelAdminControllerEntries(presentationData: PresentationData, state: ChannelAdminControllerState, accountPeerId: PeerId, channelPeer: EnginePeer?, adminPeer: EnginePeer?, adminPresence: EnginePeer.Presence?, initialParticipant: ChannelParticipant?, invite: Bool, canEdit: Bool) -> [ChannelAdminEntry] {
|
||||||
var entries: [ChannelAdminEntry] = []
|
var entries: [ChannelAdminEntry] = []
|
||||||
|
|
||||||
if let channel = channelView.peers[channelView.peerId] as? TelegramChannel, let admin = adminView.peers[adminView.peerId] {
|
if case let .channel(channel) = channelPeer, let admin = adminPeer {
|
||||||
entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence))
|
entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminPresence))
|
||||||
|
|
||||||
var isChannel = false
|
var isChannel = false
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
@ -618,7 +618,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let adminPeer = adminView.peers[adminView.peerId] as? TelegramUser, adminPeer.botInfo != nil, case .group = channel.info, invite, let channelPeer = channelView.peers[channelView.peerId], canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: initialParticipant) {
|
if case let .user(adminPeer) = adminPeer, adminPeer.botInfo != nil, case .group = channel.info, invite, let channelPeer = channelPeer, canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer._asPeer(), initialParticipant: initialParticipant) {
|
||||||
if let initialParticipant = initialParticipant, case let .member(_, _, adminInfo, _, _) = initialParticipant, adminInfo != nil {
|
if let initialParticipant = initialParticipant, case let .member(_, _, adminInfo, _, _) = initialParticipant, adminInfo != nil {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -629,7 +629,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
if !invite || state.adminRights {
|
if !invite || state.adminRights {
|
||||||
entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader))
|
entries.append(.rightsTitle(presentationData.theme, presentationData.strings.Channel_EditAdmin_PermissionsHeader))
|
||||||
|
|
||||||
if let channelPeer = channelView.peers[channelView.peerId], canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: initialParticipant) {
|
if let channelPeer = channelPeer, canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer._asPeer(), initialParticipant: initialParticipant) {
|
||||||
let accountUserRightsFlags: TelegramChatAdminRightsFlags
|
let accountUserRightsFlags: TelegramChatAdminRightsFlags
|
||||||
if channel.flags.contains(.isCreator) {
|
if channel.flags.contains(.isCreator) {
|
||||||
accountUserRightsFlags = maskRightsFlags
|
accountUserRightsFlags = maskRightsFlags
|
||||||
@ -660,7 +660,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
|
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let admin = admin as? TelegramUser, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, group: isGroup, except: .canBeAnonymous) {
|
if case let .user(admin) = admin, admin.botInfo == nil && !admin.isDeleted && channel.flags.contains(.isCreator) && areAllAdminRightsEnabled(currentRightsFlags, group: isGroup, except: .canBeAnonymous) {
|
||||||
canTransfer = true
|
canTransfer = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -717,8 +717,8 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
if canDismiss {
|
if canDismiss {
|
||||||
entries.append(.dismiss(presentationData.theme, presentationData.strings.Channel_Moderator_AccessLevelRevoke))
|
entries.append(.dismiss(presentationData.theme, presentationData.strings.Channel_Moderator_AccessLevelRevoke))
|
||||||
}
|
}
|
||||||
} else if let group = channelView.peers[channelView.peerId] as? TelegramGroup, let admin = adminView.peers[adminView.peerId] {
|
} else if case let .legacyGroup(group) = channelPeer, let admin = adminPeer {
|
||||||
entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminView.peerPresences[admin.id] as? TelegramUserPresence))
|
entries.append(.info(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, admin, adminPresence))
|
||||||
|
|
||||||
var isCreator = false
|
var isCreator = false
|
||||||
if let initialParticipant = initialParticipant, case .creator = initialParticipant {
|
if let initialParticipant = initialParticipant, case .creator = initialParticipant {
|
||||||
@ -738,7 +738,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
entries.append(.rankTitle(presentationData.theme, presentationData.strings.Group_EditAdmin_RankTitle.uppercased(), rankEnabled && state.focusedOnRank ? Int32(currentRank?.count ?? 0) : nil, rankMaxLength))
|
entries.append(.rankTitle(presentationData.theme, presentationData.strings.Group_EditAdmin_RankTitle.uppercased(), rankEnabled && state.focusedOnRank ? Int32(currentRank?.count ?? 0) : nil, rankMaxLength))
|
||||||
entries.append(.rank(presentationData.theme, presentationData.strings, isCreator ? presentationData.strings.Group_EditAdmin_RankOwnerPlaceholder : presentationData.strings.Group_EditAdmin_RankAdminPlaceholder, currentRank ?? "", rankEnabled))
|
entries.append(.rank(presentationData.theme, presentationData.strings, isCreator ? presentationData.strings.Group_EditAdmin_RankOwnerPlaceholder : presentationData.strings.Group_EditAdmin_RankAdminPlaceholder, currentRank ?? "", rankEnabled))
|
||||||
} else {
|
} else {
|
||||||
if let adminPeer = adminView.peers[adminView.peerId] as? TelegramUser, adminPeer.botInfo != nil, invite {
|
if case let .user(adminPeer) = adminPeer, adminPeer.botInfo != nil, invite {
|
||||||
if let initialParticipant = initialParticipant, case let .member(_, _, adminRights, _, _) = initialParticipant, adminRights != nil {
|
if let initialParticipant = initialParticipant, case let .member(_, _, adminRights, _, _) = initialParticipant, adminRights != nil {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -791,7 +791,7 @@ private func channelAdminControllerEntries(presentationData: PresentationData, s
|
|||||||
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
|
entries.append(.addAdminsInfo(presentationData.theme, currentRightsFlags.contains(.canAddAdmins) ? presentationData.strings.Channel_EditAdmin_PermissinAddAdminOn : presentationData.strings.Channel_EditAdmin_PermissinAddAdminOff))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let admin = admin as? TelegramUser, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true, except: .canBeAnonymous) {
|
if case let .user(admin) = admin, case .creator = group.role, admin.botInfo == nil && !admin.isDeleted && areAllAdminRightsEnabled(currentRightsFlags, group: true, except: .canBeAnonymous) {
|
||||||
entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership))
|
entries.append(.transfer(presentationData.theme, presentationData.strings.Group_EditAdmin_TransferOwnership))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -955,15 +955,23 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
errorImpl?()
|
errorImpl?()
|
||||||
})
|
})
|
||||||
|
|
||||||
let combinedView = context.account.postbox.combinedView(keys: [.peer(peerId: peerId, components: .all), .peer(peerId: adminId, components: .all)])
|
|
||||||
|
|
||||||
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
let presentationData = updatedPresentationData?.signal ?? context.sharedContext.presentationData
|
||||||
let signal = combineLatest(presentationData, statePromise.get(), combinedView)
|
let signal = combineLatest(
|
||||||
|
queue: .mainQueue(),
|
||||||
|
presentationData,
|
||||||
|
statePromise.get(),
|
||||||
|
context.engine.data.subscribe(
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId),
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Peer(id: adminId),
|
||||||
|
TelegramEngine.EngineData.Item.Peer.Presence(id: adminId)
|
||||||
|
)
|
||||||
|
)
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> map { presentationData, state, combinedView -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
|> map { presentationData, state, peerInfoData -> (ItemListControllerState, (ItemListNodeState, Any)) in
|
||||||
let channelView = combinedView.views[.peer(peerId: peerId, components: .all)] as! PeerView
|
let channelPeer = peerInfoData.0.flatMap { $0 }
|
||||||
let adminView = combinedView.views[.peer(peerId: adminId, components: .all)] as! PeerView
|
let adminPeer = peerInfoData.1.flatMap { $0 }
|
||||||
let canEdit = canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: channelView.peers[channelView.peerId]!, initialParticipant: initialParticipant)
|
let adminPresence = peerInfoData.2
|
||||||
|
let canEdit = canEditAdminRights(accountPeerId: context.account.peerId, channelPeer: channelPeer!._asPeer(), initialParticipant: initialParticipant)
|
||||||
|
|
||||||
let leftNavigationButton: ItemListNavigationButton
|
let leftNavigationButton: ItemListNavigationButton
|
||||||
if canEdit {
|
if canEdit {
|
||||||
@ -986,8 +994,9 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
updateState { current in
|
updateState { current in
|
||||||
return current.withUpdatedUpdating(true)
|
return current.withUpdatedUpdating(true)
|
||||||
}
|
}
|
||||||
if let channel = channelView.peers[channelView.peerId] as? TelegramChannel {
|
if case let .channel(channel) = channelPeer {
|
||||||
updateRightsDisposable.set((context.engine.peers.addChannelMember(peerId: peerId, memberId: adminId) |> deliverOnMainQueue).start(error: { error in
|
updateRightsDisposable.set((context.engine.peers.addChannelMember(peerId: peerId, memberId: adminId)
|
||||||
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
updateState { current in
|
updateState { current in
|
||||||
return current.withUpdatedUpdating(false)
|
return current.withUpdatedUpdating(false)
|
||||||
}
|
}
|
||||||
@ -998,12 +1007,12 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
case .tooMuchJoined:
|
case .tooMuchJoined:
|
||||||
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
|
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
|
||||||
case .restricted:
|
case .restricted:
|
||||||
if let admin = adminView.peers[adminView.peerId] {
|
if let admin = adminPeer {
|
||||||
switch channel.info {
|
switch channel.info {
|
||||||
case .broadcast:
|
case .broadcast:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
case .group:
|
case .group:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .notMutualContact:
|
case .notMutualContact:
|
||||||
@ -1020,20 +1029,20 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
updated(nil)
|
updated(nil)
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}))
|
}))
|
||||||
} else if let _ = channelView.peers[channelView.peerId] as? TelegramGroup {
|
} else if case .legacyGroup = channelPeer {
|
||||||
updateRightsDisposable.set((context.engine.peers.addGroupMember(peerId: peerId, memberId: adminId) |> deliverOnMainQueue).start(error: { error in
|
updateRightsDisposable.set((context.engine.peers.addGroupMember(peerId: peerId, memberId: adminId) |> deliverOnMainQueue).start(error: { error in
|
||||||
updateState { current in
|
updateState { current in
|
||||||
return current.withUpdatedUpdating(false)
|
return current.withUpdatedUpdating(false)
|
||||||
}
|
}
|
||||||
if case .privacy = error, let admin = adminView.peers[adminView.peerId] {
|
if case .privacy = error, let admin = adminPeer {
|
||||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
}
|
}
|
||||||
}, completed: {
|
}, completed: {
|
||||||
updated(nil)
|
updated(nil)
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
} else if let channel = channelView.peers[channelView.peerId] as? TelegramChannel {
|
} else if case let .channel(channel) = channelPeer {
|
||||||
if let initialParticipant = initialParticipant {
|
if let initialParticipant = initialParticipant {
|
||||||
var updateFlags: TelegramChatAdminRightsFlags?
|
var updateFlags: TelegramChatAdminRightsFlags?
|
||||||
var updateRank: String?
|
var updateRank: String?
|
||||||
@ -1105,12 +1114,12 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
case .tooMuchJoined:
|
case .tooMuchJoined:
|
||||||
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
|
text = presentationData.strings.Group_ErrorSupergroupConversionNotPossible
|
||||||
case .restricted:
|
case .restricted:
|
||||||
if let admin = adminView.peers[adminView.peerId] {
|
if let admin = adminPeer {
|
||||||
switch channel.info {
|
switch channel.info {
|
||||||
case .broadcast:
|
case .broadcast:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
case .group:
|
case .group:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case .notMutualContact:
|
case .notMutualContact:
|
||||||
@ -1184,7 +1193,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
return current.withUpdatedUpdating(true)
|
return current.withUpdatedUpdating(true)
|
||||||
}
|
}
|
||||||
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(engine: context.engine, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in
|
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberAdminRights(engine: context.engine, peerId: peerId, memberId: adminId, adminRights: TelegramChatAdminRights(rights: updateFlags), rank: updateRank) |> deliverOnMainQueue).start(error: { error in
|
||||||
if case let .addMemberError(addMemberError) = error, let admin = adminView.peers[adminView.peerId] {
|
if case let .addMemberError(addMemberError) = error, let admin = adminPeer {
|
||||||
var text = presentationData.strings.Login_UnknownError
|
var text = presentationData.strings.Login_UnknownError
|
||||||
switch addMemberError {
|
switch addMemberError {
|
||||||
case .tooMuchJoined:
|
case .tooMuchJoined:
|
||||||
@ -1192,9 +1201,9 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
case .restricted:
|
case .restricted:
|
||||||
switch channel.info {
|
switch channel.info {
|
||||||
case .broadcast:
|
case .broadcast:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToChannelError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
case .group:
|
case .group:
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
}
|
}
|
||||||
case .notMutualContact:
|
case .notMutualContact:
|
||||||
if case .broadcast = channel.info {
|
if case .broadcast = channel.info {
|
||||||
@ -1222,7 +1231,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if let _ = channelView.peers[channelView.peerId] as? TelegramGroup {
|
} else if case .legacyGroup = channelPeer {
|
||||||
var updateFlags: TelegramChatAdminRightsFlags?
|
var updateFlags: TelegramChatAdminRightsFlags?
|
||||||
var updateRank: String?
|
var updateRank: String?
|
||||||
updateState { current in
|
updateState { current in
|
||||||
@ -1252,8 +1261,8 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
}
|
}
|
||||||
updateRightsDisposable.set((context.engine.peers.addGroupAdmin(peerId: peerId, adminId: adminId)
|
updateRightsDisposable.set((context.engine.peers.addGroupAdmin(peerId: peerId, adminId: adminId)
|
||||||
|> deliverOnMainQueue).start(error: { error in
|
|> deliverOnMainQueue).start(error: { error in
|
||||||
if case let .addMemberError(error) = error, case .privacy = error, let admin = adminView.peers[adminView.peerId] {
|
if case let .addMemberError(error) = error, case .privacy = error, let admin = adminPeer {
|
||||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
} else if case .adminsTooMuch = error {
|
} else if case .adminsTooMuch = error {
|
||||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Group_ErrorAdminsTooMuch, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: presentationData.strings.Group_ErrorAdminsTooMuch, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), nil)
|
||||||
}
|
}
|
||||||
@ -1312,8 +1321,8 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
case let .direct(error):
|
case let .direct(error):
|
||||||
if case let .addMemberError(error) = error {
|
if case let .addMemberError(error) = error {
|
||||||
var text = presentationData.strings.Login_UnknownError
|
var text = presentationData.strings.Login_UnknownError
|
||||||
if case .restricted = error, let admin = adminView.peers[adminView.peerId] {
|
if case .restricted = error, let admin = adminPeer {
|
||||||
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(EnginePeer(admin).compactDisplayTitle, EnginePeer(admin).compactDisplayTitle).string
|
text = presentationData.strings.Privacy_GroupsAndChannels_InviteToGroupError(admin.compactDisplayTitle, admin.compactDisplayTitle).string
|
||||||
} else if case .tooMuchJoined = error {
|
} else if case .tooMuchJoined = error {
|
||||||
text = presentationData.strings.Invite_ChannelsTooMuch
|
text = presentationData.strings.Invite_ChannelsTooMuch
|
||||||
} else if case .kicked = error {
|
} else if case .kicked = error {
|
||||||
@ -1353,17 +1362,17 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
if initialParticipant?.adminInfo == nil {
|
if initialParticipant?.adminInfo == nil {
|
||||||
var isGroup: Bool = false
|
var isGroup: Bool = false
|
||||||
var peerTitle: String = ""
|
var peerTitle: String = ""
|
||||||
if let peer = channelView.peers[channelView.peerId] as? TelegramGroup {
|
if case let .legacyGroup(peer) = channelPeer {
|
||||||
isGroup = true
|
isGroup = true
|
||||||
peerTitle = peer.title
|
peerTitle = peer.title
|
||||||
} else if let peer = channelView.peers[channelView.peerId] as? TelegramChannel {
|
} else if case let .channel(peer) = channelPeer {
|
||||||
if case .group = peer.info {
|
if case .group = peer.info {
|
||||||
isGroup = true
|
isGroup = true
|
||||||
}
|
}
|
||||||
peerTitle = peer.title
|
peerTitle = peer.title
|
||||||
}
|
}
|
||||||
|
|
||||||
if let admin = adminView.peers[adminView.peerId] as? TelegramUser, admin.botInfo != nil && invite {
|
if case let .user(admin) = adminPeer, admin.botInfo != nil && invite {
|
||||||
title = presentationData.strings.Bot_AddToChat_Add_Title
|
title = presentationData.strings.Bot_AddToChat_Add_Title
|
||||||
rightNavigationButton = nil
|
rightNavigationButton = nil
|
||||||
footerItem = ChannelAdminAddBotFooterItem(theme: presentationData.theme, title: state.adminRights ? presentationData.strings.Bot_AddToChat_Add_AddAsAdmin : presentationData.strings.Bot_AddToChat_Add_AddAsMember, action: {
|
footerItem = ChannelAdminAddBotFooterItem(theme: presentationData.theme, title: state.adminRights ? presentationData.strings.Bot_AddToChat_Add_AddAsAdmin : presentationData.strings.Bot_AddToChat_Add_AddAsMember, action: {
|
||||||
@ -1395,7 +1404,7 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||||||
|
|
||||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||||
|
|
||||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelView: channelView, adminView: adminView, initialParticipant: initialParticipant, invite: invite, canEdit: canEdit), style: .blocks, focusItemTag: focusItemTag, ensureVisibleItemTag: nil, emptyStateItem: nil, footerItem: footerItem, animateChanges: true)
|
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelAdminControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelPeer: channelPeer, adminPeer: adminPeer, adminPresence: adminPresence, initialParticipant: initialParticipant, invite: invite, canEdit: canEdit), style: .blocks, focusItemTag: focusItemTag, ensureVisibleItemTag: nil, emptyStateItem: nil, footerItem: footerItem, animateChanges: true)
|
||||||
|
|
||||||
return (controllerState, (listState, arguments))
|
return (controllerState, (listState, arguments))
|
||||||
}
|
}
|
||||||
|
@ -417,10 +417,17 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let preferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.localizationListState]))
|
|
||||||
let previousState = Atomic<LocalizationListState?>(value: nil)
|
let previousState = Atomic<LocalizationListState?>(value: nil)
|
||||||
let previousEntriesHolder = Atomic<([LanguageListEntry], PresentationTheme, PresentationStrings)?>(value: nil)
|
let previousEntriesHolder = Atomic<([LanguageListEntry], PresentationTheme, PresentationStrings)?>(value: nil)
|
||||||
self.listDisposable = combineLatest(queue: .mainQueue(), context.account.postbox.combinedView(keys: [preferencesKey]), context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings, ApplicationSpecificSharedDataKeys.translationSettings]), self.presentationDataValue.get(), self.applyingCode.get(), revealedCode.get(), self.isEditing.get()).start(next: { [weak self] view, sharedData, presentationData, applyingCode, revealedCode, isEditing in
|
self.listDisposable = combineLatest(
|
||||||
|
queue: .mainQueue(),
|
||||||
|
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.LocalizationList()),
|
||||||
|
context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings, ApplicationSpecificSharedDataKeys.translationSettings]),
|
||||||
|
self.presentationDataValue.get(),
|
||||||
|
self.applyingCode.get(),
|
||||||
|
revealedCode.get(),
|
||||||
|
self.isEditing.get()
|
||||||
|
).start(next: { [weak self] localizationListState, sharedData, presentationData, applyingCode, revealedCode, isEditing in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -449,8 +456,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let localizationListState = (view.views[preferencesKey] as? PreferencesView)?.values[PreferencesKeys.localizationListState]?.get(LocalizationListState.self)
|
if !localizationListState.availableOfficialLocalizations.isEmpty {
|
||||||
if let localizationListState = localizationListState, !localizationListState.availableOfficialLocalizations.isEmpty {
|
|
||||||
strongSelf.currentListState = localizationListState
|
strongSelf.currentListState = localizationListState
|
||||||
|
|
||||||
if #available(iOS 12.0, *) {
|
if #available(iOS 12.0, *) {
|
||||||
@ -520,7 +526,7 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
|||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.push(translationSettingsController(context: strongSelf.context))
|
strongSelf.push(translationSettingsController(context: strongSelf.context))
|
||||||
}
|
}
|
||||||
}, selectLocalization: { [weak self] info in self?.selectLocalization(info) }, setItemWithRevealedOptions: setItemWithRevealedOptions, removeItem: removeItem, firstTime: previousEntriesAndPresentationData == nil, isLoading: entries.isEmpty, forceUpdate: previousEntriesAndPresentationData?.1 !== presentationData.theme || previousEntriesAndPresentationData?.2 !== presentationData.strings, animated: (previousEntriesAndPresentationData?.0.count ?? 0) != entries.count, crossfade: (previousState == nil) != (localizationListState == nil))
|
}, selectLocalization: { [weak self] info in self?.selectLocalization(info) }, setItemWithRevealedOptions: setItemWithRevealedOptions, removeItem: removeItem, firstTime: previousEntriesAndPresentationData == nil, isLoading: entries.isEmpty, forceUpdate: previousEntriesAndPresentationData?.1 !== presentationData.theme || previousEntriesAndPresentationData?.2 !== presentationData.strings, animated: (previousEntriesAndPresentationData?.0.count ?? 0) != entries.count, crossfade: (previousState == nil || previousState!.availableOfficialLocalizations.isEmpty) != localizationListState.availableOfficialLocalizations.isEmpty)
|
||||||
strongSelf.enqueueTransition(transition)
|
strongSelf.enqueueTransition(transition)
|
||||||
})
|
})
|
||||||
self.updatedDisposable = context.engine.localization.synchronizedLocalizationListState().start()
|
self.updatedDisposable = context.engine.localization.synchronizedLocalizationListState().start()
|
||||||
|
@ -1170,20 +1170,19 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
|||||||
let updateNotificationsDisposable = self.updateNotificationsDisposable
|
let updateNotificationsDisposable = self.updateNotificationsDisposable
|
||||||
|
|
||||||
let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in
|
let updateNotificationsView: (@escaping () -> Void) -> Void = { completion in
|
||||||
let key: PostboxViewKey = .peerNotificationSettings(peerIds: Set(mode.peerIds))
|
updateNotificationsDisposable.set(context.engine.data.subscribe(EngineDataMap(
|
||||||
|
mode.peerIds.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init)
|
||||||
updateNotificationsDisposable.set(context.account.postbox.combinedView(keys: [key]).start(next: { view in
|
)).start(next: { notificationSettingsMap in
|
||||||
if let view = view.views[key] as? PeerNotificationSettingsView {
|
|
||||||
let _ = (context.engine.data.get(
|
let _ = (context.engine.data.get(
|
||||||
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
|
EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.Peer.init)),
|
||||||
EngineDataMap(view.notificationSettings.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
|
EngineDataMap(notificationSettingsMap.keys.map(TelegramEngine.EngineData.Item.Peer.NotificationSettings.init))
|
||||||
)
|
)
|
||||||
|> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in
|
|> deliverOnMainQueue).start(next: { peerMap, notificationSettingsMap in
|
||||||
updateState { current in
|
updateState { current in
|
||||||
var current = current
|
var current = current
|
||||||
for (key, value) in view.notificationSettings {
|
for (key, value) in notificationSettingsMap {
|
||||||
if let value = value as? TelegramPeerNotificationSettings,let local = current.mode.settings[key] {
|
if let local = current.mode.settings[key] {
|
||||||
if !value.isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) {
|
if !value._asNotificationSettings().isEqual(to: local.settings), let maybePeer = peerMap[key], let peer = maybePeer, let settings = notificationSettingsMap[key], !settings._asNotificationSettings().isEqual(to: local.settings) {
|
||||||
current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval)
|
current = current.withUpdatedPeerSound(peer._asPeer(), settings.messageSound._asMessageSound()).withUpdatedPeerMuteInterval(peer._asPeer(), settings.muteState.timeInterval)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1193,9 +1192,6 @@ private final class NotificationExceptionsSearchContainerNode: SearchDisplayCont
|
|||||||
|
|
||||||
completion()
|
completion()
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
completion()
|
|
||||||
}
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,11 +775,12 @@ func settingsSearchableItems(context: AccountContext, notificationExceptionsList
|
|||||||
return settings.servers
|
return settings.servers
|
||||||
}
|
}
|
||||||
|
|
||||||
let localizationPreferencesKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.localizationListState]))
|
let localizations = combineLatest(
|
||||||
let localizations = combineLatest(context.account.postbox.combinedView(keys: [localizationPreferencesKey]), context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings]))
|
context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.LocalizationList()),
|
||||||
|> map { view, sharedData -> [LocalizationInfo] in
|
context.sharedContext.accountManager.sharedData(keys: [SharedDataKeys.localizationSettings])
|
||||||
if let localizationListState = (view.views[localizationPreferencesKey] as? PreferencesView)?.values[PreferencesKeys.localizationListState]?.get(LocalizationListState.self), !localizationListState.availableOfficialLocalizations.isEmpty {
|
)
|
||||||
|
|> map { localizationListState, sharedData -> [LocalizationInfo] in
|
||||||
|
if !localizationListState.availableOfficialLocalizations.isEmpty {
|
||||||
var existingIds = Set<String>()
|
var existingIds = Set<String>()
|
||||||
let availableSavedLocalizations = localizationListState.availableSavedLocalizations.filter({ info in !localizationListState.availableOfficialLocalizations.contains(where: { $0.languageCode == info.languageCode }) })
|
let availableSavedLocalizations = localizationListState.availableSavedLocalizations.filter({ info in !localizationListState.availableOfficialLocalizations.contains(where: { $0.languageCode == info.languageCode }) })
|
||||||
|
|
||||||
|
@ -313,7 +313,7 @@ public final class ShareController: ViewController {
|
|||||||
private let segmentedValues: [ShareControllerSegmentedValue]?
|
private let segmentedValues: [ShareControllerSegmentedValue]?
|
||||||
private let fromForeignApp: Bool
|
private let fromForeignApp: Bool
|
||||||
|
|
||||||
private let peers = Promise<([(EngineRenderedPeer, PeerPresence?)], EnginePeer)>()
|
private let peers = Promise<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer)>()
|
||||||
private let peersDisposable = MetaDisposable()
|
private let peersDisposable = MetaDisposable()
|
||||||
private let readyDisposable = MetaDisposable()
|
private let readyDisposable = MetaDisposable()
|
||||||
private let accountActiveDisposable = MetaDisposable()
|
private let accountActiveDisposable = MetaDisposable()
|
||||||
@ -966,7 +966,7 @@ public final class ShareController: ViewController {
|
|||||||
self.currentAccount.viewTracker.tailChatListView(groupId: .root, count: 150)
|
self.currentAccount.viewTracker.tailChatListView(groupId: .root, count: 150)
|
||||||
|> take(1)
|
|> take(1)
|
||||||
)
|
)
|
||||||
|> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, PeerPresence?)], EnginePeer), NoError> in
|
|> mapToSignal { maybeAccountPeer, view -> Signal<([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer), NoError> in
|
||||||
let accountPeer = maybeAccountPeer!
|
let accountPeer = maybeAccountPeer!
|
||||||
|
|
||||||
var peers: [EngineRenderedPeer] = []
|
var peers: [EngineRenderedPeer] = []
|
||||||
@ -980,14 +980,14 @@ public final class ShareController: ViewController {
|
|||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let key = PostboxViewKey.peerPresences(peerIds: Set(peers.map { $0.peerId }))
|
|
||||||
return account.postbox.combinedView(keys: [key])
|
return TelegramEngine(account: account).data.subscribe(EngineDataMap(
|
||||||
|> map { views -> ([(EngineRenderedPeer, PeerPresence?)], EnginePeer) in
|
peers.map { TelegramEngine.EngineData.Item.Peer.Presence(id: $0.peerId) }
|
||||||
var resultPeers: [(EngineRenderedPeer, PeerPresence?)] = []
|
))
|
||||||
if let presencesView = views.views[key] as? PeerPresencesView {
|
|> map { presenceMap -> ([(EngineRenderedPeer, EnginePeer.Presence?)], EnginePeer) in
|
||||||
|
var resultPeers: [(EngineRenderedPeer, EnginePeer.Presence?)] = []
|
||||||
for peer in peers {
|
for peer in peers {
|
||||||
resultPeers.append((peer, presencesView.presences[peer.peerId]))
|
resultPeers.append((peer, presenceMap[peer.peerId].flatMap { $0 }))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (resultPeers, accountPeer)
|
return (resultPeers, accountPeer)
|
||||||
}
|
}
|
||||||
|
@ -804,7 +804,7 @@ final class ShareControllerNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, defaultAction: ShareControllerAction?) {
|
func updatePeers(context: AccountContext, switchableAccounts: [AccountWithInfo], peers: [(EngineRenderedPeer, EnginePeer.Presence?)], accountPeer: EnginePeer, defaultAction: ShareControllerAction?) {
|
||||||
self.context = context
|
self.context = context
|
||||||
|
|
||||||
if let peersContentNode = self.peersContentNode, peersContentNode.accountPeer.id == accountPeer.id {
|
if let peersContentNode = self.peersContentNode, peersContentNode.accountPeer.id == accountPeer.id {
|
||||||
|
@ -91,13 +91,13 @@ final class ShareControllerPeerGridItem: GridItem {
|
|||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
let peer: EngineRenderedPeer?
|
let peer: EngineRenderedPeer?
|
||||||
let presence: PeerPresence?
|
let presence: EnginePeer.Presence?
|
||||||
let controllerInteraction: ShareControllerInteraction
|
let controllerInteraction: ShareControllerInteraction
|
||||||
let search: Bool
|
let search: Bool
|
||||||
|
|
||||||
let section: GridSection?
|
let section: GridSection?
|
||||||
|
|
||||||
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) {
|
init(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, controllerInteraction: ShareControllerInteraction, sectionTitle: String? = nil, search: Bool = false) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
@ -131,7 +131,7 @@ final class ShareControllerPeerGridItem: GridItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final class ShareControllerPeerGridItemNode: GridItemNode {
|
final class ShareControllerPeerGridItemNode: GridItemNode {
|
||||||
private var currentState: (AccountContext, PresentationTheme, PresentationStrings, EngineRenderedPeer?, Bool, PeerPresence?)?
|
private var currentState: (AccountContext, PresentationTheme, PresentationStrings, EngineRenderedPeer?, Bool, EnginePeer.Presence?)?
|
||||||
private let peerNode: SelectablePeerNode
|
private let peerNode: SelectablePeerNode
|
||||||
private var presenceManager: PeerPresenceStatusManager?
|
private var presenceManager: PeerPresenceStatusManager?
|
||||||
|
|
||||||
@ -171,14 +171,14 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: PeerPresence?, search: Bool, synchronousLoad: Bool, force: Bool) {
|
func setup(context: AccountContext, theme: PresentationTheme, strings: PresentationStrings, peer: EngineRenderedPeer?, presence: EnginePeer.Presence?, search: Bool, synchronousLoad: Bool, force: Bool) {
|
||||||
if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || !arePeerPresencesEqual(self.currentState!.5, presence) {
|
if force || self.currentState == nil || self.currentState!.0 !== context || self.currentState!.3 != peer || self.currentState!.5 != presence {
|
||||||
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
|
let itemTheme = SelectablePeerNodeTheme(textColor: theme.actionSheet.primaryTextColor, secretTextColor: theme.chatList.secretTitleColor, selectedTextColor: theme.actionSheet.controlAccentColor, checkBackgroundColor: theme.actionSheet.opaqueItemBackgroundColor, checkFillColor: theme.actionSheet.controlAccentColor, checkColor: theme.actionSheet.checkContentColor, avatarPlaceholderColor: theme.list.mediaPlaceholderColor)
|
||||||
|
|
||||||
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
|
||||||
var online = false
|
var online = false
|
||||||
if case let .user(peer) = peer?.peer, let presence = presence as? TelegramUserPresence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId {
|
if case let .user(peer) = peer?.peer, let presence = presence, !isServicePeer(peer) && !peer.flags.contains(.isSupport) && peer.id != context.account.peerId {
|
||||||
let relativeStatus = relativeUserPresenceStatus(EnginePeer.Presence(presence), relativeTo: timestamp)
|
let relativeStatus = relativeUserPresenceStatus(presence, relativeTo: timestamp)
|
||||||
if case .online = relativeStatus {
|
if case .online = relativeStatus {
|
||||||
online = true
|
online = true
|
||||||
}
|
}
|
||||||
@ -220,8 +220,8 @@ final class ShareControllerPeerGridItemNode: GridItemNode {
|
|||||||
}
|
}
|
||||||
self.currentState = (context, theme, strings, peer, search, presence)
|
self.currentState = (context, theme, strings, peer, search, presence)
|
||||||
self.setNeedsLayout()
|
self.setNeedsLayout()
|
||||||
if let presence = presence as? TelegramUserPresence {
|
if let presence = presence {
|
||||||
self.presenceManager?.reset(presence: EnginePeer.Presence(presence))
|
self.presenceManager?.reset(presence: presence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.updateSelection(animated: false)
|
self.updateSelection(animated: false)
|
||||||
|
@ -20,7 +20,7 @@ private let subtitleFont = Font.regular(12.0)
|
|||||||
private struct SharePeerEntry: Comparable, Identifiable {
|
private struct SharePeerEntry: Comparable, Identifiable {
|
||||||
let index: Int32
|
let index: Int32
|
||||||
let peer: EngineRenderedPeer
|
let peer: EngineRenderedPeer
|
||||||
let presence: PeerPresence?
|
let presence: EnginePeer.Presence?
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
|
|
||||||
@ -35,13 +35,10 @@ private struct SharePeerEntry: Comparable, Identifiable {
|
|||||||
if lhs.peer != rhs.peer {
|
if lhs.peer != rhs.peer {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if let lhsPresence = lhs.presence, let rhsPresence = rhs.presence {
|
if lhs.presence != rhs.presence {
|
||||||
if !lhsPresence.isEqual(to: rhsPresence) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else if (lhs.presence != nil) != (rhs.presence != nil) {
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,9 +112,9 @@ final class SharePeersContainerNode: ASDisplayNode, ShareContentContainerNode {
|
|||||||
private var validLayout: (CGSize, CGFloat)?
|
private var validLayout: (CGSize, CGFloat)?
|
||||||
private var overrideGridOffsetTransition: ContainedViewLayoutTransition?
|
private var overrideGridOffsetTransition: ContainedViewLayoutTransition?
|
||||||
|
|
||||||
let peersValue = Promise<[(EngineRenderedPeer, PeerPresence?)]>()
|
let peersValue = Promise<[(EngineRenderedPeer, EnginePeer.Presence?)]>()
|
||||||
|
|
||||||
init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(EngineRenderedPeer, PeerPresence?)], accountPeer: EnginePeer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) {
|
init(sharedContext: SharedAccountContext, context: AccountContext, switchableAccounts: [AccountWithInfo], theme: PresentationTheme, strings: PresentationStrings, nameDisplayOrder: PresentationPersonNameOrder, peers: [(EngineRenderedPeer, EnginePeer.Presence?)], accountPeer: EnginePeer, controllerInteraction: ShareControllerInteraction, externalShare: Bool, switchToAnotherAccount: @escaping () -> Void, debugAction: @escaping () -> Void, extendedInitialReveal: Bool, segmentedValues: [ShareControllerSegmentedValue]?) {
|
||||||
self.sharedContext = sharedContext
|
self.sharedContext = sharedContext
|
||||||
self.context = context
|
self.context = context
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
@ -36,7 +36,7 @@ private enum ShareSearchRecentEntryStableId: Hashable {
|
|||||||
|
|
||||||
private enum ShareSearchRecentEntry: Comparable, Identifiable {
|
private enum ShareSearchRecentEntry: Comparable, Identifiable {
|
||||||
case topPeers(PresentationTheme, PresentationStrings)
|
case topPeers(PresentationTheme, PresentationStrings)
|
||||||
case peer(index: Int, theme: PresentationTheme, peer: Peer, associatedPeer: Peer?, presence: PeerPresence?, PresentationStrings)
|
case peer(index: Int, theme: PresentationTheme, peer: Peer, associatedPeer: Peer?, presence: EnginePeer.Presence?, PresentationStrings)
|
||||||
|
|
||||||
var stableId: ShareSearchRecentEntryStableId {
|
var stableId: ShareSearchRecentEntryStableId {
|
||||||
switch self {
|
switch self {
|
||||||
@ -62,7 +62,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
case let .peer(lhsIndex, lhsTheme, lhsPeer, lhsAssociatedPeer, lhsPresence, lhsStrings):
|
case let .peer(lhsIndex, lhsTheme, lhsPeer, lhsAssociatedPeer, lhsPresence, lhsStrings):
|
||||||
if case let .peer(rhsIndex, rhsTheme, rhsPeer, rhsAssociatedPeer, rhsPresence, rhsStrings) = rhs, lhsPeer.isEqual(rhsPeer) && arePeersEqual(lhsAssociatedPeer, rhsAssociatedPeer) && lhsIndex == rhsIndex && lhsStrings === rhsStrings && lhsTheme === rhsTheme && arePeerPresencesEqual(lhsPresence, rhsPresence) {
|
if case let .peer(rhsIndex, rhsTheme, rhsPeer, rhsAssociatedPeer, rhsPresence, rhsStrings) = rhs, lhsPeer.isEqual(rhsPeer) && arePeersEqual(lhsAssociatedPeer, rhsAssociatedPeer) && lhsIndex == rhsIndex && lhsStrings === rhsStrings && lhsTheme === rhsTheme && lhsPresence == rhsPresence {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
@ -102,7 +102,7 @@ private enum ShareSearchRecentEntry: Comparable, Identifiable {
|
|||||||
private struct ShareSearchPeerEntry: Comparable, Identifiable {
|
private struct ShareSearchPeerEntry: Comparable, Identifiable {
|
||||||
let index: Int32
|
let index: Int32
|
||||||
let peer: EngineRenderedPeer?
|
let peer: EngineRenderedPeer?
|
||||||
let presence: PeerPresence?
|
let presence: EnginePeer.Presence?
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
let strings: PresentationStrings
|
let strings: PresentationStrings
|
||||||
|
|
||||||
|
@ -464,17 +464,16 @@ public func sentShareItems(account: Account, to peerIds: [PeerId], items: [Prepa
|
|||||||
return enqueueMessagesToMultiplePeers(account: account, peerIds: peerIds, messages: messages)
|
return enqueueMessagesToMultiplePeers(account: account, peerIds: peerIds, messages: messages)
|
||||||
|> castError(Void.self)
|
|> castError(Void.self)
|
||||||
|> mapToSignal { messageIds -> Signal<Float, Void> in
|
|> mapToSignal { messageIds -> Signal<Float, Void> in
|
||||||
let key: PostboxViewKey = .messages(Set(messageIds))
|
return TelegramEngine(account: account).data.subscribe(EngineDataMap(
|
||||||
return account.postbox.combinedView(keys: [key])
|
messageIds.map(TelegramEngine.EngineData.Item.Messages.Message.init)
|
||||||
|
))
|
||||||
|> castError(Void.self)
|
|> castError(Void.self)
|
||||||
|> mapToSignal { view -> Signal<Float, Void> in
|
|> mapToSignal { messages -> Signal<Float, Void> in
|
||||||
if let messagesView = view.views[key] as? MessagesView {
|
for (_, message) in messages {
|
||||||
for (_, message) in messagesView.messages {
|
if let message = message, message.flags.contains(.Unsent) {
|
||||||
if message.flags.contains(.Unsent) {
|
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return .single(1.0)
|
return .single(1.0)
|
||||||
}
|
}
|
||||||
|> take(1)
|
|> take(1)
|
||||||
|
@ -1968,15 +1968,14 @@ public final class PresentationGroupCallImpl: PresentationGroupCall {
|
|||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|> runOn(.mainQueue())
|
|> runOn(.mainQueue())
|
||||||
} else {
|
} else {
|
||||||
rawAdminIds = accountContext.account.postbox.combinedView(keys: [.cachedPeerData(peerId: peerId)])
|
rawAdminIds = accountContext.engine.data.subscribe(
|
||||||
|> map { views -> Set<PeerId> in
|
TelegramEngine.EngineData.Item.Peer.LegacyGroupParticipants(id: peerId)
|
||||||
guard let view = views.views[.cachedPeerData(peerId: peerId)] as? CachedPeerDataView else {
|
)
|
||||||
|
|> map { participants -> Set<PeerId> in
|
||||||
|
guard case let .known(participants) = participants else {
|
||||||
return Set()
|
return Set()
|
||||||
}
|
}
|
||||||
guard let cachedData = view.cachedPeerData as? CachedGroupData, let participants = cachedData.participants else {
|
return Set(participants.compactMap { item -> PeerId? in
|
||||||
return Set()
|
|
||||||
}
|
|
||||||
return Set(participants.participants.compactMap { item -> PeerId? in
|
|
||||||
switch item {
|
switch item {
|
||||||
case .creator, .admin:
|
case .creator, .admin:
|
||||||
return item.peerId
|
return item.peerId
|
||||||
|
@ -2,7 +2,7 @@ import SwiftSignalKit
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public final class EngineTotalReadCounters {
|
public final class EngineTotalReadCounters {
|
||||||
private let state: ChatListTotalUnreadState
|
fileprivate let state: ChatListTotalUnreadState
|
||||||
|
|
||||||
public init(state: ChatListTotalUnreadState) {
|
public init(state: ChatListTotalUnreadState) {
|
||||||
self.state = state
|
self.state = state
|
||||||
@ -13,8 +13,14 @@ public final class EngineTotalReadCounters {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public extension EngineTotalReadCounters {
|
||||||
|
func _asCounters() -> ChatListTotalUnreadState {
|
||||||
|
return self.state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public struct EnginePeerReadCounters: Equatable {
|
public struct EnginePeerReadCounters: Equatable {
|
||||||
private let state: CombinedPeerReadState?
|
fileprivate let state: CombinedPeerReadState?
|
||||||
|
|
||||||
public init(state: CombinedPeerReadState?) {
|
public init(state: CombinedPeerReadState?) {
|
||||||
self.state = state
|
self.state = state
|
||||||
@ -64,6 +70,10 @@ public extension EnginePeerReadCounters {
|
|||||||
init(incomingReadId: EngineMessage.Id.Id, outgoingReadId: EngineMessage.Id.Id, count: Int32, markedUnread: Bool) {
|
init(incomingReadId: EngineMessage.Id.Id, outgoingReadId: EngineMessage.Id.Id, count: Int32, markedUnread: Bool) {
|
||||||
self.init(state: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, .idBased(maxIncomingReadId: incomingReadId, maxOutgoingReadId: outgoingReadId, maxKnownId: max(incomingReadId, outgoingReadId), count: count, markedUnread: markedUnread))]))
|
self.init(state: CombinedPeerReadState(states: [(Namespaces.Message.Cloud, .idBased(maxIncomingReadId: incomingReadId, maxOutgoingReadId: outgoingReadId, maxKnownId: max(incomingReadId, outgoingReadId), count: count, markedUnread: markedUnread))]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func _asReadCounters() -> CombinedPeerReadState? {
|
||||||
|
return self.state
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public extension TelegramEngine.EngineData.Item {
|
public extension TelegramEngine.EngineData.Item {
|
||||||
@ -260,5 +270,63 @@ public extension TelegramEngine.EngineData.Item {
|
|||||||
return view.inclusion.groupId.flatMap(EngineChatList.Group.init)
|
return view.inclusion.groupId.flatMap(EngineChatList.Group.init)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct MessageCount: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||||
|
public struct ItemKey: Hashable {
|
||||||
|
public var peerId: EnginePeer.Id
|
||||||
|
public var tag: MessageTags
|
||||||
|
}
|
||||||
|
|
||||||
|
public typealias Result = Int?
|
||||||
|
|
||||||
|
fileprivate var peerId: EnginePeer.Id
|
||||||
|
fileprivate var tag: MessageTags
|
||||||
|
public var mapKey: ItemKey {
|
||||||
|
return ItemKey(peerId: self.peerId, tag: self.tag)
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(peerId: EnginePeer.Id, tag: MessageTags) {
|
||||||
|
self.peerId = peerId
|
||||||
|
self.tag = tag
|
||||||
|
}
|
||||||
|
|
||||||
|
var key: PostboxViewKey {
|
||||||
|
return .historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)
|
||||||
|
}
|
||||||
|
|
||||||
|
func extract(view: PostboxView) -> Result {
|
||||||
|
guard let view = view as? MessageHistoryTagSummaryView else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
return view.count.flatMap(Int.init)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct TopMessage: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||||
|
public typealias Result = EngineMessage?
|
||||||
|
|
||||||
|
fileprivate var id: EnginePeer.Id
|
||||||
|
public var mapKey: EnginePeer.Id {
|
||||||
|
return self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(id: EnginePeer.Id) {
|
||||||
|
self.id = id
|
||||||
|
}
|
||||||
|
|
||||||
|
var key: PostboxViewKey {
|
||||||
|
return .topChatMessage(peerIds: [self.id])
|
||||||
|
}
|
||||||
|
|
||||||
|
func extract(view: PostboxView) -> Result {
|
||||||
|
guard let view = view as? TopChatMessageView else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
guard let message = view.messages[self.id] else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return EngineMessage(message)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ import SwiftSignalKit
|
|||||||
import Postbox
|
import Postbox
|
||||||
|
|
||||||
public typealias EngineExportedPeerInvitation = ExportedInvitation
|
public typealias EngineExportedPeerInvitation = ExportedInvitation
|
||||||
|
public typealias EngineSecretChatKeyFingerprint = SecretChatKeyFingerprint
|
||||||
|
|
||||||
public enum EnginePeerCachedInfoItem<T> {
|
public enum EnginePeerCachedInfoItem<T> {
|
||||||
case known(T)
|
case known(T)
|
||||||
@ -782,5 +783,34 @@ public extension TelegramEngine.EngineData.Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public struct SecretChatKeyFingerprint: TelegramEngineDataItem, TelegramEngineMapKeyDataItem, PostboxViewDataItem {
|
||||||
|
public typealias Result = EngineSecretChatKeyFingerprint?
|
||||||
|
|
||||||
|
fileprivate var id: EnginePeer.Id
|
||||||
|
public var mapKey: EnginePeer.Id {
|
||||||
|
return self.id
|
||||||
|
}
|
||||||
|
|
||||||
|
public init(id: EnginePeer.Id) {
|
||||||
|
self.id = id
|
||||||
|
}
|
||||||
|
|
||||||
|
var key: PostboxViewKey {
|
||||||
|
return .peerChatState(peerId: self.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func extract(view: PostboxView) -> Result {
|
||||||
|
guard let view = view as? PeerChatStateView else {
|
||||||
|
preconditionFailure()
|
||||||
|
}
|
||||||
|
|
||||||
|
if let peerChatState = view.chatState?.getLegacy() as? SecretChatState {
|
||||||
|
return peerChatState.keyFingerprint
|
||||||
|
} else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,37 @@ public final class EngineDataList<Item: TelegramEngineDataItem & TelegramEngineM
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class EngineDataOptional<Item: TelegramEngineDataItem>: TelegramEngineDataItem, AnyPostboxViewDataItem {
|
||||||
|
public typealias Result = Item.Result?
|
||||||
|
|
||||||
|
private let item: Item?
|
||||||
|
|
||||||
|
public init(_ item: Item?) {
|
||||||
|
self.item = item
|
||||||
|
}
|
||||||
|
|
||||||
|
var keys: [PostboxViewKey] {
|
||||||
|
var keys = Set<PostboxViewKey>()
|
||||||
|
if let item = self.item {
|
||||||
|
for key in (item as! AnyPostboxViewDataItem).keys {
|
||||||
|
keys.insert(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Array(keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func _extract(views: [PostboxViewKey: PostboxView]) -> Any {
|
||||||
|
var result: [Item.Result] = []
|
||||||
|
|
||||||
|
if let item = self.item {
|
||||||
|
let itemResult = (item as! AnyPostboxViewDataItem)._extract(views: views)
|
||||||
|
result.append(itemResult as! Item.Result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public extension TelegramEngine {
|
public extension TelegramEngine {
|
||||||
final class EngineData {
|
final class EngineData {
|
||||||
public struct Item {
|
public struct Item {
|
||||||
|
@ -59,10 +59,9 @@ private final class DeviceSpecificContactImportContexts {
|
|||||||
if context.reference != reference {
|
if context.reference != reference {
|
||||||
context.reference = reference
|
context.reference = reference
|
||||||
|
|
||||||
let key: PostboxViewKey = .basicPeer(peerId)
|
let signal = TelegramEngine(account: account).data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
let signal = account.postbox.combinedView(keys: [key])
|
|> map { peer -> String? in
|
||||||
|> map { view -> String? in
|
if case let .user(user) = peer {
|
||||||
if let user = (view.views[key] as? BasicPeerView)?.peer as? TelegramUser {
|
|
||||||
return user.phone
|
return user.phone
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
|
@ -8567,28 +8567,22 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
})
|
})
|
||||||
|
|
||||||
if case let .peer(peerId) = self.chatLocation {
|
if case let .peer(peerId) = self.chatLocation {
|
||||||
let unreadCountsKey: PostboxViewKey = .unreadCounts(items: [.peer(peerId), .total(nil)])
|
self.chatUnreadCountDisposable = (self.context.engine.data.subscribe(
|
||||||
let notificationSettingsKey: PostboxViewKey = .peerNotificationSettings(peerIds: Set([peerId]))
|
TelegramEngine.EngineData.Item.Messages.PeerUnreadCount(id: peerId),
|
||||||
self.chatUnreadCountDisposable = (self.context.account.postbox.combinedView(keys: [unreadCountsKey, notificationSettingsKey])
|
TelegramEngine.EngineData.Item.Messages.TotalReadCounters(),
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] views in
|
TelegramEngine.EngineData.Item.Peer.NotificationSettings(id: peerId)
|
||||||
if let strongSelf = self {
|
)
|
||||||
var unreadCount: Int32 = 0
|
|> deliverOnMainQueue).start(next: { [weak self] peerUnreadCount, totalReadCounters, notificationSettings in
|
||||||
var totalChatCount: Int32 = 0
|
guard let strongSelf = self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let unreadCount: Int32 = Int32(peerUnreadCount)
|
||||||
|
|
||||||
let inAppSettings = strongSelf.context.sharedContext.currentInAppNotificationSettings.with { $0 }
|
let inAppSettings = strongSelf.context.sharedContext.currentInAppNotificationSettings.with { $0 }
|
||||||
if let view = views.views[unreadCountsKey] as? UnreadMessageCountsView {
|
let totalChatCount: Int32 = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: totalReadCounters._asCounters()).0
|
||||||
if let count = view.count(for: .peer(peerId)) {
|
|
||||||
unreadCount = count
|
|
||||||
}
|
|
||||||
if let (_, state) = view.total() {
|
|
||||||
let (count, _) = renderedTotalUnreadCount(inAppSettings: inAppSettings, totalUnreadState: state)
|
|
||||||
totalChatCount = count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let view = views.views[notificationSettingsKey] as? PeerNotificationSettingsView, let notificationSettings = view.notificationSettings[peerId] {
|
|
||||||
var globalRemainingUnreadChatCount = totalChatCount
|
var globalRemainingUnreadChatCount = totalChatCount
|
||||||
if !notificationSettings.isRemovedFromTotalUnreadCount(default: false) && unreadCount > 0 {
|
if !notificationSettings._asNotificationSettings().isRemovedFromTotalUnreadCount(default: false) && unreadCount > 0 {
|
||||||
if case .messages = inAppSettings.totalUnreadCountDisplayCategory {
|
if case .messages = inAppSettings.totalUnreadCountDisplayCategory {
|
||||||
globalRemainingUnreadChatCount -= unreadCount
|
globalRemainingUnreadChatCount -= unreadCount
|
||||||
} else {
|
} else {
|
||||||
@ -8601,8 +8595,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||||||
} else {
|
} else {
|
||||||
strongSelf.navigationItem.badge = ""
|
strongSelf.navigationItem.badge = ""
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId) |> deliverOnMainQueue).start(next: { [weak self] mentionCount, reactionCount in
|
self.chatUnreadMentionCountDisposable = (self.context.account.viewTracker.unseenPersonalMessagesAndReactionCount(peerId: peerId) |> deliverOnMainQueue).start(next: { [weak self] mentionCount, reactionCount in
|
||||||
|
@ -931,20 +931,15 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
|
|
||||||
let customChannelDiscussionReadState: Signal<MessageId?, NoError>
|
let customChannelDiscussionReadState: Signal<MessageId?, NoError>
|
||||||
if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
if case let .peer(peerId) = chatLocation, peerId.namespace == Namespaces.Peer.CloudChannel {
|
||||||
let cachedDataKey = PostboxViewKey.cachedPeerData(peerId: peerId)
|
customChannelDiscussionReadState = context.engine.data.subscribe(
|
||||||
let peerKey = PostboxViewKey.basicPeer(peerId)
|
TelegramEngine.EngineData.Item.Peer.LinkedDiscussionPeerId(id: peerId),
|
||||||
customChannelDiscussionReadState = context.account.postbox.combinedView(keys: [cachedDataKey, peerKey])
|
TelegramEngine.EngineData.Item.Peer.Peer(id: peerId)
|
||||||
|> mapToSignal { views -> Signal<PeerId?, NoError> in
|
)
|
||||||
guard let view = views.views[cachedDataKey] as? CachedPeerDataView else {
|
|> mapToSignal { linkedDiscussionPeerId, peer -> Signal<PeerId?, NoError> in
|
||||||
|
guard case let .channel(peer) = peer, case .broadcast = peer.info else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
guard let peer = (views.views[peerKey] as? BasicPeerView)?.peer as? TelegramChannel, case .broadcast = peer.info else {
|
guard case let .known(value) = linkedDiscussionPeerId else {
|
||||||
return .single(nil)
|
|
||||||
}
|
|
||||||
guard let cachedData = view.cachedPeerData as? CachedChannelData else {
|
|
||||||
return .single(nil)
|
|
||||||
}
|
|
||||||
guard case let .known(value) = cachedData.linkedDiscussionPeerId else {
|
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
return .single(value)
|
return .single(value)
|
||||||
@ -954,13 +949,10 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
|||||||
guard let discussionPeerId = discussionPeerId else {
|
guard let discussionPeerId = discussionPeerId else {
|
||||||
return .single(nil)
|
return .single(nil)
|
||||||
}
|
}
|
||||||
let key = PostboxViewKey.combinedReadState(peerId: discussionPeerId)
|
|
||||||
return context.account.postbox.combinedView(keys: [key])
|
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Messages.PeerReadCounters(id: discussionPeerId))
|
||||||
|> map { views -> MessageId? in
|
|> map { readCounters -> MessageId? in
|
||||||
guard let view = views.views[key] as? CombinedReadStateView else {
|
guard let state = readCounters._asReadCounters() else {
|
||||||
return nil
|
|
||||||
}
|
|
||||||
guard let state = view.state else {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
for (namespace, namespaceState) in state.states {
|
for (namespace, namespaceState) in state.states {
|
||||||
|
@ -1071,16 +1071,10 @@ final class ChatMediaInputNode: ChatInputNode {
|
|||||||
})
|
})
|
||||||
self.trendingInteraction = trendingInteraction
|
self.trendingInteraction = trendingInteraction
|
||||||
|
|
||||||
let preferencesViewKey: PostboxViewKey = .preferences(keys: Set([PreferencesKeys.appConfiguration]))
|
let reactions: Signal<[String], NoError> = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Configuration.App())
|
||||||
let reactions: Signal<[String], NoError> = context.account.postbox.combinedView(keys: [preferencesViewKey])
|
|> map { appConfiguration -> [String] in
|
||||||
|> map { views -> [String] in
|
|
||||||
let defaultReactions: [String] = ["👍", "👎", "😍", "😂", "😯", "😕", "😢", "😡", "💪", "👏", "🙈", "😒"]
|
let defaultReactions: [String] = ["👍", "👎", "😍", "😂", "😯", "😕", "😢", "😡", "💪", "👏", "🙈", "😒"]
|
||||||
guard let view = views.views[preferencesViewKey] as? PreferencesView else {
|
|
||||||
return defaultReactions
|
|
||||||
}
|
|
||||||
guard let appConfiguration = view.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) else {
|
|
||||||
return defaultReactions
|
|
||||||
}
|
|
||||||
guard let data = appConfiguration.data, let emojis = data["gif_search_emojies"] as? [String] else {
|
guard let data = appConfiguration.data, let emojis = data["gif_search_emojies"] as? [String] else {
|
||||||
return defaultReactions
|
return defaultReactions
|
||||||
}
|
}
|
||||||
|
@ -142,9 +142,11 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.statusPromise.set(context.account.postbox.combinedView(keys: [PostboxViewKey.historyTagSummaryView(tag: tagMask, peerId: peerId, namespace: Namespaces.Message.Cloud)])
|
self.statusPromise.set(context.engine.data.subscribe(
|
||||||
|> map { views -> PeerInfoStatusData? in
|
TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: tagMask)
|
||||||
let count: Int32 = (views.views[PostboxViewKey.historyTagSummaryView(tag: tagMask, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView)?.count ?? 0
|
)
|
||||||
|
|> map { count -> PeerInfoStatusData? in
|
||||||
|
let count: Int = count ?? 0
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2015,34 +2015,14 @@ final class PeerInfoVisualMediaPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScro
|
|||||||
case .music:
|
case .music:
|
||||||
summaries.append(.music)
|
summaries.append(.music)
|
||||||
}
|
}
|
||||||
return context.account.postbox.combinedView(keys: summaries.map { tag in
|
|
||||||
return PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)
|
return context.engine.data.subscribe(EngineDataMap(
|
||||||
})
|
summaries.map { TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: $0) }
|
||||||
|> map { views -> (ContentType, [MessageTags: Int32]) in
|
))
|
||||||
switch contentType {
|
|> map { summaries -> (ContentType, [MessageTags: Int32]) in
|
||||||
case .photoOrVideo:
|
|
||||||
summaries.append(.photo)
|
|
||||||
summaries.append(.video)
|
|
||||||
case .photo:
|
|
||||||
summaries.append(.photo)
|
|
||||||
case .video:
|
|
||||||
summaries.append(.video)
|
|
||||||
case .gifs:
|
|
||||||
summaries.append(.gif)
|
|
||||||
case .files:
|
|
||||||
summaries.append(.file)
|
|
||||||
case .voiceAndVideoMessages:
|
|
||||||
summaries.append(.voiceOrInstantVideo)
|
|
||||||
case .music:
|
|
||||||
summaries.append(.music)
|
|
||||||
}
|
|
||||||
var result: [MessageTags: Int32] = [:]
|
var result: [MessageTags: Int32] = [:]
|
||||||
for tag in summaries {
|
for (key, count) in summaries {
|
||||||
if let view = views.views[PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView {
|
result[key.tag] = count.flatMap(Int32.init) ?? 0
|
||||||
result[tag] = view.count ?? 0
|
|
||||||
} else {
|
|
||||||
result[tag] = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return (contentType, result)
|
return (contentType, result)
|
||||||
}
|
}
|
||||||
|
@ -565,25 +565,20 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
return disposable
|
return disposable
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
var combinedKeys: [PostboxViewKey] = []
|
|
||||||
|
var secretChatKeyFingerprint: Signal<EngineSecretChatKeyFingerprint?, NoError> = .single(nil)
|
||||||
if let secretChatId = secretChatId {
|
if let secretChatId = secretChatId {
|
||||||
combinedKeys.append(.peerChatState(peerId: secretChatId))
|
secretChatKeyFingerprint = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.SecretChatKeyFingerprint(id: secretChatId))
|
||||||
}
|
}
|
||||||
|
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.viewTracker.peerView(peerId, updateData: true),
|
context.account.viewTracker.peerView(peerId, updateData: true),
|
||||||
peerInfoAvailableMediaPanes(context: context, peerId: peerId),
|
peerInfoAvailableMediaPanes(context: context, peerId: peerId),
|
||||||
context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()),
|
context.engine.data.subscribe(TelegramEngine.EngineData.Item.NotificationSettings.Global()),
|
||||||
context.account.postbox.combinedView(keys: combinedKeys),
|
secretChatKeyFingerprint,
|
||||||
status
|
status
|
||||||
)
|
)
|
||||||
|> map { peerView, availablePanes, globalNotificationSettings, combinedView, status -> PeerInfoScreenData in
|
|> map { peerView, availablePanes, globalNotificationSettings, encryptionKeyFingerprint, status -> PeerInfoScreenData in
|
||||||
var encryptionKeyFingerprint: SecretChatKeyFingerprint?
|
|
||||||
if let secretChatId = secretChatId, let peerChatStateView = combinedView.views[.peerChatState(peerId: secretChatId)] as? PeerChatStateView {
|
|
||||||
if let peerChatState = peerChatStateView.chatState?.getLegacy() as? SecretChatState {
|
|
||||||
encryptionKeyFingerprint = peerChatState.keyFingerprint
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var availablePanes = availablePanes
|
var availablePanes = availablePanes
|
||||||
if availablePanes != nil, groupsInCommon != nil, let cachedData = peerView.cachedData as? CachedUserData {
|
if availablePanes != nil, groupsInCommon != nil, let cachedData = peerView.cachedData as? CachedUserData {
|
||||||
if cachedData.commonGroupCount != 0 {
|
if cachedData.commonGroupCount != 0 {
|
||||||
|
@ -6766,24 +6766,20 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func displayMediaGalleryContextMenu(source: ContextReferenceContentNode, gesture: ContextGesture?) {
|
private func displayMediaGalleryContextMenu(source: ContextReferenceContentNode, gesture: ContextGesture?) {
|
||||||
let summaryTags: [MessageTags] = [.photo, .video]
|
|
||||||
let peerId = self.peerId
|
let peerId = self.peerId
|
||||||
let _ = (context.account.postbox.combinedView(keys: summaryTags.map { tag in
|
|
||||||
return PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)
|
let _ = (self.context.engine.data.get(EngineDataMap([
|
||||||
})
|
TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: .photo),
|
||||||
|> take(1)
|
TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: .video)
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] views in
|
]))
|
||||||
|
|> deliverOnMainQueue).start(next: { [weak self] messageCounts in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var mediaCount: [MessageTags: Int32] = [:]
|
var mediaCount: [MessageTags: Int32] = [:]
|
||||||
for tag in summaryTags {
|
for (key, count) in messageCounts {
|
||||||
if let view = views.views[PostboxViewKey.historyTagSummaryView(tag: tag, peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView {
|
mediaCount[key.tag] = count.flatMap(Int32.init) ?? 0
|
||||||
mediaCount[tag] = view.count ?? 0
|
|
||||||
} else {
|
|
||||||
mediaCount[tag] = 0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let photoCount: Int32 = mediaCount[.photo] ?? 0
|
let photoCount: Int32 = mediaCount[.photo] ?? 0
|
||||||
|
@ -875,12 +875,11 @@ final class PeerInfoGifPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScrollViewDe
|
|||||||
self.animationTimer = animationTimer
|
self.animationTimer = animationTimer
|
||||||
animationTimer.start()
|
animationTimer.start()
|
||||||
|
|
||||||
self.statusPromise.set(context.account.postbox.combinedView(keys: [PostboxViewKey.historyTagSummaryView(tag: tagMaskForType(self.contentType), peerId: peerId, namespace: Namespaces.Message.Cloud)])
|
self.statusPromise.set(context.engine.data.subscribe(
|
||||||
|> map { [weak self] views -> PeerInfoStatusData? in
|
TelegramEngine.EngineData.Item.Messages.MessageCount(peerId: peerId, tag: tagMaskForType(self.contentType))
|
||||||
guard let strongSelf = self else {
|
)
|
||||||
return nil
|
|> map { count -> PeerInfoStatusData? in
|
||||||
}
|
let count: Int = count ?? 0
|
||||||
let count: Int32 = (views.views[PostboxViewKey.historyTagSummaryView(tag: tagMaskForType(strongSelf.contentType), peerId: peerId, namespace: Namespaces.Message.Cloud)] as? MessageHistoryTagSummaryView)?.count ?? 0
|
|
||||||
if count == 0 {
|
if count == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -198,15 +198,16 @@ final class WidgetDataContext {
|
|||||||
if peerIds.isEmpty {
|
if peerIds.isEmpty {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let topMessagesKey: PostboxViewKey = .topChatMessage(peerIds: Array(peerIds))
|
|
||||||
|
|
||||||
accountSignals.append(account.postbox.combinedView(keys: [topMessagesKey])
|
accountSignals.append(TelegramEngine(account: account).data.subscribe(EngineDataMap(
|
||||||
|> map { combinedView -> [WidgetDataPeer] in
|
peerIds.map(TelegramEngine.EngineData.Item.Messages.TopMessage.init)
|
||||||
guard let topMessages = combinedView.views[topMessagesKey] as? TopChatMessageView else {
|
))
|
||||||
return []
|
|> map { topMessages -> [WidgetDataPeer] in
|
||||||
}
|
|
||||||
var result: [WidgetDataPeer] = []
|
var result: [WidgetDataPeer] = []
|
||||||
for (peerId, message) in topMessages.messages {
|
for (peerId, message) in topMessages {
|
||||||
|
guard let message = message else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
guard let peer = message.peers[message.id.peerId] else {
|
guard let peer = message.peers[message.id.peerId] else {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -227,7 +228,7 @@ final class WidgetDataContext {
|
|||||||
name = peer.debugDisplayTitle
|
name = peer.debugDisplayTitle
|
||||||
}
|
}
|
||||||
|
|
||||||
result.append(WidgetDataPeer(id: peerId.toInt64(), name: name, lastName: lastName, letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(accountPeerId: account.peerId, message: EngineMessage(message))))
|
result.append(WidgetDataPeer(id: peerId.toInt64(), name: name, lastName: lastName, letters: [], avatarPath: nil, badge: nil, message: WidgetDataPeer.Message(accountPeerId: account.peerId, message: message)))
|
||||||
}
|
}
|
||||||
result.sort(by: { lhs, rhs in
|
result.sort(by: { lhs, rhs in
|
||||||
return lhs.id < rhs.id
|
return lhs.id < rhs.id
|
||||||
|
Loading…
x
Reference in New Issue
Block a user