Various UI fixes

This commit is contained in:
Ilya Laktyushin 2020-07-09 06:06:33 +03:00
parent d1efc8f36e
commit a50a19623a
8 changed files with 103 additions and 55 deletions

View File

@ -532,7 +532,7 @@ public protocol SharedAccountContext: class {
func makeProxySettingsController(context: AccountContext) -> ViewController func makeProxySettingsController(context: AccountContext) -> ViewController
func makeLocalizationListController(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 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 makePrivacyAndSecurityController(context: AccountContext) -> ViewController
func navigateToChatController(_ params: NavigateToChatControllerParams) func navigateToChatController(_ params: NavigateToChatControllerParams)
func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void) func openExternalUrl(context: AccountContext, urlContext: OpenURLContext, url: String, forceExternal: Bool, presentationData: PresentationData, navigationController: NavigationController?, dismissInput: @escaping () -> Void)

View File

@ -2743,9 +2743,9 @@
[self setPlayButtonHidden:true animated:false]; [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; _resetDotPosition = true;
[self resetDotImage]; [self resetDotImage];
} }
@ -2754,7 +2754,7 @@
- (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber editingEndValueDidChange:(NSTimeInterval)endValue - (void)videoScrubber:(TGMediaPickerGalleryVideoScrubber *)__unused videoScrubber editingEndValueDidChange:(NSTimeInterval)endValue
{ {
if (endValue < _dotPosition) { if (endValue < _dotPosition || videoScrubber.trimStartValue > _dotPosition) {
_resetDotPosition = true; _resetDotPosition = true;
[self resetDotImage]; [self resetDotImage];
} }

View File

@ -555,7 +555,7 @@ public func channelAdminsController(context: AccountContext, peerId initialPeerI
|> deliverOnMainQueue).start(next: { peer in |> deliverOnMainQueue).start(next: { peer in
if peer is TelegramGroup { if peer is TelegramGroup {
} else { } else {
pushControllerImpl?(context.sharedContext.makeChatRecentActionsController(context: context, peer: peer)) pushControllerImpl?(context.sharedContext.makeChatRecentActionsController(context: context, peer: peer, adminPeerId: nil))
} }
}) })
}) })

View File

