mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-05 19:28:46 +02:00
Various improvements
This commit is contained in:
parent
92c350b559
commit
ea090a6858
15 changed files with 168 additions and 70 deletions
|
|
@ -16176,6 +16176,7 @@ Error: %8$@";
|
|||
"CreatePoll.OptionsNeededOne" = "Add at least one option";
|
||||
"CreatePoll.QuizCorrectOptionNeeded" = "Select a correct option";
|
||||
"CreatePoll.QuizCorrectOptionNeededMultiple" = "Select at least one correct option";
|
||||
"CreatePoll.QuizCountryNeeded" = "Select at least one country";
|
||||
|
||||
"Stars.Intro.Transaction.Commission.Title" = "%@ commission";
|
||||
|
||||
|
|
@ -16192,7 +16193,7 @@ Error: %8$@";
|
|||
"CreatePoll.AllowedCountries.Countries_1" = "%@ country";
|
||||
"CreatePoll.AllowedCountries.Countries_any" = "%@ countries";
|
||||
|
||||
"Chat.Poll.Restriction.Subscribers" = "Only subscribers of **%@** can vote";
|
||||
"Chat.Poll.Restriction.Subscribers" = "Only subscribers of **%@** can vote.";
|
||||
"Chat.Poll.Restriction.Subscribers.TimeLimit" = "Only subscribers who joined more than **24 hours** ago can vote.";
|
||||
"Chat.Poll.Restriction.Country" = "Only users from %@ can vote.";
|
||||
"Chat.Poll.Restriction.SubscribersCountry" = "Only subscribers of **%@** from %@ can vote.";
|
||||
|
|
@ -16232,3 +16233,26 @@ Error: %8$@";
|
|||
"Login.Fee.GetPremiumForDays" = "Get Telegram Premium for %@";
|
||||
"Login.Fee.GetPremiumForDays.Days_1" = "%@ day";
|
||||
"Login.Fee.GetPremiumForDays.Days_any" = "%@ days";
|
||||
|
||||
"PeerInfo.DeleteReaction" = "Delete Reaction";
|
||||
"Chat.DeleteReactionInfo" = "Tap and hold to delete reaction.";
|
||||
|
||||
"Chat.AdminActionSheet.DeleteReactionTitle" = "Delete 1 Reaction";
|
||||
"Chat.AdminActionSheet.DeleteAllMessages" = "Delete All Messages";
|
||||
"Chat.AdminActionSheet.DeleteAllReactions" = "Delete All Reactions";
|
||||
|
||||
"Conversation.CalendarSearch.Title" = "Search";
|
||||
"Conversation.CalendarSearch.Done" = "Done";
|
||||
|
||||
"ScheduleMessage.SilentPosting.YouEnabled" = "You will receive a silent notification";
|
||||
"ScheduleMessage.SilentPosting.YouDisabled" = "You will be notified";
|
||||
"ScheduleMessage.SilentPosting.UserEnabled" = "%@ will receive a silent notification";
|
||||
"ScheduleMessage.SilentPosting.UserDisabled" = "%@ will be notified";
|
||||
"ScheduleMessage.SilentPosting.GroupEnabled" = "Members will receive a silent notification";
|
||||
"ScheduleMessage.SilentPosting.GroupDisabled" = "Members will be notified";
|
||||
"ScheduleMessage.SilentPosting.ChannelEnabled" = "Subscribers will receive a silent notification";
|
||||
"ScheduleMessage.SilentPosting.ChannelDisabled" = "Subscribers will be notified";
|
||||
|
||||
"Settings.ChatAutomation" = "Chat Automation";
|
||||
"Settings.ChatAutomationInfo" = "Add a bot to reply to messages on your behalf.";
|
||||
"Settings.ChatAutomationOff" = "Off";
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ private let markdownInlineHTMLInlineIntent = InlinePresentationIntent(rawValue:
|
|||
|
||||
private let markdownDefaultBlockImageDimensions = PixelDimensions(width: 1200, height: 900)
|
||||
private let markdownDefaultInlineImageDimensions = PixelDimensions(width: 18, height: 18)
|
||||
private let markdownImageParsingEnabled = false
|
||||
private let markdownTaskListUncheckedNumber = "\u{001f}tg-md-task:unchecked"
|
||||
private let markdownTaskListCheckedNumber = "\u{001f}tg-md-task:checked"
|
||||
private let markdownRawHTMLTagRegex = try! NSRegularExpression(pattern: #"</?([A-Za-z][A-Za-z0-9:-]*)\b[^>]*?>"#)
|
||||
|
|
@ -353,6 +354,9 @@ private final class MarkdownConversionContext {
|
|||
}
|
||||
|
||||
func resolveImage(attributes: [NSAttributedString.Key: Any]) -> MarkdownResolvedImage? {
|
||||
guard markdownImageParsingEnabled else {
|
||||
return nil
|
||||
}
|
||||
guard let imageUrl = markdownImageURL(attributes: attributes) else {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -1166,10 +1170,8 @@ private func markdownBlocks(from node: MarkdownIntentNode, context: MarkdownConv
|
|||
switch level {
|
||||
case Int.min ... 1:
|
||||
return [.title(text)]
|
||||
case 2:
|
||||
return [.header(text)]
|
||||
default:
|
||||
return [.heading(text: text, level: Int32(max(3, min(level, 6))))]
|
||||
return [.heading(text: text, level: Int32(max(2, min(level, 6))))]
|
||||
}
|
||||
case .paragraph:
|
||||
guard let inlineContent = markdownInlineContent(from: node.attributedText, context: context) else {
|
||||
|
|
|
|||
|
|
@ -7389,3 +7389,25 @@ private final class AdsInfoContextReferenceContentSource: ContextReferenceConten
|
|||
return ContextControllerReferenceViewInfo(referenceView: self.sourceView, contentAreaInScreenSpace: UIScreen.main.bounds.inset(by: self.insets), insets: self.contentInsets)
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChatListNavigationTarget {
|
||||
public let chatListController: ChatListControllerImpl
|
||||
public let popToController: ViewController?
|
||||
}
|
||||
|
||||
public func resolveChatListNavigationTarget(navigationController: NavigationController, excluding excludedController: ViewController? = nil) -> ChatListNavigationTarget? {
|
||||
for case let controller as ViewController in navigationController.viewControllers.reversed() {
|
||||
if let excludedController, controller === excludedController {
|
||||
continue
|
||||
}
|
||||
if let chatListController = controller as? ChatListControllerImpl, !chatListController.previewing {
|
||||
return ChatListNavigationTarget(chatListController: chatListController, popToController: controller)
|
||||
}
|
||||
}
|
||||
|
||||
if let controller = navigationController.viewControllers.first as? TabBarController, let chatListController = controller.currentController as? ChatListControllerImpl {
|
||||
return ChatListNavigationTarget(chatListController: chatListController, popToController: nil)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,5 +92,18 @@ public func chatTextLinkEditController(
|
|||
dismissImpl = { [weak alertController] in
|
||||
alertController?.dismiss(completion: nil)
|
||||
}
|
||||
|
||||
if link == nil {
|
||||
Queue.mainQueue().after(0.1, {
|
||||
let pasteboard = UIPasteboard.general
|
||||
if pasteboard.hasURLs {
|
||||
if inputState.value.string.isEmpty, let url = pasteboard.url?.absoluteString, !url.isEmpty {
|
||||
let value = NSAttributedString(string: url)
|
||||
inputState.setValue(value, selectionRange: 0 ..< value.length)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return alertController
|
||||
}
|
||||
|
|
|
|||
|
|
@ -302,9 +302,8 @@ private func adminUserActionsTitle(
|
|||
} else {
|
||||
return strings.Chat_AdminActionSheet_DeleteTitle(Int32(messageCount))
|
||||
}
|
||||
case .chatReaction(_):
|
||||
//TODO:localize
|
||||
return "Delete 1 Reaction"
|
||||
case .chatReaction:
|
||||
return strings.Chat_AdminActionSheet_DeleteReactionTitle
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -535,14 +534,13 @@ private final class AdminUserActionsContentComponent: Component {
|
|||
))))
|
||||
}
|
||||
} else {
|
||||
//TODO:localize
|
||||
subItems.append(
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: component.theme,
|
||||
style: .glass,
|
||||
title: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Delete all Messages",
|
||||
string: component.strings.Chat_AdminActionSheet_DeleteAllMessages,
|
||||
font: Font.regular(component.presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: component.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
|
|
@ -568,7 +566,7 @@ private final class AdminUserActionsContentComponent: Component {
|
|||
style: .glass,
|
||||
title: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Delete all Reactions",
|
||||
string: component.strings.Chat_AdminActionSheet_DeleteAllReactions,
|
||||
font: Font.regular(component.presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: component.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public final class AlertMultilineInputFieldComponent: Component {
|
|||
public fileprivate(set) var value: NSAttributedString = NSAttributedString()
|
||||
public fileprivate(set) var animateError: () -> Void = {}
|
||||
public fileprivate(set) var activateInput: () -> Void = {}
|
||||
fileprivate var setValueImpl: ((NSAttributedString, Range<Int>) -> Void)?
|
||||
fileprivate let valuePromise = ValuePromise<NSAttributedString>(NSAttributedString())
|
||||
public var valueSignal: Signal<NSAttributedString, NoError> {
|
||||
return self.valuePromise.get()
|
||||
|
|
@ -32,6 +33,13 @@ public final class AlertMultilineInputFieldComponent: Component {
|
|||
|
||||
public init() {
|
||||
}
|
||||
|
||||
public func setValue(_ value: NSAttributedString, selectionRange: Range<Int>? = nil) {
|
||||
let selectionRange = selectionRange ?? (value.length ..< value.length)
|
||||
self.value = value
|
||||
self.valuePromise.set(value)
|
||||
self.setValueImpl?(value, selectionRange)
|
||||
}
|
||||
}
|
||||
|
||||
public enum FormatMenuAvailability: Equatable {
|
||||
|
|
@ -226,13 +234,18 @@ public final class AlertMultilineInputFieldComponent: Component {
|
|||
func update(component: AlertMultilineInputFieldComponent, availableSize: CGSize, state: EmptyComponentState, environment: Environment<AlertComponentEnvironment>, transition: ComponentTransition) -> CGSize {
|
||||
var resetText: NSAttributedString?
|
||||
if self.component == nil {
|
||||
resetText = component.initialValue
|
||||
resetText = component.initialValue ?? (component.externalState.value.length == 0 ? nil : component.externalState.value)
|
||||
component.externalState.animateError = { [weak self] in
|
||||
self?.animateError()
|
||||
}
|
||||
component.externalState.activateInput = { [weak self] in
|
||||
self?.activateInput()
|
||||
}
|
||||
component.externalState.setValueImpl = { [weak self] value, selectionRange in
|
||||
if let textFieldView = self?.textField.view as? TextFieldComponent.View {
|
||||
textFieldView.updateText(value, selectionRange: selectionRange)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let isFirstTime = self.component == nil
|
||||
|
|
|
|||
|
|
@ -2918,31 +2918,42 @@ public class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
|
|||
if case .public = poll.publicity {
|
||||
item.controllerInteraction.openMessagePollResults(item.message.id, option.opaqueIdentifier)
|
||||
} else if isRestricted {
|
||||
let locale = localeWithStrings(item.presentationData.strings)
|
||||
let countryNames = poll.countries.map { id in
|
||||
if let countryName = locale.localizedString(forRegionCode: id) {
|
||||
return countryName
|
||||
} else {
|
||||
return id
|
||||
}
|
||||
}
|
||||
var countries: String = ""
|
||||
if countryNames.count == 1, let country = countryNames.first {
|
||||
countries = "**\(country)**"
|
||||
} else {
|
||||
for i in 0 ..< countryNames.count {
|
||||
countries.append("**\(countryNames[i])**")
|
||||
if i == countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesLastDelimiter)
|
||||
} else if i < countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesDelimiter)
|
||||
let text: String
|
||||
|
||||
let peerName = item.message.peers[item.message.id.peerId].flatMap(EnginePeer.init)?.compactDisplayTitle ?? ""
|
||||
if !poll.countries.isEmpty {
|
||||
let locale = localeWithStrings(item.presentationData.strings)
|
||||
let countryNames = poll.countries.map { id in
|
||||
if let countryName = locale.localizedString(forRegionCode: id) {
|
||||
return countryName
|
||||
} else {
|
||||
return id
|
||||
}
|
||||
}
|
||||
var countries: String = ""
|
||||
if countryNames.count == 1, let country = countryNames.first {
|
||||
countries = "**\(country)**"
|
||||
} else {
|
||||
for i in 0 ..< countryNames.count {
|
||||
countries.append("**\(countryNames[i])**")
|
||||
if i == countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesLastDelimiter)
|
||||
} else if i < countryNames.count - 2 {
|
||||
countries.append(item.presentationData.strings.Chat_Poll_Restriction_Country_CountriesDelimiter)
|
||||
}
|
||||
}
|
||||
}
|
||||
if poll.restrictToSubscribers {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_SubscribersCountry(peerName, countries).string
|
||||
} else {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_Country(countries).string
|
||||
}
|
||||
} else {
|
||||
text = item.presentationData.strings.Chat_Poll_Restriction_Subscribers(peerName).string
|
||||
}
|
||||
//TODO:localize
|
||||
let controller = UndoOverlayController(
|
||||
presentationData: item.context.sharedContext.currentPresentationData.with { $0 },
|
||||
content: .banned(text: "Only users from \(countries) can vote."),
|
||||
content: .banned(text: text),
|
||||
elevatedLayout: true,
|
||||
position: .bottom,
|
||||
action: { _ in return true }
|
||||
|
|
|
|||
|
|
@ -174,42 +174,39 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
let isSilentPosting = self.isSilentPosting
|
||||
let _ = (component.context.engine.data.get(TelegramEngine.EngineData.Item.Peer.Peer(id: peerId))
|
||||
|> deliverOnMainQueue).start(next: { [weak self] peer in
|
||||
guard let self, let peer, let controller = self.environment?.controller() else {
|
||||
guard let self, let peer, let environment = self.environment, let controller = self.environment?.controller() else {
|
||||
return
|
||||
}
|
||||
|
||||
var isChannel = false
|
||||
if case let .channel(channel) = peer, case .broadcast = channel.info {
|
||||
isChannel = true
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let text: String
|
||||
if case let .user(user) = peer {
|
||||
if user.id == component.context.account.peerId {
|
||||
if isSilentPosting {
|
||||
text = "You will receive a silent notification"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_YouEnabled
|
||||
} else {
|
||||
text = "You will be notified"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_YouDisabled
|
||||
}
|
||||
} else {
|
||||
if isSilentPosting {
|
||||
text = "\(peer.compactDisplayTitle) will receive a silent notification"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_UserEnabled(peer.compactDisplayTitle).string
|
||||
} else {
|
||||
text = "\(peer.compactDisplayTitle) will be notified"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_UserDisabled(peer.compactDisplayTitle).string
|
||||
}
|
||||
}
|
||||
} else if isChannel {
|
||||
if isSilentPosting {
|
||||
text = "Subscribers will receive a silent notification"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_ChannelEnabled
|
||||
} else {
|
||||
text = "Subscribers will be notified"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_ChannelDisabled
|
||||
}
|
||||
} else {
|
||||
if isSilentPosting {
|
||||
text = "Members will receive a silent notification"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_GroupEnabled
|
||||
} else {
|
||||
text = "Members will be notified"
|
||||
text = environment.strings.ScheduleMessage_SilentPosting_GroupDisabled
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -272,8 +269,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
case .poll:
|
||||
title = strings.CreatePoll_Deadline_Title
|
||||
case .search:
|
||||
//TODO:localize
|
||||
title = "Search"
|
||||
title = strings.Conversation_CalendarSearch_Title
|
||||
}
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
|
|
@ -554,8 +550,7 @@ private final class ChatScheduleTimeSheetContentComponent: Component {
|
|||
case .poll:
|
||||
buttonTitle = strings.CreatePoll_Deadline_SetDeadline
|
||||
case .search:
|
||||
//TODO:localize
|
||||
buttonTitle = "Done"
|
||||
buttonTitle = strings.Conversation_CalendarSearch_Done
|
||||
}
|
||||
|
||||
let buttonSideInset: CGFloat = 30.0
|
||||
|
|
|
|||
|
|
@ -3099,9 +3099,8 @@ public class ComposePollScreen: ViewControllerComponentContainer, AttachmentCont
|
|||
text = presentationData.strings.CreatePoll_QuizCorrectOptionNeeded
|
||||
}
|
||||
case .countriesNeeded:
|
||||
//TODO:localize
|
||||
title = nil
|
||||
text = "Select at least one country"
|
||||
text = presentationData.strings.CreatePoll_QuizCountryNeeded
|
||||
}
|
||||
|
||||
let controller = UndoOverlayController(
|
||||
|
|
|
|||
|
|
@ -426,8 +426,7 @@ final class InnerTextSelectionTipContainerNode: ASDisplayNode {
|
|||
icon = UIImage(bundleImageName: "Chat/Context Menu/Tip")
|
||||
case .deleteReaction:
|
||||
self.action = nil
|
||||
//TODO:localize
|
||||
self.text = "Tap and hold to delete reaction."
|
||||
self.text = self.presentationData.strings.Chat_DeleteReactionInfo
|
||||
self.targetSelectionIndex = nil
|
||||
icon = nil
|
||||
isUserInteractionEnabled = false
|
||||
|
|
|
|||
|
|
@ -378,8 +378,7 @@ func infoItems(
|
|||
|
||||
if let reactionSourceMessageId = reactionSourceMessageId {
|
||||
if canDeleteReaction {
|
||||
//TODO:localize
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenActionItem(id: ItemDeleteReaction, text: "Delete Reaction", color: .destructive, action: {
|
||||
items[currentPeerInfoSection]!.append(PeerInfoScreenActionItem(id: ItemDeleteReaction, text: presentationData.strings.PeerInfo_DeleteReaction, color: .destructive, action: {
|
||||
interaction.openDeleteReaction(reactionSourceMessageId)
|
||||
}))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4592,20 +4592,20 @@ final class PeerInfoScreenNode: ViewControllerTracingNode, PeerInfoScreenNodePro
|
|||
guard let controller = self.controller, let navigationController = controller.navigationController as? NavigationController else {
|
||||
return
|
||||
}
|
||||
guard let tabController = navigationController.viewControllers.first as? TabBarController else {
|
||||
guard let navigationTarget = resolveChatListNavigationTarget(navigationController: navigationController, excluding: controller) else {
|
||||
return
|
||||
}
|
||||
for childController in tabController.controllers {
|
||||
if let chatListController = childController as? ChatListController {
|
||||
chatListController.maybeAskForPeerChatRemoval(peer: EngineRenderedPeer(peer: peer), joined: false, deleteGloballyIfPossible: globally, completion: { [weak navigationController] deleted in
|
||||
if deleted {
|
||||
navigationController?.popToRoot(animated: true)
|
||||
}
|
||||
}, removed: {
|
||||
})
|
||||
break
|
||||
navigationTarget.chatListController.maybeAskForPeerChatRemoval(peer: EngineRenderedPeer(peer: peer), joined: false, deleteGloballyIfPossible: globally, completion: { [weak navigationController] deleted in
|
||||
guard deleted, let navigationController = navigationController else {
|
||||
return
|
||||
}
|
||||
}
|
||||
if let popToController = navigationTarget.popToController {
|
||||
let _ = navigationController.popToViewController(popToController, animated: true)
|
||||
} else {
|
||||
navigationController.popToRoot(animated: true)
|
||||
}
|
||||
}, removed: {
|
||||
})
|
||||
}
|
||||
|
||||
func deleteProfilePhoto(_ item: PeerInfoAvatarListItem) {
|
||||
|
|
|
|||
|
|
@ -496,18 +496,17 @@ func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoState, conte
|
|||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let automationBotTitle: String
|
||||
if let botPeer = data.businessConnectedBot {
|
||||
let _ = botPeer
|
||||
automationBotTitle = "@\(botPeer.compactDisplayTitle)"
|
||||
} else {
|
||||
automationBotTitle = "Off"
|
||||
automationBotTitle = presentationData.strings.Settings_ChatAutomationOff
|
||||
}
|
||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerChatAutomation, label: .text(automationBotTitle), additionalBadgeLabel: nil, text: "Chat Automation", icon: PresentationResourcesSettings.aiTools, action: {
|
||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerChatAutomation, label: .text(automationBotTitle), additionalBadgeLabel: nil, text: presentationData.strings.Settings_ChatAutomation, icon: PresentationResourcesSettings.aiTools, action: {
|
||||
interaction.editingOpenBusinessChatBots()
|
||||
}))
|
||||
items[.info]!.append(PeerInfoScreenCommentItem(id: ItemPeerChatAutomationHelp, text: "Add a bot to reply to messages on your behalf."))
|
||||
items[.info]!.append(PeerInfoScreenCommentItem(id: ItemPeerChatAutomationHelp, text: presentationData.strings.Settings_ChatAutomationInfo))
|
||||
|
||||
items[.account]!.append(PeerInfoScreenActionItem(id: ItemAddAccount, text: presentationData.strings.Settings_AddAnotherAccount, alignment: .center, action: {
|
||||
interaction.openSettings(.addAccount)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ public func quickReplyNameAlertController(context: AccountContext, updatedPresen
|
|||
component: AnyComponent(
|
||||
AlertInputFieldComponent(
|
||||
context: context,
|
||||
initialValue: nil,
|
||||
initialValue: value,
|
||||
placeholder: strings.QuickReply_ShortcutPlaceholder,
|
||||
characterLimit: characterLimit,
|
||||
hasClearButton: false,
|
||||
|
|
@ -58,6 +58,21 @@ public func quickReplyNameAlertController(context: AccountContext, updatedPresen
|
|||
autocorrectionType: .no,
|
||||
isInitiallyFocused: true,
|
||||
externalState: inputState,
|
||||
shouldChangeText: { updatedText in
|
||||
if updatedText.isEmpty {
|
||||
return true
|
||||
}
|
||||
for scalar in updatedText.unicodeScalars {
|
||||
if scalar.value == 0x5f || scalar.value == 0x200c || scalar.value == 0xb7 || (scalar.value >= 0xd80 && scalar.value <= 0xdff) {
|
||||
continue
|
||||
}
|
||||
if CharacterSet.letters.contains(scalar) || CharacterSet.decimalDigits.contains(scalar) {
|
||||
continue
|
||||
}
|
||||
return false
|
||||
}
|
||||
return true
|
||||
},
|
||||
returnKeyAction: {
|
||||
applyImpl?()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9385,10 +9385,19 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
|||
guard case let .peer(peerId) = self.chatLocation else {
|
||||
return
|
||||
}
|
||||
let navigationTarget = self.effectiveNavigationController.flatMap { navigationController in
|
||||
resolveChatListNavigationTarget(navigationController: navigationController, excluding: self)
|
||||
}
|
||||
self.commitPurposefulAction()
|
||||
self.chatDisplayNode.historyNode.disconnect()
|
||||
let _ = self.context.engine.peers.removePeerChat(peerId: peerId, reportChatSpam: reportChatSpam).startStandalone()
|
||||
self.effectiveNavigationController?.popToRoot(animated: true)
|
||||
if let navigationController = self.effectiveNavigationController {
|
||||
if let navigationTarget, let popToController = navigationTarget.popToController {
|
||||
let _ = navigationController.popToViewController(popToController, animated: true)
|
||||
} else {
|
||||
navigationController.popToRoot(animated: true)
|
||||
}
|
||||
}
|
||||
|
||||
let _ = self.context.engine.privacy.requestUpdatePeerIsBlocked(peerId: peerId, isBlocked: true).startStandalone()
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue