mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
3f12448474
commit
c026f5af0b
@ -1150,9 +1150,33 @@ private final class ProfileGiftsContextImpl {
|
||||
self.actionDisposable.set(
|
||||
_internal_updateStarGiftAddedToProfile(account: self.account, reference: reference, added: added).startStrict()
|
||||
)
|
||||
|
||||
if let index = self.gifts.firstIndex(where: { $0.reference == reference }) {
|
||||
self.gifts[index] = self.gifts[index].withSavedToProfile(added)
|
||||
if !added && self.gifts[index].pinnedToTop {
|
||||
let pinnedGifts = self.gifts.filter { $0.pinnedToTop && $0.reference != reference }
|
||||
let existingGifts = Set(pinnedGifts.compactMap { $0.reference })
|
||||
|
||||
var updatedGifts: [ProfileGiftsContext.State.StarGift] = []
|
||||
for gift in self.gifts {
|
||||
if let reference = gift.reference, existingGifts.contains(reference) {
|
||||
continue
|
||||
}
|
||||
var gift = gift
|
||||
if gift.reference == reference {
|
||||
gift = gift.withPinnedToTop(false).withSavedToProfile(false)
|
||||
}
|
||||
updatedGifts.append(gift)
|
||||
}
|
||||
updatedGifts.sort { lhs, rhs in
|
||||
lhs.date > rhs.date
|
||||
}
|
||||
updatedGifts.insert(contentsOf: pinnedGifts, at: 0)
|
||||
self.gifts = updatedGifts
|
||||
} else {
|
||||
self.gifts[index] = self.gifts[index].withSavedToProfile(added)
|
||||
}
|
||||
}
|
||||
|
||||
if let index = self.filteredGifts.firstIndex(where: { $0.reference == reference }) {
|
||||
self.filteredGifts[index] = self.filteredGifts[index].withSavedToProfile(added)
|
||||
if !self.filter.contains(.hidden) && !added {
|
||||
@ -1164,9 +1188,14 @@ private final class ProfileGiftsContextImpl {
|
||||
|
||||
func updateStarGiftPinnedToTop(reference: StarGiftReference, pinnedToTop: Bool) {
|
||||
var pinnedGifts = self.gifts.filter { $0.pinnedToTop }
|
||||
var saveToProfile = false
|
||||
if var gift = self.gifts.first(where: { $0.reference == reference }) {
|
||||
gift = gift.withPinnedToTop(pinnedToTop)
|
||||
if pinnedToTop {
|
||||
if !gift.savedToProfile {
|
||||
gift = gift.withSavedToProfile(true)
|
||||
saveToProfile = true
|
||||
}
|
||||
pinnedGifts.append(gift)
|
||||
} else {
|
||||
pinnedGifts.removeAll(where: { $0.reference == reference })
|
||||
@ -1192,8 +1221,15 @@ private final class ProfileGiftsContextImpl {
|
||||
}
|
||||
self.pushState()
|
||||
|
||||
var signal = _internal_updateStarGiftsPinnedToTop(account: self.account, peerId: self.peerId, references: pinnedGifts.compactMap { $0.reference })
|
||||
|
||||
if saveToProfile {
|
||||
signal = _internal_updateStarGiftAddedToProfile(account: self.account, reference: reference, added: true)
|
||||
|> then(signal)
|
||||
}
|
||||
|
||||
self.actionDisposable.set(
|
||||
_internal_updateStarGiftsPinnedToTop(account: self.account, peerId: self.peerId, references: pinnedGifts.compactMap { $0.reference }).startStrict(completed: { [weak self] in
|
||||
(signal |> deliverOn(self.queue)).startStrict(completed: { [weak self] in
|
||||
self?.reload()
|
||||
})
|
||||
)
|
||||
@ -1201,13 +1237,19 @@ private final class ProfileGiftsContextImpl {
|
||||
|
||||
public func updatePinnedToTopStarGifts(references: [StarGiftReference]) {
|
||||
let existingGifts = Set(references)
|
||||
var saveSignals: [Signal<Never, NoError>] = []
|
||||
let currentPinnedGifts = self.gifts.filter { gift in
|
||||
if let reference = gift.reference {
|
||||
return existingGifts.contains(reference)
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}.map { $0.withPinnedToTop(true) }
|
||||
}.map { gift in
|
||||
if !gift.savedToProfile, let reference = gift.reference {
|
||||
saveSignals.append(_internal_updateStarGiftAddedToProfile(account: self.account, reference: reference, added: true))
|
||||
}
|
||||
return gift.withPinnedToTop(true).withSavedToProfile(true)
|
||||
}
|
||||
|
||||
var updatedGifts: [ProfileGiftsContext.State.StarGift] = []
|
||||
for gift in self.gifts {
|
||||
@ -1231,8 +1273,15 @@ private final class ProfileGiftsContextImpl {
|
||||
|
||||
self.pushState()
|
||||
|
||||
var signal = _internal_updateStarGiftsPinnedToTop(account: self.account, peerId: self.peerId, references: pinnedGifts.compactMap { $0.reference })
|
||||
if !saveSignals.isEmpty {
|
||||
signal = combineLatest(saveSignals)
|
||||
|> ignoreValues
|
||||
|> then(signal)
|
||||
}
|
||||
|
||||
self.actionDisposable.set(
|
||||
_internal_updateStarGiftsPinnedToTop(account: self.account, peerId: self.peerId, references: pinnedGifts.compactMap { $0.reference }).startStrict(completed: { [weak self] in
|
||||
(signal |> deliverOn(self.queue)).startStrict(completed: { [weak self] in
|
||||
self?.reload()
|
||||
})
|
||||
)
|
||||
|
@ -664,7 +664,7 @@ public final class GiftItemComponent: Component {
|
||||
|
||||
var iconBackgroundSize: CGSize?
|
||||
if component.isEditing {
|
||||
if !component.isPinned {
|
||||
if !component.isPinned && backgroundColor != nil {
|
||||
iconBackgroundSize = CGSize(width: 48.0, height: 48.0)
|
||||
}
|
||||
} else {
|
||||
@ -710,7 +710,7 @@ public final class GiftItemComponent: Component {
|
||||
iconBackground.layer.animateScale(from: 1.0, to: 0.01, duration: 0.2, removeOnCompletion: false)
|
||||
}
|
||||
|
||||
if component.isPinned || component.isEditing {
|
||||
if component.isPinned || (component.isEditing && backgroundColor != nil) {
|
||||
let pinnedIcon: UIImageView
|
||||
if let currentIcon = self.pinnedIcon {
|
||||
pinnedIcon = currentIcon
|
||||
|
@ -43,9 +43,11 @@ final class PeerInfoPaneTabsContainerPaneNode: ASDisplayNode {
|
||||
|
||||
private let titleNode: ImmediateTextNode
|
||||
private let buttonNode: HighlightTrackingButtonNode
|
||||
private var iconLayers: [InlineStickerItemLayer] = []
|
||||
private var iconLayers: [AnyHashable: InlineStickerItemLayer] = [:]
|
||||
|
||||
private var isSelected: Bool = false
|
||||
private var icons: [ProfileGiftsContext.State.StarGift] = []
|
||||
private var titleWidth: CGFloat?
|
||||
|
||||
init(pressed: @escaping () -> Void) {
|
||||
self.pressed = pressed
|
||||
@ -67,27 +69,53 @@ final class PeerInfoPaneTabsContainerPaneNode: ASDisplayNode {
|
||||
self.pressed()
|
||||
}
|
||||
|
||||
func updateText(context: AccountContext, title: String, icons: [TelegramMediaFile] = [], isSelected: Bool, presentationData: PresentationData) {
|
||||
func updateText(context: AccountContext, title: String, icons: [ProfileGiftsContext.State.StarGift] = [], isSelected: Bool, presentationData: PresentationData) {
|
||||
self.isSelected = isSelected
|
||||
self.titleNode.attributedText = NSAttributedString(string: title, font: Font.medium(14.0), textColor: isSelected ? presentationData.theme.list.itemAccentColor : presentationData.theme.list.itemSecondaryTextColor)
|
||||
self.icons = icons
|
||||
|
||||
if !icons.isEmpty {
|
||||
if self.iconLayers.isEmpty {
|
||||
for icon in icons {
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
var validIds = Set<AnyHashable>()
|
||||
var index = 0
|
||||
for icon in icons {
|
||||
let id: AnyHashable
|
||||
if let reference = icon.reference {
|
||||
id = reference
|
||||
} else {
|
||||
id = index
|
||||
}
|
||||
validIds.insert(id)
|
||||
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
if let _ = self.iconLayers[id] {
|
||||
|
||||
} else {
|
||||
var file: TelegramMediaFile?
|
||||
switch icon.gift {
|
||||
case let .generic(gift):
|
||||
file = gift.file
|
||||
case let .unique(gift):
|
||||
for attribute in gift.attributes {
|
||||
if case let .model(_, fileValue, _) = attribute {
|
||||
file = fileValue
|
||||
}
|
||||
}
|
||||
}
|
||||
guard let file else {
|
||||
continue
|
||||
}
|
||||
|
||||
let emoji = ChatTextInputTextCustomEmojiAttribute(
|
||||
interactivelySelectedFromPackId: nil,
|
||||
fileId: icon.fileId.id,
|
||||
file: icon
|
||||
fileId: file.fileId.id,
|
||||
file: file
|
||||
)
|
||||
|
||||
let animationLayer = InlineStickerItemLayer(
|
||||
context: .account(context),
|
||||
userLocation: .other,
|
||||
attemptSynchronousLoad: false,
|
||||
emoji: emoji,
|
||||
file: icon,
|
||||
file: file,
|
||||
cache: context.animationCache,
|
||||
renderer: context.animationRenderer,
|
||||
unique: true,
|
||||
@ -96,12 +124,30 @@ final class PeerInfoPaneTabsContainerPaneNode: ASDisplayNode {
|
||||
loopCount: 1
|
||||
)
|
||||
animationLayer.isVisibleForAnimations = true
|
||||
self.iconLayers.append(animationLayer)
|
||||
self.iconLayers[id] = animationLayer
|
||||
self.layer.addSublayer(animationLayer)
|
||||
|
||||
animationLayer.animateAlpha(from: 0.0, to: 1.0, duration: 0.2)
|
||||
animationLayer.animateScale(from: 0.01, to: 1.0, duration: 0.2)
|
||||
}
|
||||
index += 1
|
||||
}
|
||||
|
||||
var removeIds: [AnyHashable] = []
|
||||
for (id, layer) in self.iconLayers {
|
||||
if !validIds.contains(id) {
|
||||
removeIds.append(id)
|
||||
layer.animateScale(from: 1.0, to: 0.01, duration: 0.25, removeOnCompletion: false)
|
||||
layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.25, removeOnCompletion: false, completion: { _ in
|
||||
layer.removeFromSuperlayer()
|
||||
})
|
||||
}
|
||||
}
|
||||
for id in removeIds {
|
||||
self.iconLayers.removeValue(forKey: id)
|
||||
}
|
||||
} else {
|
||||
for layer in self.iconLayers {
|
||||
for (_, layer) in self.iconLayers {
|
||||
layer.removeFromSuperlayer()
|
||||
}
|
||||
self.iconLayers.removeAll()
|
||||
@ -115,24 +161,54 @@ final class PeerInfoPaneTabsContainerPaneNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
func updateLayout(height: CGFloat) -> CGFloat {
|
||||
var totalWidth: CGFloat = 0.0
|
||||
let titleSize = self.titleNode.updateLayout(CGSize(width: 200.0, height: .greatestFiniteMagnitude))
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
totalWidth = titleSize.width
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
let spacing: CGFloat = 1.0
|
||||
|
||||
self.titleNode.frame = CGRect(origin: CGPoint(x: 0.0, y: floor((height - titleSize.height) / 2.0)), size: titleSize)
|
||||
self.titleWidth = titleSize.width
|
||||
|
||||
var totalWidth = titleSize.width
|
||||
if !self.iconLayers.isEmpty {
|
||||
totalWidth += 2.0
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
let spacing: CGFloat = 1.0
|
||||
for iconlayer in self.iconLayers {
|
||||
iconlayer.frame = CGRect(origin: CGPoint(x: totalWidth, y: 15.0), size: iconSize)
|
||||
totalWidth += iconSize.width + spacing
|
||||
}
|
||||
totalWidth += (iconSize.width + spacing) * CGFloat(self.iconLayers.count)
|
||||
totalWidth -= spacing
|
||||
}
|
||||
|
||||
self.layoutIcons(transition: .animated(duration: 0.3, curve: .spring))
|
||||
|
||||
return totalWidth
|
||||
}
|
||||
|
||||
func layoutIcons(transition: ContainedViewLayoutTransition) {
|
||||
guard let titleWidth = self.titleWidth else {
|
||||
return
|
||||
}
|
||||
let iconSize = CGSize(width: 18.0, height: 18.0)
|
||||
let spacing: CGFloat = 1.0
|
||||
|
||||
var origin = CGPoint(x: titleWidth + 2.0, y: 15.0)
|
||||
|
||||
var index = 0
|
||||
for icon in self.icons {
|
||||
let id: AnyHashable
|
||||
if let reference = icon.reference {
|
||||
id = reference
|
||||
} else {
|
||||
id = index
|
||||
}
|
||||
if let layer = self.iconLayers[id] {
|
||||
var iconTransition = transition
|
||||
if layer.frame.width.isZero {
|
||||
iconTransition = .immediate
|
||||
}
|
||||
iconTransition.updateFrame(layer: layer, frame: CGRect(origin: origin, size: iconSize))
|
||||
}
|
||||
origin.x += iconSize.width + spacing
|
||||
index += 1
|
||||
}
|
||||
}
|
||||
|
||||
func updateArea(size: CGSize, sideInset: CGFloat) {
|
||||
self.buttonNode.frame = CGRect(origin: CGPoint(x: -sideInset, y: 0.0), size: CGSize(width: size.width + sideInset * 2.0, height: size.height))
|
||||
}
|
||||
@ -141,7 +217,7 @@ final class PeerInfoPaneTabsContainerPaneNode: ASDisplayNode {
|
||||
struct PeerInfoPaneSpecifier: Equatable {
|
||||
var key: PeerInfoPaneKey
|
||||
var title: String
|
||||
var icons: [TelegramMediaFile]
|
||||
var icons: [ProfileGiftsContext.State.StarGift]
|
||||
}
|
||||
|
||||
private func interpolateFrame(from fromValue: CGRect, to toValue: CGRect, t: CGFloat) -> CGRect {
|
||||
@ -1189,7 +1265,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
||||
|
||||
self.tabsContainerNode.update(size: CGSize(width: size.width - sideInset * 2.0, height: tabsHeight), presentationData: presentationData, paneList: availablePanes.map { key in
|
||||
let title: String
|
||||
var icons: [TelegramMediaFile] = []
|
||||
var icons: [ProfileGiftsContext.State.StarGift] = []
|
||||
switch key {
|
||||
case .stories:
|
||||
title = presentationData.strings.PeerInfo_PaneStories
|
||||
@ -1223,19 +1299,9 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, ASGestureRecognizerDelegat
|
||||
title = presentationData.strings.PeerInfo_SavedMessagesTabTitle
|
||||
case .gifts:
|
||||
title = presentationData.strings.PeerInfo_PaneGifts
|
||||
icons = data?.profileGiftsContext?.currentState?.gifts.prefix(3).compactMap { gift in
|
||||
switch gift.gift {
|
||||
case let .generic(gift):
|
||||
return gift.file
|
||||
case let .unique(gift):
|
||||
for attribute in gift.attributes {
|
||||
if case let .model(_, file, _) = attribute {
|
||||
return file
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
} ?? []
|
||||
if let gifts = data?.profileGiftsContext?.currentState?.gifts.prefix(3) {
|
||||
icons = Array(gifts)
|
||||
}
|
||||
}
|
||||
return PeerInfoPaneSpecifier(key: key, title: title, icons: icons)
|
||||
}, selectedPane: self.currentPaneKey, disableSwitching: disableTabSwitching, transitionFraction: self.transitionFraction, transition: transition)
|
||||
|
@ -76,7 +76,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
}
|
||||
|
||||
private var starsProducts: [ProfileGiftsContext.State.StarGift]?
|
||||
private var starsItems: [AnyHashable: (ProfileGiftsContext.State.StarGift, ComponentView<Empty>)] = [:]
|
||||
private var starsItems: [AnyHashable: (StarGiftReference?, ComponentView<Empty>)] = [:]
|
||||
private var resultsAreFiltered = false
|
||||
private var resultsAreEmpty = false
|
||||
|
||||
@ -90,6 +90,13 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
}
|
||||
private var reorderedReferencesPromise = ValuePromise<[StarGiftReference]?>(nil)
|
||||
|
||||
private var reorderedPinnedReferences: Set<StarGiftReference>? {
|
||||
didSet {
|
||||
self.reorderedPinnedReferencesPromise.set(self.reorderedPinnedReferences)
|
||||
}
|
||||
}
|
||||
private var reorderedPinnedReferencesPromise = ValuePromise<Set<StarGiftReference>?>(nil)
|
||||
|
||||
private var reorderRecognizer: ReorderGestureRecognizer?
|
||||
|
||||
private let maxPinnedCount: Int
|
||||
@ -136,17 +143,24 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
for reference in reorderedReferences {
|
||||
if let index = stateItems.firstIndex(where: { $0.reference == reference }) {
|
||||
seenIds.insert(reference)
|
||||
fixedStateItems.append(stateItems[index])
|
||||
var item = stateItems[index]
|
||||
if self.reorderedPinnedReferences?.contains(reference) == true, !item.pinnedToTop {
|
||||
item = item.withPinnedToTop(true)
|
||||
}
|
||||
fixedStateItems.append(item)
|
||||
}
|
||||
}
|
||||
|
||||
for item in stateItems {
|
||||
if let reference = item.reference, !seenIds.contains(reference) {
|
||||
var item = item
|
||||
if self.reorderedPinnedReferences?.contains(reference) == true, !item.pinnedToTop {
|
||||
item = item.withPinnedToTop(true)
|
||||
}
|
||||
fixedStateItems.append(item)
|
||||
}
|
||||
}
|
||||
stateItems = fixedStateItems
|
||||
//self.reorderedReferences = fixedStateItems.compactMap(\.reference)
|
||||
}
|
||||
self.starsProducts = stateItems
|
||||
self.pinnedReferences = Array(stateItems.filter { $0.pinnedToTop }.compactMap { $0.reference })
|
||||
@ -218,7 +232,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
private func item(at point: CGPoint) -> (AnyHashable, ComponentView<Empty>)? {
|
||||
let localPoint = self.scrollNode.view.convert(point, from: self.view)
|
||||
for (id, visibleItem) in self.starsItems {
|
||||
if let view = visibleItem.1.view, view.frame.contains(localPoint) {
|
||||
if let view = visibleItem.1.view, view.frame.contains(localPoint), let reference = visibleItem.0, self.pinnedReferences.contains(reference) {
|
||||
return (id, visibleItem.1)
|
||||
}
|
||||
}
|
||||
@ -258,6 +272,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
|
||||
Queue.mainQueue().after(1.0) {
|
||||
self.reorderedReferences = nil
|
||||
self.reorderedPinnedReferences = nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -281,7 +296,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
} else {
|
||||
self.reorderingItem = nil
|
||||
}
|
||||
self.updateScrolling(transition: .spring(duration: 0.3))
|
||||
self.updateScrolling(transition: item == nil ? .spring(duration: 0.3) : .immediate)
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,9 +311,9 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
if visibleItem.1 === visibleReorderingItem.1 {
|
||||
continue
|
||||
}
|
||||
if let view = visibleItem.1.view, view.frame.contains(targetPosition), let reorderItem = self.starsItems[id]?.0 {
|
||||
if let targetIndex = starsProducts.firstIndex(where: { $0.reference == visibleItem.0.reference }) {
|
||||
self.reorderIfPossible(item: reorderItem, toIndex: targetIndex)
|
||||
if let view = visibleItem.1.view, view.frame.contains(targetPosition), let reorderItemReference = self.starsItems[id]?.0 {
|
||||
if let targetIndex = starsProducts.firstIndex(where: { $0.reference == visibleItem.0 }) {
|
||||
self.reorderIfPossible(reference: reorderItemReference, toIndex: targetIndex)
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -307,7 +322,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
}
|
||||
}
|
||||
|
||||
private func reorderIfPossible(item: ProfileGiftsContext.State.StarGift, toIndex: Int) {
|
||||
private func reorderIfPossible(reference: StarGiftReference, toIndex: Int) {
|
||||
if let items = self.starsProducts {
|
||||
var toIndex = toIndex
|
||||
|
||||
@ -322,7 +337,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
return item.reference
|
||||
}
|
||||
|
||||
if let reference = item.reference, let fromIndex = ids.firstIndex(of: reference) {
|
||||
if let fromIndex = ids.firstIndex(of: reference) {
|
||||
if fromIndex < toIndex {
|
||||
ids.insert(reference, at: toIndex + 1)
|
||||
ids.remove(at: fromIndex)
|
||||
@ -401,7 +416,7 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
visibleItem = current
|
||||
} else {
|
||||
visibleItem = ComponentView()
|
||||
self.starsItems[itemId] = (product, visibleItem)
|
||||
self.starsItems[itemId] = (product.reference, visibleItem)
|
||||
itemTransition = .immediate
|
||||
}
|
||||
|
||||
@ -450,11 +465,38 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
isEditing: self.isReordering,
|
||||
mode: .profile,
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
guard let self, let presentationData = self.currentParams?.presentationData else {
|
||||
return
|
||||
}
|
||||
if self.isReordering {
|
||||
|
||||
if !product.pinnedToTop, let reference = product.reference, let items = self.starsProducts {
|
||||
if self.pinnedReferences.count >= self.maxPinnedCount {
|
||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(self.maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
return
|
||||
}
|
||||
|
||||
var reorderedPinnedReferences = Set<StarGiftReference>()
|
||||
if let current = self.reorderedPinnedReferences {
|
||||
reorderedPinnedReferences = current
|
||||
}
|
||||
reorderedPinnedReferences.insert(reference)
|
||||
self.reorderedPinnedReferences = reorderedPinnedReferences
|
||||
|
||||
if let maxPinnedIndex = items.lastIndex(where: { $0.pinnedToTop }) {
|
||||
var reorderedReferences: [StarGiftReference]
|
||||
if let current = self.reorderedReferences {
|
||||
reorderedReferences = current
|
||||
} else {
|
||||
let ids = items.compactMap { item -> StarGiftReference? in
|
||||
return item.reference
|
||||
}
|
||||
reorderedReferences = ids
|
||||
}
|
||||
reorderedReferences.removeAll(where: { $0 == reference })
|
||||
reorderedReferences.insert(reference, at: maxPinnedIndex + 1)
|
||||
self.reorderedReferences = reorderedReferences
|
||||
}
|
||||
}
|
||||
} else {
|
||||
let controller = GiftViewScreen(
|
||||
context: self.context,
|
||||
@ -517,10 +559,15 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
}
|
||||
}
|
||||
var itemFrame = itemFrame
|
||||
var isReordering = false
|
||||
if let reorderingItem = self.reorderingItem, itemId == reorderingItem.id {
|
||||
itemFrame = itemFrame.size.centered(around: reorderingItem.position)
|
||||
isReordering = true
|
||||
}
|
||||
if itemView.layer.animation(forKey: "position") != nil && !isReordering {
|
||||
} else {
|
||||
itemTransition.setFrame(view: itemView, frame: itemFrame)
|
||||
}
|
||||
itemTransition.setFrame(view: itemView, frame: itemFrame)
|
||||
|
||||
if self.isReordering && product.pinnedToTop {
|
||||
if itemView.layer.animation(forKey: "shaking_position") == nil {
|
||||
@ -933,34 +980,36 @@ public final class PeerInfoGiftsPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
|
||||
var items: [ContextMenuItem] = []
|
||||
if canManage {
|
||||
items.append(.action(ContextMenuActionItem(text: gift.pinnedToTop ? strings.PeerInfo_Gifts_Context_Unpin : strings.PeerInfo_Gifts_Context_Pin , icon: { theme in generateTintedImage(image: UIImage(bundleImageName: gift.pinnedToTop ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
c?.dismiss(completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let pinnedToTop = !gift.pinnedToTop
|
||||
|
||||
if pinnedToTop && self.pinnedReferences.count >= self.maxPinnedCount {
|
||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(self.maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
return
|
||||
}
|
||||
|
||||
if let reference = gift.reference {
|
||||
self.profileGifts.updateStarGiftPinnedToTop(reference: reference, pinnedToTop: pinnedToTop)
|
||||
}
|
||||
|
||||
let toastTitle: String?
|
||||
let toastText: String
|
||||
if !pinnedToTop {
|
||||
toastTitle = nil
|
||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastUnpinned_Text
|
||||
} else {
|
||||
toastTitle = presentationData.strings.PeerInfo_Gifts_ToastPinned_Title
|
||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastPinned_Text
|
||||
}
|
||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: !pinnedToTop ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
})
|
||||
})))
|
||||
if case .unique = gift.gift {
|
||||
items.append(.action(ContextMenuActionItem(text: gift.pinnedToTop ? strings.PeerInfo_Gifts_Context_Unpin : strings.PeerInfo_Gifts_Context_Pin , icon: { theme in generateTintedImage(image: UIImage(bundleImageName: gift.pinnedToTop ? "Chat/Context Menu/Unpin" : "Chat/Context Menu/Pin"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
c?.dismiss(completion: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
let pinnedToTop = !gift.pinnedToTop
|
||||
|
||||
if pinnedToTop && self.pinnedReferences.count >= self.maxPinnedCount {
|
||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.PeerInfo_Gifts_ToastPinLimit_Text(Int32(self.maxPinnedCount)), timeout: nil, customUndoText: nil), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
return
|
||||
}
|
||||
|
||||
if let reference = gift.reference {
|
||||
self.profileGifts.updateStarGiftPinnedToTop(reference: reference, pinnedToTop: pinnedToTop)
|
||||
}
|
||||
|
||||
let toastTitle: String?
|
||||
let toastText: String
|
||||
if !pinnedToTop {
|
||||
toastTitle = nil
|
||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastUnpinned_Text
|
||||
} else {
|
||||
toastTitle = presentationData.strings.PeerInfo_Gifts_ToastPinned_Title
|
||||
toastText = presentationData.strings.PeerInfo_Gifts_ToastPinned_Text
|
||||
}
|
||||
self.parentController?.present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: !pinnedToTop ? "anim_toastunpin" : "anim_toastpin", scale: 0.06, colors: [:], title: toastTitle, text: toastText, customUndoText: nil, timeout: 5), elevatedLayout: true, animateInAsReplacement: false, action: { _ in return false }), in: .window(.root))
|
||||
})
|
||||
})))
|
||||
}
|
||||
|
||||
if canReorder {
|
||||
items.append(.action(ContextMenuActionItem(text: strings.PeerInfo_Gifts_Context_Reorder, icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/ReorderItems"), color: theme.contextMenu.primaryColor) }, action: { [weak self] c, f in
|
||||
|
Loading…
x
Reference in New Issue
Block a user