mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Merge branches 'master' and 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
74c22e8c18
@ -11613,9 +11613,9 @@ Sorry for the inconvenience.";
|
||||
|
||||
"CollectibleItemInfo.StoreName" = "Fragment";
|
||||
"CollectibleItemInfo.UsernameTitle" = "%@ is a collectible username that belongs to";
|
||||
"CollectibleItemInfo.UsernameText" = "The %1$@ username was acquired on %2$@ on %3$@ for %4$@ (%5$@).";
|
||||
"CollectibleItemInfo.UsernameText" = "The username %1$@ was acquired on %2$@ on %3$@ for %4$@ (%5$@).";
|
||||
"CollectibleItemInfo.PhoneTitle" = "%@ is a collectible phone number that belongs to";
|
||||
"CollectibleItemInfo.PhoneText" = "The %1$@ phone number was acquired on %2$@ on %3$@ for %4$@ (%5$@).";
|
||||
"CollectibleItemInfo.PhoneText" = "The phone number %1$@ was acquired on %2$@ on %3$@ for %4$@ (%5$@).";
|
||||
"CollectibleItemInfo.ButtonOpenInfo" = "Learn More";
|
||||
"CollectibleItemInfo.ButtonCopyUsername" = "Copy Link";
|
||||
"CollectibleItemInfo.ButtonCopyPhone" = "Copy Phone Number";
|
||||
@ -11660,7 +11660,7 @@ Sorry for the inconvenience.";
|
||||
"ChatList.BirthdaySingleTitle" = "It's %@'s **birthday** today! 🎂";
|
||||
"ChatList.BirthdaySingleText" = "Gift them Telegram Premium.";
|
||||
|
||||
"ChatList.BirthdayMultipleTitle_1" = "%@ contact have **birthday** today! 🎂";
|
||||
"ChatList.BirthdayMultipleTitle_1" = "%@ contact has a **birthday** today! 🎂";
|
||||
"ChatList.BirthdayMultipleTitle_any" = "%@ contacts have **birthdays** today! 🎂";
|
||||
"ChatList.BirthdayMultipleText" = "Gift them Telegram Premium.";
|
||||
|
||||
@ -11689,7 +11689,7 @@ Sorry for the inconvenience.";
|
||||
"Monetization.BalanceTitle" = "AVAILABLE BALANCE";
|
||||
"Monetization.Balance.ZeroInfo" = "You will be able to collect rewards using Fragment, a third-party platform used by advertisers to pay for ads. [Learn More >]()";
|
||||
"Monetization.Balance.AvailableInfo" = "You can collect your reward using Fragment, a third-party platform used by advertisers to pay for ads. [Learn More >]()";
|
||||
"Monetization.Balance.ComingLaterInfo" = "In the coming weeks you will be able to collect your reward using Fragment, a third-party platform used by advertisers to pay ads. [Learn More >]()";
|
||||
"Monetization.Balance.ComingLaterInfo" = "In the coming weeks, you will be able to collect rewards using Fragment, a third-party platform used by advertisers to pay for ads. [Learn More >]()";
|
||||
|
||||
"Monetization.BalanceInfo_URL" = "https://telegram.org";
|
||||
"Monetization.BalanceWithdraw" = "Withdraw via Fragment";
|
||||
@ -11733,14 +11733,14 @@ Sorry for the inconvenience.";
|
||||
"Monetization.Intro.Withdrawal.Text" = "You can withdraw your TON any time.";
|
||||
|
||||
"Monetization.Intro.Info.Title" = "What's #TON?";
|
||||
"Monetization.Intro.Info.Text" = "TON is a blockchain platform and cryptocurrency that Telegram uses for its high speed and low commisions on transactions. [Learn More >]()";
|
||||
"Monetization.Intro.Info.Text" = "TON is a blockchain platform and cryptocurrency that Telegram uses for its high speed and commissions on transactions. [Learn More >]()";
|
||||
"Monetization.Intro.Info.Text_URL" = "https://ton.org";
|
||||
|
||||
"Monetization.Intro.Understood" = "Understood";
|
||||
|
||||
"ReportAd.Title" = "Report Ad";
|
||||
"ReportAd.Help" = "Learn more about our [Ad Policies and Guidelines]().";
|
||||
"ReportAd.Help_URL" = "https://promote.telegram.org/guidelines";
|
||||
"ReportAd.Help" = "Learn more about [Telegram Ad Policies and Guidelines]().";
|
||||
"ReportAd.Help_URL" = "https://ads.telegram.org/guidelines";
|
||||
"ReportAd.Reported" = "We will review this ad to ensure it matches our [Ad Policies and Guidelines]().";
|
||||
"ReportAd.Hidden" = "Ads are hidden now.";
|
||||
|
||||
|
@ -175,16 +175,16 @@ class BarsComponentController: GeneralChartComponentController {
|
||||
calculatingRange: horizontalRange,
|
||||
addBounds: true) {
|
||||
let (range, labels) = verticalLimitsLabels(verticalRange: range, secondary: false)
|
||||
if verticalScalesRenderer.verticalRange.end != range {
|
||||
// if verticalScalesRenderer.verticalRange.end != range {
|
||||
verticalScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
|
||||
}
|
||||
// }
|
||||
verticalScalesRenderer.setVisible(true, animated: animated)
|
||||
|
||||
if let secondaryScalesRenderer = self.secondaryScalesRenderer {
|
||||
let (range, labels) = verticalLimitsLabels(verticalRange: range, secondary: true)
|
||||
if secondaryScalesRenderer.verticalRange.end != range {
|
||||
let (_, labels) = verticalLimitsLabels(verticalRange: range, secondary: true)
|
||||
// if secondaryScalesRenderer.verticalRange.end != range {
|
||||
secondaryScalesRenderer.setup(verticalLimitsLabels: labels, animated: animated)
|
||||
}
|
||||
// }
|
||||
secondaryScalesRenderer.setVisible(true, animated: animated)
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@
|
||||
import Foundation
|
||||
#if os(macOS)
|
||||
import Cocoa
|
||||
|
||||
typealias UIColor = NSColor
|
||||
#else
|
||||
import UIKit
|
||||
#endif
|
||||
|
@ -0,0 +1,5 @@
|
||||
import Foundation
|
||||
import SwiftSignalKit
|
||||
import AVFoundation
|
||||
import UIKit
|
||||
|
@ -365,7 +365,7 @@ public final class RevenueStatsTransactionsContext {
|
||||
}
|
||||
}
|
||||
|
||||
public enum RequestRevenueWithdrawalError {
|
||||
public enum RequestRevenueWithdrawalError : Equatable {
|
||||
case generic
|
||||
case twoStepAuthMissing
|
||||
case twoStepAuthTooFresh(Int32)
|
||||
|
@ -53,6 +53,7 @@ swift_library(
|
||||
"//submodules/TelegramUI/Components/ListItemSwipeOptionContainer",
|
||||
"//submodules/UndoUI",
|
||||
"//submodules/ShareController",
|
||||
"//submodules/ContextUI",
|
||||
],
|
||||
visibility = [
|
||||
"//visibility:public",
|
||||
|
@ -21,6 +21,7 @@ final class BusinessLinkListItemComponent: Component {
|
||||
let action: () -> Void
|
||||
let deleteAction: () -> Void
|
||||
let shareAction: () -> Void
|
||||
let contextAction: ((ContextExtractedContentContainingView, ContextGesture) -> Void)?
|
||||
|
||||
init(
|
||||
context: AccountContext,
|
||||
@ -29,7 +30,8 @@ final class BusinessLinkListItemComponent: Component {
|
||||
link: TelegramBusinessChatLinks.Link,
|
||||
action: @escaping () -> Void,
|
||||
deleteAction: @escaping () -> Void,
|
||||
shareAction: @escaping () -> Void
|
||||
shareAction: @escaping () -> Void,
|
||||
contextAction: ((ContextExtractedContentContainingView, ContextGesture) -> Void)?
|
||||
) {
|
||||
self.context = context
|
||||
self.theme = theme
|
||||
@ -38,6 +40,7 @@ final class BusinessLinkListItemComponent: Component {
|
||||
self.action = action
|
||||
self.deleteAction = deleteAction
|
||||
self.shareAction = shareAction
|
||||
self.contextAction = contextAction
|
||||
}
|
||||
|
||||
static func ==(lhs: BusinessLinkListItemComponent, rhs: BusinessLinkListItemComponent) -> Bool {
|
||||
@ -56,7 +59,8 @@ final class BusinessLinkListItemComponent: Component {
|
||||
return true
|
||||
}
|
||||
|
||||
final class View: UIView, ListSectionComponent.ChildView {
|
||||
final class View: ContextControllerSourceView, ListSectionComponent.ChildView {
|
||||
private let extractedContainerView: ContextExtractedContentContainingView
|
||||
private let containerButton: HighlightTrackingButton
|
||||
private let swipeOptionContainer: ListItemSwipeOptionContainer
|
||||
|
||||
@ -71,7 +75,10 @@ final class BusinessLinkListItemComponent: Component {
|
||||
var customUpdateIsHighlighted: ((Bool) -> Void)?
|
||||
private(set) var separatorInset: CGFloat = 0.0
|
||||
|
||||
private var isExtractedToContextMenu: Bool = false
|
||||
|
||||
override init(frame: CGRect) {
|
||||
self.extractedContainerView = ContextExtractedContentContainingView()
|
||||
self.containerButton = HighlightTrackingButton()
|
||||
self.containerButton.layer.anchorPoint = CGPoint()
|
||||
self.containerButton.isExclusiveTouch = true
|
||||
@ -80,6 +87,11 @@ final class BusinessLinkListItemComponent: Component {
|
||||
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.extractedContainerView)
|
||||
self.targetViewForActivationProgress = self.extractedContainerView.contentView
|
||||
|
||||
self.extractedContainerView.contentView.addSubview(self.swipeOptionContainer)
|
||||
|
||||
self.containerButton.addTarget(self, action: #selector(self.pressed), for: .touchUpInside)
|
||||
self.containerButton.internalHighligthedChanged = { [weak self] isHighlighted in
|
||||
guard let self else {
|
||||
@ -108,9 +120,38 @@ final class BusinessLinkListItemComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
self.addSubview(self.swipeOptionContainer)
|
||||
|
||||
self.swipeOptionContainer.addSubview(self.containerButton)
|
||||
|
||||
self.extractedContainerView.isExtractedToContextPreviewUpdated = { [weak self] value in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
self.containerButton.clipsToBounds = value
|
||||
self.containerButton.backgroundColor = value ? component.theme.list.itemBlocksBackgroundColor : nil
|
||||
self.containerButton.layer.cornerRadius = value ? 10.0 : 0.0
|
||||
}
|
||||
self.extractedContainerView.willUpdateIsExtractedToContextPreview = { [weak self] value, transition in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.isExtractedToContextMenu = value
|
||||
|
||||
let mappedTransition: Transition
|
||||
if value {
|
||||
mappedTransition = Transition(transition)
|
||||
} else {
|
||||
mappedTransition = Transition(animation: .curve(duration: 0.2, curve: .easeInOut))
|
||||
}
|
||||
self.componentState?.updated(transition: mappedTransition)
|
||||
}
|
||||
|
||||
self.activated = { [weak self] gesture, _ in
|
||||
guard let self, let component = self.component else {
|
||||
gesture.cancel()
|
||||
return
|
||||
}
|
||||
component.contextAction?(self.extractedContainerView, gesture)
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@ -128,13 +169,21 @@ final class BusinessLinkListItemComponent: Component {
|
||||
self.component = component
|
||||
self.componentState = state
|
||||
|
||||
let leftInset: CGFloat = 0.0
|
||||
let leftContentInset: CGFloat = 62.0
|
||||
let rightInset: CGFloat = 8.0
|
||||
var rightInset: CGFloat = 8.0
|
||||
let topInset: CGFloat = 9.0
|
||||
let bottomInset: CGFloat = 9.0
|
||||
let titleViewCountSpacing: CGFloat = 4.0
|
||||
let titleTextSpacing: CGFloat = 4.0
|
||||
|
||||
var innerInsets = UIEdgeInsets()
|
||||
if self.isExtractedToContextMenu {
|
||||
rightInset += 2.0
|
||||
innerInsets.left += 2.0
|
||||
innerInsets.right += 2.0
|
||||
}
|
||||
|
||||
let viewCountText: String
|
||||
if component.link.viewCount == 0 {
|
||||
viewCountText = component.strings.Business_Links_ItemNoClicks
|
||||
@ -149,7 +198,7 @@ final class BusinessLinkListItemComponent: Component {
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 100.0, height: 100.0)
|
||||
)
|
||||
let viewCountFrame = CGRect(origin: CGPoint(x: availableSize.width - rightInset - viewCountSize.width, y: topInset + 2.0), size: viewCountSize)
|
||||
let viewCountFrame = CGRect(origin: CGPoint(x: availableSize.width - rightInset - innerInsets.left - viewCountSize.width, y: topInset + 2.0), size: viewCountSize)
|
||||
if let viewCountView = self.viewCount.view {
|
||||
if viewCountView.superview == nil {
|
||||
viewCountView.isUserInteractionEnabled = false
|
||||
@ -166,9 +215,9 @@ final class BusinessLinkListItemComponent: Component {
|
||||
text: .plain(NSAttributedString(string: component.link.title ?? component.link.url, font: Font.regular(16.0), textColor: component.theme.list.itemPrimaryTextColor))
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width - leftContentInset - rightInset - viewCountSize.width - titleViewCountSpacing, height: 100.0)
|
||||
containerSize: CGSize(width: availableSize.width - leftInset - leftContentInset - rightInset - viewCountSize.width - titleViewCountSpacing, height: 100.0)
|
||||
)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftContentInset, y: topInset), size: titleSize)
|
||||
let titleFrame = CGRect(origin: CGPoint(x: leftInset + leftContentInset, y: topInset), size: titleSize)
|
||||
if let titleView = self.title.view {
|
||||
if titleView.superview == nil {
|
||||
titleView.isUserInteractionEnabled = false
|
||||
@ -213,7 +262,7 @@ final class BusinessLinkListItemComponent: Component {
|
||||
adjustQuoteFontSize: false,
|
||||
cachedMessageSyntaxHighlight: nil
|
||||
)
|
||||
let (textLayout, textApply) = asyncLayout(TextNodeLayoutArguments(attributedString: textString, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: availableSize.width - leftContentInset - rightInset, height: 100.0)))
|
||||
let (textLayout, textApply) = asyncLayout(TextNodeLayoutArguments(attributedString: textString, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: availableSize.width - leftContentInset - leftInset - rightInset, height: 100.0)))
|
||||
let _ = textApply(TextNodeWithEntities.Arguments(
|
||||
context: component.context,
|
||||
cache: component.context.animationCache,
|
||||
@ -222,7 +271,7 @@ final class BusinessLinkListItemComponent: Component {
|
||||
attemptSynchronous: true
|
||||
))
|
||||
let textSize = textLayout.size
|
||||
let textFrame = CGRect(origin: CGPoint(x: leftContentInset, y: titleFrame.maxY + titleTextSpacing), size: textLayout.size)
|
||||
let textFrame = CGRect(origin: CGPoint(x: leftInset + leftContentInset, y: titleFrame.maxY + titleTextSpacing), size: textLayout.size)
|
||||
if self.text.textNode.view.superview == nil {
|
||||
self.text.textNode.view.isUserInteractionEnabled = false
|
||||
self.containerButton.addSubview(self.text.textNode.view)
|
||||
@ -237,18 +286,25 @@ final class BusinessLinkListItemComponent: Component {
|
||||
self.iconView.isUserInteractionEnabled = false
|
||||
self.containerButton.addSubview(self.iconView)
|
||||
}
|
||||
let iconFrame = CGRect(origin: CGPoint(x: floor((leftContentInset - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size)
|
||||
let iconFrame = CGRect(origin: CGPoint(x: leftInset + floor((leftContentInset - image.size.width) * 0.5), y: floor((size.height - image.size.height) * 0.5)), size: image.size)
|
||||
transition.setFrame(view: self.iconView, frame: iconFrame)
|
||||
}
|
||||
|
||||
let swipeOptionContainerFrame = CGRect(origin: CGPoint(x: 0.0, y: 0.0), size: size)
|
||||
transition.setFrame(view: self.swipeOptionContainer, frame: swipeOptionContainerFrame)
|
||||
|
||||
transition.setPosition(view: self.containerButton, position: CGPoint())
|
||||
transition.setBounds(view: self.containerButton, bounds: CGRect(origin: self.containerButton.bounds.origin, size: size))
|
||||
let containerButtonFrame = CGRect(origin: CGPoint(x: innerInsets.left, y: innerInsets.top), size: CGSize(width: size.width - innerInsets.left - innerInsets.right, height: size.height - innerInsets.top - innerInsets.bottom))
|
||||
|
||||
transition.setPosition(view: self.containerButton, position: containerButtonFrame.origin)
|
||||
transition.setBounds(view: self.containerButton, bounds: CGRect(origin: self.containerButton.bounds.origin, size: containerButtonFrame.size))
|
||||
|
||||
self.swipeOptionContainer.updateLayout(size: swipeOptionContainerFrame.size, leftInset: 0.0, rightInset: 0.0)
|
||||
|
||||
let resultBounds = CGRect(origin: CGPoint(), size: size)
|
||||
transition.setFrame(view: self.extractedContainerView, frame: resultBounds)
|
||||
transition.setFrame(view: self.extractedContainerView.contentView, frame: resultBounds)
|
||||
self.extractedContainerView.contentRect = resultBounds
|
||||
|
||||
var rightOptions: [ListItemSwipeOptionContainer.Option] = []
|
||||
rightOptions = [
|
||||
ListItemSwipeOptionContainer.Option(
|
||||
|
@ -18,6 +18,7 @@ import BundleIconComponent
|
||||
import TextFormat
|
||||
import UndoUI
|
||||
import ShareController
|
||||
import ContextUI
|
||||
|
||||
final class BusinessLinksSetupScreenComponent: Component {
|
||||
typealias EnvironmentType = ViewControllerComponentContainer.Environment
|
||||
@ -535,6 +536,54 @@ final class BusinessLinksSetupScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
self.openShareLink(url: link.url)
|
||||
},
|
||||
contextAction: { [weak self] sourceView, gesture in
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
var itemList: [ContextMenuItem] = []
|
||||
itemList.append(.action(ContextMenuActionItem(
|
||||
text: presentationData.strings.Business_Links_ItemActionShare,
|
||||
textColor: .primary,
|
||||
icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Share"), color: theme.contextMenu.primaryColor) },
|
||||
action: { [weak self] c, _ in
|
||||
c.dismiss(completion: {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.openShareLink(url: link.url)
|
||||
})
|
||||
})
|
||||
))
|
||||
itemList.append(.action(ContextMenuActionItem(
|
||||
text: presentationData.strings.Common_Delete,
|
||||
textColor: .destructive,
|
||||
icon: { theme in generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Delete"), color: theme.contextMenu.destructiveColor) },
|
||||
action: { [weak self] c, _ in
|
||||
c.dismiss(completion: {
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
self.openDeleteLink(url: link.url)
|
||||
})
|
||||
})
|
||||
))
|
||||
let items = ContextController.Items(content: .list(itemList))
|
||||
|
||||
let controller = ContextController(
|
||||
presentationData: presentationData,
|
||||
source: .extracted(BusineesLinkListContextExtractedContentSource(contentView: sourceView)), items: .single(items), recognizer: nil, gesture: gesture)
|
||||
|
||||
self.environment?.controller()?.forEachController({ controller in
|
||||
if let controller = controller as? UndoOverlayController {
|
||||
controller.dismiss()
|
||||
}
|
||||
return true
|
||||
})
|
||||
self.environment?.controller()?.presentInGlobalOverlay(controller)
|
||||
}
|
||||
))))
|
||||
}
|
||||
@ -708,3 +757,23 @@ public final class BusinessLinksSetupScreen: ViewControllerComponentContainer {
|
||||
super.containerLayoutUpdated(layout, transition: transition)
|
||||
}
|
||||
}
|
||||
|
||||
private final class BusineesLinkListContextExtractedContentSource: ContextExtractedContentSource {
|
||||
let keepInPlace: Bool = false
|
||||
let ignoreContentTouches: Bool = false
|
||||
let blurBackground: Bool = true
|
||||
|
||||
private let contentView: ContextExtractedContentContainingView
|
||||
|
||||
init(contentView: ContextExtractedContentContainingView) {
|
||||
self.contentView = contentView
|
||||
}
|
||||
|
||||
func takeView() -> ContextControllerTakeViewInfo? {
|
||||
return ContextControllerTakeViewInfo(containingItem: .view(self.contentView), contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||
}
|
||||
|
||||
func putBack() -> ContextControllerPutBackViewInfo? {
|
||||
return ContextControllerPutBackViewInfo(contentAreaInScreenSpace: UIScreen.main.bounds)
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"app": "10.9.2",
|
||||
"app": "10.10",
|
||||
"bazel": "7.0.2",
|
||||
"xcode": "15.2",
|
||||
|
Loading…
x
Reference in New Issue
Block a user