Various fixes

This commit is contained in:
Ilya Laktyushin 2025-02-26 21:53:14 +04:00
parent d43f05d7eb
commit 3f12448474
9 changed files with 94 additions and 63 deletions

View File

@ -13887,7 +13887,11 @@ Sorry for the inconvenience.";
"Chat.NonContactUser.UpdatedName" = "User updated name %1$@"; "Chat.NonContactUser.UpdatedName" = "User updated name %1$@";
"Chat.NonContactUser.UpdatedPhoto" = "User updated photo %1$@"; "Chat.NonContactUser.UpdatedPhoto" = "User updated photo %1$@";
"Chat.NonContactUser.UpdatedToday" = "today";
"Chat.NonContactUser.UpdatedMinutes_1" = "%@ minute ago";
"Chat.NonContactUser.UpdatedMinutes_any" = "%@ minutes ago";
"Chat.NonContactUser.UpdatedHours_1" = "%@ hour ago";
"Chat.NonContactUser.UpdatedHours_any" = "%@ hours ago";
"Chat.NonContactUser.UpdatedDays_1" = "%@ day ago"; "Chat.NonContactUser.UpdatedDays_1" = "%@ day ago";
"Chat.NonContactUser.UpdatedDays_any" = "%@ days ago"; "Chat.NonContactUser.UpdatedDays_any" = "%@ days ago";
@ -13933,3 +13937,39 @@ Sorry for the inconvenience.";
"PeerInfo.Gifts.ToastUnpinned.Text" = "Gift Unpinned."; "PeerInfo.Gifts.ToastUnpinned.Text" = "Gift Unpinned.";
"PeerInfo.Gifts.ToastPinned.Title" = "Gift Pinned"; "PeerInfo.Gifts.ToastPinned.Title" = "Gift Pinned";
"PeerInfo.Gifts.ToastPinned.Text" = "Now it will always be shown on the top."; "PeerInfo.Gifts.ToastPinned.Text" = "Now it will always be shown on the top.";
"Chat.PaidMessage.Confirm.Title" = "Confirm Payment";
"Chat.PaidMessage.Confirm.DontAskAgain" = "Don't ask again";
"Chat.PaidMessage.Confirm.PayForMessage_1" = "Pay for %@ Message";
"Chat.PaidMessage.Confirm.PayForMessage_any" = "Pay for %@ Messages";
"Chat.PaidMessage.Confirm.Single.Text" = "**%1$@** charges **%2$@** per incoming message. Would you like to pay **%3$@** to send %4$@?";
"Chat.PaidMessage.Confirm.Multiple.Text" = "You selected %1$@ who charge Stars for messages. Would you like to pay **%2$@** Stars to send %3$@?";
"Chat.PaidMessage.Confirm.Text.Users_1" = "**%@** user";
"Chat.PaidMessage.Confirm.Text.Users_any" = "**%@** users";
"Chat.PaidMessage.Confirm.Text.Messages_1" = "**%@** message";
"Chat.PaidMessage.Confirm.Text.Messages_any" = "**%@** messages";
"Chat.PaidMessage.Confirm.Text.Stars_1" = "%@ Star";
"Chat.PaidMessage.Confirm.Text.Stars_any" = "%@ Stars";
"Chat.PaidMessage.RemoveFee.Title" = "Remove Fee";
"Chat.PaidMessage.RemoveFee.Text" = "Are you sure you want to allow **%@** to message you for free?";
"Chat.PaidMessage.RemoveFee.Yes" = "Yes";
"Chat.PaidMessage.RemoveFee.Refund" = "Refund already paid **%@**";
"Chat.PaidMessage.RemoveFee.Refund.Stars_1" = "%@ Star";
"Chat.PaidMessage.RemoveFee.Refund.Stars_any" = "%@ Stars";
"Chat.PaidMessage.Sent.Title_1" = "Message Sent";
"Chat.PaidMessage.Sent.Title_any" = "%@ Messages Sent";
"Chat.PaidMessage.Sent.Text" = "You paid %@";
"Chat.PaidMessage.Sent.Text.Stars_1" = "%@ Star";
"Chat.PaidMessage.Sent.Text.Stars_any" = "%@ Stars";
"Chat.PaidMessageFee.Text" = "%1$@ must pay %2$@ for each message to you.";
"Chat.PaidMessageFee.RemoveFee" = "Remove Fee";
"Privacy.Review.Review" = "Review";
"Privacy.Review.Calls.Title" = "Call Settings";
"Privacy.Review.Calls.Text" = "You've restricted who can message you, but anyone can still call you. Would you like to review these settings?";
"Privacy.Review.Invite.Title" = "Invitation Settings";
"Privacy.Review.Invite.Text" = "You've restricted who can message you, but anyone can still invite you to groups and channels. Would you like to review these settings?";