@ -95,15 +95,15 @@ private enum StatsEntry: ItemListNodeEntry {
case topWeekdaysGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType) case topWeekdaysGraph(PresentationTheme, PresentationStrings, PresentationDateTimeFormat, StatsGraph, ChartType)
case topPostersTitle(PresentationTheme, String, String) 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 topPostersExpand(PresentationTheme, String)
case topAdminsTitle(PresentationTheme, String, 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 topAdminsExpand(PresentationTheme, String)
case topInvitersTitle(PresentationTheme, String, 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) case topInvitersExpand(PresentationTheme, String)
var section: ItemListSectionId { var section: ItemListSectionId {
@ -175,19 +175,19 @@ private enum StatsEntry: ItemListNodeEntry {
return 17 return 17
case .topPostersTitle: case .topPostersTitle:
return 1000 return 1000
case let .topPoster(index, _, _, _, _, _, _): case let .topPoster(index, _, _, _, _, _, _, _):
return 1001 + index return 1001 + index
case .topPostersExpand: case .topPostersExpand:
return 1999 return 1999
case .topAdminsTitle: case .topAdminsTitle:
return 2000 return 2000
case let .topAdmin(index, _, _, _, _, _, _): case let .topAdmin(index, _, _, _, _, _, _, _):
return 2001 + index return 2001 + index
case .topAdminsExpand: case .topAdminsExpand:
return 2999 return 2999
case .topInvitersTitle: case .topInvitersTitle:
return 3000 return 3000
case let .topInviter(index, _, _, _, _, _, _): case let .topInviter(index, _, _, _, _, _, _, _):
return 3001 + index return 3001 + index
case .topInvitersExpand: case .topInvitersExpand:
return 3999 return 3999
@ -310,8 +310,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .topPoster(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopPoster, lhsRevealed): case let .topPoster(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopPoster, lhsRevealed, lhsCanPromote):
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 { 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 return true
} else { } else {
return false return false
@ -328,8 +328,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .topAdmin(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopAdmin, lhsRevealed): case let .topAdmin(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopAdmin, lhsRevealed, lhsCanPromote):
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 { 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 return true
} else { } else {
return false return false
@ -346,8 +346,8 @@ private enum StatsEntry: ItemListNodeEntry {
} else { } else {
return false return false
} }
case let .topInviter(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopInviter, lhsRevealed): case let .topInviter(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsPeer, lhsTopInviter, lhsRevealed, lhsCanPromote):
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 { 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 return true
} else { } else {
return false return false
@ -394,7 +394,7 @@ private enum StatsEntry: ItemListNodeEntry {
let .topHoursGraph(_, _, _, graph, type), let .topHoursGraph(_, _, _, graph, type),
let .topWeekdaysGraph(_, _, _, graph, type): let .topWeekdaysGraph(_, _, _, graph, type):
return StatsGraphItem(presentationData: presentationData, graph: graph, type: type, sectionId: self.section, style: .blocks) 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] = [] var textComponents: [String] = []
if topPoster.messageCount > 0 { if topPoster.messageCount > 0 {
textComponents.append(strings.Stats_GroupTopPosterMessages(topPoster.messageCount)) 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: { options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopPoster_History, action: {
arguments.openPeerHistory(peer.id) arguments.openPeerHistory(peer.id)
})) }))
options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { if canPromote {
arguments.promotePeer(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: { }))
}
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) arguments.openPeer(peer.id)
}, setPeerIdWithRevealedOptions: { peerId, fromPeerId in }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in
arguments.setPostersPeerIdWithRevealedOptions(peerId, fromPeerId) 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: { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: {
arguments.expandTopPosters() arguments.expandTopPosters()
}) })
case let .topAdmin(_, _, strings, dateTimeFormat, peer, topAdmin, revealed): case let .topAdmin(_, _, strings, dateTimeFormat, peer, topAdmin, revealed, canPromote):
var textComponents: [String] = [] var textComponents: [String] = []
if topAdmin.deletedCount > 0 { if topAdmin.deletedCount > 0 {
textComponents.append(strings.Stats_GroupTopAdminDeletions(topAdmin.deletedCount)) 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: { options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopAdmin_Actions, action: {
arguments.openPeerAdminActions(peer.id) arguments.openPeerAdminActions(peer.id)
})) }))
options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopAdmin_Promote, action: { if canPromote {
arguments.promotePeer(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: { }))
}
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) arguments.openPeer(peer.id)
}, setPeerIdWithRevealedOptions: { peerId, fromPeerId in }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in
arguments.setAdminsPeerIdWithRevealedOptions(peerId, fromPeerId) 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: { return ItemListPeerActionItem(presentationData: presentationData, icon: PresentationResourcesItemList.downArrowImage(theme), title: title, sectionId: self.section, editing: false, action: {
arguments.expandTopAdmins() arguments.expandTopAdmins()
}) })
case let .topInviter(_, _, strings, dateTimeFormat, peer, topInviter, revealed): case let .topInviter(_, _, strings, dateTimeFormat, peer, topInviter, revealed, canPromote):
var textComponents: [String] = [] var textComponents: [String] = []
textComponents.append(strings.Stats_GroupTopInviterInvites(topInviter.inviteCount)) textComponents.append(strings.Stats_GroupTopInviterInvites(topInviter.inviteCount))
var options: [ItemListPeerItemRevealOption] = [] var options: [ItemListPeerItemRevealOption] = []
options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopPoster_History, action: { options.append(ItemListPeerItemRevealOption(type: .accent, title: strings.Stats_GroupTopPoster_History, action: {
arguments.openPeerHistory(peer.id) arguments.openPeerHistory(peer.id)
})) }))
options.append(ItemListPeerItemRevealOption(type: .neutral, title: strings.Stats_GroupTopPoster_Promote, action: { if canPromote {
arguments.promotePeer(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: { }))
}
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) arguments.openPeer(peer.id)
}, setPeerIdWithRevealedOptions: { peerId, fromPeerId in }, setPeerIdWithRevealedOptions: { peerId, fromPeerId in
arguments.setInvitersPeerIdWithRevealedOptions(peerId, fromPeerId) 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] = [] var entries: [StatsEntry] = []
if let data = data { 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(.topWeekdaysTitle(presentationData.theme, presentationData.strings.Stats_GroupTopWeekdaysTitle))
entries.append(.topWeekdaysGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.topWeekdaysGraph, .pie)) entries.append(.topWeekdaysGraph(presentationData.theme, presentationData.strings, presentationData.dateTimeFormat, data.topWeekdaysGraph, .pie))
} }
if let peers = peers { if let peers = peers {
let canPromote = canEditAdminRights(accountPeerId: accountPeerId, channelPeer: channelPeer, initialParticipant: nil)
if !data.topPosters.isEmpty { if !data.topPosters.isEmpty {
entries.append(.topPostersTitle(presentationData.theme, presentationData.strings.Stats_GroupTopPostersTitle, dates)) entries.append(.topPostersTitle(presentationData.theme, presentationData.strings.Stats_GroupTopPostersTitle, dates))
var index: Int32 = 0 var index: Int32 = 0
@ -534,7 +541,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat
for topPoster in topPosters { for topPoster in topPosters {
if let peer = peers[topPoster.peerId], topPoster.messageCount > 0 { 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 index += 1
} }
} }
@ -557,7 +564,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat
for topAdmin in data.topAdmins { for topAdmin in data.topAdmins {
if let peer = peers[topAdmin.peerId], (topAdmin.deletedCount + topAdmin.kickedCount + topAdmin.bannedCount) > 0 { 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 index += 1
} }
} }
@ -580,7 +587,7 @@ private func groupStatsControllerEntries(state: GroupStatsState, data: GroupStat
for topInviter in data.topInviters { for topInviter in data.topInviters {
if let peer = peers[topInviter.peerId], topInviter.inviteCount > 0 { 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 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 { public func groupStatsController(context: AccountContext, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
let statePromise = ValuePromise(GroupStatsState()) let statePromise = ValuePromise(GroupStatsState())
let stateValue = Atomic(value: GroupStatsState()) let stateValue = Atomic(value: GroupStatsState())
@ -793,9 +829,10 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached
let previousData = Atomic<GroupStats?>(value: nil) let previousData = Atomic<GroupStats?>(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 |> 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) let previous = previousData.swap(data)
var emptyStateItem: ItemListControllerEmptyStateItem? var emptyStateItem: ItemListControllerEmptyStateItem?
if data == nil { if data == nil {
@ -805,9 +842,9 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached
emptyStateItem = ItemListLoadingIndicatorEmptyStateItem(theme: presentationData.theme) 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 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)) return (controllerState, (listState, arguments))
} }
@ -852,7 +889,7 @@ public func groupStatsController(context: AccountContext, peerId: PeerId, cached
let _ = (context.account.postbox.loadedPeerWithId(peerId) let _ = (context.account.postbox.loadedPeerWithId(peerId)
|> take(1) |> take(1)
|> deliverOnMainQueue).start(next: { peer in |> 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) navigationController.pushViewController(controller)
}) })
} }

View File

@ -18,6 +18,7 @@ final class ChatRecentActionsController: TelegramBaseController {
private let context: AccountContext private let context: AccountContext
private let peer: Peer private let peer: Peer
private let initialAdminPeerId: PeerId?
private var presentationData: PresentationData private var presentationData: PresentationData
private var presentationDataDisposable: Disposable? private var presentationDataDisposable: Disposable?
@ -26,9 +27,10 @@ final class ChatRecentActionsController: TelegramBaseController {
private let titleView: ChatRecentActionsTitleView private let titleView: ChatRecentActionsTitleView
init(context: AccountContext, peer: Peer) { init(context: AccountContext, peer: Peer, adminPeerId: PeerId?) {
self.context = context self.context = context
self.peer = peer self.peer = peer
self.initialAdminPeerId = adminPeerId
self.presentationData = context.sharedContext.currentPresentationData.with { $0 } self.presentationData = context.sharedContext.currentPresentationData.with { $0 }
@ -174,6 +176,11 @@ final class ChatRecentActionsController: TelegramBaseController {
return self?.navigationController as? NavigationController return self?.navigationController as? NavigationController
}) })
if let adminPeerId = self.initialAdminPeerId {
self.controllerNode.updateFilter(events: .all, adminPeerIds: [adminPeerId])
self.updateTitle()
}
self.displayNodeDidLoad() self.displayNodeDidLoad()
} }

View File

@ -1915,7 +1915,8 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
private let requestUpdateLayout: () -> Void private let requestUpdateLayout: () -> Void
let avatarNode: PeerInfoEditingAvatarNode let avatarNode: PeerInfoEditingAvatarNode
let avatarTextNode: HighlightableButtonNode let avatarTextNode: ImmediateTextNode
let avatarButtonNode: HighlightableButtonNode
var itemNodes: [PeerInfoHeaderTextFieldNodeKey: PeerInfoHeaderTextFieldNode] = [:] var itemNodes: [PeerInfoHeaderTextFieldNodeKey: PeerInfoHeaderTextFieldNode] = [:]
@ -1925,13 +1926,15 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
self.avatarNode = PeerInfoEditingAvatarNode(context: context) self.avatarNode = PeerInfoEditingAvatarNode(context: context)
self.avatarTextNode = HighlightableButtonNode() self.avatarTextNode = ImmediateTextNode()
self.avatarButtonNode = HighlightableButtonNode()
super.init() super.init()
self.addSubnode(self.avatarNode) 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() { @objc private func textPressed() {
@ -1954,14 +1957,14 @@ final class PeerInfoHeaderEditingContentNode: ASDisplayNode {
var contentHeight: CGFloat = statusBarHeight + 10.0 + avatarSize + 20.0 var contentHeight: CGFloat = statusBarHeight + 10.0 + avatarSize + 20.0
if canEditPeerInfo(context: self.context, peer: peer) { if canEditPeerInfo(context: self.context, peer: peer) {
if self.avatarTextNode.supernode == nil { if self.avatarButtonNode.supernode == nil {
self.addSubnode(self.avatarTextNode) 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.updateLayout(CGSize(width: width, height: 32.0))
transition.updateFrame(node: self.avatarTextNode, frame: CGRect(origin: CGPoint(), size: avatarTextSize))
let avatarTextSize = self.avatarTextNode.measure(CGSize(width: width, height: 32.0)) transition.updateFrame(node: self.avatarButtonNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - avatarTextSize.width) / 2.0), y: contentHeight - 1.0), size: avatarTextSize))
transition.updateFrame(node: self.avatarTextNode, frame: CGRect(origin: CGPoint(x: floorToScreenPixels((width - avatarTextSize.width) / 2.0), y: contentHeight - 1.0), size: avatarTextSize))
contentHeight += 32.0 contentHeight += 32.0
} }

View File

@ -4144,7 +4144,8 @@ private final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewD
assetsController?.dismiss() assetsController?.dismiss()
self?.updateProfilePhoto(result) self?.updateProfilePhoto(result)
})) }))
strongSelf.controller?.present(controller, in: .window(.root)) controller.navigationPresentation = .modal
strongSelf.controller?.push(controller)
} }
mixin.didFinishWithImage = { [weak self] image in mixin.didFinishWithImage = { [weak self] image in
if let image = image { if let image = image {

View File

@ -1096,8 +1096,8 @@ public final class SharedAccountContextImpl: SharedAccountContext {
return peerSharedMediaControllerImpl(context: context, peerId: peerId) return peerSharedMediaControllerImpl(context: context, peerId: peerId)
} }
public func makeChatRecentActionsController(context: AccountContext, peer: Peer) -> ViewController { public func makeChatRecentActionsController(context: AccountContext, peer: Peer, adminPeerId: PeerId?) -> ViewController {
return ChatRecentActionsController(context: context, peer: peer) return ChatRecentActionsController(context: context, peer: peer, adminPeerId: adminPeerId)
} }
public func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void) { public func presentContactsWarningSuppression(context: AccountContext, present: (ViewController, Any?) -> Void) {