mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'eabc08372b143abc3d1c35a890fa9d619dd43111'
This commit is contained in:
commit
5aca2dee08
@ -6029,7 +6029,7 @@ Sorry for the inconvenience.";
|
||||
|
||||
"GroupInfo.Permissions.BroadcastTitle" = "Broadcast Group";
|
||||
"GroupInfo.Permissions.BroadcastConvert" = "Convert to Broadcast Group";
|
||||
"GroupInfo.Permissions.BroadcastConvertInfo" = "Broadcast groups can have over %@ members, but only admins can send message in them.";
|
||||
"GroupInfo.Permissions.BroadcastConvertInfo" = "Broadcast groups can have over %@ members, but only admins can send messages in them.";
|
||||
|
||||
"GroupInfo.GroupHistoryShort" = "Chat History";
|
||||
|
||||
@ -6068,6 +6068,8 @@ Sorry for the inconvenience.";
|
||||
"BroadcastGroups.ConfirmationAlert.Text" = "Regular members of the group (non-admins) will irrevocably lose their right to post messages in the group.\n\nThis action **cannot** be undone.";
|
||||
"BroadcastGroups.ConfirmationAlert.Convert" = "Convert";
|
||||
|
||||
"BroadcastGroups.Success" = "Your group can now have more than %@ members.";
|
||||
|
||||
"BroadcastGroups.LimitAlert.Title" = "Limit Reached";
|
||||
"BroadcastGroups.LimitAlert.Text" = "Your group has reached a limit of **%@** members.\n\nYou can increase this limit by converting the group to a **broadcast group** where only admins can post. Interested?";
|
||||
"BroadcastGroups.LimitAlert.LearnMore" = "Learn More";
|
||||
@ -6079,3 +6081,5 @@ Sorry for the inconvenience.";
|
||||
"Channel.AdminLog.MessageChangedAutoremoveTimeoutRemove" = "%1$@ disabled auto-remove timer";
|
||||
|
||||
"ChannelInfo.InviteLink.RevokeAlert.Text" = "Are you sure you want to revoke this link? Once you do, no one will be able to join the channel using it.";
|
||||
|
||||
"Group.Info.Members" = "Members";
|
||||
|
@ -122,7 +122,7 @@ private func mappedInsertEntries(context: AccountContext, presentationData: Item
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
||||
case let .groupCall(peer, _, isActive):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListGroupCallItem(presentationData: presentationData, context: context, style: showSettings ? .blocks : .plain, peer: peer, isActive: isActive, editing: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .messageEntry(topMessage, messages, _, _, dateTimeFormat, editing, hasActiveRevealControls, displayHeader):
|
||||
case let .messageEntry(topMessage, messages, _, _, dateTimeFormat, editing, hasActiveRevealControls, displayHeader, _):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListCallItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, context: context, style: showSettings ? .blocks : .plain, topMessage: topMessage, messages: messages, editing: editing, revealed: hasActiveRevealControls, displayHeader: displayHeader, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .holeEntry(_, theme):
|
||||
return ListViewInsertItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListHoleItem(theme: theme), directionHint: entry.directionHint)
|
||||
@ -141,7 +141,7 @@ private func mappedUpdateEntries(context: AccountContext, presentationData: Item
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: 0), directionHint: entry.directionHint)
|
||||
case let .groupCall(peer, _, isActive):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListGroupCallItem(presentationData: presentationData, context: context, style: showSettings ? .blocks : .plain, peer: peer, isActive: isActive, editing: false, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .messageEntry(topMessage, messages, _, _, dateTimeFormat, editing, hasActiveRevealControls, displayHeader):
|
||||
case let .messageEntry(topMessage, messages, _, _, dateTimeFormat, editing, hasActiveRevealControls, displayHeader, _):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListCallItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, context: context, style: showSettings ? .blocks : .plain, topMessage: topMessage, messages: messages, editing: editing, revealed: hasActiveRevealControls, displayHeader: displayHeader, interaction: nodeInteraction), directionHint: entry.directionHint)
|
||||
case let .holeEntry(_, theme):
|
||||
return ListViewUpdateItem(index: entry.index, previousIndex: entry.previousIndex, item: CallListHoleItem(theme: theme), directionHint: entry.directionHint)
|
||||
|
@ -81,7 +81,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
||||
case displayTab(PresentationTheme, String, Bool)
|
||||
case displayTabInfo(PresentationTheme, String)
|
||||
case groupCall(peer: Peer, editing: Bool, isActive: Bool)
|
||||
case messageEntry(topMessage: Message, messages: [Message], theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, editing: Bool, hasActiveRevealControls: Bool, displayHeader: Bool)
|
||||
case messageEntry(topMessage: Message, messages: [Message], theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, editing: Bool, hasActiveRevealControls: Bool, displayHeader: Bool, missed: Bool)
|
||||
case holeEntry(index: MessageIndex, theme: PresentationTheme)
|
||||
|
||||
var sortIndex: SortIndex {
|
||||
@ -92,7 +92,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
||||
return .displayTabInfo
|
||||
case let .groupCall(peer, _, _):
|
||||
return .groupCall(peer.id, peer.compactDisplayTitle)
|
||||
case let .messageEntry(message, _, _, _, _, _, _, _):
|
||||
case let .messageEntry(message, _, _, _, _, _, _, _, _):
|
||||
return .message(message.index)
|
||||
case let .holeEntry(index, _):
|
||||
return .hole(index)
|
||||
@ -107,7 +107,7 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
||||
return .setting(1)
|
||||
case let .groupCall(peer, _, _):
|
||||
return .groupCall(peer.id)
|
||||
case let .messageEntry(message, _, _, _, _, _, _, _):
|
||||
case let .messageEntry(message, _, _, _, _, _, _, _, _):
|
||||
return .message(message.index)
|
||||
case let .holeEntry(index, _):
|
||||
return .hole(index)
|
||||
@ -147,8 +147,8 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
case let .messageEntry(lhsMessage, lhsMessages, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsEditing, lhsHasRevealControls, lhsDisplayHeader):
|
||||
if case let .messageEntry(rhsMessage, rhsMessages, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsEditing, rhsHasRevealControls, rhsDisplayHeader) = rhs {
|
||||
case let .messageEntry(lhsMessage, lhsMessages, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsEditing, lhsHasRevealControls, lhsDisplayHeader, lhsMissed):
|
||||
if case let .messageEntry(rhsMessage, rhsMessages, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsEditing, rhsHasRevealControls, rhsDisplayHeader, rhsMissed) = rhs {
|
||||
if lhsTheme !== rhsTheme {
|
||||
return false
|
||||
}
|
||||
@ -158,6 +158,9 @@ enum CallListNodeEntry: Comparable, Identifiable {
|
||||
if lhsDateTimeFormat != rhsDateTimeFormat {
|
||||
return false
|
||||
}
|
||||
if lhsMissed != rhsMissed {
|
||||
return false
|
||||
}
|
||||
if lhsEditing != rhsEditing {
|
||||
return false
|
||||
}
|
||||
@ -197,28 +200,30 @@ func callListNodeEntriesForView(view: CallListView, groupCalls: [Peer], state: C
|
||||
for entry in view.entries {
|
||||
switch entry {
|
||||
case let .message(topMessage, messages):
|
||||
result.append(.messageEntry(topMessage: topMessage, messages: messages, theme: state.presentationData.theme, strings: state.presentationData.strings, dateTimeFormat: state.dateTimeFormat, editing: state.editing, hasActiveRevealControls: state.messageIdWithRevealedOptions == topMessage.id, displayHeader: !showSettings && isRecentCalls))
|
||||
result.append(.messageEntry(topMessage: topMessage, messages: messages, theme: state.presentationData.theme, strings: state.presentationData.strings, dateTimeFormat: state.dateTimeFormat, editing: state.editing, hasActiveRevealControls: state.messageIdWithRevealedOptions == topMessage.id, displayHeader: !showSettings && isRecentCalls, missed: !isRecentCalls))
|
||||
case let .hole(index):
|
||||
result.append(.holeEntry(index: index, theme: state.presentationData.theme))
|
||||
}
|
||||
}
|
||||
|
||||
if !showSettings && isRecentCalls {
|
||||
for peer in groupCalls.sorted(by: { lhs, rhs in
|
||||
let lhsTitle = lhs.compactDisplayTitle
|
||||
let rhsTitle = rhs.compactDisplayTitle
|
||||
if lhsTitle != rhsTitle {
|
||||
return lhsTitle < rhsTitle
|
||||
if view.later == nil {
|
||||
if !showSettings && isRecentCalls {
|
||||
for peer in groupCalls.sorted(by: { lhs, rhs in
|
||||
let lhsTitle = lhs.compactDisplayTitle
|
||||
let rhsTitle = rhs.compactDisplayTitle
|
||||
if lhsTitle != rhsTitle {
|
||||
return lhsTitle < rhsTitle
|
||||
}
|
||||
return lhs.id < rhs.id
|
||||
}).reversed() {
|
||||
result.append(.groupCall(peer: peer, editing: state.editing, isActive: currentGroupCallPeerId == peer.id))
|
||||
}
|
||||
return lhs.id < rhs.id
|
||||
}).reversed() {
|
||||
result.append(.groupCall(peer: peer, editing: state.editing, isActive: currentGroupCallPeerId == peer.id))
|
||||
}
|
||||
}
|
||||
|
||||
if showSettings {
|
||||
result.append(.displayTabInfo(state.presentationData.theme, state.presentationData.strings.CallSettings_TabIconDescription))
|
||||
result.append(.displayTab(state.presentationData.theme, state.presentationData.strings.CallSettings_TabIcon, showCallsTab))
|
||||
|
||||
if showSettings {
|
||||
result.append(.displayTabInfo(state.presentationData.theme, state.presentationData.strings.CallSettings_TabIconDescription))
|
||||
result.append(.displayTab(state.presentationData.theme, state.presentationData.strings.CallSettings_TabIcon, showCallsTab))
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
@ -346,7 +346,7 @@ public class ItemListInviteLinkItemNode: ListViewItemNode, ItemListItemNode {
|
||||
if count > 0 {
|
||||
subtitleText = item.presentationData.strings.InviteLink_PeopleJoinedShort(count)
|
||||
} else {
|
||||
if let usageLimit = invite.usageLimit, count == 0 {
|
||||
if let usageLimit = invite.usageLimit, count == 0 && !availability.isZero {
|
||||
subtitleText = item.presentationData.strings.InviteLink_PeopleCanJoin(usageLimit)
|
||||
} else {
|
||||
subtitleText = availability.isZero ? item.presentationData.strings.InviteLink_PeopleJoinedShortNoneExpired : item.presentationData.strings.InviteLink_PeopleJoinedShortNone
|
||||
|
@ -199,7 +199,7 @@ private enum ChannelMembersEntry: ItemListNodeEntry {
|
||||
} else {
|
||||
text = .presence
|
||||
}
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: participant.peer, presence: participant.presences[participant.peer.id], text: text, label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: true, sectionId: self.section, action: {
|
||||
return ItemListPeerItem(presentationData: presentationData, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, context: arguments.context, peer: participant.peer, presence: participant.presences[participant.peer.id], text: text, label: .none, editing: editing, switchValue: nil, enabled: enabled, selectable: participant.peer.id != arguments.context.account.peerId, sectionId: self.section, action: {
|
||||
arguments.openPeer(participant.peer)
|
||||
}, setPeerIdWithRevealedOptions: { previousId, id in
|
||||
arguments.setPeerIdWithRevealedOptions(previousId, id)
|
||||
@ -263,7 +263,7 @@ private struct ChannelMembersControllerState: Equatable {
|
||||
}
|
||||
}
|
||||
|
||||
private func ChannelMembersControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelMembersEntry] {
|
||||
private func channelMembersControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelMembersControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelMembersEntry] {
|
||||
if participants == nil || participants?.count == nil {
|
||||
return []
|
||||
}
|
||||
@ -515,7 +515,7 @@ public func channelMembersController(context: AccountContext, peerId: PeerId) ->
|
||||
previousPeers = peers
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.Channel_Subscribers_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, secondaryRightNavigationButton: secondaryRightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: ChannelMembersControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: peers), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && peers != nil && previous!.count >= peers!.count)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelMembersControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: peers), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && peers != nil && previous!.count >= peers!.count)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
@ -98,17 +98,17 @@ private enum ChannelPermissionsEntry: ItemListNodeEntry {
|
||||
return .index(0)
|
||||
case let .permission(_, index, _, _, _, _):
|
||||
return .index(1 + index)
|
||||
case .slowmodeHeader:
|
||||
return .index(998)
|
||||
case .slowmode:
|
||||
return .index(999)
|
||||
case .slowmodeInfo:
|
||||
return .index(1000)
|
||||
case .conversionHeader:
|
||||
return .index(1001)
|
||||
return .index(998)
|
||||
case .conversion:
|
||||
return .index(1002)
|
||||
return .index(999)
|
||||
case .conversionInfo:
|
||||
return .index(1000)
|
||||
case .slowmodeHeader:
|
||||
return .index(1001)
|
||||
case .slowmode:
|
||||
return .index(1002)
|
||||
case .slowmodeInfo:
|
||||
return .index(1003)
|
||||
case .kicked:
|
||||
return .index(1004)
|
||||
@ -436,7 +436,7 @@ private func completeRights(_ flags: TelegramChatBannedRightsFlags) -> TelegramC
|
||||
return result
|
||||
}
|
||||
|
||||
private func channelPermissionsControllerEntries(presentationData: PresentationData, view: PeerView, state: ChannelPermissionsControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelPermissionsEntry] {
|
||||
private func channelPermissionsControllerEntries(context: AccountContext, presentationData: PresentationData, view: PeerView, state: ChannelPermissionsControllerState, participants: [RenderedChannelParticipant]?) -> [ChannelPermissionsEntry] {
|
||||
var entries: [ChannelPermissionsEntry] = []
|
||||
|
||||
if let channel = view.peers[view.peerId] as? TelegramChannel, let participants = participants, let cachedData = view.cachedData as? CachedChannelData, let defaultBannedRights = channel.defaultBannedRights {
|
||||
@ -466,16 +466,17 @@ private func channelPermissionsControllerEntries(presentationData: PresentationD
|
||||
rightIndex += 1
|
||||
}
|
||||
|
||||
if channel.flags.contains(.isCreator) && effectiveRightsFlags.contains(.banSendMessages) && !channel.flags.contains(.isGigagroup) {
|
||||
let participantsLimit = context.currentLimitsConfiguration.with { $0 }.maxSupergroupMemberCount
|
||||
if channel.flags.contains(.isCreator) && !channel.flags.contains(.isGigagroup), let memberCount = cachedData.participantsSummary.memberCount, memberCount > participantsLimit - 1000 {
|
||||
entries.append(.conversionHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_BroadcastTitle.uppercased()))
|
||||
entries.append(.conversion(presentationData.theme, presentationData.strings.GroupInfo_Permissions_BroadcastConvert))
|
||||
entries.append(.conversionInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_BroadcastConvertInfo(presentationStringsFormattedNumber(200000, presentationData.dateTimeFormat.groupingSeparator)).0))
|
||||
} else {
|
||||
entries.append(.slowmodeHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SlowmodeHeader))
|
||||
entries.append(.slowmode(presentationData.theme, presentationData.strings, state.modifiedSlowmodeTimeout ?? (cachedData.slowModeTimeout ?? 0)))
|
||||
entries.append(.slowmodeInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SlowmodeInfo))
|
||||
entries.append(.conversionInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_BroadcastConvertInfo(presentationStringsFormattedNumber(participantsLimit, presentationData.dateTimeFormat.groupingSeparator)).0))
|
||||
}
|
||||
|
||||
entries.append(.slowmodeHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SlowmodeHeader))
|
||||
entries.append(.slowmode(presentationData.theme, presentationData.strings, state.modifiedSlowmodeTimeout ?? (cachedData.slowModeTimeout ?? 0)))
|
||||
entries.append(.slowmodeInfo(presentationData.theme, presentationData.strings.GroupInfo_Permissions_SlowmodeInfo))
|
||||
|
||||
entries.append(.kicked(presentationData.theme, presentationData.strings.GroupInfo_Permissions_Removed, cachedData.participantsSummary.kickedCount.flatMap({ $0 == 0 ? "" : "\($0)" }) ?? ""))
|
||||
entries.append(.exceptionsHeader(presentationData.theme, presentationData.strings.GroupInfo_Permissions_Exceptions))
|
||||
entries.append(.add(presentationData.theme, presentationData.strings.GroupInfo_Permissions_AddException))
|
||||
@ -926,7 +927,7 @@ public func channelPermissionsController(context: AccountContext, peerId origina
|
||||
}
|
||||
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.GroupInfo_Permissions_Title), leftNavigationButton: nil, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelPermissionsControllerEntries(presentationData: presentationData, view: view, state: state, participants: participants), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && participants != nil && previous!.count >= participants!.count)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: channelPermissionsControllerEntries(context: context, presentationData: presentationData, view: view, state: state, participants: participants), style: .blocks, emptyStateItem: emptyStateItem, searchItem: searchItem, animateChanges: previous != nil && participants != nil && previous!.count >= participants!.count)
|
||||
|
||||
return (controllerState, (listState, arguments))
|
||||
}
|
||||
|
@ -231,6 +231,9 @@ public final class PermissionController: ViewController {
|
||||
self.controllerNode.allow = { [weak self] in
|
||||
self?.allow?()
|
||||
}
|
||||
self.controllerNode.dismiss = { [weak self] in
|
||||
self?.dismiss()
|
||||
}
|
||||
self.controllerNode.openPrivacyPolicy = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.context.sharedContext.openExternalUrl(context: strongSelf.context, urlContext: .generic, url: "https://telegram.org/privacy", forceExternal: true, presentationData: strongSelf.context.sharedContext.currentPresentationData.with { $0 }, navigationController: nil, dismissInput: {})
|
||||
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -187,6 +187,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
private let botStart: ChatControllerInitialBotStart?
|
||||
|
||||
private let peerDisposable = MetaDisposable()
|
||||
private let titleDisposable = MetaDisposable()
|
||||
private let navigationActionDisposable = MetaDisposable()
|
||||
private var networkStateDisposable: Disposable?
|
||||
|
||||
@ -2788,48 +2789,48 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
}
|
||||
|
||||
self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, hasScheduledMessages, self.reportIrrelvantGeoNoticePromise.get(), pinnedCountSignal, self.presentationInterfaceStatePromise.get())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount, presentationInterfaceState in
|
||||
|
||||
self.titleDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, pinnedCountSignal, self.presentationInterfaceStatePromise.get())
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, pinnedCount, presentationInterfaceState in
|
||||
if let strongSelf = self {
|
||||
var isScheduledMessages = false
|
||||
if case .scheduledMessages = strongSelf.presentationInterfaceState.subject {
|
||||
if case .scheduledMessages = presentationInterfaceState.subject {
|
||||
isScheduledMessages = true
|
||||
}
|
||||
|
||||
if let peer = peerViewMainPeer(peerView) {
|
||||
if let selectionState = presentationInterfaceState.interfaceState.selectionState {
|
||||
if selectionState.selectedIds.count > 0 {
|
||||
strongSelf.chatTitleView?.titleContent = .custom(strongSelf.presentationData.strings.Conversation_SelectedMessages(Int32(selectionState.selectedIds.count)), nil, false)
|
||||
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectedMessages(Int32(selectionState.selectedIds.count)), nil, false)
|
||||
} else {
|
||||
if let reportReason = presentationInterfaceState.reportReason {
|
||||
let title: String
|
||||
switch reportReason {
|
||||
case .spam:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonSpam
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonSpam
|
||||
case .fake:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonFake
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonFake
|
||||
case .violence:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonViolence
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonViolence
|
||||
case .porno:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonPornography
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonPornography
|
||||
case .childAbuse:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonChildAbuse
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonChildAbuse
|
||||
case .copyright:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonCopyright
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonCopyright
|
||||
case .custom:
|
||||
title = strongSelf.presentationData.strings.ReportPeer_ReasonOther
|
||||
title = presentationInterfaceState.strings.ReportPeer_ReasonOther
|
||||
case .irrelevantLocation:
|
||||
title = ""
|
||||
}
|
||||
strongSelf.chatTitleView?.titleContent = .custom(title, strongSelf.presentationInterfaceState.strings.Conversation_SelectMessages, false)
|
||||
strongSelf.chatTitleView?.titleContent = .custom(title, presentationInterfaceState.strings.Conversation_SelectMessages, false)
|
||||
} else {
|
||||
strongSelf.chatTitleView?.titleContent = .custom(strongSelf.presentationInterfaceState.strings.Conversation_SelectMessages, nil, false)
|
||||
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Conversation_SelectMessages, nil, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if case .pinnedMessages = strongSelf.presentationInterfaceState.subject {
|
||||
strongSelf.chatTitleView?.titleContent = .custom(strongSelf.presentationData.strings.Chat_TitlePinnedMessages(Int32(pinnedCount ?? 1)), nil, false)
|
||||
if case .pinnedMessages = presentationInterfaceState.subject {
|
||||
strongSelf.chatTitleView?.titleContent = .custom(presentationInterfaceState.strings.Chat_TitlePinnedMessages(Int32(pinnedCount ?? 1)), nil, false)
|
||||
} else {
|
||||
strongSelf.chatTitleView?.titleContent = .peer(peerView: peerView, onlineMemberCount: onlineMemberCount, isScheduledMessages: isScheduledMessages)
|
||||
let imageOverride: AvatarNodeImageOverride?
|
||||
@ -2847,7 +2848,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}))
|
||||
|
||||
self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(), peerView.get(), onlineMemberCount, hasScheduledMessages, self.reportIrrelvantGeoNoticePromise.get(), pinnedCountSignal)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, onlineMemberCount, hasScheduledMessages, peerReportNotice, pinnedCount in
|
||||
if let strongSelf = self {
|
||||
if strongSelf.peerView === peerView && strongSelf.reportIrrelvantGeoNotice == peerReportNotice && strongSelf.hasScheduledMessages == hasScheduledMessages {
|
||||
return
|
||||
}
|
||||
@ -3103,12 +3109,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
|
||||
let peerView = context.account.viewTracker.peerView(peerId)
|
||||
|
||||
self.titleDisposable.set(nil)
|
||||
self.peerDisposable.set((combineLatest(queue: Queue.mainQueue(),
|
||||
peerView,
|
||||
messagePromise.get(),
|
||||
hasScheduledMessages
|
||||
messagePromise.get()
|
||||
)
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, message, onlineMemberCount in
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peerView, message in
|
||||
if let strongSelf = self {
|
||||
var count = 0
|
||||
if let message = message {
|
||||
@ -3583,6 +3589,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.galleryHiddenMesageAndMediaDisposable.dispose()
|
||||
self.temporaryHiddenGalleryMediaDisposable.dispose()
|
||||
self.peerDisposable.dispose()
|
||||
self.titleDisposable.dispose()
|
||||
self.messageContextDisposable.dispose()
|
||||
self.controllerNavigationDisposable.dispose()
|
||||
self.sentMessageEventsDisposable.dispose()
|
||||
@ -7068,7 +7075,9 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let attributedTitle = NSAttributedString(string: strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_Title, font: Font.medium(17.0), textColor: strongSelf.presentationData.theme.actionSheet.primaryTextColor, paragraphAlignment: .center)
|
||||
let body = MarkdownAttributeSet(font: Font.regular(13.0), textColor: strongSelf.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let bold = MarkdownAttributeSet(font: Font.semibold(13.0), textColor: strongSelf.presentationData.theme.actionSheet.primaryTextColor)
|
||||
let text = strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_Text(presentationStringsFormattedNumber(200000, strongSelf.presentationData.dateTimeFormat.groupingSeparator)).0
|
||||
|
||||
let participantsLimit = strongSelf.context.currentLimitsConfiguration.with { $0 }.maxSupergroupMemberCount
|
||||
let text = strongSelf.presentationData.strings.BroadcastGroups_LimitAlert_Text(presentationStringsFormattedNumber(participantsLimit, strongSelf.presentationData.dateTimeFormat.groupingSeparator)).0
|
||||
let attributedText = parseMarkdownIntoAttributedString(text, attributes: MarkdownAttributes(body: body, bold: bold, link: body, linkAttribute: { _ in return nil }), textAlignment: .center)
|
||||
|
||||
let controller = richTextAlertController(context: strongSelf.context, title: attributedTitle, text: attributedText, actions: [TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {
|
||||
|
@ -1158,6 +1158,14 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
previewing = false
|
||||
}
|
||||
|
||||
var isSelectionEnabled = true
|
||||
if previewing {
|
||||
isSelectionEnabled = false
|
||||
} else if case .pinnedMessages = self.chatPresentationInterfaceState.subject {
|
||||
isSelectionEnabled = false
|
||||
}
|
||||
self.historyNode.isSelectionGestureEnabled = isSelectionEnabled
|
||||
|
||||
var inputPanelSize: CGSize?
|
||||
var immediatelyLayoutInputPanelAndAnimateAppearance = false
|
||||
var secondaryInputPanelSize: CGSize?
|
||||
|
@ -573,7 +573,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private(set) var isScrollAtBottomPosition = false
|
||||
public var isScrollAtBottomPositionUpdated: (() -> Void)?
|
||||
|
||||
@ -589,6 +589,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
let isTopReplyThreadMessageShown = ValuePromise<Bool>(false, ignoreRepeated: true)
|
||||
let topVisibleMessageRange = ValuePromise<ChatTopVisibleMessageRange?>(nil, ignoreRepeated: true)
|
||||
|
||||
var isSelectionGestureEnabled = true
|
||||
|
||||
private let clientId: Atomic<Int32>
|
||||
|
||||
public init(context: AccountContext, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>, tagMask: MessageTags?, source: ChatHistoryListSource = .default, subject: ChatControllerSubject?, controllerInteraction: ChatControllerInteraction, selectedMessages: Signal<Set<MessageId>?, NoError>, mode: ChatHistoryListMode = .bubbles) {
|
||||
@ -1173,10 +1175,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
guard let strongSelf = self else {
|
||||
return false
|
||||
}
|
||||
if case .pinnedMessages = strongSelf.subject {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return strongSelf.isSelectionGestureEnabled
|
||||
}
|
||||
self.view.addGestureRecognizer(selectionRecognizer)
|
||||
}
|
||||
|
@ -763,12 +763,16 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
|
||||
let membersContext = PeerInfoMembersContext(context: context, peerId: groupId)
|
||||
|
||||
let membersData: Signal<PeerInfoMembersData?, NoError> = membersContext.state
|
||||
|> map { state -> PeerInfoMembersData? in
|
||||
if state.members.count > 5 {
|
||||
return .longList(membersContext)
|
||||
let membersData: Signal<PeerInfoMembersData?, NoError> = combineLatest(membersContext.state, context.account.viewTracker.peerView(groupId, updateData: false))
|
||||
|> map { state, view -> PeerInfoMembersData? in
|
||||
if let peer = peerViewMainPeer(view) as? TelegramChannel, peer.flags.contains(.isGigagroup) {
|
||||
return nil
|
||||
} else {
|
||||
return .shortList(membersContext: membersContext, members: state.members)
|
||||
if state.members.count > 5 {
|
||||
return .longList(membersContext)
|
||||
} else {
|
||||
return .shortList(membersContext: membersContext, members: state.members)
|
||||
}
|
||||
}
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
|
@ -2259,6 +2259,8 @@ final class PeerInfoHeaderMultiLineTextFieldNode: ASDisplayNode, PeerInfoHeaderT
|
||||
let textColor = presentationData.theme.list.itemPrimaryTextColor
|
||||
|
||||
self.textNode.typingAttributes = [NSAttributedString.Key.font.rawValue: titleFont, NSAttributedString.Key.foregroundColor.rawValue: textColor]
|
||||
self.textNode.keyboardAppearance = presentationData.theme.rootController.keyboardColor.keyboardAppearance
|
||||
self.textNode.tintColor = presentationData.theme.list.itemAccentColor
|
||||
|
||||
self.textNode.clipsToBounds = true
|
||||
self.textNode.delegate = self
|
||||
|
@ -1180,15 +1180,15 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
}))
|
||||
}
|
||||
} else if let channel = data.peer as? TelegramChannel {
|
||||
let ItemUsername = 1
|
||||
let ItemInviteLinks = 2
|
||||
let ItemDiscussionGroup = 3
|
||||
let ItemSignMessages = 4
|
||||
let ItemSignMessagesHelp = 5
|
||||
let ItemAutoremove = 6
|
||||
|
||||
switch channel.info {
|
||||
case .broadcast:
|
||||
let ItemUsername = 1
|
||||
let ItemInviteLinks = 2
|
||||
let ItemDiscussionGroup = 3
|
||||
let ItemSignMessages = 4
|
||||
let ItemSignMessagesHelp = 5
|
||||
let ItemAutoremove = 6
|
||||
|
||||
if channel.flags.contains(.isCreator) {
|
||||
let linkText: String
|
||||
if let username = channel.username {
|
||||
@ -1266,13 +1266,16 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
let ItemUsername = 101
|
||||
let ItemLinkedChannel = 102
|
||||
let ItemPreHistory = 103
|
||||
let ItemStickerPack = 104
|
||||
let ItemPermissions = 105
|
||||
let ItemAdmins = 106
|
||||
let ItemLocationHeader = 107
|
||||
let ItemLocation = 108
|
||||
let ItemLocationSetup = 109
|
||||
let ItemAutoremove = 110
|
||||
let ItemInviteLinks = 104
|
||||
let ItemStickerPack = 105
|
||||
let ItemPermissions = 106
|
||||
let ItemMembers = 107
|
||||
let ItemAdmins = 108
|
||||
let ItemRemovedUsers = 109
|
||||
let ItemLocationHeader = 110
|
||||
let ItemLocation = 111
|
||||
let ItemLocationSetup = 112
|
||||
let ItemAutoremove = 113
|
||||
|
||||
let isCreator = channel.flags.contains(.isCreator)
|
||||
let isPublic = channel.username != nil
|
||||
@ -1316,7 +1319,6 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
items[.peerPublicSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemUsername, label: .text(isPublic ? presentationData.strings.Channel_Setup_TypePublic : presentationData.strings.Channel_Setup_TypePrivate), text: presentationData.strings.GroupInfo_GroupType, icon: UIImage(bundleImageName: "Chat/Info/GroupMembersIcon"), action: {
|
||||
interaction.editingOpenPublicLinkSetup()
|
||||
}))
|
||||
|
||||
}
|
||||
|
||||
if cachedData.flags.contains(.canChangeUsername) {
|
||||
@ -1378,13 +1380,25 @@ private func editingItems(data: PeerInfoScreenData?, context: AccountContext, pr
|
||||
activePermissionCount = count
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList.count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/MenuIcons/SetPasscode"), action: {
|
||||
interaction.openPermissions()
|
||||
}))
|
||||
if !channel.flags.contains(.isGigagroup) {
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPermissions, label: .text(activePermissionCount.flatMap({ "\($0)/\(allGroupPermissionList.count)" }) ?? ""), text: presentationData.strings.GroupInfo_Permissions, icon: UIImage(bundleImageName: "Settings/MenuIcons/SetPasscode"), action: {
|
||||
interaction.openPermissions()
|
||||
}))
|
||||
} else {
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemMembers, label: .text(cachedData.participantsSummary.memberCount.flatMap { "\(presentationStringsFormattedNumber($0, presentationData.dateTimeFormat.groupingSeparator))" } ?? ""), text: presentationData.strings.Group_Info_Members, icon: UIImage(bundleImageName: "Chat/Info/GroupMembersIcon"), action: {
|
||||
interaction.openParticipantsSection(.members)
|
||||
}))
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAdmins, label: .text(cachedData.participantsSummary.adminCount.flatMap { "\(presentationStringsFormattedNumber($0, presentationData.dateTimeFormat.groupingSeparator))" } ?? ""), text: presentationData.strings.GroupInfo_Administrators, icon: UIImage(bundleImageName: "Chat/Info/GroupAdminsIcon"), action: {
|
||||
interaction.openParticipantsSection(.admins)
|
||||
}))
|
||||
|
||||
if channel.flags.contains(.isGigagroup) {
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemRemovedUsers, label: .text(cachedData.participantsSummary.kickedCount.flatMap { $0 > 0 ? "\(presentationStringsFormattedNumber($0, presentationData.dateTimeFormat.groupingSeparator))" : "" } ?? ""), text: presentationData.strings.GroupInfo_Permissions_Removed, icon: UIImage(bundleImageName: "Chat/Info/GroupRemovedIcon"), action: {
|
||||
interaction.openParticipantsSection(.banned)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user