mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Various fixes
This commit is contained in:
parent
c93e02a58e
commit
c654227b83
15 changed files with 167 additions and 19 deletions
|
|
@ -1218,7 +1218,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
|||
}
|
||||
|
||||
if !data.includePeers.peers.isEmpty && data.categories.isEmpty && !data.excludeRead && !data.excludeMuted && !data.excludeArchived && data.excludePeers.isEmpty {
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_ContextMenuShare, textColor: .primary, badge: data.hasSharedLinks ? nil : ContextMenuActionBadge(value: self.presentationData.strings.ChatList_ContextMenuBadgeNew, color: .accent, style: .label), icon: { theme in
|
||||
items.append(.action(ContextMenuActionItem(text: self.presentationData.strings.ChatList_ContextMenuShare, textColor: .primary, badge: nil, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Link"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] c, f in
|
||||
c?.dismiss(completion: {
|
||||
|
|
|
|||
|
|
@ -236,12 +236,11 @@ public final class ShimmerEffectForegroundNode: ASDisplayNode {
|
|||
|
||||
let image: UIImage?
|
||||
if horizontal {
|
||||
let baseAlpha: CGFloat = 0.1
|
||||
//let baseAlpha: CGFloat = 0.1
|
||||
image = generateImage(CGSize(width: effectSize ?? 200.0, height: 16.0), opaque: false, scale: 1.0, rotatedContext: { size, context in
|
||||
context.clear(CGRect(origin: CGPoint(), size: size))
|
||||
|
||||
let foregroundColor = UIColor(white: 1.0, alpha: min(1.0, baseAlpha * 4.0))
|
||||
|
||||
//let foregroundColor = foregroundColor //.withAlphaComponent(min(1.0, baseAlpha * 3.0))
|
||||
if let shadowImage {
|
||||
UIGraphicsPushContext(context)
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ public enum SummarizeError {
|
|||
case invalidMessageId
|
||||
case limitExceeded
|
||||
case invalidLanguage
|
||||
case limitExceededPremium
|
||||
}
|
||||
|
||||
func _internal_summarizeMessage(account: Account, messageId: EngineMessage.Id, translateToLang: String?) -> Signal<Never, SummarizeError> {
|
||||
|
|
@ -35,6 +36,8 @@ func _internal_summarizeMessage(account: Account, messageId: EngineMessage.Id, t
|
|||
return .invalidMessageId
|
||||
} else if error.errorDescription == "TO_LANG_INVALID" {
|
||||
return .invalidLanguage
|
||||
} else if error.errorDescription == "SUMMARY_FLOOD_PREMIUM" {
|
||||
return .limitExceededPremium
|
||||
} else {
|
||||
return .generic
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ import LottieMetal
|
|||
import AvatarNode
|
||||
import ChatMessageSuggestedPostInfoNode
|
||||
|
||||
import AlertComponent
|
||||
import PremiumStarComponent
|
||||
|
||||
private struct BubbleItemAttributes {
|
||||
var index: Int?
|
||||
var isAttachment: Bool
|
||||
|
|
@ -6994,7 +6997,19 @@ public class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewI
|
|||
}
|
||||
if requestSummary {
|
||||
let _ = (item.context.engine.messages.summarizeMessage(messageId: item.message.id, translateToLang: translateToLanguage)
|
||||
|> deliverOnMainQueue).start()
|
||||
|> deliverOnMainQueue).start(error: { error in
|
||||
if case .limitExceededPremium = error, let parentController = item.controllerInteraction.navigationController()?.topViewController as? ViewController {
|
||||
item.controllerInteraction.summarizedMessageIds.remove(item.message.id)
|
||||
let _ = item.controllerInteraction.requestMessageUpdate(item.message.id, false)
|
||||
let controller = premiumAlertController(
|
||||
context: item.context,
|
||||
parentController: parentController,
|
||||
title: "AI Summary",
|
||||
text: "Summarize large messages with AI – unlimited with Telegram Premium."
|
||||
)
|
||||
parentController.present(controller, in: .window(.root))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7221,3 +7236,115 @@ public final class NameNavigateButton: HighlightableButton {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func premiumAlertController(
|
||||
context: AccountContext,
|
||||
parentController: ViewController,
|
||||
title: String? = nil,
|
||||
text: String
|
||||
) -> ViewController {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let strings = presentationData.strings
|
||||
|
||||
var content: [AnyComponentWithIdentity<AlertComponentEnvironment>] = []
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "header",
|
||||
component: AnyComponent(
|
||||
AlertPremiumStarComponent()
|
||||
)
|
||||
))
|
||||
|
||||
let title = strings.PremiumNeeded_Title
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "title",
|
||||
component: AnyComponent(
|
||||
AlertTitleComponent(title: title)
|
||||
)
|
||||
))
|
||||
content.append(AnyComponentWithIdentity(
|
||||
id: "text",
|
||||
component: AnyComponent(
|
||||
AlertTextComponent(content: .plain(text))
|
||||
)
|
||||
))
|
||||
|
||||
let alertController = AlertScreen(
|
||||
context: context,
|
||||
content: content,
|
||||
actions: [
|
||||
.init(title: strings.Common_Cancel),
|
||||
.init(title: strings.PremiumNeeded_Subscribe, type: .default, action: { [weak parentController] in
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .nameColor, forceDark: false, dismissed: nil)
|
||||
parentController?.push(controller)
|
||||
})
|
||||
]
|
||||
)
|
||||
return alertController
|
||||
}
|
||||
|
||||
private final class AlertPremiumStarComponent: Component {
|
||||
public typealias EnvironmentType = AlertComponentEnvironment
|
||||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public static func ==(lhs: AlertPremiumStarComponent, rhs: AlertPremiumStarComponent) -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
public final class View: UIView {
|
||||
private let clippingView = UIView()
|
||||
private let icon = ComponentView<Empty>()
|
||||
|
||||
private var component: AlertPremiumStarComponent?
|
||||
private weak var state: EmptyComponentState?
|
||||
|
||||
func update(component: AlertPremiumStarComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<AlertComponentEnvironment>, transition: ComponentTransition) -> CGSize {
|
||||
self.component = component
|
||||
self.state = state
|
||||
|
||||
let environment = environment[AlertComponentEnvironment.self]
|
||||
|
||||
let starHeight: CGFloat = 105.0
|
||||
let starSize = self.icon.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(
|
||||
PremiumStarComponent(
|
||||
theme: environment.theme,
|
||||
isIntro: false,
|
||||
isVisible: true,
|
||||
hasIdleAnimations: true,
|
||||
colors: [
|
||||
UIColor(rgb: 0x6a94ff),
|
||||
UIColor(rgb: 0x9472fd),
|
||||
UIColor(rgb: 0xe26bd3)
|
||||
]
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: availableSize.width + 60.0, height: 200.0)
|
||||
)
|
||||
if let view = self.icon.view {
|
||||
if view.superview == nil {
|
||||
self.addSubview(self.clippingView)
|
||||
self.clippingView.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: 0.0, y: -24.0), size: starSize)
|
||||
}
|
||||
|
||||
self.clippingView.clipsToBounds = true
|
||||
self.clippingView.layer.cornerRadius = 35.0
|
||||
self.clippingView.frame = CGRect(origin: CGPoint(x: -30.0, y: -22.0), size: CGSize(width: starSize.width, height: starSize.height))
|
||||
|
||||
return CGSize(width: availableSize.width, height: starHeight + 10.0)
|
||||
}
|
||||
}
|
||||
|
||||
public func makeView() -> View {
|
||||
return View(frame: CGRect())
|
||||
}
|
||||
|
||||
public func update(view: View, availableSize: CGSize, state: EmptyComponentState, environment: Environment<AlertComponentEnvironment>, transition: ComponentTransition) -> CGSize {
|
||||
return view.update(component: self, availableSize: availableSize, state: state, environment: environment, transition: transition)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1565,7 +1565,7 @@ public final class ChatMessageInteractiveFileNode: ASDisplayNode {
|
|||
if isTranslating, !rects.isEmpty {
|
||||
if self.shimmeringNodes.isEmpty {
|
||||
for rects in rects {
|
||||
let shimmeringNode = ShimmeringLinkNode(color: arguments.message.effectivelyIncoming(arguments.context.account.peerId) ? arguments.presentationData.theme.theme.chat.message.incoming.secondaryTextColor.withAlphaComponent(0.1) : arguments.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
let shimmeringNode = ShimmeringLinkNode(color: arguments.message.effectivelyIncoming(arguments.context.account.peerId) ? arguments.presentationData.theme.theme.chat.message.incoming.accentTextColor.withAlphaComponent(0.1) : arguments.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
shimmeringNode.updateRects(rects)
|
||||
shimmeringNode.frame = self.bounds
|
||||
shimmeringNode.updateLayout(self.bounds.size)
|
||||
|
|
|
|||
|
|
@ -1679,7 +1679,7 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
if isTranslating, !rects.isEmpty {
|
||||
if self.shimmeringNodes.isEmpty {
|
||||
for rects in rects {
|
||||
let shimmeringNode = ShimmeringLinkNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
let shimmeringNode = ShimmeringLinkNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
shimmeringNode.updateRects(rects)
|
||||
shimmeringNode.frame = self.bounds
|
||||
shimmeringNode.updateLayout(self.bounds.size)
|
||||
|
|
|
|||
|
|
@ -897,6 +897,7 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
}
|
||||
strongSelf.textAccessibilityOverlayNode.frame = textFrame
|
||||
|
||||
isTranslating = true
|
||||
strongSelf.updateIsTranslating(isTranslating)
|
||||
|
||||
if let statusSizeAndApply {
|
||||
|
|
@ -1258,7 +1259,14 @@ public class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
if let current = self.shimmeringNode {
|
||||
shimmeringNode = current
|
||||
} else {
|
||||
shimmeringNode = ShimmeringLinkNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
let color: UIColor
|
||||
let isIncoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
if item.presentationData.theme.theme.overallDarkAppearance {
|
||||
color = isIncoming ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor.withAlphaComponent(0.1)
|
||||
} else {
|
||||
color = isIncoming ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1)
|
||||
}
|
||||
shimmeringNode = ShimmeringLinkNode(color: color)
|
||||
shimmeringNode.updateRects(rects)
|
||||
shimmeringNode.frame = self.textNode.textNode.frame
|
||||
shimmeringNode.updateLayout(self.textNode.textNode.frame.size)
|
||||
|
|
|
|||
|
|
@ -1481,8 +1481,8 @@ public class ChatMessageTodoBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
|
||||
if isTranslating, !rects.isEmpty {
|
||||
if self.shimmeringNodes.isEmpty {
|
||||
for rects in rects {
|
||||
let shimmeringNode = ShimmeringLinkNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
for rects in rects {
|
||||
let shimmeringNode = ShimmeringLinkNode(color: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor.withAlphaComponent(0.1) : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor.withAlphaComponent(0.1))
|
||||
shimmeringNode.updateRects(rects)
|
||||
shimmeringNode.frame = self.bounds
|
||||
shimmeringNode.updateLayout(self.bounds.size)
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ public final class ShimmeringLinkNode: ASDisplayNode {
|
|||
self.shimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: size), within: size)
|
||||
self.borderShimmerEffectNode.updateAbsoluteRect(CGRect(origin: .zero, size: size), within: size)
|
||||
|
||||
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: self.color.withAlphaComponent(min(1.0, self.color.alpha * 1.2)), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
||||
self.borderShimmerEffectNode.update(backgroundColor: .clear, foregroundColor: self.color.withAlphaComponent(min(1.0, self.color.alpha * 1.5)), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
||||
self.shimmerEffectNode.update(backgroundColor: .clear, foregroundColor: self.color.withMultipliedAlpha(1.75), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
||||
self.borderShimmerEffectNode.update(backgroundColor: .clear, foregroundColor: self.color.withMultipliedAlpha(2.0), horizontal: true, effectSize: nil, globalTimeOffset: false, duration: nil)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2551,6 +2551,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||
let upgradePerks = Child(List<Empty>.self)
|
||||
let upgradeKeepName = Child(PlainButtonComponent.self)
|
||||
let upgradePriceButton = Child(PlainButtonComponent.self)
|
||||
let variantsMeasureDescription = Child(MultilineTextComponent.self)
|
||||
|
||||
let spaceRegex = try? NSRegularExpression(pattern: "\\[(.*?)\\]", options: [])
|
||||
|
||||
|
|
@ -3076,6 +3077,16 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||
if let previewPatternColor = giftCompositionExternalState.previewPatternColor {
|
||||
buttonColor = previewPatternColor
|
||||
}
|
||||
|
||||
let variantsMeasureDescription = variantsMeasureDescription.update(
|
||||
component: MultilineTextComponent(text: .plain(NSAttributedString(string: strings.Gift_Upgrade_ViewAllVariants, font: Font.semibold(13.0), textColor: .clear))),
|
||||
availableSize: context.availableSize,
|
||||
transition: .immediate
|
||||
)
|
||||
context.add(variantsMeasureDescription
|
||||
.position(CGPoint(x: -10000.0, y: -10000.0))
|
||||
)
|
||||
|
||||
let upgradeDescription = upgradeDescription.update(
|
||||
component: PlainButtonComponent(
|
||||
content: AnyComponent(
|
||||
|
|
@ -3131,7 +3142,7 @@ private final class GiftViewSheetContent: CombinedComponent {
|
|||
},
|
||||
animateScale: false
|
||||
),
|
||||
availableSize: CGSize(width: 280.0, height: 24.0),
|
||||
availableSize: CGSize(width: variantsMeasureDescription.size.width + 87.0, height: 24.0),
|
||||
transition: context.transition
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -2184,7 +2184,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
} else {
|
||||
programTitleValue = .text(presentationData.strings.PeerInfo_ItemAffiliateProgram_ValueOff)
|
||||
}
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliateProgram, label: programTitleValue, additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_ItemAffiliateProgram_Title, icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
items[.peerDataSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemAffiliateProgram, label: programTitleValue, additionalBadgeLabel: nil, text: presentationData.strings.PeerInfo_ItemAffiliateProgram_Title, icon: PresentationResourcesSettings.affiliateProgram, action: {
|
||||
interaction.editingOpenAffiliateProgram()
|
||||
}))
|
||||
}
|
||||
|
|
@ -2467,7 +2467,7 @@ private func editingItems(data: PeerInfoScreenData?, boostStatus: ChannelBoostSt
|
|||
labelString = NSAttributedString(string: presentationData.strings.PeerInfo_AllowChannelMessages_Off, font: labelFont, textColor: labelColor)
|
||||
}
|
||||
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .attributedText(labelString), additionalBadgeLabel: presentationData.strings.Settings_New, text: presentationData.strings.PeerInfo_AllowChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: {
|
||||
items[.peerSettings]!.append(PeerInfoScreenDisclosureItem(id: ItemPostSuggestionsSettings, label: .attributedText(labelString), additionalBadgeLabel: nil, text: presentationData.strings.PeerInfo_AllowChannelMessages, icon: PresentationResourcesSettings.channelMessages, action: {
|
||||
interaction.editingOpenPostSuggestionsSetup()
|
||||
}))
|
||||
|
||||
|
|
|
|||
|
|
@ -372,7 +372,7 @@ public class ItemListReactionItemNode: ListViewItemNode, ItemListItemNode {
|
|||
|
||||
if let animationContent = animationContent {
|
||||
let iconBoundingSize = CGSize(width: 28.0, height: 28.0)
|
||||
let iconOffsetX: CGFloat = 0.0
|
||||
let iconOffsetX: CGFloat = -6.0
|
||||
let iconSize = strongSelf.iconView.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(EmojiStatusComponent(
|
||||
|
|
|
|||
|
|
@ -835,7 +835,7 @@ final class StarsTransactionsScreenComponent: Component {
|
|||
footer: nil,
|
||||
items: [
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemComponentAdaptor(
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: environment.strings.Monetization_EarnStarsInfo_Title, titleBadge: presentationData.strings.Settings_New, label: environment.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
itemGenerator: ItemListDisclosureItem(presentationData: ItemListPresentationData(presentationData), icon: PresentationResourcesSettings.earnStars, title: environment.strings.Monetization_EarnStarsInfo_Title, titleBadge: nil, label: environment.strings.Monetization_EarnStarsInfo_Text, labelStyle: .multilineDetailText, sectionId: 0, style: .blocks, action: {
|
||||
}),
|
||||
params: ListViewItemLayoutParams(width: availableSize.width, leftInset: 0.0, rightInset: 0.0, availableHeight: 10000.0, isStandalone: true),
|
||||
action: { [weak self] in
|
||||
|
|
|
|||
|
|
@ -933,7 +933,7 @@ public final class ChatMessageTransitionNodeImpl: ASDisplayNode, ChatMessageTran
|
|||
}
|
||||
if itemNode == nil || itemNode === currentItemNode {
|
||||
if let contextController = self.contextController {
|
||||
contextController.addRelativeContentOffset(CGPoint(x: 0.0, y: offset), transition: transition)
|
||||
contextController.addRelativeContentOffset(CGPoint(x: 0.0, y: -offset), transition: transition)
|
||||
}
|
||||
if let standaloneReactionAnimation = self.standaloneReactionAnimation {
|
||||
standaloneReactionAnimation.addRelativeContentOffset(CGPoint(x: 0.0, y: -offset), transition: transition)
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ final class HashtagChatInputContextPanelNode: ChatInputContextPanelNode {
|
|||
peer: peer,
|
||||
title: self.strings.Chat_HashtagSuggestion_UseLocal_Title("#\(query)@\(addressName)").string,
|
||||
text: isGroup ? self.strings.Chat_HashtagSuggestion_UseLocal_Group_Text : self.strings.Chat_HashtagSuggestion_UseLocal_Channel_Text,
|
||||
badge: self.strings.ChatList_ContextMenuBadgeNew,
|
||||
badge: nil,
|
||||
hashtag: "\(query)@\(addressName)",
|
||||
revealed: false,
|
||||
isAdditionalRecent: false
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue