mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit '0ae2f9b53a2b0c1d369492dfb9c2bb36f6ea6e8d' into beta
This commit is contained in:
commit
a47dd6ff9e
submodules
MediaPickerUI/Sources
PremiumUI/Sources
TelegramCore/Sources
TelegramUI
Components
CameraScreen/Sources
Gifts
GiftStoreScreen/Sources
GiftViewScreen/Sources
PeerInfo/PeerInfoScreen/Sources
Stars/StarsWithdrawalScreen/Sources
Sources
@ -528,29 +528,7 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
if case let .assets(_, mode) = controller.subject, [.wallpaper, .story, .addImage, .cover, .createSticker, .createAvatar].contains(mode) {
|
||||
|
||||
} else {
|
||||
let selectionGesture = MediaPickerGridSelectionGesture<TGMediaSelectableItem>()
|
||||
selectionGesture.delegate = self.wrappedGestureRecognizerDelegate
|
||||
selectionGesture.began = { [weak self] in
|
||||
self?.controller?.cancelPanGesture()
|
||||
}
|
||||
selectionGesture.updateIsScrollEnabled = { [weak self] isEnabled in
|
||||
self?.gridNode.scrollView.isScrollEnabled = isEnabled
|
||||
}
|
||||
selectionGesture.itemAt = { [weak self] point in
|
||||
if let self, let itemNode = self.gridNode.itemNodeAtPoint(point) as? MediaPickerGridItemNode, let selectableItem = itemNode.selectableItem {
|
||||
return (selectableItem, self.controller?.interaction?.selectionState?.isIdentifierSelected(selectableItem.uniqueIdentifier) ?? false)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
selectionGesture.updateSelection = { [weak self] asset, selected in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controller?.interaction?.selectionState?.setItem(asset, selected: selected, animated: true, sender: nil)
|
||||
}
|
||||
}
|
||||
selectionGesture.sideInset = 44.0
|
||||
self.gridNode.view.addGestureRecognizer(selectionGesture)
|
||||
self.selectionGesture = selectionGesture
|
||||
self.setupSelectionGesture()
|
||||
}
|
||||
|
||||
if let controller = self.controller, case let .assets(collection, _) = controller.subject, collection != nil {
|
||||
@ -713,6 +691,35 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
}
|
||||
}
|
||||
|
||||
func setupSelectionGesture() {
|
||||
guard self.selectionGesture == nil else {
|
||||
return
|
||||
}
|
||||
let selectionGesture = MediaPickerGridSelectionGesture<TGMediaSelectableItem>()
|
||||
selectionGesture.delegate = self.wrappedGestureRecognizerDelegate
|
||||
selectionGesture.began = { [weak self] in
|
||||
self?.controller?.cancelPanGesture()
|
||||
}
|
||||
selectionGesture.updateIsScrollEnabled = { [weak self] isEnabled in
|
||||
self?.gridNode.scrollView.isScrollEnabled = isEnabled
|
||||
}
|
||||
selectionGesture.itemAt = { [weak self] point in
|
||||
if let self, let itemNode = self.gridNode.itemNodeAtPoint(point) as? MediaPickerGridItemNode, let selectableItem = itemNode.selectableItem {
|
||||
return (selectableItem, self.controller?.interaction?.selectionState?.isIdentifierSelected(selectableItem.uniqueIdentifier) ?? false)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
selectionGesture.updateSelection = { [weak self] asset, selected in
|
||||
if let strongSelf = self {
|
||||
strongSelf.controller?.interaction?.selectionState?.setItem(asset, selected: selected, animated: true, sender: nil)
|
||||
}
|
||||
}
|
||||
selectionGesture.sideInset = 44.0
|
||||
self.gridNode.view.addGestureRecognizer(selectionGesture)
|
||||
self.selectionGesture = selectionGesture
|
||||
}
|
||||
|
||||
@objc private func cameraTapped() {
|
||||
guard let camera = self.modernCamera, let previewView = self.modernCameraView else {
|
||||
return
|
||||
@ -2352,9 +2359,6 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
let transition = ContainedViewLayoutTransition.animated(duration: 0.25, curve: .easeInOut)
|
||||
var moreIsVisible = false
|
||||
if case let .assets(_, mode) = self.subject, [.story, .createSticker].contains(mode) {
|
||||
if count == 1 {
|
||||
self.requestAttachmentMenuExpansion()
|
||||
}
|
||||
moreIsVisible = true
|
||||
} else if case let .media(media) = self.subject {
|
||||
self.titleView.title = media.count == 1 ? self.presentationData.strings.Attachment_Pasteboard : self.presentationData.strings.Attachment_SelectedMedia(count)
|
||||
@ -2618,6 +2622,8 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
||||
|
||||
self.navigationItem.setRightBarButton(nil, animated: true)
|
||||
self.explicitMultipleSelection = true
|
||||
self.controllerNode.setupSelectionGesture()
|
||||
self.requestAttachmentMenuExpansion()
|
||||
|
||||
if let state = self.controllerNode.state {
|
||||
self.controllerNode.updateState(state)
|
||||
|
@ -1108,6 +1108,10 @@ private final class SheetContent: CombinedComponent {
|
||||
func layoutLevel(_ level: Int32) {
|
||||
var perks: [LevelSectionComponent.Perk] = []
|
||||
|
||||
if !isGroup && level >= requiredBoostSubjectLevel(subject: .autoTranslate, group: isGroup, context: component.context, configuration: premiumConfiguration) {
|
||||
perks.append(.autoTranslate)
|
||||
}
|
||||
|
||||
perks.append(.story(level))
|
||||
|
||||
if !isGroup {
|
||||
@ -1171,12 +1175,6 @@ private final class SheetContent: CombinedComponent {
|
||||
if !isGroup && level >= requiredBoostSubjectLevel(subject: .noAds, group: isGroup, context: component.context, configuration: premiumConfiguration) {
|
||||
perks.append(.noAds)
|
||||
}
|
||||
if !isGroup && level >= requiredBoostSubjectLevel(subject: .autoTranslate, group: isGroup, context: component.context, configuration: premiumConfiguration) {
|
||||
perks.append(.autoTranslate)
|
||||
}
|
||||
// if !isGroup && level >= requiredBoostSubjectLevel(subject: .wearGift, group: isGroup, context: component.context, configuration: premiumConfiguration) {
|
||||
// perks.append(.wearGift)
|
||||
// }
|
||||
|
||||
levelItems.append(
|
||||
AnyComponentWithIdentity(
|
||||
|
@ -103,6 +103,10 @@ private final class FetchImpl {
|
||||
init(range: Range<Int64>) {
|
||||
self.range = range
|
||||
}
|
||||
|
||||
deinit {
|
||||
self.disposable?.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
private final class HashRangeData {
|
||||
|
@ -2494,7 +2494,7 @@ private final class ResaleGiftsContextImpl {
|
||||
let filterAttributes = self.filterAttributes
|
||||
let currentAttributesHash = self.attributesHash
|
||||
|
||||
let dataState = self.dataState
|
||||
let dataState = self.dataState
|
||||
|
||||
if case let .ready(true, initialNextOffset) = dataState {
|
||||
self.dataState = .loading
|
||||
|
@ -2553,6 +2553,8 @@ public class CameraScreenImpl: ViewController, CameraScreen {
|
||||
transitionCircleLayer.animateScale(from: sourceLocalFrame.width / 320.0, to: 6.0, duration: 0.6, timingFunction: kCAMediaTimingFunctionSpring, removeOnCompletion: false, completion: { _ in
|
||||
self.view.mask = nil
|
||||
colorFillView.removeFromSuperview()
|
||||
|
||||
self.requestUpdateLayout(hasAppeared: true, transition: .immediate)
|
||||
})
|
||||
} else {
|
||||
if case .story = controller.mode {
|
||||
|
@ -95,7 +95,8 @@ final class GiftStoreScreenComponent: Component {
|
||||
|
||||
private var starsStateDisposable: Disposable?
|
||||
private var starsState: StarsContext.State?
|
||||
private var initialCount: Int?
|
||||
private var initialCount: Int32?
|
||||
private var showLoading = true
|
||||
|
||||
private var component: GiftStoreScreenComponent?
|
||||
private(set) weak var state: State?
|
||||
@ -338,7 +339,9 @@ final class GiftStoreScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes([])
|
||||
self.scrollToTop()
|
||||
},
|
||||
animateScale: false
|
||||
)
|
||||
@ -357,7 +360,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
var emptyResultsActionFrame = CGRect(
|
||||
origin: CGPoint(
|
||||
x: floorToScreenPixels((availableWidth - emptyResultsActionSize.width) / 2.0),
|
||||
y: max(self.scrollView.contentSize.height - 8.0, availableHeight - bottomInset - emptyResultsActionSize.height - 16.0)
|
||||
y: max(self.scrollView.contentSize.height - 70.0, availableHeight - bottomInset - emptyResultsActionSize.height - 16.0)
|
||||
),
|
||||
size: emptyResultsActionSize
|
||||
)
|
||||
@ -435,7 +438,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
if view.superview == nil {
|
||||
view.alpha = 0.0
|
||||
fadeTransition.setAlpha(view: view, alpha: 1.0)
|
||||
self.insertSubview(view, belowSubview: self.loadingNode.view)
|
||||
self.scrollView.addSubview(view)
|
||||
}
|
||||
view.bounds = CGRect(origin: .zero, size: emptyResultsActionFrame.size)
|
||||
ComponentTransition.immediate.setPosition(view: view, position: emptyResultsActionFrame.center)
|
||||
@ -451,7 +454,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
}
|
||||
|
||||
let bottomContentOffset = max(0.0, self.scrollView.contentSize.height - self.scrollView.contentOffset.y - self.scrollView.frame.height)
|
||||
if interactive, bottomContentOffset < 320.0 {
|
||||
if interactive, bottomContentOffset < 1000.0 {
|
||||
self.state?.starGiftsContext.loadMore()
|
||||
}
|
||||
}
|
||||
@ -471,6 +474,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateSorting(.value)
|
||||
self.scrollToTop()
|
||||
})))
|
||||
@ -481,6 +485,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateSorting(.date)
|
||||
self.scrollToTop()
|
||||
})))
|
||||
@ -491,6 +496,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateSorting(.number)
|
||||
self.scrollToTop()
|
||||
})))
|
||||
@ -514,7 +520,13 @@ final class GiftStoreScreenComponent: Component {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}.sorted(by: { lhs, rhs in
|
||||
if case let .model(_, lhsFile, _) = lhs, case let .model(_, rhsFile, _) = rhs, let lhsCount = self.state?.starGiftsState?.attributeCount[.model(lhsFile.fileId.id)], let rhsCount = self.state?.starGiftsState?.attributeCount[.model(rhsFile.fileId.id)] {
|
||||
return lhsCount > rhsCount
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
let currentFilterAttributes = self.state?.starGiftsState?.filterAttributes ?? []
|
||||
let selectedModelAttributes = currentFilterAttributes.filter { attribute in
|
||||
@ -564,6 +576,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
updatedFilterAttributes.append(attribute)
|
||||
}
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
},
|
||||
@ -577,6 +590,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
}
|
||||
return true
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
}
|
||||
@ -607,7 +621,13 @@ final class GiftStoreScreenComponent: Component {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}.sorted(by: { lhs, rhs in
|
||||
if case let .backdrop(_, lhsId, _, _, _, _, _) = lhs, case let .backdrop(_, rhsId, _, _, _, _, _) = rhs, let lhsCount = self.state?.starGiftsState?.attributeCount[.backdrop(lhsId)], let rhsCount = self.state?.starGiftsState?.attributeCount[.backdrop(rhsId)] {
|
||||
return lhsCount > rhsCount
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
let currentFilterAttributes = self.state?.starGiftsState?.filterAttributes ?? []
|
||||
let selectedBackdropAttributes = currentFilterAttributes.filter { attribute in
|
||||
@ -657,6 +677,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
updatedFilterAttributes.append(attribute)
|
||||
}
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
},
|
||||
@ -670,6 +691,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
}
|
||||
return true
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
}
|
||||
@ -700,7 +722,13 @@ final class GiftStoreScreenComponent: Component {
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}.sorted(by: { lhs, rhs in
|
||||
if case let .pattern(_, lhsFile, _) = lhs, case let .pattern(_, rhsFile, _) = rhs, let lhsCount = self.state?.starGiftsState?.attributeCount[.pattern(lhsFile.fileId.id)], let rhsCount = self.state?.starGiftsState?.attributeCount[.pattern(rhsFile.fileId.id)] {
|
||||
return lhsCount > rhsCount
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
|
||||
let currentFilterAttributes = self.state?.starGiftsState?.filterAttributes ?? []
|
||||
let selectedPatternAttributes = currentFilterAttributes.filter { attribute in
|
||||
@ -750,6 +778,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
updatedFilterAttributes.append(attribute)
|
||||
}
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
},
|
||||
@ -763,6 +792,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
}
|
||||
return true
|
||||
}
|
||||
self.showLoading = true
|
||||
self.state?.starGiftsContext.updateFilterAttributes(updatedFilterAttributes)
|
||||
self.scrollToTop()
|
||||
}
|
||||
@ -804,6 +834,12 @@ final class GiftStoreScreenComponent: Component {
|
||||
self.component = component
|
||||
|
||||
let isLoading = self.effectiveIsLoading
|
||||
if case let .ready(loadMore, nextOffset) = self.state?.starGiftsState?.dataState {
|
||||
if loadMore && nextOffset == nil {
|
||||
} else {
|
||||
self.showLoading = false
|
||||
}
|
||||
}
|
||||
|
||||
let theme = environment.theme
|
||||
let strings = environment.strings
|
||||
@ -812,7 +848,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
self.backgroundColor = environment.theme.list.blocksBackgroundColor
|
||||
}
|
||||
|
||||
let bottomContentInset: CGFloat = 24.0
|
||||
let bottomContentInset: CGFloat = 56.0
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
let headerSideInset: CGFloat = 24.0 + environment.safeInsets.left
|
||||
|
||||
@ -927,7 +963,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
}
|
||||
|
||||
let effectiveCount: Int32
|
||||
if let count = self.effectiveGifts?.count, count > 0 || self.initialCount != nil {
|
||||
if let count = self.state?.starGiftsState?.count, count > 0 || self.initialCount != nil {
|
||||
if self.initialCount == nil {
|
||||
self.initialCount = count
|
||||
}
|
||||
@ -1047,6 +1083,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
|
||||
let loadingTransition: ComponentTransition = .easeInOut(duration: 0.25)
|
||||
|
||||
var showingFilters = false
|
||||
let filterSize = self.filterSelector.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(FilterSelectorComponent(
|
||||
@ -1069,6 +1106,7 @@ final class GiftStoreScreenComponent: Component {
|
||||
|
||||
if let initialCount = self.initialCount, initialCount >= minimumCountToDisplayFilters {
|
||||
loadingTransition.setAlpha(view: filterSelectorView, alpha: 1.0)
|
||||
showingFilters = true
|
||||
}
|
||||
}
|
||||
|
||||
@ -1112,8 +1150,8 @@ final class GiftStoreScreenComponent: Component {
|
||||
|
||||
self.updateScrolling(transition: transition)
|
||||
|
||||
if isLoading {
|
||||
self.loadingNode.update(size: availableSize, theme: environment.theme, transition: .immediate)
|
||||
if isLoading && self.showLoading {
|
||||
self.loadingNode.update(size: availableSize, theme: environment.theme, showFilters: !showingFilters, transition: .immediate)
|
||||
loadingTransition.setAlpha(view: self.loadingNode.view, alpha: 1.0)
|
||||
} else {
|
||||
loadingTransition.setAlpha(view: self.loadingNode.view, alpha: 0.0)
|
||||
|
@ -125,7 +125,7 @@ final class LoadingShimmerNode: ASDisplayNode {
|
||||
private let backgroundColorNode: ASDisplayNode
|
||||
private let effectNode: SearchShimmerEffectNode
|
||||
private let maskNode: ASImageNode
|
||||
private var currentParams: (size: CGSize, theme: PresentationTheme)?
|
||||
private var currentParams: (size: CGSize, theme: PresentationTheme, showFilters: Bool)?
|
||||
|
||||
override init() {
|
||||
self.backgroundColorNode = ASDisplayNode()
|
||||
@ -142,11 +142,11 @@ final class LoadingShimmerNode: ASDisplayNode {
|
||||
self.addSubnode(self.maskNode)
|
||||
}
|
||||
|
||||
func update(size: CGSize, theme: PresentationTheme, transition: ContainedViewLayoutTransition) {
|
||||
func update(size: CGSize, theme: PresentationTheme, showFilters: Bool, transition: ContainedViewLayoutTransition) {
|
||||
let color = theme.list.itemSecondaryTextColor.mixedWith(theme.list.blocksBackgroundColor, alpha: 0.85)
|
||||
|
||||
if self.currentParams?.size != size || self.currentParams?.theme !== theme {
|
||||
self.currentParams = (size, theme)
|
||||
if self.currentParams?.size != size || self.currentParams?.theme !== theme || self.currentParams?.showFilters != showFilters {
|
||||
self.currentParams = (size, theme, showFilters)
|
||||
|
||||
self.backgroundColorNode.backgroundColor = color
|
||||
|
||||
@ -156,10 +156,12 @@ final class LoadingShimmerNode: ASDisplayNode {
|
||||
|
||||
let sideInset: CGFloat = 16.0
|
||||
|
||||
let filterSpacing: CGFloat = 6.0
|
||||
let filterWidth = (size.width - sideInset * 2.0 - filterSpacing * 3.0) / 4.0
|
||||
for i in 0 ..< 4 {
|
||||
context.addPath(CGPath(roundedRect: CGRect(origin: CGPoint(x: sideInset + (filterWidth + filterSpacing) * CGFloat(i), y: 0.0), size: CGSize(width: filterWidth, height: 28.0)), cornerWidth: 14.0, cornerHeight: 14.0, transform: nil))
|
||||
if showFilters {
|
||||
let filterSpacing: CGFloat = 6.0
|
||||
let filterWidth = (size.width - sideInset * 2.0 - filterSpacing * 3.0) / 4.0
|
||||
for i in 0 ..< 4 {
|
||||
context.addPath(CGPath(roundedRect: CGRect(origin: CGPoint(x: sideInset + (filterWidth + filterSpacing) * CGFloat(i), y: 0.0), size: CGSize(width: filterWidth, height: 28.0)), cornerWidth: 14.0, cornerHeight: 14.0, transform: nil))
|
||||
}
|
||||
}
|
||||
|
||||
var currentY: CGFloat = 39.0 + 7.0
|
||||
|
@ -958,7 +958,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
||||
|
||||
let location = CGRect(origin: CGPoint(x: absoluteLocation.x, y: absoluteLocation.y - 12.0), size: CGSize())
|
||||
let tooltipController = TooltipScreen(account: self.context.account, sharedContext: self.context.sharedContext, text: .plain(text: text), style: .wide, location: .point(location, .bottom), displayDuration: .default, inset: 16.0, shouldDismissOnTouch: { _, _ in
|
||||
return .ignore
|
||||
return .dismiss(consume: false)
|
||||
})
|
||||
controller.present(tooltipController, in: .current)
|
||||
}
|
||||
|
@ -2164,7 +2164,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
let ItemBanned = 11
|
||||
let ItemRecentActions = 12
|
||||
let ItemAffiliatePrograms = 13
|
||||
let ItemPostSuggestionsSettings = 14
|
||||
//let ItemPostSuggestionsSettings = 14
|
||||
let ItemPeerAutoTranslate = 15
|
||||
|
||||
let isCreator = channel.flags.contains(.isCreator)
|
||||
@ -2214,9 +2214,9 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
||||
}))
|
||||
|
||||
//TODO:localize
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .text("Off"), additionalBadgeLabel: presentationData.strings.Settings_New, text: "Post Suggestions", icon: UIImage(bundleImageName: "Chat/Info/PostSuggestionsIcon"), action: {
|
||||
/*items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .text("Off"), additionalBadgeLabel: presentationData.strings.Settings_New, text: "Post Suggestions", icon: UIImage(bundleImageName: "Chat/Info/PostSuggestionsIcon"), action: {
|
||||
interaction.editingOpenPostSuggestionsSetup()
|
||||
}))
|
||||
}))*/
|
||||
}
|
||||
|
||||
if isCreator || (channel.adminRights?.rights.contains(.canChangeInfo) == true) {
|
||||
|
@ -279,7 +279,7 @@ private final class SheetContent: CombinedComponent {
|
||||
case .starGiftResell:
|
||||
let amountInfoString: NSAttributedString
|
||||
if let value = state.amount?.value, value > 0 {
|
||||
let starsValue = Int32(floor(Float(value) * Float(resaleConfiguration.paidMessageCommissionPermille) / 1000.0))
|
||||
let starsValue = Int32(floor(Float(value) * Float(resaleConfiguration.starGiftCommissionPermille) / 1000.0))
|
||||
let starsString = environment.strings.Stars_SellGift_AmountInfo_Stars(starsValue)
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SellGift_AmountInfo(starsString).string, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
|
||||
@ -288,7 +288,7 @@ private final class SheetContent: CombinedComponent {
|
||||
amountRightLabel = "≈\(formatTonUsdValue(Int64(starsValue), divide: false, rate: usdRate, dateTimeFormat: environment.dateTimeFormat))"
|
||||
}
|
||||
} else {
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SellGift_AmountInfo("\(resaleConfiguration.paidMessageCommissionPermille / 10)%").string, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
amountInfoString = NSAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.Stars_SellGift_AmountInfo("\(resaleConfiguration.starGiftCommissionPermille / 10)%").string, attributes: amountMarkdownAttributes, textAlignment: .natural))
|
||||
}
|
||||
amountFooter = AnyComponent(MultilineTextComponent(
|
||||
text: .plain(amountInfoString),
|
||||
|
@ -539,6 +539,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
var customEmojiContainerView: CustomEmojiContainerView?
|
||||
|
||||
let textInputBackgroundNode: ASImageNode
|
||||
var textInputBackgroundTapRecognizer: TouchDownGestureRecognizer?
|
||||
private var transparentTextInputBackgroundImage: UIImage?
|
||||
let actionButtons: ChatTextInputActionButtonsNode
|
||||
private let slowModeButton: BoostSlowModeButton
|
||||
@ -1089,6 +1090,7 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
return false
|
||||
}
|
||||
}
|
||||
self.textInputBackgroundTapRecognizer = recognizer
|
||||
self.textInputBackgroundNode.isUserInteractionEnabled = true
|
||||
self.textInputBackgroundNode.view.addGestureRecognizer(recognizer)
|
||||
|
||||
@ -1166,6 +1168,11 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
textInputNode.isUserInteractionEnabled = !self.sendingTextDisabled
|
||||
self.textInputNode = textInputNode
|
||||
|
||||
if let textInputBackgroundTapRecognizer = self.textInputBackgroundTapRecognizer {
|
||||
self.textInputBackgroundTapRecognizer = nil
|
||||
self.textInputBackgroundNode.view.removeGestureRecognizer(textInputBackgroundTapRecognizer)
|
||||
}
|
||||
|
||||
var accessoryButtonsWidth: CGFloat = 0.0
|
||||
var firstButton = true
|
||||
for (_, button) in self.accessoryItemButtons {
|
||||
|
Loading…
x
Reference in New Issue
Block a user