mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Convert legacy group to supergroup
This commit is contained in:
parent
fbc393c51c
commit
1b79f229c3
@ -9,7 +9,7 @@ public enum ConvertGroupToSupergroupError {
|
||||
case tooManyChannels
|
||||
}
|
||||
|
||||
func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
||||
func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId, additionalProcessing: ((EnginePeer.Id) -> Signal<Never, NoError>)?) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
||||
return account.network.request(Api.functions.messages.migrateChat(chatId: peerId.id._internalGetInt64Value()))
|
||||
|> mapError { error -> ConvertGroupToSupergroupError in
|
||||
if error.errorDescription == "CHANNELS_TOO_MUCH" {
|
||||
@ -20,7 +20,6 @@ func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId) -> Sig
|
||||
}
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||
|> mapToSignal { updates -> Signal<PeerId, ConvertGroupToSupergroupError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
var createdPeerId: PeerId?
|
||||
for message in updates.messages {
|
||||
if apiMessagePeerId(message) != peerId {
|
||||
@ -30,19 +29,35 @@ func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId) -> Sig
|
||||
}
|
||||
|
||||
if let createdPeerId = createdPeerId {
|
||||
return account.postbox.multiplePeersView([createdPeerId])
|
||||
|> filter { view in
|
||||
return view.peers[createdPeerId] != nil
|
||||
let additionalProcessingValue: Signal<Never, NoError> = additionalProcessing?(createdPeerId) ?? Signal<Never, NoError>.complete()
|
||||
|
||||
return additionalProcessingValue
|
||||
|> map { _ -> Bool in }
|
||||
|> castError(ConvertGroupToSupergroupError.self)
|
||||
|> then(Signal<Bool, ConvertGroupToSupergroupError>.single(true))
|
||||
|> mapToSignal { _ ->Signal<PeerId, ConvertGroupToSupergroupError> in
|
||||
account.stateManager.addUpdates(updates)
|
||||
|
||||
return _internal_fetchAndUpdateCachedPeerData(accountPeerId: account.peerId, peerId: createdPeerId, network: account.network, postbox: account.postbox)
|
||||
|> castError(ConvertGroupToSupergroupError.self)
|
||||
|> mapToSignal { _ -> Signal<PeerId, ConvertGroupToSupergroupError> in
|
||||
return account.postbox.multiplePeersView([createdPeerId])
|
||||
|> filter { view in
|
||||
return view.peers[createdPeerId] != nil
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return createdPeerId
|
||||
}
|
||||
|> mapError { _ -> ConvertGroupToSupergroupError in
|
||||
}
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||
}
|
||||
}
|
||||
|> take(1)
|
||||
|> map { _ in
|
||||
return createdPeerId
|
||||
}
|
||||
|> mapError { _ -> ConvertGroupToSupergroupError in
|
||||
}
|
||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||
} else {
|
||||
account.stateManager.addUpdates(updates)
|
||||
return .fail(.generic)
|
||||
}
|
||||
return .fail(.generic)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,8 +134,8 @@ public extension TelegramEngine {
|
||||
return _internal_chatOnlineMembers(postbox: self.account.postbox, network: self.account.network, peerId: peerId)
|
||||
}
|
||||
|
||||
public func convertGroupToSupergroup(peerId: PeerId) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
||||
return _internal_convertGroupToSupergroup(account: self.account, peerId: peerId)
|
||||
public func convertGroupToSupergroup(peerId: PeerId, additionalProcessing: ((EnginePeer.Id) -> Signal<Never, NoError>)? = nil) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
||||
return _internal_convertGroupToSupergroup(account: self.account, peerId: peerId, additionalProcessing: additionalProcessing)
|
||||
}
|
||||
|
||||
public func createGroup(title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<CreateGroupResult?, CreateGroupError> {
|
||||
|
@ -350,40 +350,42 @@ enum PeerInfoMembersData: Equatable {
|
||||
}
|
||||
|
||||
private func peerInfoScreenInputData(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal<PeerInfoScreenInputData, NoError> {
|
||||
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> map { peer -> PeerInfoScreenInputData in
|
||||
guard let peer = peer else {
|
||||
return .none
|
||||
}
|
||||
if case let .user(user) = peer {
|
||||
if isSettings && user.id == context.account.peerId {
|
||||
return .settings
|
||||
} else {
|
||||
let kind: PeerInfoScreenInputUserKind
|
||||
if user.flags.contains(.isSupport) {
|
||||
kind = .support
|
||||
} else if user.botInfo != nil {
|
||||
kind = .bot
|
||||
return `deferred` {
|
||||
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> mapToSignal { peer -> Signal<PeerInfoScreenInputData, NoError> in
|
||||
guard let peer = peer else {
|
||||
return .single(.none)
|
||||
}
|
||||
if case let .user(user) = peer {
|
||||
if isSettings && user.id == context.account.peerId {
|
||||
return .single(.settings)
|
||||
} else {
|
||||
kind = .user
|
||||
let kind: PeerInfoScreenInputUserKind
|
||||
if user.flags.contains(.isSupport) {
|
||||
kind = .support
|
||||
} else if user.botInfo != nil {
|
||||
kind = .bot
|
||||
} else {
|
||||
kind = .user
|
||||
}
|
||||
return .single(.user(userId: user.id, secretChatId: nil, kind: kind))
|
||||
}
|
||||
return .user(userId: user.id, secretChatId: nil, kind: kind)
|
||||
}
|
||||
} else if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
return .group(groupId: channel.id)
|
||||
} else if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
return .single(.group(groupId: channel.id))
|
||||
} else {
|
||||
return .single(.channel)
|
||||
}
|
||||
} else if case let .legacyGroup(group) = peer {
|
||||
return .single(.group(groupId: group.id))
|
||||
} else if case let .secretChat(secretChat) = peer {
|
||||
return .single(.user(userId: secretChat.regularPeerId, secretChatId: peer.id, kind: .user))
|
||||
} else {
|
||||
return .channel
|
||||
return .single(.none)
|
||||
}
|
||||
} else if case let .legacyGroup(group) = peer {
|
||||
return .group(groupId: group.id)
|
||||
} else if case let .secretChat(secretChat) = peer {
|
||||
return .user(userId: secretChat.regularPeerId, secretChatId: peer.id, kind: .user)
|
||||
} else {
|
||||
return .none
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
}
|
||||
|> distinctUntilChanged
|
||||
}
|
||||
|
||||
func keepPeerInfoScreenDataHot(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>) -> Signal<Never, NoError> {
|
||||
@ -547,6 +549,8 @@ func peerInfoScreenSettingsData(context: AccountContext, peerId: EnginePeer.Id,
|
||||
func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, isSettings: Bool, hintGroupInCommon: PeerId?, existingRequestsContext: PeerInvitationImportersContext?, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>) -> Signal<PeerInfoScreenData, NoError> {
|
||||
return peerInfoScreenInputData(context: context, peerId: peerId, isSettings: isSettings)
|
||||
|> mapToSignal { inputData -> Signal<PeerInfoScreenData, NoError> in
|
||||
let wasUpgradedGroup = Atomic<Bool?>(value: nil)
|
||||
|
||||
switch inputData {
|
||||
case .none, .settings:
|
||||
return .single(PeerInfoScreenData(
|
||||
@ -914,7 +918,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
threadData,
|
||||
context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
||||
)
|
||||
|> map { peerView, availablePanes, globalNotificationSettings, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests, threadData, preferencesView -> PeerInfoScreenData in
|
||||
|> mapToSignal { peerView, availablePanes, globalNotificationSettings, status, membersData, currentInvitationsContext, invitations, currentRequestsContext, requests, threadData, preferencesView -> Signal<PeerInfoScreenData, NoError> in
|
||||
var discussionPeer: Peer?
|
||||
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
||||
discussionPeer = peer
|
||||
@ -931,6 +935,11 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
|
||||
var canManageInvitations = false
|
||||
if let group = peerViewMainPeer(peerView) as? TelegramGroup {
|
||||
let previousValue = wasUpgradedGroup.swap(group.migrationReference != nil)
|
||||
if group.migrationReference != nil, let previousValue, !previousValue {
|
||||
return .never()
|
||||
}
|
||||
|
||||
if case .creator = group.role {
|
||||
canManageInvitations = true
|
||||
} else if case let .admin(rights, _) = group.role, rights.rights.contains(.canInviteUsers) {
|
||||
@ -960,7 +969,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
|
||||
let appConfiguration: AppConfiguration = preferencesView.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
|
||||
|
||||
return PeerInfoScreenData(
|
||||
return .single(PeerInfoScreenData(
|
||||
peer: peerView.peers[groupId],
|
||||
chatPeer: peerView.peers[groupId],
|
||||
cachedData: peerView.cachedData,
|
||||
@ -981,7 +990,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
||||
threadData: threadData,
|
||||
appConfiguration: appConfiguration,
|
||||
isPowerSavingEnabled: nil
|
||||
)
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1823,6 +1823,8 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
let ItemAdmins = 105
|
||||
let ItemMemberRequests = 106
|
||||
let ItemReactions = 107
|
||||
let ItemTopics = 108
|
||||
let ItemTopicsText = 109
|
||||
|
||||
var canViewAdminsAndBanned = false
|
||||
|
||||
@ -1852,6 +1854,33 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
||||
interaction.editingOpenPreHistorySetup()
|
||||
}))
|
||||
|
||||
var canSetupTopics = false
|
||||
if case .creator = group.role {
|
||||
canSetupTopics = true
|
||||
}
|
||||
var topicsLimitedReason: TopicsLimitedReason?
|
||||
if let appConfiguration = data.appConfiguration {
|
||||
var minParticipants = 200
|
||||
if let data = appConfiguration.data, let value = data["forum_upgrade_participants_min"] as? Double {
|
||||
minParticipants = Int(value)
|
||||
}
|
||||
if Int(group.participantCount) < minParticipants {
|
||||
topicsLimitedReason = .participants(minParticipants)
|
||||
}
|
||||
}
|
||||
|
||||
if canSetupTopics {
|
||||
items[.peerPublicSettings]!.append(PeerInfoScreenSwitchItem(id: ItemTopics, text: presentationData.strings.PeerInfo_OptionTopics, value: false, icon: UIImage(bundleImageName: "Settings/Menu/Topics"), isLocked: topicsLimitedReason != nil, toggled: { value in
|
||||
if let topicsLimitedReason = topicsLimitedReason {
|
||||
interaction.displayTopicsLimited(topicsLimitedReason)
|
||||
} else {
|
||||
interaction.toggleForumTopics(value)
|
||||
}
|
||||
}))
|
||||
|
||||
items[.peerPublicSettings]!.append(PeerInfoScreenCommentItem(id: ItemTopicsText, text: presentationData.strings.PeerInfo_OptionTopicsText))
|
||||
}
|
||||
|
||||
let label: String
|
||||
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
||||
switch allowedReactions {
|
||||
@ -2228,7 +2257,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
let _ = strongSelf.context.engine.peers.setChannelForumMode(id: strongSelf.peerId, isForum: value).start()
|
||||
strongSelf.toggleForumTopics(isEnabled: value)
|
||||
},
|
||||
displayTopicsLimited: { [weak self] reason in
|
||||
guard let self else {
|
||||
@ -6515,6 +6544,61 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
||||
self.controller?.push(peerAllowedReactionListController(context: self.context, updatedPresentationData: self.controller?.updatedPresentationData, peerId: peer.id))
|
||||
}
|
||||
|
||||
private func toggleForumTopics(isEnabled: Bool) {
|
||||
guard let data = self.data, let peer = data.peer else {
|
||||
return
|
||||
}
|
||||
if peer is TelegramGroup {
|
||||
if isEnabled {
|
||||
let context = self.context
|
||||
let signal: Signal<EnginePeer.Id?, NoError> = self.context.engine.peers.convertGroupToSupergroup(peerId: self.peerId, additionalProcessing: { upgradedPeerId -> Signal<Never, NoError> in
|
||||
return context.engine.peers.setChannelForumMode(id: upgradedPeerId, isForum: isEnabled)
|
||||
})
|
||||
|> map(Optional.init)
|
||||
|> `catch` { [weak self] error -> Signal<PeerId?, NoError> in
|
||||
switch error {
|
||||
case .tooManyChannels:
|
||||
Queue.mainQueue().async {
|
||||
self?.controller?.push(oldChannelsController(context: context, intent: .upgrade))
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
return .single(nil)
|
||||
}
|
||||
|> mapToSignal { upgradedPeerId -> Signal<PeerId?, NoError> in
|
||||
guard let upgradedPeerId = upgradedPeerId else {
|
||||
return .single(nil)
|
||||
}
|
||||
return .single(upgradedPeerId)
|
||||
}
|
||||
|> deliverOnMainQueue
|
||||
|
||||
let _ = signal.start(next: { [weak self] resultPeerId in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
guard let resultPeerId else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = (self.context.engine.peers.setChannelForumMode(id: resultPeerId, isForum: isEnabled)
|
||||
|> deliverOnMainQueue).start(completed: { [weak self] in
|
||||
guard let self, let controller = self.controller else {
|
||||
return
|
||||
}
|
||||
/*if let navigationController = controller.navigationController as? NavigationController {
|
||||
rebuildControllerStackAfterSupergroupUpgrade(controller: controller, navigationController: navigationController)
|
||||
}*/
|
||||
controller.dismiss()
|
||||
})
|
||||
})
|
||||
}
|
||||
} else {
|
||||
let _ = self.context.engine.peers.setChannelForumMode(id: self.peerId, isForum: isEnabled).start()
|
||||
}
|
||||
}
|
||||
|
||||
private func editingToggleMessageSignatures(value: Bool) {
|
||||
self.toggleShouldChannelMessagesSignaturesDisposable.set(self.context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: self.peerId, enabled: value).start())
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user