View File

@ -973,7 +973,7 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
text = presentationInterfaceState.strings.MediaPicker_Send text = presentationInterfaceState.strings.MediaPicker_Send
} }
actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, minimized: isMinimized, text: text, interfaceState: presentationInterfaceState) actionButtonsSize = self.actionButtons.updateLayout(size: CGSize(width: 44.0, height: minimalHeight), transition: transition, minimized: isMinimized, text: text, interfaceState: presentationInterfaceState)
textBackgroundInset = 44.0 - actionButtonsSize.width textBackgroundInset = actionButtonsSize.width - 44.0
} else { } else {
actionButtonsSize = CGSize(width: 44.0, height: minimalHeight) actionButtonsSize = CGSize(width: 44.0, height: minimalHeight)
} }
@ -981,11 +981,11 @@ public class AttachmentTextInputPanelNode: ASDisplayNode, TGCaptionPanelView, AS
let actionButtonsFrame = CGRect(origin: CGPoint(x: width - rightInset - actionButtonsSize.width + 1.0 - UIScreenPixel + composeButtonsOffset, y: panelHeight - minimalHeight), size: actionButtonsSize) let actionButtonsFrame = CGRect(origin: CGPoint(x: width - rightInset - actionButtonsSize.width + 1.0 - UIScreenPixel + composeButtonsOffset, y: panelHeight - minimalHeight), size: actionButtonsSize)
transition.updateFrame(node: self.actionButtons, frame: actionButtonsFrame) transition.updateFrame(node: self.actionButtons, frame: actionButtonsFrame)
let textInputBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: textInputFrame.size.width + composeButtonsOffset + textBackgroundInset, height: textInputFrame.size.height)) let textInputBackgroundFrame = CGRect(origin: CGPoint(), size: CGSize(width: textInputFrame.size.width + composeButtonsOffset, height: textInputFrame.size.height))
transition.updateFrame(node: self.textInputContainerBackgroundNode, frame: textInputBackgroundFrame) transition.updateFrame(node: self.textInputContainerBackgroundNode, frame: textInputBackgroundFrame)
transition.updateFrame(layer: self.textInputBackgroundNode.layer, frame: CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top, width: baseWidth - textFieldInsets.left - textFieldInsets.right + composeButtonsOffset + textBackgroundInset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom)) transition.updateFrame(layer: self.textInputBackgroundNode.layer, frame: CGRect(x: leftInset + textFieldInsets.left, y: textFieldInsets.top, width: baseWidth - textFieldInsets.left - textFieldInsets.right + composeButtonsOffset - textBackgroundInset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom))
transition.updateFrame(layer: self.textInputBackgroundImageNode.layer, frame: CGRect(x: 0.0, y: 0.0, width: baseWidth - textFieldInsets.left - textFieldInsets.right + composeButtonsOffset + textBackgroundInset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom)) transition.updateFrame(layer: self.textInputBackgroundImageNode.layer, frame: CGRect(x: 0.0, y: 0.0, width: baseWidth - textFieldInsets.left - textFieldInsets.right + composeButtonsOffset - textBackgroundInset, height: panelHeight - textFieldInsets.top - textFieldInsets.bottom))
var textInputViewRealInsets = UIEdgeInsets() var textInputViewRealInsets = UIEdgeInsets()
if let presentationInterfaceState = self.presentationInterfaceState { if let presentationInterfaceState = self.presentationInterfaceState {

View File

@ -1470,16 +1470,15 @@ public func privacyAndSecurityController(
} }
showPrivacySuggestionImpl = { showPrivacySuggestionImpl = {
//TODO:localize
let presentationData = context.sharedContext.currentPresentationData.with { $0 } let presentationData = context.sharedContext.currentPresentationData.with { $0 }
if reviewCallPrivacySuggestion { if reviewCallPrivacySuggestion {
reviewCallPrivacySuggestion = false reviewCallPrivacySuggestion = false
let alertController = textAlertController( let alertController = textAlertController(
context: context, context: context,
title: "Call Settings", title: presentationData.strings.Privacy_Review_Calls_Title,
text: "You've restricted who can message you, but anyone can still call you. Would you like to review these settings?", text: presentationData.strings.Privacy_Review_Calls_Text,
actions: [ actions: [
TextAlertAction(type: .defaultAction, title: "Review", action: { TextAlertAction(type: .defaultAction, title: presentationData.strings.Privacy_Review_Review, action: {
arguments.openVoiceCallPrivacy() arguments.openVoiceCallPrivacy()
}), }),
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
@ -1495,10 +1494,10 @@ public func privacyAndSecurityController(
reviewInvitePrivacySuggestion = false reviewInvitePrivacySuggestion = false
let alertController = textAlertController( let alertController = textAlertController(
context: context, context: context,
title: "Invitation Settings", title: presentationData.strings.Privacy_Review_Invite_Title,
text: "You've restricted who can message you, but anyone can still invite you to groups and channels. Would you like to review these settings?", text: presentationData.strings.Privacy_Review_Invite_Text,
actions: [ actions: [
TextAlertAction(type: .defaultAction, title: "Review", action: { TextAlertAction(type: .defaultAction, title: presentationData.strings.Privacy_Review_Review, action: {
arguments.openGroupsPrivacy() arguments.openGroupsPrivacy()
}), }),
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {

View File

@ -659,3 +659,15 @@ public func stringForRemainingMuteInterval(strings: PresentationStrings, muteInt
return strings.MuteExpires_Days(Int32(round(Float(value) / (24 * 60 * 60)))) return strings.MuteExpires_Days(Int32(round(Float(value) / (24 * 60 * 60))))
} }
} }
public func stringForIntervalSinceUpdateAction(strings: PresentationStrings, value: Int32) -> String {
let timestamp = Int32(CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970)
let value = max(1 * 60, timestamp - value)
if value <= 1 * 60 * 60 {
return strings.Chat_NonContactUser_UpdatedMinutes(Int32(round(Float(value) / 60)))
} else if value <= 24 * 60 * 60 {
return strings.Chat_NonContactUser_UpdatedHours(Int32(round(Float(value) / (60 * 60))))
} else {
return strings.Chat_NonContactUser_UpdatedDays(Int32(round(Float(value) / (24 * 60 * 60))))
}
}

View File

@ -1283,8 +1283,7 @@ final class AvatarEditorScreenComponent: Component {
case .suggest: case .suggest:
buttonText = strings.AvatarEditor_SuggestProfilePhoto buttonText = strings.AvatarEditor_SuggestProfilePhoto
case .user: case .user:
//TODO:localize buttonText = strings.AvatarEditor_SetProfilePhoto
buttonText = "Set My Photo" //strings.AvatarEditor_SetProfilePhoto
case .group, .forum: case .group, .forum:
buttonText = strings.AvatarEditor_SetGroupPhoto buttonText = strings.AvatarEditor_SetGroupPhoto
case .channel: case .channel:

View File

@ -424,17 +424,9 @@ public func chatMessagePaymentAlertController(
var completionImpl: (() -> Void)? var completionImpl: (() -> Void)?
var dismissImpl: (() -> Void)? var dismissImpl: (() -> Void)?
//TODO:localize let title = presentationData.strings.Chat_PaidMessage_Confirm_Title
let title = "Confirm Payment" let actionTitle = presentationData.strings.Chat_PaidMessage_Confirm_PayForMessage(count)
let actionTitle: String let messagesString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Messages(count)
let messagesString: String
if count > 1 {
messagesString = "**\(count)** messages"
actionTitle = "Pay for \(count) Messages"
} else {
messagesString = "**\(count)** message"
actionTitle = "Pay for 1 Message"
}
let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: actionTitle, action: { let actions: [TextAlertAction] = [TextAlertAction(type: .defaultAction, title: actionTitle, action: {
completionImpl?() completionImpl?()
@ -442,17 +434,20 @@ public func chatMessagePaymentAlertController(
}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
dismissImpl?() dismissImpl?()
})] })]
let text: String let text: String
if peers.count == 1, let peer = peers.first { if peers.count == 1, let peer = peers.first {
text = "**\(peer.compactDisplayTitle)** charges **\(amount.value) Stars** per incoming message. Would you like to pay **\(amount.value * Int64(count)) Stars** to send \(messagesString)?" let amountString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Stars(Int32(amount.value))
let totalString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Stars(Int32(amount.value * Int64(count)))
text = presentationData.strings.Chat_PaidMessage_Confirm_Single_Text(peer.compactDisplayTitle, amountString, totalString, messagesString).string
} else { } else {
let amount = totalAmount ?? amount let amount = totalAmount ?? amount
text = "You selected **\(peers.count)** users who charge Stars for messages. Would you like to pay **\(amount.value)** Stars to send \(messagesString)?" let usersString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Users(Int32(peers.count))
let totalString = presentationData.strings.Chat_PaidMessage_Confirm_Text_Stars(Int32(amount.value * Int64(count)))
text = presentationData.strings.Chat_PaidMessage_Confirm_Multiple_Text(usersString, totalString, messagesString).string
} }
let optionText = hasCheck ? "Don't ask again" : nil let optionText = hasCheck ? presentationData.strings.Chat_PaidMessage_Confirm_DontAskAgain : nil
let contentNode = ChatMessagePaymentAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, optionText: optionText, actions: actions, alignment: .vertical) let contentNode = ChatMessagePaymentAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, optionText: optionText, actions: actions, alignment: .vertical)
@ -470,8 +465,6 @@ public func chatMessagePaymentAlertController(
return controller return controller
} }
public func chatMessageRemovePaymentAlertController( public func chatMessageRemovePaymentAlertController(
context: AccountContext? = nil, context: AccountContext? = nil,
presentationData: PresentationData, presentationData: PresentationData,
@ -488,20 +481,19 @@ public func chatMessageRemovePaymentAlertController(
var completionImpl: (() -> Void)? var completionImpl: (() -> Void)?
var dismissImpl: (() -> Void)? var dismissImpl: (() -> Void)?
//TODO:localize
let actions: [TextAlertAction] = [ let actions: [TextAlertAction] = [
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: { TextAlertAction(type: .genericAction, title: strings.Common_Cancel, action: {
dismissImpl?() dismissImpl?()
}), }),
TextAlertAction(type: .defaultAction, title: "Yes", action: { TextAlertAction(type: .defaultAction, title: strings.Chat_PaidMessage_RemoveFee_Yes, action: {
completionImpl?() completionImpl?()
dismissImpl?() dismissImpl?()
}) })
] ]
let title = "Remove Fee" let title = strings.Chat_PaidMessage_RemoveFee_Title
let text = "Are you sure you want to allow **\(peer.compactDisplayTitle)** to message you for free?" let text = strings.Chat_PaidMessage_RemoveFee_Text(peer.compactDisplayTitle).string
let optionText = amount.flatMap { "Refund already paid **\($0.value) Stars**" } let optionText = amount.flatMap { strings.Chat_PaidMessage_RemoveFee_Refund(strings.Chat_PaidMessage_RemoveFee_Refund_Stars(Int32($0.value))).string }
let contentNode = ChatMessagePaymentAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, optionText: optionText, actions: actions, alignment: .horizontal) let contentNode = ChatMessagePaymentAlertContentNode(theme: AlertControllerTheme(presentationData: presentationData), ptheme: theme, strings: strings, title: title, text: text, optionText: optionText, actions: actions, alignment: .horizontal)

View File

@ -21,12 +21,14 @@ extension ChatControllerImpl {
return return
} }
if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars { if let sendPaidMessageStars = self.presentationInterfaceState.sendPaidMessageStars {
let totalAmount = sendPaidMessageStars.value * Int64(count)
let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id) let _ = (ApplicationSpecificNotice.dismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id)
|> deliverOnMainQueue).start(next: { [weak self] dismissedAmount in |> deliverOnMainQueue).start(next: { [weak self] dismissedAmount in
guard let self, let starsContext = self.context.starsContext else { guard let self, let starsContext = self.context.starsContext else {
return return
} }
if let dismissedAmount, dismissedAmount == sendPaidMessageStars.value, let currentState = starsContext.currentState, currentState.balance > sendPaidMessageStars { if let dismissedAmount, dismissedAmount == sendPaidMessageStars.value, let currentState = starsContext.currentState, currentState.balance.value > totalAmount, count < 3 && totalAmount < 100 {
completion(true) completion(true)
self.displayPaidMessageUndo(count: count, amount: sendPaidMessageStars) self.displayPaidMessageUndo(count: count, amount: sendPaidMessageStars)
} else { } else {
@ -52,14 +54,14 @@ extension ChatControllerImpl {
let _ = ApplicationSpecificNotice.setDismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id, amount: sendPaidMessageStars.value).start() let _ = ApplicationSpecificNotice.setDismissedPaidMessageWarningNamespace(accountManager: self.context.sharedContext.accountManager, peerId: peer.id, amount: sendPaidMessageStars.value).start()
} }
if let currentState = starsContext.currentState, currentState.balance < sendPaidMessageStars { if let currentState = starsContext.currentState, currentState.balance.value < totalAmount {
let _ = (self.context.engine.payments.starsTopUpOptions() let _ = (self.context.engine.payments.starsTopUpOptions()
|> take(1) |> take(1)
|> deliverOnMainQueue).startStandalone(next: { [weak self] options in |> deliverOnMainQueue).startStandalone(next: { [weak self] options in
guard let self else { guard let self else {
return return
} }
let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: sendPaidMessageStars.value), completion: { _ in let controller = self.context.sharedContext.makeStarsPurchaseScreen(context: self.context, starsContext: starsContext, options: options, purpose: .sendMessage(peerId: peer.id, requiredStars: totalAmount), completion: { _ in
completion(false) completion(false)
}) })
self.push(controller) self.push(controller)
@ -89,18 +91,11 @@ extension ChatControllerImpl {
self.context.engine.messages.forceSendPostponedPaidMessage(peerId: peerId) self.context.engine.messages.forceSendPostponedPaidMessage(peerId: peerId)
} }
//TODO:localize let title = self.presentationData.strings.Chat_PaidMessage_Sent_Title(count)
let title: String let text = self.presentationData.strings.Chat_PaidMessage_Sent_Text(self.presentationData.strings.Chat_PaidMessage_Sent_Text_Stars(Int32(amount.value * Int64(count)))).string
if count > 1 {
title = "\(count) Messages Sent"
} else {
title = "Message Sent"
}
let textItems: [AnimatedTextComponent.Item] = [ let textItems: [AnimatedTextComponent.Item] = [
AnimatedTextComponent.Item(id: 0, content: .text("You paid \(amount.value * Int64(count)) Stars")) AnimatedTextComponent.Item(id: 0, content: .text(text))
] ]
let controller = UndoOverlayController(presentationData: self.presentationData, content: .starsSent(context: self.context, title: title, text: textItems), elevatedLayout: false, position: .top, action: { [weak self] action in let controller = UndoOverlayController(presentationData: self.presentationData, content: .starsSent(context: self.context, title: title, text: textItems), elevatedLayout: false, position: .top, action: { [weak self] action in
guard let self else { guard let self else {
return false return false

View File

@ -89,14 +89,13 @@ final class ChatFeePanelNode: ASDisplayNode {
if self.theme !== interfaceState.theme { if self.theme !== interfaceState.theme {
self.theme = interfaceState.theme self.theme = interfaceState.theme
self.separatorNode.backgroundColor = interfaceState.theme.rootController.navigationBar.separatorColor self.separatorNode.backgroundColor = interfaceState.theme.rootController.navigationBar.separatorColor
//TODO:localize self.removeTextNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PaidMessageFee_RemoveFee, font: Font.regular(17.0), textColor: interfaceState.theme.chat.inputPanel.panelControlAccentColor)
self.removeTextNode.attributedText = NSAttributedString(string: "Remove Fee", font: Font.regular(17.0), textColor: interfaceState.theme.chat.inputPanel.panelControlAccentColor)
} }
let paidMessageStars = interfaceState.contactStatus?.peerStatusSettings?.paidMessageStars?.value ?? 0 let paidMessageStars = interfaceState.contactStatus?.peerStatusSettings?.paidMessageStars?.value ?? 0
if let peer = interfaceState.renderedPeer?.peer.flatMap(EnginePeer.init) { if let peer = interfaceState.renderedPeer?.peer.flatMap(EnginePeer.init) {
let attributedText = NSMutableAttributedString(string: "\(peer.compactDisplayTitle) must pay ⭐️\(paidMessageStars) for each message to you.", font: Font.regular(12.0), textColor: interfaceState.theme.rootController.navigationBar.secondaryTextColor) let attributedText = NSMutableAttributedString(string: interfaceState.strings.Chat_PaidMessageFee_Text(peer.compactDisplayTitle, "⭐️\(paidMessageStars)").string, font: Font.regular(12.0), textColor: interfaceState.theme.rootController.navigationBar.secondaryTextColor)
let range = (attributedText.string as NSString).range(of: "⭐️") let range = (attributedText.string as NSString).range(of: "⭐️")
if range.location != NSNotFound { if range.location != NSNotFound {
attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: true)), range: range) attributedText.addAttribute(ChatTextInputAttributes.customEmoji, value: ChatTextInputTextCustomEmojiAttribute(interactivelySelectedFromPackId: nil, fileId: 0, file: nil, custom: .stars(tinted: true)), range: range)

View File

@ -11,6 +11,7 @@ import ChatMessageItemCommon
import TextFormat import TextFormat
import Markdown import Markdown
import Display import Display
import TelegramStringFormatting
struct ChatHistoryEntriesForViewState { struct ChatHistoryEntriesForViewState {
private var messageStableIdToLocalId: [UInt32: Int64] = [:] private var messageStableIdToLocalId: [UInt32: Int64] = [:]
@ -442,11 +443,8 @@ func chatHistoryEntriesForView(
if peerStatusSettings.flags.contains(.canAddContact) || peerStatusSettings.flags.contains(.canReport) || peerStatusSettings.flags.contains(.canBlock) { if peerStatusSettings.flags.contains(.canAddContact) || peerStatusSettings.flags.contains(.canReport) || peerStatusSettings.flags.contains(.canBlock) {
if let chatPeer, let photoChangeDate = peerStatusSettings.photoChangeDate, photoChangeDate > 0 { if let chatPeer, let photoChangeDate = peerStatusSettings.photoChangeDate, photoChangeDate > 0 {
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) let timeText = stringForIntervalSinceUpdateAction(strings: presentationData.strings, value: photoChangeDate)
let days = Int32(floor(Float(currentTime - photoChangeDate) / 86400.0)) let text = presentationData.strings.Chat_NonContactUser_UpdatedPhoto(timeText)
let text = presentationData.strings.Chat_NonContactUser_UpdatedPhoto(
days == 0 ? presentationData.strings.Chat_NonContactUser_UpdatedToday : presentationData.strings.Chat_NonContactUser_UpdatedDays(days)
)
var entities: [MessageTextEntity] = [] var entities: [MessageTextEntity] = []
for range in text.ranges { for range in text.ranges {
entities.append(MessageTextEntity(range: range.range.lowerBound ..< range.range.upperBound, type: .Bold)) entities.append(MessageTextEntity(range: range.range.lowerBound ..< range.range.upperBound, type: .Bold))
@ -485,11 +483,8 @@ func chatHistoryEntriesForView(
} }
if let chatPeer, let nameChangeDate = peerStatusSettings.nameChangeDate, nameChangeDate > 0 { if let chatPeer, let nameChangeDate = peerStatusSettings.nameChangeDate, nameChangeDate > 0 {
let currentTime = Int32(CFAbsoluteTimeGetCurrent() + kCFAbsoluteTimeIntervalSince1970) let timeText = stringForIntervalSinceUpdateAction(strings: presentationData.strings, value: nameChangeDate)
let days = Int32(floor(Float(currentTime - nameChangeDate) / 86400.0)) let text = presentationData.strings.Chat_NonContactUser_UpdatedName(timeText)
let text = presentationData.strings.Chat_NonContactUser_UpdatedName(
days == 0 ? presentationData.strings.Chat_NonContactUser_UpdatedToday : presentationData.strings.Chat_NonContactUser_UpdatedDays(days)
)
var entities: [MessageTextEntity] = [] var entities: [MessageTextEntity] = []
for range in text.ranges { for range in text.ranges {
entities.append(MessageTextEntity(range: range.range.lowerBound ..< range.range.upperBound, type: .Bold)) entities.append(MessageTextEntity(range: range.range.lowerBound ..< range.range.upperBound, type: .Bold))