mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Various improvements
This commit is contained in:
parent
7d65064f9b
commit
c05a1dd17c
5 changed files with 373 additions and 83 deletions
|
|
@ -1697,7 +1697,17 @@ public func channelAdminController(context: AccountContext, updatedPresentationD
|
|||
})
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||
let rightNavigationButton: ItemListNavigationButton?
|
||||
if state.focusedOnRank {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
rightButtonActionImpl()
|
||||
})
|
||||
footerItem = nil
|
||||
} else {
|
||||
rightNavigationButton = nil
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, 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, channelPeer: channelPeer, adminPeer: adminPeer, adminPresence: adminPresence, initialParticipant: initialParticipant, invite: invite, canEdit: canEdit), style: .blocks, focusItemTag: nil, ensureVisibleItemTag: nil, emptyStateItem: nil, footerItem: footerItem, animateChanges: true)
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import PresentationDataUtils
|
|||
import ItemListAvatarAndNameInfoItem
|
||||
import OldChannelsController
|
||||
|
||||
private let rankMaxLength: Int32 = 16
|
||||
|
||||
private final class ChannelBannedMemberControllerArguments {
|
||||
let context: AccountContext
|
||||
let toggleRight: (TelegramChatBannedRightsFlags, Bool) -> Void
|
||||
|
|
@ -23,8 +25,12 @@ private final class ChannelBannedMemberControllerArguments {
|
|||
let openTimeout: () -> Void
|
||||
let delete: () -> Void
|
||||
let openPeer: () -> Void
|
||||
let updateRank: (String, String) -> Void
|
||||
let updateFocusedOnRank: (Bool) -> Void
|
||||
let dismissInput: () -> Void
|
||||
let animateError: () -> Void
|
||||
|
||||
init(context: AccountContext, toggleRight: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, toggleRightWhileDisabled: @escaping (TelegramChatBannedRightsFlags) -> Void, toggleIsOptionExpanded: @escaping (TelegramChatBannedRightsFlags) -> Void, openTimeout: @escaping () -> Void, delete: @escaping () -> Void, openPeer: @escaping () -> Void) {
|
||||
init(context: AccountContext, toggleRight: @escaping (TelegramChatBannedRightsFlags, Bool) -> Void, toggleRightWhileDisabled: @escaping (TelegramChatBannedRightsFlags) -> Void, toggleIsOptionExpanded: @escaping (TelegramChatBannedRightsFlags) -> Void, openTimeout: @escaping () -> Void, delete: @escaping () -> Void, openPeer: @escaping () -> Void, updateRank: @escaping (String, String) -> Void, updateFocusedOnRank: @escaping (Bool) -> Void, dismissInput: @escaping () -> Void, animateError: @escaping () -> Void) {
|
||||
self.context = context
|
||||
self.toggleRight = toggleRight
|
||||
self.toggleRightWhileDisabled = toggleRightWhileDisabled
|
||||
|
|
@ -32,6 +38,10 @@ private final class ChannelBannedMemberControllerArguments {
|
|||
self.openTimeout = openTimeout
|
||||
self.delete = delete
|
||||
self.openPeer = openPeer
|
||||
self.updateRank = updateRank
|
||||
self.updateFocusedOnRank = updateFocusedOnRank
|
||||
self.dismissInput = dismissInput
|
||||
self.animateError = animateError
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -40,6 +50,19 @@ private enum ChannelBannedMemberSection: Int32 {
|
|||
case rights
|
||||
case timeout
|
||||
case delete
|
||||
case rank
|
||||
}
|
||||
|
||||
private enum ChannelBannedMemberEntryTag: ItemListItemTag {
|
||||
case rank
|
||||
|
||||
func isEqual(to other: ItemListItemTag) -> Bool {
|
||||
if let other = other as? ChannelBannedMemberEntryTag, self == other {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum ChannelBannedMemberEntryStableId: Hashable {
|
||||
|
|
@ -49,6 +72,10 @@ private enum ChannelBannedMemberEntryStableId: Hashable {
|
|||
case timeout
|
||||
case exceptionInfo
|
||||
case delete
|
||||
case rankTitle
|
||||
case rankPreview
|
||||
case rank
|
||||
case rankInfo
|
||||
}
|
||||
|
||||
private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
||||
|
|
@ -58,6 +85,10 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
|||
case timeout(PresentationTheme, String, String)
|
||||
case exceptionInfo(PresentationTheme, String)
|
||||
case delete(PresentationTheme, String)
|
||||
case rankTitle(PresentationTheme, String, Int32?, Int32)
|
||||
case rankPreview(PresentationTheme, PresentationStrings, EnginePeer, String, Bool)
|
||||
case rank(PresentationTheme, PresentationStrings, String, String, Bool)
|
||||
case rankInfo(PresentationTheme, String, Bool)
|
||||
|
||||
var section: ItemListSectionId {
|
||||
switch self {
|
||||
|
|
@ -69,6 +100,8 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
|||
return ChannelBannedMemberSection.timeout.rawValue
|
||||
case .delete:
|
||||
return ChannelBannedMemberSection.delete.rawValue
|
||||
case .rankTitle, .rankPreview, .rank, .rankInfo:
|
||||
return ChannelBannedMemberSection.rank.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -86,6 +119,14 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
|||
return .exceptionInfo
|
||||
case .delete:
|
||||
return .delete
|
||||
case .rankTitle:
|
||||
return .rankTitle
|
||||
case .rankPreview:
|
||||
return .rankPreview
|
||||
case .rank:
|
||||
return .rank
|
||||
case .rankInfo:
|
||||
return .rankInfo
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -167,50 +208,109 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
|||
} else {
|
||||
return false
|
||||
}
|
||||
case let .rankTitle(lhsTheme, lhsText, lhsCount, lhsLimit):
|
||||
if case let .rankTitle(rhsTheme, rhsText, rhsCount, rhsLimit) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsCount == rhsCount, lhsLimit == rhsLimit {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .rankPreview(lhsTheme, lhsStrings, lhsPeer, lhsRank, lhsIsOwner):
|
||||
if case let .rankPreview(rhsTheme, rhsStrings, rhsPeer, rhsRank, rhsIsOwner) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsPeer == rhsPeer, lhsRank == rhsRank, lhsIsOwner == rhsIsOwner {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .rank(lhsTheme, lhsStrings, lhsPlaceholder, lhsValue, lhsEnabled):
|
||||
if case let .rank(rhsTheme, rhsStrings, rhsPlaceholder, rhsValue, rhsEnabled) = rhs, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsPlaceholder == rhsPlaceholder, lhsValue == rhsValue, lhsEnabled == rhsEnabled {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .rankInfo(lhsTheme, lhsText, lhsTrimBottomInset):
|
||||
if case let .rankInfo(rhsTheme, rhsText, rhsTrimBottomInset) = rhs, lhsTheme === rhsTheme, lhsText == rhsText, lhsTrimBottomInset == rhsTrimBottomInset {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static func <(lhs: ChannelBannedMemberEntry, rhs: ChannelBannedMemberEntry) -> Bool {
|
||||
switch lhs {
|
||||
case .info:
|
||||
switch rhs {
|
||||
case .info:
|
||||
switch rhs {
|
||||
case .info:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .rightsHeader:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case let .rightItem(_, lhsIndex, _, _, _, _, _, _):
|
||||
switch rhs {
|
||||
case .info, .rightsHeader:
|
||||
return false
|
||||
case let .rightItem(_, rhsIndex, _, _, _, _, _, _):
|
||||
return lhsIndex < rhsIndex
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .timeout:
|
||||
switch rhs {
|
||||
case .delete, .exceptionInfo:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
case .exceptionInfo:
|
||||
switch rhs {
|
||||
case .delete:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
case .delete:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .rightsHeader:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case let .rightItem(_, lhsIndex, _, _, _, _, _, _):
|
||||
switch rhs {
|
||||
case .info, .rightsHeader:
|
||||
return false
|
||||
case let .rightItem(_, rhsIndex, _, _, _, _, _, _):
|
||||
return lhsIndex < rhsIndex
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .timeout:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .exceptionInfo:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .exceptionInfo:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .delete:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .exceptionInfo, .delete:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .rankTitle:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .delete, .rankTitle:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
case .rankPreview:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .delete, .rankTitle, .rankPreview:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
||||
case .rank:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .delete, .rankTitle, .rankPreview, .rank:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
|
||||
case .rankInfo:
|
||||
switch rhs {
|
||||
case .info, .rightsHeader, .rightItem, .timeout, .delete, .rankTitle, .rankPreview, .rank, .rankInfo:
|
||||
return false
|
||||
default:
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -269,6 +369,31 @@ private enum ChannelBannedMemberEntry: ItemListNodeEntry {
|
|||
return ItemListActionItem(presentationData: presentationData, systemStyle: .glass, title: text, kind: .destructive, alignment: .center, sectionId: self.section, style: .blocks, action: {
|
||||
arguments.delete()
|
||||
})
|
||||
case let .rankTitle(_, text, count, limit):
|
||||
var accessoryText: ItemListSectionHeaderAccessoryText?
|
||||
if let count = count {
|
||||
accessoryText = ItemListSectionHeaderAccessoryText(value: "\(limit - count)", color: count > limit ? .destructive : .generic)
|
||||
}
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: text, accessoryText: accessoryText, sectionId: self.section)
|
||||
case let .rankPreview(_, _, peer, rank, _):
|
||||
let globalPresentationData = arguments.context.sharedContext.currentPresentationData.with { $0 }
|
||||
return arguments.context.sharedContext.makeChatRankPreviewItem(context: arguments.context, peer: peer, rank: rank, rankRole: .member, theme: presentationData.theme, strings: presentationData.strings, wallpaper: globalPresentationData.chatWallpaper, fontSize: globalPresentationData.chatFontSize, chatBubbleCorners: globalPresentationData.chatBubbleCorners, dateTimeFormat: presentationData.dateTimeFormat, nameOrder: presentationData.nameDisplayOrder, sectionId: self.section)
|
||||
case let .rank(_, _, placeholder, text, enabled):
|
||||
return ItemListSingleLineInputItem(presentationData: presentationData, systemStyle: .glass, title: NSAttributedString(string: "", textColor: .black), text: text, placeholder: placeholder, type: .regular(capitalization: false, autocorrection: true), spacing: 0.0, clearType: enabled ? .always : .none, enabled: enabled, tag: ChannelBannedMemberEntryTag.rank, sectionId: self.section, textUpdated: { updatedText in
|
||||
arguments.updateRank(text, updatedText)
|
||||
}, shouldUpdateText: { text in
|
||||
if text.containsEmoji {
|
||||
arguments.animateError()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}, updatedFocus: { focus in
|
||||
arguments.updateFocusedOnRank(focus)
|
||||
}, action: {
|
||||
arguments.dismissInput()
|
||||
})
|
||||
case let .rankInfo(_, text, trimBottomInset):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section, additionalOuterInsets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: trimBottomInset ? -44.0 : 0.0, right: 0.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -279,6 +404,8 @@ private struct ChannelBannedMemberControllerState: Equatable {
|
|||
var updatedTimeout: Int32?
|
||||
var updating: Bool = false
|
||||
var expandedPermissions = Set<TelegramChatBannedRightsFlags>()
|
||||
var updatedRank: String?
|
||||
var focusedOnRank: Bool
|
||||
}
|
||||
|
||||
func completeRights(_ flags: TelegramChatBannedRightsFlags) -> TelegramChatBannedRightsFlags {
|
||||
|
|
@ -353,7 +480,22 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation
|
|||
index += 1
|
||||
}
|
||||
|
||||
if !editMember {
|
||||
if editMember {
|
||||
let currentRank: String?
|
||||
if let updatedRank = state.updatedRank {
|
||||
currentRank = updatedRank
|
||||
} else if let initialParticipant = initialParticipant {
|
||||
currentRank = initialParticipant.rank
|
||||
} else {
|
||||
currentRank = nil
|
||||
}
|
||||
|
||||
let rankEnabled = !state.updating
|
||||
entries.append(.rankTitle(presentationData.theme, presentationData.strings.Group_EditAdmin_MemberTagTitle.uppercased(), rankEnabled && state.focusedOnRank ? Int32(currentRank?.count ?? 0) : nil, rankMaxLength))
|
||||
entries.append(.rankPreview(presentationData.theme, presentationData.strings, member, currentRank ?? "0️⃣", false))
|
||||
entries.append(.rank(presentationData.theme, presentationData.strings, presentationData.strings.EditRank_Placeholder, currentRank ?? "", rankEnabled))
|
||||
entries.append(.rankInfo(presentationData.theme, presentationData.strings.Group_EditAdmin_MemberTagInfo(member.compactDisplayTitle).string, false))
|
||||
} else {
|
||||
entries.append(.timeout(presentationData.theme, presentationData.strings.GroupPermission_Duration, currentTimeoutString))
|
||||
|
||||
if let initialParticipant = initialParticipant, case let .member(_, _, _, banInfo?, _, _) = initialParticipant, let initialBannedBy = initialBannedBy {
|
||||
|
|
@ -415,7 +557,23 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation
|
|||
index += 1
|
||||
}
|
||||
|
||||
if !editMember {
|
||||
if editMember {
|
||||
let currentRank: String?
|
||||
if let updatedRank = state.updatedRank {
|
||||
currentRank = updatedRank
|
||||
} else if let initialParticipant = initialParticipant {
|
||||
currentRank = initialParticipant.rank
|
||||
} else {
|
||||
currentRank = nil
|
||||
}
|
||||
|
||||
let rankEnabled = !state.updating
|
||||
entries.append(.rankTitle(presentationData.theme, presentationData.strings.Group_EditAdmin_MemberTagTitle.uppercased(), rankEnabled && state.focusedOnRank ? Int32(currentRank?.count ?? 0) : nil, rankMaxLength))
|
||||
entries.append(.rankPreview(presentationData.theme, presentationData.strings, member, currentRank ?? "0️⃣", false))
|
||||
entries.append(.rank(presentationData.theme, presentationData.strings, presentationData.strings.EditRank_Placeholder, currentRank ?? "", rankEnabled))
|
||||
entries.append(.rankInfo(presentationData.theme, presentationData.strings.Group_EditAdmin_MemberTagInfo(member.compactDisplayTitle).string, false))
|
||||
|
||||
} else {
|
||||
entries.append(.timeout(presentationData.theme, presentationData.strings.GroupPermission_Duration, currentTimeoutString))
|
||||
|
||||
if let initialParticipant = initialParticipant, case let .member(_, _, _, banInfo?, _, _) = initialParticipant, let initialBannedBy = initialBannedBy {
|
||||
|
|
@ -429,7 +587,7 @@ private func channelBannedMemberControllerEntries(presentationData: Presentation
|
|||
}
|
||||
|
||||
public func channelBannedMemberController(context: AccountContext, updatedPresentationData: (initial: PresentationData, signal: Signal<PresentationData, NoError>)? = nil, peerId: PeerId, memberId: PeerId, editMember: Bool = false, initialParticipant: ChannelParticipant?, updated: @escaping (TelegramChatBannedRights?) -> Void, upgradedToSupergroup: @escaping (PeerId, @escaping () -> Void) -> Void) -> ViewController {
|
||||
let initialState = ChannelBannedMemberControllerState(referenceTimestamp: Int32(Date().timeIntervalSince1970), updatedFlags: nil, updatedTimeout: nil, updating: false)
|
||||
let initialState = ChannelBannedMemberControllerState(referenceTimestamp: Int32(Date().timeIntervalSince1970), updatedFlags: nil, updatedTimeout: nil, updating: false, updatedRank: nil, focusedOnRank: false)
|
||||
let statePromise = ValuePromise(initialState, ignoreRepeated: true)
|
||||
let stateValue = Atomic(value: initialState)
|
||||
let updateState: ((ChannelBannedMemberControllerState) -> ChannelBannedMemberControllerState) -> Void = { f in
|
||||
|
|
@ -441,9 +599,15 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
let updateRightsDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updateRightsDisposable)
|
||||
|
||||
let updateRankDisposable = MetaDisposable()
|
||||
actionsDisposable.add(updateRankDisposable)
|
||||
|
||||
var dismissImpl: (() -> Void)?
|
||||
var presentControllerImpl: ((ViewController, Any?) -> Void)?
|
||||
var pushControllerImpl: ((ViewController) -> Void)?
|
||||
var dismissInputImpl: (() -> Void)?
|
||||
var errorImpl: (() -> Void)?
|
||||
var scrollToRankImpl: (() -> Void)?
|
||||
|
||||
let peerView = Promise<PeerView>()
|
||||
peerView.set(context.account.viewTracker.peerView(peerId))
|
||||
|
|
@ -475,8 +639,7 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
} else {
|
||||
effectiveRightsFlags = defaultBannedRightsFlags
|
||||
}
|
||||
|
||||
|
||||
|
||||
if rights == .banSendMedia {
|
||||
if value {
|
||||
effectiveRightsFlags.remove(rights)
|
||||
|
|
@ -623,6 +786,28 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
pushControllerImpl?(controller)
|
||||
}
|
||||
})
|
||||
}, updateRank: { previousRank, updatedRank in
|
||||
if updatedRank != previousRank {
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.updatedRank = updatedRank
|
||||
return state
|
||||
}
|
||||
}
|
||||
}, updateFocusedOnRank: { focusedOnRank in
|
||||
updateState { state in
|
||||
var state = state
|
||||
state.focusedOnRank = focusedOnRank
|
||||
return state
|
||||
}
|
||||
|
||||
if focusedOnRank {
|
||||
scrollToRankImpl?()
|
||||
}
|
||||
}, dismissInput: {
|
||||
dismissInputImpl?()
|
||||
}, animateError: {
|
||||
errorImpl?()
|
||||
})
|
||||
|
||||
var peerDataItems: [TelegramEngine.EngineData.Item.Peer.Peer] = []
|
||||
|
|
@ -670,6 +855,16 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
return
|
||||
}
|
||||
|
||||
var updateRank: String?
|
||||
updateState { current in
|
||||
updateRank = current.updatedRank?.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
return current
|
||||
}
|
||||
if let updateRank = updateRank, updateRank.count > rankMaxLength || updateRank.containsEmoji {
|
||||
errorImpl?()
|
||||
return
|
||||
}
|
||||
|
||||
var resolvedRights: TelegramChatBannedRights?
|
||||
if let initialParticipant = initialParticipant {
|
||||
var updateFlags: TelegramChatBannedRightsFlags?
|
||||
|
|
@ -738,12 +933,27 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
previousRights = banInfo?.rights
|
||||
}
|
||||
|
||||
let updateRankSignal: (PeerId) -> Signal<Void, NoError>
|
||||
if let updateRank {
|
||||
updateRankSignal = { peerId in
|
||||
return context.peerChannelMemberCategoriesContextsManager.updateMemberRank(engine: context.engine, peerId: peerId, memberId: memberId, rank: updateRank)
|
||||
|> `catch` { _ -> Signal<Void, NoError> in
|
||||
return .single(Void())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
updateRankSignal = { _ in return .complete() }
|
||||
}
|
||||
|
||||
if let resolvedRights = resolvedRights, previousRights != resolvedRights {
|
||||
let cleanResolvedRightsFlags = resolvedRights.flags.union(defaultBannedRightsFlags)
|
||||
let cleanResolvedRights = TelegramChatBannedRights(flags: cleanResolvedRightsFlags, untilDate: resolvedRights.untilDate)
|
||||
|
||||
|
||||
if cleanResolvedRights.flags.isEmpty && previousRights == nil {
|
||||
dismissImpl?()
|
||||
updateRankDisposable.set((updateRankSignal(peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
dismissImpl?()
|
||||
}))
|
||||
} else {
|
||||
let applyRights: () -> Void = {
|
||||
updateState { state in
|
||||
|
|
@ -770,9 +980,15 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
return .single(nil)
|
||||
}
|
||||
|
||||
let rankSignal = updateRankSignal(upgradedPeerId)
|
||||
|
||||
return context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: upgradedPeerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||
return .complete()
|
||||
return rankSignal
|
||||
|> mapToSignal { _ -> Signal<PeerId?, NoError> in
|
||||
return .complete()
|
||||
}
|
||||
}
|
||||
|> then(.single(upgradedPeerId))
|
||||
}
|
||||
|
|
@ -799,36 +1015,42 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
}))
|
||||
} else {
|
||||
updateRightsDisposable.set((context.peerChannelMemberCategoriesContextsManager.updateMemberBannedRights(engine: context.engine, peerId: peerId, memberId: memberId, bannedRights: cleanResolvedRights)
|
||||
|> deliverOnMainQueue).start(error: { _ in
|
||||
|
||||
}, completed: {
|
||||
if previousRights == nil {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.GroupPermission_AddSuccess, false)), nil)
|
||||
}
|
||||
updated(cleanResolvedRights.flags.isEmpty ? nil : cleanResolvedRights)
|
||||
dismissImpl?()
|
||||
}))
|
||||
|> deliverOnMainQueue).start(error: { _ in
|
||||
|
||||
}, completed: {
|
||||
if previousRights == nil {
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(OverlayStatusController(theme: presentationData.theme, type: .genericSuccess(presentationData.strings.GroupPermission_AddSuccess, false)), nil)
|
||||
}
|
||||
updated(cleanResolvedRights.flags.isEmpty ? nil : cleanResolvedRights)
|
||||
dismissImpl?()
|
||||
}))
|
||||
|
||||
updateRankDisposable.set(updateRankSignal(peerId).start())
|
||||
}
|
||||
}
|
||||
|
||||
let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
items.append(ActionSheetTextItem(title: presentationData.strings.GroupPermission_ApplyAlertText(EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string))
|
||||
items.append(ActionSheetButtonItem(title: presentationData.strings.GroupPermission_ApplyAlertAction, color: .accent, font: .default, enabled: true, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
applyRights()
|
||||
}))
|
||||
actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
})
|
||||
])])
|
||||
presentControllerImpl?(actionSheet, nil)
|
||||
applyRights()
|
||||
// let presentationData = updatedPresentationData?.initial ?? context.sharedContext.currentPresentationData.with { $0 }
|
||||
// let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||
// var items: [ActionSheetItem] = []
|
||||
// items.append(ActionSheetTextItem(title: presentationData.strings.GroupPermission_ApplyAlertText(EnginePeer(peer).displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string))
|
||||
// items.append(ActionSheetButtonItem(title: presentationData.strings.GroupPermission_ApplyAlertAction, color: .accent, font: .default, enabled: true, action: { [weak actionSheet] in
|
||||
// actionSheet?.dismissAnimated()
|
||||
// applyRights()
|
||||
// }))
|
||||
// actionSheet.setItemGroups([ActionSheetItemGroup(items: items), ActionSheetItemGroup(items: [
|
||||
// ActionSheetButtonItem(title: presentationData.strings.Common_Cancel, color: .accent, font: .bold, action: { [weak actionSheet] in
|
||||
// actionSheet?.dismissAnimated()
|
||||
// })
|
||||
// ])])
|
||||
// presentControllerImpl?(actionSheet, nil)
|
||||
}
|
||||
} else {
|
||||
dismissImpl?()
|
||||
updateRankDisposable.set((updateRankSignal(peerId)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
dismissImpl?()
|
||||
}))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -845,11 +1067,21 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
}
|
||||
}
|
||||
|
||||
let footerItem = ChannelParticipantFooterItem(theme: presentationData.theme, title: footerButtonTitle, displayProgress: state.updating, action: {
|
||||
rightButtonActionImpl()
|
||||
})
|
||||
let rightNavigationButton: ItemListNavigationButton?
|
||||
let footerItem: ItemListControllerFooterItem?
|
||||
if state.focusedOnRank {
|
||||
rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Done), style: .bold, enabled: true, action: {
|
||||
rightButtonActionImpl()
|
||||
})
|
||||
footerItem = nil
|
||||
} else {
|
||||
rightNavigationButton = nil
|
||||
footerItem = ChannelParticipantFooterItem(theme: presentationData.theme, title: footerButtonTitle, displayProgress: state.updating, action: {
|
||||
rightButtonActionImpl()
|
||||
})
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: false)
|
||||
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelBannedMemberControllerEntries(presentationData: presentationData, state: state, accountPeerId: context.account.peerId, channelPeer: channelPeer, memberPeer: memberPeer, memberPresence: memberPresence, initialParticipant: initialParticipant, initialBannedBy: initialBannedByPeer, editMember: editMember), style: .blocks, emptyStateItem: nil, footerItem: footerItem, animateChanges: true)
|
||||
|
||||
|
|
@ -870,5 +1102,41 @@ public func channelBannedMemberController(context: AccountContext, updatedPresen
|
|||
pushControllerImpl = { [weak controller] c in
|
||||
controller?.push(c)
|
||||
}
|
||||
|
||||
let hapticFeedback = HapticFeedback()
|
||||
errorImpl = { [weak controller] in
|
||||
hapticFeedback.error()
|
||||
controller?.forEachItemNode { itemNode in
|
||||
if let itemNode = itemNode as? ItemListSingleLineInputItemNode {
|
||||
itemNode.animateError()
|
||||
}
|
||||
}
|
||||
}
|
||||
scrollToRankImpl = { [weak controller] in
|
||||
controller?.afterLayout({
|
||||
guard let controller = controller else {
|
||||
return
|
||||
}
|
||||
|
||||
var resultItemNode: ListViewItemNode?
|
||||
let _ = controller.frameForItemNode({ itemNode in
|
||||
if let itemNode = itemNode as? ItemListSingleLineInputItemNode {
|
||||
if let tag = itemNode.tag as? ChannelBannedMemberEntryTag, tag == .rank {
|
||||
resultItemNode = itemNode
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
})
|
||||
if let resultItemNode = resultItemNode {
|
||||
Queue.mainQueue().after(0.1) {
|
||||
controller.ensureItemNodeVisible(resultItemNode, atTop: true)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
dismissInputImpl = { [weak controller] in
|
||||
controller?.view.endEditing(true)
|
||||
}
|
||||
return controller
|
||||
}
|
||||
|
|
|
|||
|
|
@ -685,9 +685,15 @@ public func channelMembersController(context: AccountContext, updatedPresentatio
|
|||
}))
|
||||
}, openParticipant: { participant, isGroup in
|
||||
if isGroup {
|
||||
let controller = channelBannedMemberController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, memberId: participant.peer.id, editMember: true, initialParticipant: participant.participant, updated: { rights in
|
||||
}, upgradedToSupergroup: { _, _ in })
|
||||
pushControllerImpl?(controller)
|
||||
if let _ = participant.participant.adminInfo {
|
||||
let controller = channelAdminController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, adminId: participant.participant.peerId, initialParticipant: participant.participant, updated: { _ in
|
||||
}, upgradedToSupergroup: { _, _ in }, transferedOwnership: { _ in })
|
||||
pushControllerImpl?(controller)
|
||||
} else {
|
||||
let controller = channelBannedMemberController(context: context, updatedPresentationData: updatedPresentationData, peerId: peerId, memberId: participant.peer.id, editMember: true, initialParticipant: participant.participant, updated: { rights in
|
||||
}, upgradedToSupergroup: { _, _ in })
|
||||
pushControllerImpl?(controller)
|
||||
}
|
||||
} else {
|
||||
if let infoController = context.sharedContext.makePeerInfoController(context: context, updatedPresentationData: nil, peer: participant.peer, mode: .generic, avatarInitiallyExpanded: false, fromChat: false, requestsContext: nil) {
|
||||
pushControllerImpl?(infoController)
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ public struct PresentationResourcesRootController {
|
|||
|
||||
public static func navigationShareIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.navigationShareIcon.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: theme.rootController.navigationBar.accentTextColor)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Input/Accessory Panels/MessageSelectionForward"), color: theme.rootController.navigationBar.buttonColor)
|
||||
})
|
||||
// return theme.image(PresentationResourceKey.navigationShareIcon.rawValue, generateShareButtonImage)
|
||||
}
|
||||
|
|
@ -113,7 +113,7 @@ public struct PresentationResourcesRootController {
|
|||
|
||||
public static func navigationMoreCircledIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.navigationMoreCircledIcon.rawValue, { theme in
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat List/NavigationMore"), color: theme.rootController.navigationBar.accentTextColor)
|
||||
generateTintedImage(image: UIImage(bundleImageName: "Chat List/NavigationMore"), color: theme.rootController.navigationBar.buttonColor)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -125,7 +125,7 @@ public struct PresentationResourcesRootController {
|
|||
|
||||
public static func navigationAddIcon(_ theme: PresentationTheme) -> UIImage? {
|
||||
return theme.image(PresentationResourceKey.navigationAddIcon.rawValue, { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat List/AddIcon"), color: theme.rootController.navigationBar.accentTextColor)
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat List/AddIcon"), color: theme.rootController.navigationBar.buttonColor)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2343,7 +2343,13 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
|||
return result
|
||||
}, to: &text, entities: &entities)
|
||||
} else {
|
||||
|
||||
appendAttributedText(text: self.presentationData.strings.Channel_AdminLog_MessageRankNew(newRank), generateEntities: { index in
|
||||
var result: [MessageTextEntityType] = []
|
||||
if index == 0 {
|
||||
result.append(.Bold)
|
||||
}
|
||||
return result
|
||||
}, to: &text, entities: &entities)
|
||||
}
|
||||
var attributes: [MessageAttribute] = []
|
||||
if !entities.isEmpty {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue