mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Bot preview
This commit is contained in:
parent
9b49738353
commit
7ac40d5b78
@ -191,6 +191,10 @@ public final class SparseItemGrid: ASDisplayNode {
|
|||||||
preconditionFailure()
|
preconditionFailure()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open var isReorderable: Bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
public init() {
|
public init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1148,7 +1152,7 @@ public final class SparseItemGrid: ASDisplayNode {
|
|||||||
|
|
||||||
var itemScale: CGFloat
|
var itemScale: CGFloat
|
||||||
let itemCornerRadius: CGFloat
|
let itemCornerRadius: CGFloat
|
||||||
if self.isReordering {
|
if self.isReordering && item.isReorderable {
|
||||||
itemScale = (itemFrame.height - 6.0 * 2.0) / itemFrame.height
|
itemScale = (itemFrame.height - 6.0 * 2.0) / itemFrame.height
|
||||||
itemCornerRadius = 10.0
|
itemCornerRadius = 10.0
|
||||||
} else {
|
} else {
|
||||||
@ -1240,7 +1244,7 @@ public final class SparseItemGrid: ASDisplayNode {
|
|||||||
if let layer = item.layer {
|
if let layer = item.layer {
|
||||||
layer.update(size: layer.bounds.size, insets: layout.containerLayout.insets, displayItem: item, binding: items.itemBinding, item: contentItem)
|
layer.update(size: layer.bounds.size, insets: layout.containerLayout.insets, displayItem: item, binding: items.itemBinding, item: contentItem)
|
||||||
|
|
||||||
if self.isReordering {
|
if self.isReordering, let contentItem, contentItem.isReorderable {
|
||||||
if layer.animation(forKey: "shaking_position") == nil {
|
if layer.animation(forKey: "shaking_position") == nil {
|
||||||
startShaking(layer: layer)
|
startShaking(layer: layer)
|
||||||
}
|
}
|
||||||
|
@ -565,7 +565,7 @@ public struct StoryListContextState: Equatable {
|
|||||||
|
|
||||||
public var peerReference: PeerReference?
|
public var peerReference: PeerReference?
|
||||||
public var items: [Item]
|
public var items: [Item]
|
||||||
public var pinnedIds: Set<Int32>
|
public var pinnedIds: [Int32]
|
||||||
public var totalCount: Int
|
public var totalCount: Int
|
||||||
public var loadMoreToken: AnyHashable?
|
public var loadMoreToken: AnyHashable?
|
||||||
public var isCached: Bool
|
public var isCached: Bool
|
||||||
@ -575,7 +575,7 @@ public struct StoryListContextState: Equatable {
|
|||||||
public init(
|
public init(
|
||||||
peerReference: PeerReference?,
|
peerReference: PeerReference?,
|
||||||
items: [Item],
|
items: [Item],
|
||||||
pinnedIds: Set<Int32>,
|
pinnedIds: [Int32],
|
||||||
totalCount: Int,
|
totalCount: Int,
|
||||||
loadMoreToken: AnyHashable?,
|
loadMoreToken: AnyHashable?,
|
||||||
isCached: Bool,
|
isCached: Bool,
|
||||||
@ -633,7 +633,7 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
self.peerId = peerId
|
self.peerId = peerId
|
||||||
self.isArchived = isArchived
|
self.isArchived = isArchived
|
||||||
|
|
||||||
self.stateValue = State(peerReference: nil, items: [], pinnedIds: Set(), totalCount: 0, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: false, allEntityFiles: [:], isLoading: false)
|
self.stateValue = State(peerReference: nil, items: [], pinnedIds: [], totalCount: 0, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: false, allEntityFiles: [:], isLoading: false)
|
||||||
|
|
||||||
let _ = (account.postbox.transaction { transaction -> (PeerReference?, [State.Item], [Int32], Int, [MediaId: TelegramMediaFile], Bool) in
|
let _ = (account.postbox.transaction { transaction -> (PeerReference?, [State.Item], [Int32], Int, [MediaId: TelegramMediaFile], Bool) in
|
||||||
let key = ValueBoxKey(length: 8 + 1)
|
let key = ValueBoxKey(length: 8 + 1)
|
||||||
@ -723,17 +723,19 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var updatedState = State(peerReference: peerReference, items: items, pinnedIds: Set(pinnedIds), totalCount: totalCount, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: hasCache, allEntityFiles: allEntityFiles, isLoading: false)
|
var updatedState = State(peerReference: peerReference, items: items, pinnedIds: pinnedIds, totalCount: totalCount, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: hasCache, allEntityFiles: allEntityFiles, isLoading: false)
|
||||||
updatedState.items.sort(by: { lhs, rhs in
|
updatedState.items.sort(by: { lhs, rhs in
|
||||||
let lhsPinned = updatedState.pinnedIds.contains(lhs.storyItem.id)
|
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||||
let rhsPinned = updatedState.pinnedIds.contains(rhs.storyItem.id)
|
let rhsPinned = updatedState.pinnedIds.firstIndex(of: rhs.storyItem.id)
|
||||||
|
|
||||||
|
if let lhsPinned, let rhsPinned {
|
||||||
if lhsPinned != rhsPinned {
|
if lhsPinned != rhsPinned {
|
||||||
if lhsPinned {
|
return lhsPinned < rhsPinned
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
} else if (lhsPinned == nil) != (rhsPinned == nil) {
|
||||||
|
return lhsPinned != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
||||||
})
|
})
|
||||||
self.stateValue = updatedState
|
self.stateValue = updatedState
|
||||||
@ -862,7 +864,7 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
let key = ValueBoxKey(length: 8 + 1)
|
let key = ValueBoxKey(length: 8 + 1)
|
||||||
key.setInt64(0, value: peerId.toInt64())
|
key.setInt64(0, value: peerId.toInt64())
|
||||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: storyItems.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: Array(pinnedIds), totalCount: count)) {
|
if let entry = CodableEntry(CachedPeerStoryListHead(items: storyItems.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: count)) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1124,14 +1126,15 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||||
), peer: nil))
|
), peer: nil))
|
||||||
updatedState.items.sort(by: { lhs, rhs in
|
updatedState.items.sort(by: { lhs, rhs in
|
||||||
let lhsPinned = updatedState.pinnedIds.contains(lhs.storyItem.id)
|
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||||
let rhsPinned = updatedState.pinnedIds.contains(rhs.storyItem.id)
|
let rhsPinned = updatedState.pinnedIds.firstIndex(of: rhs.storyItem.id)
|
||||||
|
|
||||||
|
if let lhsPinned, let rhsPinned {
|
||||||
if lhsPinned != rhsPinned {
|
if lhsPinned != rhsPinned {
|
||||||
if lhsPinned {
|
return lhsPinned < rhsPinned
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
} else if (lhsPinned == nil) != (rhsPinned == nil) {
|
||||||
|
return lhsPinned != nil
|
||||||
}
|
}
|
||||||
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
||||||
})
|
})
|
||||||
@ -1180,14 +1183,15 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
author: item.authorId.flatMap { peers[$0].flatMap(EnginePeer.init) }
|
||||||
), peer: nil))
|
), peer: nil))
|
||||||
updatedState.items.sort(by: { lhs, rhs in
|
updatedState.items.sort(by: { lhs, rhs in
|
||||||
let lhsPinned = updatedState.pinnedIds.contains(lhs.storyItem.id)
|
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||||
let rhsPinned = updatedState.pinnedIds.contains(rhs.storyItem.id)
|
let rhsPinned = updatedState.pinnedIds.firstIndex(of: rhs.storyItem.id)
|
||||||
|
|
||||||
|
if let lhsPinned, let rhsPinned {
|
||||||
if lhsPinned != rhsPinned {
|
if lhsPinned != rhsPinned {
|
||||||
if lhsPinned {
|
return lhsPinned < rhsPinned
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
} else if (lhsPinned == nil) != (rhsPinned == nil) {
|
||||||
|
return lhsPinned != nil
|
||||||
}
|
}
|
||||||
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
||||||
})
|
})
|
||||||
@ -1204,18 +1208,19 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
case let .updatePinnedToTopList(peerId, ids):
|
case let .updatePinnedToTopList(peerId, ids):
|
||||||
if self.peerId == peerId && !self.isArchived {
|
if self.peerId == peerId && !self.isArchived {
|
||||||
let previousIds = (finalUpdatedState ?? self.stateValue).pinnedIds
|
let previousIds = (finalUpdatedState ?? self.stateValue).pinnedIds
|
||||||
if previousIds != Set(ids) {
|
if previousIds != ids {
|
||||||
var updatedState = finalUpdatedState ?? self.stateValue
|
var updatedState = finalUpdatedState ?? self.stateValue
|
||||||
updatedState.pinnedIds = Set(ids)
|
updatedState.pinnedIds = ids
|
||||||
updatedState.items.sort(by: { lhs, rhs in
|
updatedState.items.sort(by: { lhs, rhs in
|
||||||
let lhsPinned = updatedState.pinnedIds.contains(lhs.storyItem.id)
|
let lhsPinned = updatedState.pinnedIds.firstIndex(of: lhs.storyItem.id)
|
||||||
let rhsPinned = updatedState.pinnedIds.contains(rhs.storyItem.id)
|
let rhsPinned = updatedState.pinnedIds.firstIndex(of: rhs.storyItem.id)
|
||||||
|
|
||||||
|
if let lhsPinned, let rhsPinned {
|
||||||
if lhsPinned != rhsPinned {
|
if lhsPinned != rhsPinned {
|
||||||
if lhsPinned {
|
return lhsPinned < rhsPinned
|
||||||
return true
|
|
||||||
} else {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
} else if (lhsPinned == nil) != (rhsPinned == nil) {
|
||||||
|
return lhsPinned != nil
|
||||||
}
|
}
|
||||||
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
return lhs.storyItem.timestamp > rhs.storyItem.timestamp
|
||||||
})
|
})
|
||||||
@ -1235,7 +1240,7 @@ public final class PeerStoryListContext: StoryListContext {
|
|||||||
let key = ValueBoxKey(length: 8 + 1)
|
let key = ValueBoxKey(length: 8 + 1)
|
||||||
key.setInt64(0, value: peerId.toInt64())
|
key.setInt64(0, value: peerId.toInt64())
|
||||||
key.setInt8(8, value: isArchived ? 1 : 0)
|
key.setInt8(8, value: isArchived ? 1 : 0)
|
||||||
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: Array(pinnedIds), totalCount: Int32(totalCount))) {
|
if let entry = CodableEntry(CachedPeerStoryListHead(items: items.prefix(100).map { .item($0.storyItem.asStoryItem()) }, pinnedIds: pinnedIds, totalCount: Int32(totalCount))) {
|
||||||
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
transaction.putItemCacheEntry(id: ItemCacheEntryId(collectionId: Namespaces.CachedItemCollection.cachedPeerStoryListHeads, key: key), entry: entry)
|
||||||
}
|
}
|
||||||
}).start()
|
}).start()
|
||||||
@ -1308,7 +1313,7 @@ public final class SearchStoryListContext: StoryListContext {
|
|||||||
self.account = account
|
self.account = account
|
||||||
self.source = source
|
self.source = source
|
||||||
|
|
||||||
self.stateValue = State(peerReference: nil, items: [], pinnedIds: Set(), totalCount: 0, loadMoreToken: AnyHashable(""), isCached: false, hasCache: false, allEntityFiles: [:], isLoading: false)
|
self.stateValue = State(peerReference: nil, items: [], pinnedIds: [], totalCount: 0, loadMoreToken: AnyHashable(""), isCached: false, hasCache: false, allEntityFiles: [:], isLoading: false)
|
||||||
self.statePromise.set(.single(self.stateValue))
|
self.statePromise.set(.single(self.stateValue))
|
||||||
|
|
||||||
self.loadMore(completion: nil)
|
self.loadMore(completion: nil)
|
||||||
@ -2107,7 +2112,7 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||||||
|
|
||||||
self.isArchived = isArchived
|
self.isArchived = isArchived
|
||||||
|
|
||||||
self.stateValue = State(peerReference: nil, items: [], pinnedIds: Set(), totalCount: 0, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: false, allEntityFiles: [:], isLoading: false)
|
self.stateValue = State(peerReference: nil, items: [], pinnedIds: [], totalCount: 0, loadMoreToken: AnyHashable(0 as Int), isCached: true, hasCache: false, allEntityFiles: [:], isLoading: false)
|
||||||
|
|
||||||
let localStateKey: PostboxViewKey = .storiesState(key: .local)
|
let localStateKey: PostboxViewKey = .storiesState(key: .local)
|
||||||
|
|
||||||
@ -2222,7 +2227,7 @@ public final class BotPreviewStoryListContext: StoryListContext {
|
|||||||
self.stateValue = State(
|
self.stateValue = State(
|
||||||
peerReference: (peer?._asPeer()).flatMap(PeerReference.init),
|
peerReference: (peer?._asPeer()).flatMap(PeerReference.init),
|
||||||
items: items,
|
items: items,
|
||||||
pinnedIds: Set(),
|
pinnedIds: [],
|
||||||
totalCount: items.count,
|
totalCount: items.count,
|
||||||
loadMoreToken: nil,
|
loadMoreToken: nil,
|
||||||
isCached: botPreview != nil,
|
isCached: botPreview != nil,
|
||||||
|
@ -1305,7 +1305,7 @@ func peerInfoScreenData(context: AccountContext, peerId: PeerId, strings: Presen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let user = peerView.peers[peerView.peerId] as? TelegramUser, let botInfo = user.botInfo, botInfo.flags.contains(.canEdit) {
|
if let user = peerView.peers[peerView.peerId] as? TelegramUser, let botInfo = user.botInfo, botInfo.flags.contains(.hasWebApp), botInfo.flags.contains(.canEdit) {
|
||||||
availablePanes?.insert(.botPreview, at: 0)
|
availablePanes?.insert(.botPreview, at: 0)
|
||||||
} else if let cachedData = peerView.cachedData as? CachedUserData, let botPreview = cachedData.botPreview, !botPreview.media.isEmpty {
|
} else if let cachedData = peerView.cachedData as? CachedUserData, let botPreview = cachedData.botPreview, !botPreview.media.isEmpty {
|
||||||
availablePanes?.insert(.botPreview, at: 0)
|
availablePanes?.insert(.botPreview, at: 0)
|
||||||
|
@ -92,12 +92,16 @@ private final class VisualMediaItem: SparseItemGrid.Item {
|
|||||||
override var index: Int {
|
override var index: Int {
|
||||||
return self.indexValue
|
return self.indexValue
|
||||||
}
|
}
|
||||||
|
override var isReorderable: Bool {
|
||||||
|
return self.isReorderableValue
|
||||||
|
}
|
||||||
let localMonthTimestamp: Int32
|
let localMonthTimestamp: Int32
|
||||||
let peer: PeerReference
|
let peer: PeerReference
|
||||||
let storyId: StoryId
|
let storyId: StoryId
|
||||||
let story: EngineStoryItem
|
let story: EngineStoryItem
|
||||||
let authorPeer: EnginePeer?
|
let authorPeer: EnginePeer?
|
||||||
let isPinned: Bool
|
let isPinned: Bool
|
||||||
|
let isReorderableValue: Bool
|
||||||
|
|
||||||
override var id: AnyHashable {
|
override var id: AnyHashable {
|
||||||
return AnyHashable(self.storyId)
|
return AnyHashable(self.storyId)
|
||||||
@ -111,7 +115,7 @@ private final class VisualMediaItem: SparseItemGrid.Item {
|
|||||||
return VisualMediaHoleAnchor(index: self.index, storyId: self.storyId, localMonthTimestamp: self.localMonthTimestamp)
|
return VisualMediaHoleAnchor(index: self.index, storyId: self.storyId, localMonthTimestamp: self.localMonthTimestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(index: Int, peer: PeerReference, storyId: StoryId, story: EngineStoryItem, authorPeer: EnginePeer?, isPinned: Bool, localMonthTimestamp: Int32) {
|
init(index: Int, peer: PeerReference, storyId: StoryId, story: EngineStoryItem, authorPeer: EnginePeer?, isPinned: Bool, localMonthTimestamp: Int32, isReorderable: Bool) {
|
||||||
self.indexValue = index
|
self.indexValue = index
|
||||||
self.peer = peer
|
self.peer = peer
|
||||||
self.storyId = storyId
|
self.storyId = storyId
|
||||||
@ -119,6 +123,7 @@ private final class VisualMediaItem: SparseItemGrid.Item {
|
|||||||
self.authorPeer = authorPeer
|
self.authorPeer = authorPeer
|
||||||
self.isPinned = isPinned
|
self.isPinned = isPinned
|
||||||
self.localMonthTimestamp = localMonthTimestamp
|
self.localMonthTimestamp = localMonthTimestamp
|
||||||
|
self.isReorderableValue = isReorderable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2453,6 +2458,18 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}
|
}
|
||||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: isPinned ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: isPinned ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return false }), in: .current)
|
||||||
})))
|
})))
|
||||||
|
if isPinned {
|
||||||
|
//TODO:localize
|
||||||
|
items.append(.action(ContextMenuActionItem(text: "Reorder", icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in
|
||||||
|
c?.dismiss(completion: {
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
self.beginReordering()
|
||||||
|
})
|
||||||
|
})))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.StoryList_ItemAction_Edit, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in
|
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.StoryList_ItemAction_Edit, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Edit"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, _ in
|
||||||
@ -2769,6 +2786,18 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isReorderable = false
|
||||||
|
switch self.scope {
|
||||||
|
case .botPreview:
|
||||||
|
isReorderable = !item.storyItem.isPending
|
||||||
|
case let .peer(id, _, _):
|
||||||
|
if id == self.context.account.peerId {
|
||||||
|
isReorderable = state.pinnedIds.contains(item.storyItem.id)
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
mappedItems.append(VisualMediaItem(
|
mappedItems.append(VisualMediaItem(
|
||||||
index: mappedItems.count,
|
index: mappedItems.count,
|
||||||
peer: peerReference,
|
peer: peerReference,
|
||||||
@ -2776,7 +2805,8 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
story: item.storyItem,
|
story: item.storyItem,
|
||||||
authorPeer: item.peer,
|
authorPeer: item.peer,
|
||||||
isPinned: state.pinnedIds.contains(item.storyItem.id),
|
isPinned: state.pinnedIds.contains(item.storyItem.id),
|
||||||
localMonthTimestamp: Month(localTimestamp: item.storyItem.timestamp + timezoneOffset).packedValue
|
localMonthTimestamp: Month(localTimestamp: item.storyItem.timestamp + timezoneOffset).packedValue,
|
||||||
|
isReorderable: isReorderable
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
if mappedItems.count < state.totalCount, let lastItem = state.items.last, let _ = state.loadMoreToken {
|
if mappedItems.count < state.totalCount, let lastItem = state.items.last, let _ = state.loadMoreToken {
|
||||||
@ -2809,7 +2839,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
|
|
||||||
let currentSynchronous = synchronous && firstTime
|
let currentSynchronous = synchronous && firstTime
|
||||||
let currentReloadAtTop = reloadAtTop && firstTime
|
let currentReloadAtTop = reloadAtTop && firstTime
|
||||||
self.updateHistory(items: items, pinnedIds: state.pinnedIds, synchronous: currentSynchronous, reloadAtTop: currentReloadAtTop, animated: animated)
|
self.updateHistory(items: items, pinnedIds: Set(state.pinnedIds), synchronous: currentSynchronous, reloadAtTop: currentReloadAtTop, animated: animated)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func updateHistory(items: SparseItemGrid.Items, pinnedIds: Set<Int32>, synchronous: Bool, reloadAtTop: Bool, animated: Bool) {
|
private func updateHistory(items: SparseItemGrid.Items, pinnedIds: Set<Int32>, synchronous: Bool, reloadAtTop: Bool, animated: Bool) {
|
||||||
@ -2845,13 +2875,31 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func reorderIfPossible(item: SparseItemGrid.Item, toIndex: Int) {
|
private func reorderIfPossible(item: SparseItemGrid.Item, toIndex: Int) {
|
||||||
if case .botPreview = self.scope, let items = self.items, let item = item as? VisualMediaItem {
|
if let items = self.items, let item = item as? VisualMediaItem {
|
||||||
|
var toIndex = toIndex
|
||||||
|
if case .botPreview = self.scope {
|
||||||
|
} else if case let .peer(id, _, _) = self.scope {
|
||||||
|
if id == self.context.account.peerId {
|
||||||
|
let maxPinnedIndex = items.items.lastIndex(where: { ($0 as? VisualMediaItem)?.isPinned == true })
|
||||||
|
if let maxPinnedIndex {
|
||||||
|
toIndex = min(toIndex, maxPinnedIndex)
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
guard let toItem = items.items.first(where: { $0.index == toIndex }) as? VisualMediaItem else {
|
guard let toItem = items.items.first(where: { $0.index == toIndex }) as? VisualMediaItem else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if item.story.isPending || toItem.story.isPending {
|
if item.story.isPending || toItem.story.isPending {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if !item.isReorderable {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var ids = items.items.compactMap { item -> StoryId? in
|
var ids = items.items.compactMap { item -> StoryId? in
|
||||||
return (item as? VisualMediaItem)?.storyId
|
return (item as? VisualMediaItem)?.storyId
|
||||||
@ -3980,6 +4028,21 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, ASScr
|
|||||||
self.reorderedIds = nil
|
self.reorderedIds = nil
|
||||||
if case .botPreview = self.scope, let listSource = self.listSource as? BotPreviewStoryListContext {
|
if case .botPreview = self.scope, let listSource = self.listSource as? BotPreviewStoryListContext {
|
||||||
listSource.reorderItems(ids: reorderedIds)
|
listSource.reorderItems(ids: reorderedIds)
|
||||||
|
} else if case let .peer(id, _, _) = self.scope, id == self.context.account.peerId, let items = self.items {
|
||||||
|
var updatedPinnedIds: [Int32] = []
|
||||||
|
for id in reorderedIds {
|
||||||
|
inner: for item in items.items {
|
||||||
|
if let item = item as? VisualMediaItem {
|
||||||
|
if item.storyId == id {
|
||||||
|
if item.isPinned {
|
||||||
|
updatedPinnedIds.append(id.id)
|
||||||
|
break inner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let _ = self.context.engine.messages.updatePinnedToTopStories(peerId: id, ids: updatedPinnedIds).startStandalone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user