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
9d6518a738
commit
54ec998186
9 changed files with 117 additions and 55 deletions
|
|
@ -15647,3 +15647,22 @@ Error: %8$@";
|
|||
"CocoonInfo.Understood" = "Understood";
|
||||
|
||||
"Conversation.Translation.CocoonInfo" = "Translations are powered by\n**#Cocoon**. [How does it work?]()";
|
||||
|
||||
"Conversation.EmojiStake.Won" = "%1$@ won %2$@";
|
||||
"Conversation.EmojiStake.WonYou" = "You won %@";
|
||||
"Conversation.EmojiStake.Lost" = "%1$@ lost %2$@";
|
||||
"Conversation.EmojiStake.LostYou" = "You lost %@";
|
||||
|
||||
"Conversation.Dice.Stake" = "Stake:";
|
||||
"Conversation.Dice.Change" = "change";
|
||||
|
||||
"EmojiStake.Title" = "Emoji Stake";
|
||||
"EmojiStake.Description" = "An experimental feature for Telegram Premium users.";
|
||||
"EmojiStake.ResultsTitle" = "RESULTS AND RETURNS";
|
||||
"EmojiStake.StreakInfo" = "A streak resets after 3 # or a stake change.";
|
||||
"EmojiStake.StakeTitle" = "STAKE";
|
||||
"EmojiStake.StakePlaceholder" = "Amount";
|
||||
"EmojiStake.Roll" = "Save and Roll";
|
||||
|
||||
"Conversation.Summary.Title" = "AI Summary";
|
||||
"Conversation.Summary.Text" = "Tap to see original text";
|
||||
|
|
|
|||
|
|
@ -1651,7 +1651,7 @@ private class ImageRecognitionOverlayContentNode: GalleryOverlayContentNode {
|
|||
if isHidden && !self.buttonNode.isSelected {
|
||||
buttonPosition = CGPoint(x: size.width - insets.right - buttonSize.width - 59.0, y: -50.0)
|
||||
} else {
|
||||
buttonPosition = CGPoint(x: size.width - insets.right - buttonSize.width - (self.buttonNode.isSelected ? 24.0 : 59.0), y: insets.top - 50.0)
|
||||
buttonPosition = CGPoint(x: size.width - insets.right - buttonSize.width - (self.buttonNode.isSelected ? 24.0 : 59.0), y: insets.top - 58.0)
|
||||
}
|
||||
|
||||
transition.updateFrame(node: self.buttonNode, frame: CGRect(origin: buttonPosition, size: CGSize(width: buttonSize.width + 24.0, height: buttonSize.height + 24.0)))
|
||||
|
|
|
|||
|
|
@ -2113,6 +2113,10 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||
}
|
||||
}
|
||||
|
||||
self.selectedButtonNode.action = { [weak self] in
|
||||
self?.selectedPressed()
|
||||
}
|
||||
|
||||
self.navigationItem.titleView = self.titleView
|
||||
|
||||
if case let .assets(collection, mode) = self.subject, mode != .default {
|
||||
|
|
@ -2185,8 +2189,6 @@ public final class MediaPickerScreenImpl: ViewController, MediaPickerScreen, Att
|
|||
// }
|
||||
// }
|
||||
|
||||
self.selectedButtonNode.addTarget(self, action: #selector(self.selectedPressed), forControlEvents: .touchUpInside)
|
||||
|
||||
self.scrollToTop = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let webSearchController = strongSelf.webSearchController {
|
||||
|
|
@ -4030,12 +4032,13 @@ public func coverMediaPickerController(
|
|||
return controller
|
||||
}
|
||||
|
||||
private class SelectedButtonNode: HighlightTrackingButtonNode {
|
||||
private class SelectedButtonNode: ASDisplayNode {
|
||||
private let containerView: UIView
|
||||
private let backgroundView: GlassBackgroundView?
|
||||
private let background: ASImageNode?
|
||||
private let icon = ASImageNode()
|
||||
private let label = ImmediateAnimatedCountLabelNode()
|
||||
private let button = HighlightTrackingButton()
|
||||
|
||||
private let glass: Bool
|
||||
|
||||
|
|
@ -4051,6 +4054,8 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
|||
|
||||
private var count: Int32 = 0
|
||||
|
||||
var action: () -> Void = {}
|
||||
|
||||
init(theme: PresentationTheme, glass: Bool) {
|
||||
self.theme = theme
|
||||
self.glass = glass
|
||||
|
|
@ -4076,6 +4081,9 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
|||
|
||||
self.view.addSubview(self.containerView)
|
||||
if let backgroundView = self.backgroundView {
|
||||
backgroundView.contentView.addSubnode(self.icon)
|
||||
backgroundView.contentView.addSubnode(self.label)
|
||||
backgroundView.contentView.addSubview(self.button)
|
||||
self.containerView.addSubview(backgroundView)
|
||||
}
|
||||
if let background = self.background {
|
||||
|
|
@ -4083,35 +4091,19 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
|||
self.containerView.addSubnode(background)
|
||||
}
|
||||
|
||||
self.containerView.addSubnode(self.icon)
|
||||
self.containerView.addSubnode(self.label)
|
||||
|
||||
|
||||
self.highligthedChanged = { [weak self] highlighted in
|
||||
if let self {
|
||||
if glass {
|
||||
let transition = ComponentTransition(animation: .curve(duration: highlighted ? 0.25 : 0.35, curve: .spring))
|
||||
if highlighted {
|
||||
transition.setScale(view: self.containerView, scale: 1.2)
|
||||
} else {
|
||||
transition.setScale(view: self.containerView, scale: 1.0)
|
||||
}
|
||||
} else {
|
||||
if highlighted {
|
||||
self.containerView.layer.removeAnimation(forKey: "opacity")
|
||||
self.containerView.alpha = 0.4
|
||||
} else {
|
||||
self.containerView.alpha = 1.0
|
||||
self.containerView.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.button.addTarget(self, action: #selector(self.tapped), for: .touchUpInside)
|
||||
}
|
||||
|
||||
@objc private func tapped() {
|
||||
self.action()
|
||||
}
|
||||
|
||||
func update(count: Int32) -> CGSize {
|
||||
self.count = count
|
||||
|
||||
let diameter: CGFloat = self.glass ? 40.0 : 21.0
|
||||
let diameter: CGFloat = self.glass ? 44.0 : 21.0
|
||||
let font = self.glass ? Font.with(size: 17.0, weight: .medium, traits: [.monospacedNumbers]) : Font.with(size: 15.0, design: .round, weight: .semibold, traits: [.monospacedNumbers])
|
||||
|
||||
let stringValue = "\(max(1, count))"
|
||||
|
|
@ -4147,11 +4139,13 @@ private class SelectedButtonNode: HighlightTrackingButtonNode {
|
|||
self.containerView.frame = backgroundFrame
|
||||
if let backgroundView = self.backgroundView {
|
||||
backgroundView.frame = backgroundFrame
|
||||
backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height * 0.5, isDark: false, tintColor: .init(kind: .custom, color: self.theme.list.itemCheckColors.fillColor), transition: .immediate)
|
||||
backgroundView.update(size: backgroundFrame.size, cornerRadius: backgroundFrame.size.height * 0.5, isDark: false, tintColor: .init(kind: .custom, color: self.theme.list.itemCheckColors.fillColor), isInteractive: true, transition: .immediate)
|
||||
}
|
||||
if let background = self.background {
|
||||
background.frame = backgroundFrame
|
||||
}
|
||||
|
||||
self.button.frame = CGRect(origin: .zero, size: size)
|
||||
|
||||
return size
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1766,15 +1766,24 @@ public func universalServiceMessageString(presentationData: (PresentationTheme,
|
|||
attributedString = addAttributesToStringWithRanges(resultTitleString._tuple, body: bodyAttributes, argumentAttributes: [0: boldAttributes])
|
||||
} else if let dice = media as? TelegramMediaDice, let gameOutcome = dice.gameOutcome {
|
||||
if let value = dice.value {
|
||||
//TODO:localize
|
||||
|
||||
let rawString: String
|
||||
if value == 1, let tonAmount = dice.tonAmount {
|
||||
let value = formatTonAmountText(tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = "You lost $\(value)"
|
||||
if message.author?.id == accountPeerId {
|
||||
if value == 1, let tonAmount = dice.tonAmount {
|
||||
let value = formatTonAmountText(tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = strings.Conversation_EmojiStake_LostYou(value).string
|
||||
} else {
|
||||
let value = formatTonAmountText(gameOutcome.tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = strings.Conversation_EmojiStake_WonYou(value).string
|
||||
}
|
||||
} else {
|
||||
let value = formatTonAmountText(gameOutcome.tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = "You won $\(value)"
|
||||
let compactPeerName = message.peers[message.id.peerId].flatMap(EnginePeer.init)?.compactDisplayTitle ?? ""
|
||||
if value == 1, let tonAmount = dice.tonAmount {
|
||||
let value = formatTonAmountText(tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = strings.Conversation_EmojiStake_Lost(compactPeerName, value).string
|
||||
} else {
|
||||
let value = formatTonAmountText(gameOutcome.tonAmount, dateTimeFormat: dateTimeFormat)
|
||||
rawString = strings.Conversation_EmojiStake_Won(compactPeerName, value).string
|
||||
}
|
||||
}
|
||||
|
||||
let attributedText = NSMutableAttributedString(string: rawString, font: titleFont, textColor: primaryTextColor)
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ private final class SheetContent: CombinedComponent {
|
|||
let controller = environment.controller
|
||||
|
||||
let theme = environment.theme.withModalBlocksBackground()
|
||||
//let strings = environment.strings
|
||||
let strings = environment.strings
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
let sideInset: CGFloat = 16.0 + environment.safeInsets.left
|
||||
|
|
@ -91,10 +91,9 @@ private final class SheetContent: CombinedComponent {
|
|||
return (TelegramTextAttributes.URL, contents)
|
||||
})
|
||||
|
||||
//TODO:localize
|
||||
let description = description.update(
|
||||
component: BalancedTextComponent(
|
||||
text: .markdown(text: "An experimental feature for Telegram Premium users.", attributes: markdownAttributes),
|
||||
text: .markdown(text: strings.EmojiStake_Description, attributes: markdownAttributes),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0,
|
||||
lineSpacing: 0.2
|
||||
|
|
@ -110,7 +109,7 @@ private final class SheetContent: CombinedComponent {
|
|||
|
||||
let resultsTitle = resultsTitle.update(
|
||||
component: MultilineTextComponent(text: .plain(NSAttributedString(
|
||||
string: "RESULTS AND RETURNS".uppercased(),
|
||||
string: strings.EmojiStake_ResultsTitle.uppercased(),
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: theme.list.freeTextColor
|
||||
))),
|
||||
|
|
@ -186,14 +185,14 @@ private final class SheetContent: CombinedComponent {
|
|||
contentSize.height += 7.0
|
||||
|
||||
let resultsFooterAttributedText = NSMutableAttributedString(
|
||||
string: "A streak resets after 3 # or a stake change.",
|
||||
string: strings.EmojiStake_StreakInfo,
|
||||
font: Font.regular(13.0),
|
||||
textColor: theme.list.freeTextColor
|
||||
)
|
||||
if let emojiFile = state.emojiFiles?[6] {
|
||||
let range = (resultsFooterAttributedText.string as NSString).range(of: "#")
|
||||
if range.location != NSNotFound {
|
||||
resultsFooterAttributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: emojiFile.fileId.id, file: emojiFile), range: range)
|
||||
resultsFooterAttributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: emojiFile, custom: .dice, enableAnimation: false), range: range)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -240,7 +239,7 @@ private final class SheetContent: CombinedComponent {
|
|||
forceMinValue: false,
|
||||
allowZero: true,
|
||||
maxValue: nil,
|
||||
placeholderText: "Amount",
|
||||
placeholderText: strings.EmojiStake_StakePlaceholder,
|
||||
labelText: amountLabel,
|
||||
currency: .ton,
|
||||
dateTimeFormat: presentationData.dateTimeFormat,
|
||||
|
|
@ -272,14 +271,13 @@ private final class SheetContent: CombinedComponent {
|
|||
))
|
||||
]
|
||||
|
||||
//TODO:localize
|
||||
let amountSection = amountSection.update(
|
||||
component: ListSectionComponent(
|
||||
theme: theme,
|
||||
style: .glass,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "STAKE".uppercased(),
|
||||
string: strings.EmojiStake_StakeTitle.uppercased(),
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: theme.list.freeTextColor
|
||||
)),
|
||||
|
|
@ -301,10 +299,9 @@ private final class SheetContent: CombinedComponent {
|
|||
contentSize.height += 24.0
|
||||
|
||||
|
||||
//TODO:localize
|
||||
var buttonItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "icon", component: AnyComponent(BundleIconComponent(name: "Premium/Dice", tintColor: theme.list.itemCheckColors.foregroundColor))))
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: "Save and Roll", font: Font.semibold(17.0), color: theme.list.itemCheckColors.foregroundColor))))
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: environment.strings.EmojiStake_Roll, font: Font.semibold(17.0), color: theme.list.itemCheckColors.foregroundColor))))
|
||||
|
||||
let buttonInsets = ContainerViewLayout.concentricInsets(bottomInset: environment.safeInsets.bottom, innerDiameter: 52.0, sideInset: 30.0)
|
||||
let button = button.update(
|
||||
|
|
@ -449,7 +446,7 @@ private final class EmojiGameStakeSheetComponent: CombinedComponent {
|
|||
|
||||
var buttonItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "icon", component: AnyComponent(Image(image: PresentationResourcesItemList.itemListRoundTopupIcon(environment.theme), tintColor: theme.list.itemCheckColors.foregroundColor, size: CGSize(width: 16.0, height: 18.0)))))
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: "Save and Roll", font: Font.semibold(17.0), color: theme.list.itemCheckColors.foregroundColor))))
|
||||
buttonItems.append(AnyComponentWithIdentity(id: "label", component: AnyComponent(Text(text: environment.strings.EmojiStake_Roll, font: Font.semibold(17.0), color: theme.list.itemCheckColors.foregroundColor))))
|
||||
|
||||
let sheet = sheet.update(
|
||||
component: ResizableSheetComponent<EnvironmentType>(
|
||||
|
|
@ -464,7 +461,7 @@ private final class EmojiGameStakeSheetComponent: CombinedComponent {
|
|||
}
|
||||
)),
|
||||
titleItem: AnyComponent(
|
||||
Text(text: "Emoji Stake", font: Font.bold(17.0), color: theme.list.itemPrimaryTextColor)
|
||||
Text(text: environment.strings.EmojiStake_Title, font: Font.bold(17.0), color: theme.list.itemPrimaryTextColor)
|
||||
),
|
||||
leftItem: AnyComponent(
|
||||
GlassBarButtonComponent(
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ import TelegramUIPreferences
|
|||
import GenerateStickerPlaceholderImage
|
||||
import UIKitRuntimeUtils
|
||||
import ComponentFlow
|
||||
import RLottieBinding
|
||||
import GZip
|
||||
|
||||
public func generateTopicIcon(title: String, backgroundColors: [UIColor], strokeColors: [UIColor], size: CGSize) -> UIImage? {
|
||||
let realSize = size
|
||||
|
|
@ -497,6 +499,10 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||
case .verification:
|
||||
self.updateVerification()
|
||||
self.updateTintColor()
|
||||
case .dice:
|
||||
if let file {
|
||||
self.updateDice(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||
}
|
||||
}
|
||||
} else if let file = file {
|
||||
self.updateFile(file: file, attemptSynchronousLoad: attemptSynchronousLoad)
|
||||
|
|
@ -720,6 +726,44 @@ public final class InlineStickerItemLayer: MultiAnimationRenderTarget {
|
|||
}
|
||||
}
|
||||
|
||||
private func updateDice(file: TelegramMediaFile, attemptSynchronousLoad: Bool) {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
}
|
||||
let _ = (arguments.context.postbox.mediaBox.resourceData(file.resource)
|
||||
|> filter { resource in
|
||||
return resource.complete
|
||||
}
|
||||
|> map { resource -> UIImage? in
|
||||
guard var data = try? Data(contentsOf: URL(fileURLWithPath: resource.path)) else {
|
||||
return nil
|
||||
}
|
||||
if let unpackedData = TGGUnzipData(data, 5 * 1024 * 1024) {
|
||||
data = unpackedData
|
||||
}
|
||||
guard let instance = LottieInstance(data: data, fitzModifier: .none, colorReplacements: nil, cacheKey: "") else {
|
||||
return nil
|
||||
}
|
||||
let size = CGSize(width: 128.0, height: 128.0)
|
||||
if let diceContext = DrawingContext(size: size, scale: 1.0, opaque: false, clear: true) {
|
||||
instance.renderFrame(with: instance.frameCount - 1, into: diceContext.bytes.assumingMemoryBound(to: UInt8.self), width: Int32(diceContext.scaledSize.width), height: Int32(diceContext.scaledSize.height), bytesPerRow: Int32(diceContext.bytesPerRow))
|
||||
if let diceImage = diceContext.generateImage() {
|
||||
let drawingContext = DrawingContext(size: size, scale: 1.0, opaque: false, clear: true)
|
||||
drawingContext?.withFlippedContext { context in
|
||||
if let cgImage = diceImage.cgImage {
|
||||
context.draw(cgImage, in: CGRect(origin: CGPoint(x: -30.0, y: 5.0), size: CGSize(width: 180.0, height: 180.0)))
|
||||
}
|
||||
}
|
||||
return drawingContext?.generateImage()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|> deliverOnMainQueue).start(next: { image in
|
||||
self.contents = image?.cgImage
|
||||
})
|
||||
}
|
||||
|
||||
private func loadLocalAnimation() {
|
||||
guard let arguments = self.arguments else {
|
||||
return
|
||||
|
|
|
|||
|
|
@ -632,7 +632,7 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
|||
topOffset += dayHeights
|
||||
}
|
||||
|
||||
topOffset += 11.0
|
||||
topOffset += 15.0
|
||||
|
||||
transition.updateFrame(node: self.labelNode, frame: labelFrame)
|
||||
|
||||
|
|
|
|||
|
|
@ -484,18 +484,18 @@ private final class FilterHeaderButton: HighlightableButtonNode {
|
|||
component: AnyComponent(
|
||||
BundleIconComponent(
|
||||
name: "Peer Info/SortIcon",
|
||||
tintColor: theme.rootController.navigationBar.accentTextColor
|
||||
tintColor: theme.chat.inputPanel.panelControlColor
|
||||
)
|
||||
),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 30.0, height: 30.0)
|
||||
containerSize: CGSize(width: 44.0, height: 44.0)
|
||||
)
|
||||
if let view = self.icon.view {
|
||||
if view.superview == nil {
|
||||
view.isUserInteractionEnabled = false
|
||||
self.referenceNode.view.addSubview(view)
|
||||
}
|
||||
view.frame = CGRect(origin: CGPoint(x: 14.0, y: 7.0), size: iconSize)
|
||||
view.frame = CGRect(origin: CGPoint(x: 7.0, y: 7.0), size: iconSize)
|
||||
}
|
||||
|
||||
self.containerNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: 44.0, height: 44.0))
|
||||
|
|
|
|||
|
|
@ -67,10 +67,9 @@ extension ChatControllerImpl {
|
|||
var changeAction: String?
|
||||
var tonAmount: Int64?
|
||||
if canSendMessages, emoji == "🎲", case let .available(info) = gameInfo {
|
||||
//TODO:localize
|
||||
let currentStake = info.previousStake
|
||||
value = "Stake: $ \(formatTonAmountText(currentStake, dateTimeFormat: self.presentationData.dateTimeFormat))"
|
||||
changeAction = "change"
|
||||
value = "\(self.presentationData.strings.Conversation_Dice_Stake) $ \(formatTonAmountText(currentStake, dateTimeFormat: self.presentationData.dateTimeFormat))"
|
||||
changeAction = self.presentationData.strings.Conversation_Dice_Change
|
||||
tonAmount = info.previousStake
|
||||
} else {
|
||||
switch emoji {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue