mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-02 02:43:07 +00:00
Support multiple pinned threads
This commit is contained in:
parent
f1864a43b9
commit
fa95906962
@ -8241,3 +8241,6 @@ Sorry for the inconvenience.";
|
||||
"Attachment.DiscardPasteboardAlertText" = "Discard pasted items?";
|
||||
|
||||
"Undo.DeletedTopic" = "Topic Deleted";
|
||||
|
||||
"ChatList.MaxThreadPinsFinalText_1" = "Sorry, you can't pin more than **%@** thread to the top. Unpin some that are currently pinned.";
|
||||
"ChatList.MaxThreadPinsFinalText_any" = "Sorry, you can't pin more than **%@** threads to the top. Unpin some that are currently pinned.";
|
||||
|
@ -519,7 +519,19 @@ func chatForumTopicMenuItems(context: AccountContext, peerId: PeerId, threadId:
|
||||
items.append(.action(ContextMenuActionItem(text: isPinned ? presentationData.strings.ChatList_Context_Unpin : presentationData.strings.ChatList_Context_Pin, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: isPinned ? "Chat/Context Menu/Unpin": "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { _, f in
|
||||
f(.default)
|
||||
|
||||
let _ = context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId).start()
|
||||
let _ = (context.engine.peers.toggleForumChannelTopicPinned(id: peerId, threadId: threadId)
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
switch error {
|
||||
case let .limitReached(count):
|
||||
if let chatListController = chatListController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let text = presentationData.strings.ChatList_MaxThreadPinsFinalText(Int32(count))
|
||||
chatListController.present(textAlertController(context: context, title: presentationData.strings.Premium_LimitReached, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})], parseMarkdown: true), in: .window(.root))
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -1697,85 +1697,160 @@ public final class ChatListNode: ListView {
|
||||
})
|
||||
|
||||
self.reorderItem = { [weak self] fromIndex, toIndex, transactionOpaqueState -> Signal<Bool, NoError> in
|
||||
if let strongSelf = self, let filteredEntries = (transactionOpaqueState as? ChatListOpaqueTransactionState)?.chatListView.filteredEntries {
|
||||
guard case let .chatList(groupId) = strongSelf.location else {
|
||||
return .single(false)
|
||||
guard let strongSelf = self, let filteredEntries = (transactionOpaqueState as? ChatListOpaqueTransactionState)?.chatListView.filteredEntries else {
|
||||
return .single(false)
|
||||
}
|
||||
guard fromIndex >= 0 && fromIndex < filteredEntries.count && toIndex >= 0 && toIndex < filteredEntries.count else {
|
||||
return .single(false)
|
||||
}
|
||||
|
||||
switch strongSelf.location {
|
||||
case let .chatList(groupId):
|
||||
let fromEntry = filteredEntries[filteredEntries.count - 1 - fromIndex]
|
||||
let toEntry = filteredEntries[filteredEntries.count - 1 - toIndex]
|
||||
|
||||
var referenceId: EngineChatList.PinnedItem.Id?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, promoInfo, _, _, _):
|
||||
if promoInfo != nil {
|
||||
beforeAll = true
|
||||
} else {
|
||||
if case let .chatList(chatListIndex) = index {
|
||||
referenceId = .peer(chatListIndex.messageIndex.id.peerId)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if fromIndex >= 0 && fromIndex < filteredEntries.count && toIndex >= 0 && toIndex < filteredEntries.count {
|
||||
let fromEntry = filteredEntries[filteredEntries.count - 1 - fromIndex]
|
||||
let toEntry = filteredEntries[filteredEntries.count - 1 - toIndex]
|
||||
if case let .index(index) = fromEntry.sortIndex, case let .chatList(chatListIndex) = index, let _ = chatListIndex.pinningIndex {
|
||||
let location: TogglePeerChatPinnedLocation
|
||||
if let chatListFilter = chatListFilter {
|
||||
location = .filter(chatListFilter.id)
|
||||
} else {
|
||||
location = .group(groupId._asGroup())
|
||||
}
|
||||
|
||||
var referenceId: EngineChatList.PinnedItem.Id?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, promoInfo, _, _, _):
|
||||
if promoInfo != nil {
|
||||
beforeAll = true
|
||||
} else {
|
||||
if case let .chatList(chatListIndex) = index {
|
||||
referenceId = .peer(chatListIndex.messageIndex.id.peerId)
|
||||
let engine = strongSelf.context.engine
|
||||
return engine.peers.getPinnedItemIds(location: location)
|
||||
|> mapToSignal { itemIds -> Signal<Bool, NoError> in
|
||||
var itemIds = itemIds
|
||||
|
||||
var itemId: EngineChatList.PinnedItem.Id?
|
||||
switch fromEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
if case let .chatList(index) = index {
|
||||
itemId = .peer(index.messageIndex.id.peerId)
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if case let .index(index) = fromEntry.sortIndex, case let .chatList(chatListIndex) = index, let _ = chatListIndex.pinningIndex {
|
||||
let location: TogglePeerChatPinnedLocation
|
||||
if let chatListFilter = chatListFilter {
|
||||
location = .filter(chatListFilter.id)
|
||||
} else {
|
||||
location = .group(groupId._asGroup())
|
||||
}
|
||||
|
||||
let engine = strongSelf.context.engine
|
||||
return engine.peers.getPinnedItemIds(location: location)
|
||||
|> mapToSignal { itemIds -> Signal<Bool, NoError> in
|
||||
var itemIds = itemIds
|
||||
|
||||
var itemId: EngineChatList.PinnedItem.Id?
|
||||
switch fromEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
if case let .chatList(index) = index {
|
||||
itemId = .peer(index.messageIndex.id.peerId)
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let itemId = itemId {
|
||||
itemIds = itemIds.filter({ $0 != itemId })
|
||||
if let referenceId = referenceId {
|
||||
var inserted = false
|
||||
for i in 0 ..< itemIds.count {
|
||||
if itemIds[i] == referenceId {
|
||||
if fromIndex < toIndex {
|
||||
itemIds.insert(itemId, at: i + 1)
|
||||
} else {
|
||||
itemIds.insert(itemId, at: i)
|
||||
}
|
||||
inserted = true
|
||||
break
|
||||
|
||||
if let itemId = itemId {
|
||||
itemIds = itemIds.filter({ $0 != itemId })
|
||||
if let referenceId = referenceId {
|
||||
var inserted = false
|
||||
for i in 0 ..< itemIds.count {
|
||||
if itemIds[i] == referenceId {
|
||||
if fromIndex < toIndex {
|
||||
itemIds.insert(itemId, at: i + 1)
|
||||
} else {
|
||||
itemIds.insert(itemId, at: i)
|
||||
}
|
||||
inserted = true
|
||||
break
|
||||
}
|
||||
if !inserted {
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
} else if beforeAll {
|
||||
itemIds.insert(itemId, at: 0)
|
||||
} else {
|
||||
}
|
||||
if !inserted {
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
return engine.peers.reorderPinnedItemIds(location: location, itemIds: itemIds)
|
||||
} else if beforeAll {
|
||||
itemIds.insert(itemId, at: 0)
|
||||
} else {
|
||||
return .single(false)
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
return engine.peers.reorderPinnedItemIds(location: location, itemIds: itemIds)
|
||||
} else {
|
||||
return .single(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(false)
|
||||
}
|
||||
case let .forum(peerId):
|
||||
let fromEntry = filteredEntries[filteredEntries.count - 1 - fromIndex]
|
||||
let toEntry = filteredEntries[filteredEntries.count - 1 - toIndex]
|
||||
|
||||
var referenceId: Int64?
|
||||
var beforeAll = false
|
||||
switch toEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, promoInfo, _, _, _):
|
||||
if promoInfo != nil {
|
||||
beforeAll = true
|
||||
} else {
|
||||
if case let .forum(_, _, threadId, _, _) = index {
|
||||
referenceId = threadId
|
||||
}
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if case let .index(index) = fromEntry.sortIndex, case let .forum(pinningIndex, _, _, _, _) = index, case .index = pinningIndex {
|
||||
let engine = strongSelf.context.engine
|
||||
return engine.peers.getForumChannelPinnedTopics(id: peerId)
|
||||
|> mapToSignal { itemIds -> Signal<Bool, NoError> in
|
||||
var itemIds = itemIds
|
||||
|
||||
var itemId: Int64?
|
||||
switch fromEntry {
|
||||
case let .PeerEntry(index, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _):
|
||||
if case let .forum(_, _, threadId, _, _) = index {
|
||||
itemId = threadId
|
||||
}
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
if let itemId = itemId {
|
||||
itemIds = itemIds.filter({ $0 != itemId })
|
||||
if let referenceId = referenceId {
|
||||
var inserted = false
|
||||
for i in 0 ..< itemIds.count {
|
||||
if itemIds[i] == referenceId {
|
||||
if fromIndex < toIndex {
|
||||
itemIds.insert(itemId, at: i + 1)
|
||||
} else {
|
||||
itemIds.insert(itemId, at: i)
|
||||
}
|
||||
inserted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !inserted {
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
} else if beforeAll {
|
||||
itemIds.insert(itemId, at: 0)
|
||||
} else {
|
||||
itemIds.append(itemId)
|
||||
}
|
||||
return engine.peers.setForumChannelPinnedTopics(id: peerId, threadIds: itemIds)
|
||||
|> map { _ -> Bool in
|
||||
}
|
||||
|> `catch` { _ -> Signal<Bool, NoError> in
|
||||
return .single(false)
|
||||
}
|
||||
|> then(Signal<Bool, NoError>.single(true))
|
||||
} else {
|
||||
return .single(false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return .single(false)
|
||||
}
|
||||
}
|
||||
return .single(false)
|
||||
}
|
||||
var startedScrollingAtUpperBound = false
|
||||
|
||||
|
@ -386,6 +386,12 @@ func _internal_setForumChannelPinnedTopics(account: Account, id: EnginePeer.Id,
|
||||
return .fail(.generic)
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if "".isEmpty {
|
||||
return .complete()
|
||||
}
|
||||
#endif
|
||||
|
||||
return account.network.request(Api.functions.channels.reorderPinnedForumTopics(
|
||||
channel: inputChannel,
|
||||
order: threadIds.map(Int32.init(clamping:))
|
||||
|
@ -878,6 +878,12 @@ public extension TelegramEngine {
|
||||
}
|
||||
}
|
||||
|
||||
public func getForumChannelPinnedTopics(id: EnginePeer.Id) -> Signal<[Int64], NoError> {
|
||||
return self.account.postbox.transaction { transcation -> [Int64] in
|
||||
return transcation.getPeerPinnedThreads(peerId: id)
|
||||
}
|
||||
}
|
||||
|
||||
public func setForumChannelPinnedTopics(id: EnginePeer.Id, threadIds: [Int64]) -> Signal<Never, SetForumChannelTopicPinnedError> {
|
||||
return _internal_setForumChannelPinnedTopics(account: self.account, id: id, threadIds: threadIds)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user