diff --git a/submodules/AccountContext/Sources/AccountContext.swift b/submodules/AccountContext/Sources/AccountContext.swift index 1510f52b92..19f7d7932a 100644 --- a/submodules/AccountContext/Sources/AccountContext.swift +++ b/submodules/AccountContext/Sources/AccountContext.swift @@ -532,7 +532,7 @@ public protocol SharedAccountContext: class { func makeProxySettingsController(context: AccountContext) -> ViewController func makeLocalizationListController(context: AccountContext) -> ViewController func makeCreateGroupController(context: AccountContext, peerIds: [PeerId], initialTitle: String?, mode: CreateGroupMode, completion: ((PeerId, @escaping () -> Void) -> Void)?) -> ViewController - func makeChatRecentActionsController(context: AccountContext, peer: Peer) -> ViewController + func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController func makePrivacyAndSecurityController(context: AccountContext) -> ViewController func navigateToChatController(_ params: NavigateToChatControllerParams) func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void) diff --git a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m index b59f8b7d28..a3297538d9 100644 --- a/submodules/LegacyComponents/Sources/TGPhotoEditorController.m +++ b/submodules/LegacyComponents/Sources/TGPhotoEditorController.m @@ -2743,9 +2743,9 @@ [self setPlayButtonHidden:true animated:false]; } -- (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber editingStartValueDidChange:(NSTimeInterval)startValue +- (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)videoScrubber editingStartValueDidChange:(NSTimeInterval)startValue { - if (startValue > _dotPosition) { + if (startValue > _dotPosition || videoScrubber.trimEndValue < _dotPosition) { _resetDotPosition = true; [self resetDotImage]; } @@ -2754,7 +2754,7 @@ - (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber editingEndValueDidChange:(NSTimeInterval)endValue { - if (endValue < _dotPosition) { + if (endValue < _dotPosition || videoScrubber.trimStartValue > _dotPosition) { _resetDotPosition = true; [self resetDotImage]; } diff --git a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift index 98bd7c24ad..fd900c8f52 100644 --- a/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift +++ b/submodules/PeerInfoUI/Sources/ChannelAdminsController.swift @@ -555,7 +555,7 @@ public func channelAdminsController(context: AccountContext, peerId initialPeerI |> deliverOnMainQueue).start(next: { peer in if peer is TelegramGroup { } else { - pushControllerImpl?(context.sharedContext.makeChatRecentActionsController(context: context, peer: peer)) + pushControllerImpl?(context.sharedContext.makeChatRecentActionsController(context: context, peer: peer, adminPeerId: nil)) } }) }) diff --git a/submodules/StatisticsUI/Sources/GroupStatsController.swift b/submodules/StatisticsUI/Sources/GroupStatsController.swift index 438392c06f..22d12d2514 100644 --- a/submodules/StatisticsUI/Sources/GroupStatsController.swift +++ b/submodules/StatisticsUI/Sources/GroupStatsController.swift @@ -95,15 +95,15 @@ private enum StatsEntry: ItemListNodeEntry { case topWeekdaysGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType) case topPostersTitle(PresentationTheme, String, String) - case topPoster(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopPoster, Bool) + case topPoster(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopPoster, Bool, Bool) case topPostersExpand(PresentationTheme, String) case topAdminsTitle(PresentationTheme, String, String) - case topAdmin(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopAdmin, Bool) + case topAdmin(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopAdmin, Bool, Bool) case topAdminsExpand(PresentationTheme, String) case topInvitersTitle(PresentationTheme, String, String) - case topInviter(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopInviter, Bool) + case topInviter(Int32, PresentationTheme, PresentationStrings, PresentationDateTimeFormat, Peer, GroupStatsTopInviter, Bool, Bool) case topInvitersExpand(PresentationTheme, String) var section: ItemListSectionId { @@ -175,19 +175,19 @@ private enum StatsEntry: ItemListNodeEntry { return 17 case .topPostersTitle: return 1000 - case let .topPoster(index, _, _, _, _, _, _): + case let .topPoster(index, _, _, _, _, _, _, _): return 1001 + index case .topPostersExpand: return 1999 case .topAdminsTitle: return 2000 - case let .topAdmin(index, _, _, _, _, _, _): + case let .topAdmin(index, _, _, _, _, _, _, _): return 2001 + index case .topAdminsExpand: return 2999 case .topInvitersTitle: return 3000 - case let .topInviter(index, _, _, _, _, _, _): + case let .topInviter(index, _, _, _, _, _, _, _): return 3001 + index case .topInvitersExpand: return 3999 @@ -310,8 +310,8 @@ private enum StatsEntry: ItemListNodeEntry { } else { return false } - case let .topPoster(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopPoster, lhsRevealed): - if case let .topPoster(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopPoster, rhsRevealed) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopPoster == rhsTopPoster, lhsRevealed == rhsRevealed { + case let .topPoster(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopPoster, lhsRevealed, lhsCanPromote): + if case let .topPoster(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopPoster, rhsRevealed, rhsCanPromote) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopPoster == rhsTopPoster, lhsRevealed == rhsRevealed, lhsCanPromote == rhsCanPromote { return true } else { return false @@ -328,8 +328,8 @@ private enum StatsEntry: ItemListNodeEntry { } else { return false } - case let .topAdmin(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopAdmin, lhsRevealed): - if case let .topAdmin(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopAdmin, rhsRevealed) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopAdmin == rhsTopAdmin, lhsRevealed == rhsRevealed { + case let .topAdmin(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopAdmin, lhsRevealed, lhsCanPromote): + if case let .topAdmin(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopAdmin, rhsRevealed, rhsCanPromote) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopAdmin == rhsTopAdmin, lhsRevealed == rhsRevealed, lhsCanPromote == rhsCanPromote { return true } else { return false @@ -346,8 +346,8 @@ private enum StatsEntry: ItemListNodeEntry { } else { return false } - case let .topInviter(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopInviter, lhsRevealed): - if case let .topInviter(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopInviter, rhsRevealed) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopInviter == rhsTopInviter, lhsRevealed == rhsRevealed { + case let .topInviter(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopInviter, lhsRevealed, lhsCanPromote): + if case let .topInviter(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsPeer, rhsTopInviter, rhsRevealed, rhsCanPromote) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, arePeersEqual(lhsPeer, rhsPeer), lhsTopInviter == rhsTopInviter, lhsRevealed == rhsRevealed, lhsCanPromote == rhsCanPromote { return true } else { return false @@ -394,7 +394,7 @@ private enum StatsEntry: ItemListNodeEntry { let .topHoursGraph(_, _, _, graph, type), let .topWeekdaysGraph(_, _, _, graph, type): return StatsGraphItem(presentationData: presentationData, graph: graph, type: type, sectionId: self.section, style: .blocks) - case let .topPoster(_, _, strings, dateTimeFormat, peer, topPoster, revealed): + case let .topPoster(_, _, strings, dateTimeFormat, peer, topPoster, revealed, canPromote): var textComponents: [String] = [] if topPoster.messageCount > 0 { textComponents.append(strings.Stats_GroupTopPosterMessages(topPoster.messageCount)) @@ -406,10 +406,12 @@ private enum StatsEntry: ItemListNodeEntry { options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopPoster_History, action: { arguments.openPeerHistory(peer.id) })) - options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { - arguments.promotePeer(peer.id) - })) - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: { + if canPromote { + options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { + arguments.promotePeer(peer.id) + })) + } + return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: arguments.context.account.peerId != peer.id, sectionId: self.section, action: { arguments.openPeer(peer.id) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in arguments.setPostersPeerIdWithRevealedOptions(peerId, fromPeerId) @@ -418,7 +420,7 @@ private enum StatsEntry: ItemListNodeEntry { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: { arguments.expandTopPosters() }) - case let .topAdmin(_, _, strings, dateTimeFormat, peer, topAdmin, revealed): + case let .topAdmin(_, _, strings, dateTimeFormat, peer, topAdmin, revealed, canPromote): var textComponents: [String] = [] if topAdmin.deletedCount > 0 { textComponents.append(strings.Stats_GroupTopAdminDeletions(topAdmin.deletedCount)) @@ -433,10 +435,12 @@ private enum StatsEntry: ItemListNodeEntry { options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopAdmin_Actions, action: { arguments.openPeerAdminActions(peer.id) })) - options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopAdmin_Promote, action: { - arguments.promotePeer(peer.id) - })) - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: { + if canPromote { + options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopAdmin_Promote, action: { + arguments.promotePeer(peer.id) + })) + } + return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: arguments.context.account.peerId != peer.id, sectionId: self.section, action: { arguments.openPeer(peer.id) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in arguments.setAdminsPeerIdWithRevealedOptions(peerId, fromPeerId) @@ -445,17 +449,19 @@ private enum StatsEntry: ItemListNodeEntry { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: { arguments.expandTopAdmins() }) - case let .topInviter(_, _, strings, dateTimeFormat, peer, topInviter, revealed): + case let .topInviter(_, _, strings, dateTimeFormat, peer, topInviter, revealed, canPromote): var textComponents: [String] = [] textComponents.append(strings.Stats_GroupTopInviterInvites(topInviter.inviteCount)) var options: [ItemListPeerItemRevealOption] = [] options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopPoster_History, action: { arguments.openPeerHistory(peer.id) })) - options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { - arguments.promotePeer(peer.id) - })) - return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: true, sectionId: self.section, action: { + if canPromote { + options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { + arguments.promotePeer(peer.id) + })) + } + return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: .firstLast, context: arguments.context, peer: peer, height: .generic, aliasHandling: .standard, nameColor: .primary, nameStyle: .plain, presence: nil, text: .text(textComponents.joined(separator: ", ")), label: .none, editing: ItemListPeerItemEditing(editable: true, editing: false, revealed: revealed), revealOptions: ItemListPeerItemRevealOptions(options: options), switchValue: nil, enabled: true, highlighted: false, selectable: arguments.context.account.peerId != peer.id, sectionId: self.section, action: { arguments.openPeer(peer.id) }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in arguments.setInvitersPeerIdWithRevealedOptions(peerId, fromPeerId) @@ -468,7 +474,7 @@ private enum StatsEntry: ItemListNodeEntry { } } -private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStats?, peers: [PeerId: Peer]?, presentationData: PresentationData) -> [StatsEntry] { +private func groupStatsControllerEntries(accountPeerId: PeerId, state: GroupStatsState, data: GroupStats?, channelPeer: Peer, peers: [PeerId: Peer]?, presentationData: PresentationData) -> [StatsEntry] { var entries: [StatsEntry] = [] if let data = data { @@ -518,8 +524,9 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat entries.append(.topWeekdaysTitle(presentationData.theme, presentationData.strings.Stats_GroupTopWeekdaysTitle)) entries.append(.topWeekdaysGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.topWeekdaysGraph, .pie)) } - + if let peers = peers { + let canPromote = canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: nil) if !data.topPosters.isEmpty { entries.append(.topPostersTitle(presentationData.theme, presentationData.strings.Stats_GroupTopPostersTitle, dates)) var index: Int32 = 0 @@ -534,7 +541,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat for topPoster in topPosters { if let peer = peers[topPoster.peerId], topPoster.messageCount > 0 { - entries.append(.topPoster(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topPoster, topPoster.peerId == state.posterPeerIdWithRevealedOptions)) + entries.append(.topPoster(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topPoster, topPoster.peerId == state.posterPeerIdWithRevealedOptions, canPromote)) index += 1 } } @@ -557,7 +564,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat for topAdmin in data.topAdmins { if let peer = peers[topAdmin.peerId], (topAdmin.deletedCount + topAdmin.kickedCount + topAdmin.bannedCount) > 0 { - entries.append(.topAdmin(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topAdmin, topAdmin.peerId == state.adminPeerIdWithRevealedOptions)) + entries.append(.topAdmin(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topAdmin, topAdmin.peerId == state.adminPeerIdWithRevealedOptions, canPromote)) index += 1 } } @@ -580,7 +587,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat for topInviter in data.topInviters { if let peer = peers[topInviter.peerId], topInviter.inviteCount > 0 { - entries.append(.topInviter(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topInviter, topInviter.peerId == state.inviterPeerIdWithRevealedOptions)) + entries.append(.topInviter(index, presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, peer, topInviter, topInviter.peerId == state.inviterPeerIdWithRevealedOptions, canPromote)) index += 1 } } @@ -668,6 +675,35 @@ private struct GroupStatsState: Equatable { } } +private func canEditAdminRights(accountPeerId: PeerId, channelPeer: Peer, initialParticipant: ChannelParticipant?) -> Bool { + if let channel = channelPeer as? TelegramChannel { + if channel.flags.contains(.isCreator) { + return true + } else if let initialParticipant = initialParticipant { + switch initialParticipant { + case .creator: + return false + case let .member(_, _, adminInfo, _, _): + if let adminInfo = adminInfo { + return adminInfo.canBeEditedByAccountPeer || adminInfo.promotedBy == accountPeerId + } else { + return channel.hasPermission(.addAdmins) + } + } + } else { + return channel.hasPermission(.addAdmins) + } + } else if let group = channelPeer as? TelegramGroup { + if case .creator = group.role { + return true + } else { + return false + } + } else { + return false + } +} + public func groupStatsController(context: AccountContext, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController { let statePromise = ValuePromise(GroupStatsState()) let stateValue = Atomic(value: GroupStatsState()) @@ -793,9 +829,10 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached let previousData = Atomic(value: nil) - let signal = combineLatest(statePromise.get(), context.sharedContext.presentationData, dataPromise.get(), peersPromise.get(), longLoadingSignal) + + let signal = combineLatest(statePromise.get(), context.sharedContext.presentationData, dataPromise.get(), context.account.postbox.loadedPeerWithId(peerId), peersPromise.get(), longLoadingSignal) |> deliverOnMainQueue - |> map { state, presentationData, data, peers, longLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in + |> map { state, presentationData, data, channelPeer, peers, longLoading -> (ItemListControllerState, (ItemListNodeState, Any)) in let previous = previousData.swap(data) var emptyStateItem: ItemListControllerEmptyStateItem? if data == nil { @@ -805,9 +842,9 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) } } - + let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ChannelInfo_Stats), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true) - let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: groupStatsControllerEntries(state: state, data: data, peers: peers, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) + let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: groupStatsControllerEntries(accountPeerId: context.account.peerId, state: state, data: data, channelPeer: channelPeer, peers: peers, presentationData: presentationData), style: .blocks, emptyStateItem: emptyStateItem, crossfadeState: previous == nil, animateChanges: false) return (controllerState, (listState, arguments)) } @@ -852,7 +889,7 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached let _ = (context.account.postbox.loadedPeerWithId(peerId) |> take(1) |> deliverOnMainQueue).start(next: { peer in - let controller = context.sharedContext.makeChatRecentActionsController(context: context, peer: peer) + let controller = context.sharedContext.makeChatRecentActionsController(context: context, peer: peer, adminPeerId: participantPeerId) navigationController.pushViewController(controller) }) } diff --git a/submodules/TelegramUI/Sources/ChatRecentActionsController.swift b/submodules/TelegramUI/Sources/ChatRecentActionsController.swift index c92630b7b5..2be30eb2bf 100644 --- a/submodules/TelegramUI/Sources/ChatRecentActionsController.swift +++ b/submodules/TelegramUI/Sources/ChatRecentActionsController.swift @@ -18,6 +18,7 @@ final class ChatRecentActionsController: TelegramBaseController { private let context: AccountContext private let peer: Peer + private let initialAdminPeerId: PeerId? private var presentationData: PresentationData private var presentationDataDisposable: Disposable? @@ -26,9 +27,10 @@ final class ChatRecentActionsController: TelegramBaseController { private let titleView: ChatRecentActionsTitleView - init(context: AccountContext, peer: Peer) { + init(context: AccountContext, peer: Peer, adminPeerId: PeerId?) { self.context = context self.peer = peer + self.initialAdminPeerId = adminPeerId self.presentationData = context.sharedContext.currentPresentationData.with { $0 } @@ -174,6 +176,11 @@ final class ChatRecentActionsController: TelegramBaseController { return self?.navigationController as? NavigationController }) + if let adminPeerId = self.initialAdminPeerId { + self.controllerNode.updateFilter(events: .all, adminPeerIds: [adminPeerId]) + self.updateTitle() + } + self.displayNodeDidLoad() } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift index 43dbec9028..b4472b5be3 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoHeaderNode.swift @@ -1915,7 +1915,8 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode { private let requestUpdateLayout: () -> Void let avatarNode: PeerInfoEditingAvatarNode - let avatarTextNode: HighlightableButtonNode + let avatarTextNode: ImmediateTextNode + let avatarButtonNode: HighlightableButtonNode var itemNodes: [PeerInfoHeaderTextFieldNodeKey: PeerInfoHeaderTextFieldNode] = [:] @@ -1925,13 +1926,15 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode { self.avatarNode = PeerInfoEditingAvatarNode(context: context) - self.avatarTextNode = HighlightableButtonNode() + self.avatarTextNode = ImmediateTextNode() + self.avatarButtonNode = HighlightableButtonNode() super.init() self.addSubnode(self.avatarNode) + self.avatarButtonNode.addSubnode(self.avatarTextNode) - self.avatarTextNode.addTarget(self, action: #selector(textPressed), forControlEvents: .touchUpInside) + self.avatarButtonNode.addTarget(self, action: #selector(textPressed), forControlEvents: .touchUpInside) } @objc private func textPressed() { @@ -1954,14 +1957,14 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode { var contentHeight: CGFloat = statusBarHeight + 10.0 + avatarSize + 20.0 if canEditPeerInfo(context: self.context, peer: peer) { - if self.avatarTextNode.supernode == nil { - self.addSubnode(self.avatarTextNode) + if self.avatarButtonNode.supernode == nil { + self.addSubnode(self.avatarButtonNode) } + self.avatarTextNode.attributedText = NSAttributedString(string: presentationData.strings.Settings_SetNewProfilePhotoOrVideo, font: Font.regular(17.0), textColor: presentationData.theme.list.itemAccentColor) - self.avatarTextNode.setAttributedTitle(NSAttributedString(string: presentationData.strings.Settings_SetNewProfilePhotoOrVideo, font: Font.regular(17.0), textColor: presentationData.theme.list.itemAccentColor), for: []) - - let avatarTextSize = self.avatarTextNode.measure(CGSize(width: width, height: 32.0)) - transition.updateFrame(node: self.avatarTextNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - avatarTextSize.width) / 2.0), y: contentHeight - 1.0), size: avatarTextSize)) + let avatarTextSize = self.avatarTextNode.updateLayout(CGSize(width: width, height: 32.0)) + transition.updateFrame(node: self.avatarTextNode, frame: CGRect(origin: CGPoint(), size: avatarTextSize)) + transition.updateFrame(node: self.avatarButtonNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - avatarTextSize.width) / 2.0), y: contentHeight - 1.0), size: avatarTextSize)) contentHeight += 32.0 } diff --git a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift index 771705c682..7eaf7a2000 100644 --- a/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift +++ b/submodules/TelegramUI/Sources/PeerInfo/PeerInfoScreen.swift @@ -4144,7 +4144,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD assetsController?.dismiss() self?.updateProfilePhoto(result) })) - strongSelf.controller?.present(controller, in: .window(.root)) + controller.navigationPresentation = .modal + strongSelf.controller?.push(controller) } mixin.didFinishWithImage = { [weak self] image in if let image = image { diff --git a/submodules/TelegramUI/Sources/SharedAccountContext.swift b/submodules/TelegramUI/Sources/SharedAccountContext.swift index 125285ed05..b8d6dbfb2d 100644 --- a/submodules/TelegramUI/Sources/SharedAccountContext.swift +++ b/submodules/TelegramUI/Sources/SharedAccountContext.swift @@ -1096,8 +1096,8 @@ public final class SharedAccountContextImpl: SharedAccountContext { return peerSharedMediaControllerImpl(context: context, peerId: peerId) } - public func makeChatRecentActionsController(context: AccountContext, peer: Peer) -> ViewController { - return ChatRecentActionsController(context: context, peer: peer) + public func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController { + return ChatRecentActionsController(context: context, peer: peer, adminPeerId: adminPeerId) } public func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void) {