mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-02 00:17:02 +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
|
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()))
|
return account.network.request(Api.functions.messages.migrateChat(chatId: peerId.id._internalGetInt64Value()))
|
||||||
|> mapError { error -> ConvertGroupToSupergroupError in
|
|> mapError { error -> ConvertGroupToSupergroupError in
|
||||||
if error.errorDescription == "CHANNELS_TOO_MUCH" {
|
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))
|
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||||
|> mapToSignal { updates -> Signal<PeerId, ConvertGroupToSupergroupError> in
|
|> mapToSignal { updates -> Signal<PeerId, ConvertGroupToSupergroupError> in
|
||||||
account.stateManager.addUpdates(updates)
|
|
||||||
var createdPeerId: PeerId?
|
var createdPeerId: PeerId?
|
||||||
for message in updates.messages {
|
for message in updates.messages {
|
||||||
if apiMessagePeerId(message) != peerId {
|
if apiMessagePeerId(message) != peerId {
|
||||||
@ -30,6 +29,18 @@ func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId) -> Sig
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let createdPeerId = createdPeerId {
|
if let createdPeerId = createdPeerId {
|
||||||
|
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])
|
return account.postbox.multiplePeersView([createdPeerId])
|
||||||
|> filter { view in
|
|> filter { view in
|
||||||
return view.peers[createdPeerId] != nil
|
return view.peers[createdPeerId] != nil
|
||||||
@ -42,8 +53,12 @@ func _internal_convertGroupToSupergroup(account: Account, peerId: PeerId) -> Sig
|
|||||||
}
|
}
|
||||||
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
|> timeout(5.0, queue: Queue.concurrentDefaultQueue(), alternate: .fail(.generic))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
account.stateManager.addUpdates(updates)
|
||||||
return .fail(.generic)
|
return .fail(.generic)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ConvertGroupToGigagroupError {
|
public enum ConvertGroupToGigagroupError {
|
||||||
|
@ -134,8 +134,8 @@ public extension TelegramEngine {
|
|||||||
return _internal_chatOnlineMembers(postbox: self.account.postbox, network: self.account.network, peerId: peerId)
|
return _internal_chatOnlineMembers(postbox: self.account.postbox, network: self.account.network, peerId: peerId)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func convertGroupToSupergroup(peerId: PeerId) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
public func convertGroupToSupergroup(peerId: PeerId, additionalProcessing: ((EnginePeer.Id) -> Signal<Never, NoError>)? = nil) -> Signal<PeerId, ConvertGroupToSupergroupError> {
|
||||||
return _internal_convertGroupToSupergroup(account: self.account, peerId: peerId)
|
return _internal_convertGroupToSupergroup(account: self.account, peerId: peerId, additionalProcessing: additionalProcessing)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func createGroup(title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<CreateGroupResult?, CreateGroupError> {
|
public func createGroup(title: String, peerIds: [PeerId], ttlPeriod: Int32?) -> Signal<CreateGroupResult?, CreateGroupError> {
|
||||||
|
@ -350,14 +350,15 @@ enum PeerInfoMembersData: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func peerInfoScreenInputData(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal<PeerInfoScreenInputData, NoError> {
|
private func peerInfoScreenInputData(context: AccountContext, peerId: EnginePeer.Id, isSettings: Bool) -> Signal<PeerInfoScreenInputData, NoError> {
|
||||||
|
return `deferred` {
|
||||||
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
return context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||||
|> map { peer -> PeerInfoScreenInputData in
|
|> mapToSignal { peer -> Signal<PeerInfoScreenInputData, NoError> in
|
||||||
guard let peer = peer else {
|
guard let peer = peer else {
|
||||||
return .none
|
return .single(.none)
|
||||||
}
|
}
|
||||||
if case let .user(user) = peer {
|
if case let .user(user) = peer {
|
||||||
if isSettings && user.id == context.account.peerId {
|
if isSettings && user.id == context.account.peerId {
|
||||||
return .settings
|
return .single(.settings)
|
||||||
} else {
|
} else {
|
||||||
let kind: PeerInfoScreenInputUserKind
|
let kind: PeerInfoScreenInputUserKind
|
||||||
if user.flags.contains(.isSupport) {
|
if user.flags.contains(.isSupport) {
|
||||||
@ -367,23 +368,24 @@ private func peerInfoScreenInputData(context: AccountContext, peerId: EnginePeer
|
|||||||
} else {
|
} else {
|
||||||
kind = .user
|
kind = .user
|
||||||
}
|
}
|
||||||
return .user(userId: user.id, secretChatId: nil, kind: kind)
|
return .single(.user(userId: user.id, secretChatId: nil, kind: kind))
|
||||||
}
|
}
|
||||||
} else if case let .channel(channel) = peer {
|
} else if case let .channel(channel) = peer {
|
||||||
if case .group = channel.info {
|
if case .group = channel.info {
|
||||||
return .group(groupId: channel.id)
|
return .single(.group(groupId: channel.id))
|
||||||
} else {
|
} else {
|
||||||
return .channel
|
return .single(.channel)
|
||||||
}
|
}
|
||||||
} else if case let .legacyGroup(group) = peer {
|
} else if case let .legacyGroup(group) = peer {
|
||||||
return .group(groupId: group.id)
|
return .single(.group(groupId: group.id))
|
||||||
} else if case let .secretChat(secretChat) = peer {
|
} else if case let .secretChat(secretChat) = peer {
|
||||||
return .user(userId: secretChat.regularPeerId, secretChatId: peer.id, kind: .user)
|
return .single(.user(userId: secretChat.regularPeerId, secretChatId: peer.id, kind: .user))
|
||||||
} else {
|
} else {
|
||||||
return .none
|
return .single(.none)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|> distinctUntilChanged
|
|> distinctUntilChanged
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func keepPeerInfoScreenDataHot(context: AccountContext, peerId: PeerId, chatLocation: ChatLocation, chatLocationContextHolder: Atomic<ChatLocationContextHolder?>) -> Signal<Never, NoError> {
|
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> {
|
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)
|
return peerInfoScreenInputData(context: context, peerId: peerId, isSettings: isSettings)
|
||||||
|> mapToSignal { inputData -> Signal<PeerInfoScreenData, NoError> in
|
|> mapToSignal { inputData -> Signal<PeerInfoScreenData, NoError> in
|
||||||
|
let wasUpgradedGroup = Atomic<Bool?>(value: nil)
|
||||||
|
|
||||||
switch inputData {
|
switch inputData {
|
||||||
case .none, .settings:
|
case .none, .settings:
|
||||||
return .single(PeerInfoScreenData(
|
return .single(PeerInfoScreenData(
|
||||||
@ -914,7 +918,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData,
|
threadData,
|
||||||
context.account.postbox.preferencesView(keys: [PreferencesKeys.appConfiguration])
|
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?
|
var discussionPeer: Peer?
|
||||||
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
if case let .known(maybeLinkedDiscussionPeerId) = (peerView.cachedData as? CachedChannelData)?.linkedDiscussionPeerId, let linkedDiscussionPeerId = maybeLinkedDiscussionPeerId, let peer = peerView.peers[linkedDiscussionPeerId] {
|
||||||
discussionPeer = peer
|
discussionPeer = peer
|
||||||
@ -931,6 +935,11 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
|
|
||||||
var canManageInvitations = false
|
var canManageInvitations = false
|
||||||
if let group = peerViewMainPeer(peerView) as? TelegramGroup {
|
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 {
|
if case .creator = group.role {
|
||||||
canManageInvitations = true
|
canManageInvitations = true
|
||||||
} else if case let .admin(rights, _) = group.role, rights.rights.contains(.canInviteUsers) {
|
} 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
|
let appConfiguration: AppConfiguration = preferencesView.values[PreferencesKeys.appConfiguration]?.get(AppConfiguration.self) ?? .defaultValue
|
||||||
|
|
||||||
return PeerInfoScreenData(
|
return .single(PeerInfoScreenData(
|
||||||
peer: peerView.peers[groupId],
|
peer: peerView.peers[groupId],
|
||||||
chatPeer: peerView.peers[groupId],
|
chatPeer: peerView.peers[groupId],
|
||||||
cachedData: peerView.cachedData,
|
cachedData: peerView.cachedData,
|
||||||
@ -981,7 +990,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
threadData: threadData,
|
threadData: threadData,
|
||||||
appConfiguration: appConfiguration,
|
appConfiguration: appConfiguration,
|
||||||
isPowerSavingEnabled: nil
|
isPowerSavingEnabled: nil
|
||||||
)
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1823,6 +1823,8 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
|||||||
let ItemAdmins = 105
|
let ItemAdmins = 105
|
||||||
let ItemMemberRequests = 106
|
let ItemMemberRequests = 106
|
||||||
let ItemReactions = 107
|
let ItemReactions = 107
|
||||||
|
let ItemTopics = 108
|
||||||
|
let ItemTopicsText = 109
|
||||||
|
|
||||||
var canViewAdminsAndBanned = false
|
var canViewAdminsAndBanned = false
|
||||||
|
|
||||||
@ -1852,6 +1854,33 @@ private func editingItems(data: PeerInfoScreenData?, state: PeerInfoState, chatL
|
|||||||
interaction.editingOpenPreHistorySetup()
|
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
|
let label: String
|
||||||
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
if let cachedData = data.cachedData as? CachedGroupData, case let .known(allowedReactions) = cachedData.allowedReactions {
|
||||||
switch allowedReactions {
|
switch allowedReactions {
|
||||||
@ -2228,7 +2257,7 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, UIScrollViewDelegate
|
|||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let _ = strongSelf.context.engine.peers.setChannelForumMode(id: strongSelf.peerId, isForum: value).start()
|
strongSelf.toggleForumTopics(isEnabled: value)
|
||||||
},
|
},
|
||||||
displayTopicsLimited: { [weak self] reason in
|
displayTopicsLimited: { [weak self] reason in
|
||||||
guard let self else {
|
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))
|
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) {
|
private func editingToggleMessageSignatures(value: Bool) {
|
||||||
self.toggleShouldChannelMessagesSignaturesDisposable.set(self.context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: self.peerId, enabled: value).start())
|
self.toggleShouldChannelMessagesSignaturesDisposable.set(self.context.engine.peers.toggleShouldChannelMessagesSignatures(peerId: self.peerId, enabled: value).start())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user