mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-10-08 19:10:53 +00:00
Business
This commit is contained in:
parent
c69ba2c089
commit
42b14666a2
@ -11390,3 +11390,190 @@ to respond to messages faster.";
|
||||
"Story.Editor.DiscardText" = "If you go back now, you will lose any changes you made.";
|
||||
|
||||
"Premium.Business.Description" = "Turn your account to a business page with these additional features.";
|
||||
|
||||
"Attachment.Reply" = "Reply";
|
||||
|
||||
"ChatList.ItemMoreMessagesFormat_1" = "+1 MORE";
|
||||
"ChatList.ItemMoreMessagesFormat_any" = "+%d MORE";
|
||||
"ChatList.ItemMenuEdit" = "Edit";
|
||||
"ChatList.ItemMenuDelete" = "Delete";
|
||||
"ChatList.PeerTypeNonContact" = "non-contact";
|
||||
|
||||
"ChatListFilter.TagLabelNoTag" = "NO TAG";
|
||||
"ChatListFilter.TagLabelPremiumExpired" = "PREMIUM EXPIRED";
|
||||
"ChatListFilter.TagSectionTitle" = "FOLDER COLOR";
|
||||
"ChatListFilter.TagSectionFooter" = "This color will be used for the folder's tag in the chat list";
|
||||
"ChatListFilter.TagPremiumRequiredTooltipText" = "Subscribe to **Telegram Premium** to select folder color.";
|
||||
"ChatListFilterList.ShowTags" = "Show Folder Tags";
|
||||
"ChatListFilterList.ShowTagsFooter" = "Display folder names for each chat in the chat list.";
|
||||
|
||||
"PeerInfo.BusinessHours.DayOpen24h" = "open 24 hours";
|
||||
"PeerInfo.BusinessHours.DayClosed" = "closed";
|
||||
"PeerInfo.BusinessHours.StatusOpen" = "Open";
|
||||
"PeerInfo.BusinessHours.StatusClosed" = "Closed";
|
||||
"PeerInfo.BusinessHours.StatusOpensInMinutes_1" = "Opens in one minute";
|
||||
"PeerInfo.BusinessHours.StatusOpensInMinutes_any" = "Opens in %d minutes";
|
||||
"PeerInfo.BusinessHours.StatusOpensInHours_1" = "Opens in one hour";
|
||||
"PeerInfo.BusinessHours.StatusOpensInHours_any" = "Opens in %d hours";
|
||||
"PeerInfo.BusinessHours.StatusOpensOnDate" = "Opens %@";
|
||||
"PeerInfo.BusinessHours.TimezoneSwitchMy" = "my time";
|
||||
"PeerInfo.BusinessHours.TimezoneSwitchBusiness" = "local time";
|
||||
"PeerInfo.BusinessHours.Label" = "business hours";
|
||||
"PeerInfo.Location.Label" = "location";
|
||||
|
||||
"QuickReplies.EmptyState.Title" = "No Quick Replies";
|
||||
"QuickReplies.EmptyState.Text" = "Set up shortcuts with rich text and media to respond to messages faster.";
|
||||
"QuickReplies.EmptyState.AddButton" = "Add Quick Reply";
|
||||
|
||||
"Chat.CommandList.EditQuickReplies" = "Edit Quick Replies";
|
||||
|
||||
"Conversation.EditingQuickReplyPanelTitle" = "Edit Quick Reply";
|
||||
|
||||
"Chat.Placeholder.QuickReply" = "Add quick reply..";
|
||||
"Chat.Placeholder.GreetingMessage" = "Add greeting message...";
|
||||
"Chat.Placeholder.AwayMessage" = "Add away message...";
|
||||
|
||||
"Chat.QuickReplyMessageLimitReachedText_1" = "Limit of %d message reached";
|
||||
"Chat.QuickReplyMessageLimitReachedText_any" = "Limit of %d messages reached";
|
||||
|
||||
"Chat.EmptyState.QuickReply.Title" = "New Quick Reply";
|
||||
"Chat.EmptyState.QuickReply.Text1" = "· Enter a message below that will be sent in chats when you type \"**/%@\"**.";
|
||||
"Chat.EmptyState.QuickReply.Text2" = "· You can access Quick Replies in any chat by typing \"/\" or using the Attachment menu.";
|
||||
"EmptyState.GreetingMessage.Title" = "New Greeting Message";
|
||||
"EmptyState.GreetingMessage.Text" = "Create greetings that will be automatically sent to new customers";
|
||||
"EmptyState.AwayMessage.Title" = "New Away Message";
|
||||
"EmptyState.AwayMessage.Text" = "Add messages that are automatically sent when you are off.";
|
||||
|
||||
"QuickReply.Title" = "Quick Replies";
|
||||
"QuickReply.SelectedTitle_1" = "%d Selected";
|
||||
"QuickReply.SelectedTitle_any" = "%d Selected";
|
||||
|
||||
"QuickReply.ShortcutPlaceholder" = "Shortcut";
|
||||
"QuickReply.CreateShortcutTitle" = "New Quick Reply";
|
||||
"QuickReply.CreateShortcutText" = "Add a shortcut for your quick reply.";
|
||||
"QuickReply.EditShortcutTitle" = "Edit Shortcut";
|
||||
"QuickReply.EditShortcutText" = "Add a new name for your shortcut.";
|
||||
"QuickReply.ShortcutExistsInlineError" = "Shortcut with that name already exists";
|
||||
|
||||
"QuickReply.ChatRemoveGeneric.Title" = "Remove Shortcut";
|
||||
"QuickReply.ChatRemoveGeneric.Text" = "You didn't create a quick reply message. Exiting will remove the shortcut.";
|
||||
"QuickReply.ChatRemoveGreetingMessage.Title" = "Remove Greeting Message";
|
||||
"QuickReply.ChatRemoveGreetingMessage.Text" = "You didn't create a greeting message. Exiting will remove it.";
|
||||
"QuickReply.ChatRemoveAwayMessage.Title" = "Remove Away Message";
|
||||
"QuickReply.ChatRemoveAwayMessage.Text" = "You didn't create an away message. Exiting will remove it.";
|
||||
"QuickReply.ChatRemoveGeneric.DeleteAction" = "Delete";
|
||||
"QuickReply.TitleGreetingMessage" = "Greeting Message";
|
||||
"QuickReply.TitleAwayMessage" = "Away Message";
|
||||
|
||||
"QuickReply.InlineCreateAction" = "New Quick Reply";
|
||||
"QuickReply.DeleteConfirmationSingle" = "Delete Quick Reply";
|
||||
"QuickReply.DeleteConfirmationMultiple" = "Delete Quick Replies";
|
||||
"QuickReply.DeleteAction_1" = "Delete 1 Quick Reply";
|
||||
"QuickReply.DeleteAction_any" = "Delete %d Quick Replies";
|
||||
|
||||
"TimeZoneSelection.Title" = "Time Zone";
|
||||
|
||||
"BusinessMessageSetup.TitleGreetingMessage" = "Greeting Message";
|
||||
"BusinessMessageSetup.TextGreetingMessage" = "Greet customers when they message you the first time or after a period of no activity.";
|
||||
"BusinessMessageSetup.TitleAwayMessage" = "Away Message";
|
||||
"BusinessMessageSetup.TextAwayMessage" = "Automatically reply with a message when you are away.";
|
||||
"BusinessMessageSetup.ToggleGreetingMessage" = "Send Greeting Message";
|
||||
"BusinessMessageSetup.ToggleAwayMessage" = "Send Away Message";
|
||||
"BusinessMessageSetup.CreateGreetingMessage" = "Create a Greeting Message";
|
||||
"BusinessMessageSetup.CreateAwayMessage" = "Create an Away Message";
|
||||
"BusinessMessageSetup.GreetingMessageSectionHeader" = "GREETING MESSAGE";
|
||||
"BusinessMessageSetup.AwayMessageSectionHeader" = "AWAY MESSAGE";
|
||||
|
||||
"BusinessMessageSetup.ScheduleSectionHeader" = "SCHEDULE";
|
||||
"BusinessMessageSetup.ScheduleAlways" = "Always Send";
|
||||
"BusinessMessageSetup.ScheduleOutsideBusinessHours" = "Outside of Business Hours";
|
||||
"BusinessMessageSetup.ScheduleCustom" = "Custom Schedule";
|
||||
"BusinessMessageSetup.ScheduleStartTime" = "Start Time";
|
||||
"BusinessMessageSetup.ScheduleEndTime" = "End Time";
|
||||
"BusinessMessageSetup.ScheduleTimePlaceholder" = "Set";
|
||||
|
||||
"BusinessMessageSetup.SendWhenOffline" = "Only if Offline";
|
||||
"BusinessMessageSetup.SendWhenOfflineFooter" = "Don't send the away message if you've recently been online.";
|
||||
|
||||
"BusinessMessageSetup.ErrorNoRecipients.Text" = "No recipients selected. Reset?";
|
||||
"BusinessMessageSetup.ErrorNoRecipients.ResetAction" = "Reset";
|
||||
"BusinessMessageSetup.ErrorScheduleEndTimeBeforeStartTime.Text" = "Custom schedule end time must be larger than start time.";
|
||||
"BusinessMessageSetup.ErrorScheduleTimeMissing.Text" = "Custom schedule time is missing.";
|
||||
"BusinessMessageSetup.ErrorScheduleStartTimeMissing.Text" = "Custom schedule start time is missing.";
|
||||
"BusinessMessageSetup.ErrorScheduleEndTimeMissing.Text" = "Custom schedule end time is missing.";
|
||||
"BusinessMessageSetup.ErrorScheduleTime.ResetAction" = "Reset";
|
||||
|
||||
"BusinessMessageSetup.RecipientsSectionHeader" = "RECIPIENTS";
|
||||
"BusinessMessageSetup.RecipientsOptionAllExcept" = "All 1-to-1 Chats Except...";
|
||||
"BusinessMessageSetup.RecipientsOptionOnly" = "Only Selected Chats";
|
||||
|
||||
"BusinessMessageSetup.Recipients.AddExclude" = "Exclude Chats...";
|
||||
"BusinessMessageSetup.Recipients.AddInclude" = "Include Chats...";
|
||||
|
||||
"BusinessMessageSetup.Recipients.CategoryExistingChats" = "Existing Chats";
|
||||
"BusinessMessageSetup.Recipients.CategoryNewChats" = "New Chats";
|
||||
"BusinessMessageSetup.Recipients.CategoryContacts" = "Contacts";
|
||||
"BusinessMessageSetup.Recipients.CategoryNonContacts" = "Non-Contacts";
|
||||
"BusinessMessageSetup.Recipients.IncludeSearchTitle" = "Include Chats";
|
||||
"BusinessMessageSetup.Recipients.ExcludeSearchTitle" = "Exclude Chats";
|
||||
|
||||
"BusinessMessageSetup.Recipients.IncludedSectionHeader" = "INCLUDED CHATS";
|
||||
"BusinessMessageSetup.Recipients.ExcludedSectionHeader" = "EXCLUDED CHATS";
|
||||
"BusinessMessageSetup.Recipients.GreetingMessageFooter" = "Choose chats or entire chat categories for sending a greeting message.";
|
||||
"BusinessMessageSetup.Recipients.AwayMessageFooter" = "Choose chats or entire chat categories for sending an away message.";
|
||||
|
||||
"BusinessMessageSetup.InactivitySectionHeader" = "PERIOD OF NO ACTIVITY";
|
||||
"BusinessMessageSetup.InactivitySectionFooter" = "Choose how many days should pass after your last interaction with a recipient to send them the greeting in response to their message.";
|
||||
|
||||
"BusinessHoursSetup.Title" = "Business Hours";
|
||||
"BusinessHoursSetup.Text" = "Turn this on to show your opening hours schedule to your customers.";
|
||||
|
||||
"BusinessHoursSetup.MainToggle" = "Show Business Hours";
|
||||
|
||||
"BusinessHoursSetup.DaySwitch" = "Open On This Day";
|
||||
"BusinessHoursSetup.DayIntervalStart" = "Opening time";
|
||||
"BusinessHoursSetup.DayIntervalEnd" = "Closing time";
|
||||
"BusinessHoursSetup.DayIntervalRemove" = "Remove";
|
||||
"BusinessHoursSetup.AddSectionFooter" = "Specify your working hours during the day.";
|
||||
"BusinessHoursSetup.AddAction" = "Add a Set of Hours";
|
||||
|
||||
"BusinessHoursSetup.ErrorIntersectingHours.Text" = "Business hours are intersecting. Reset?";
|
||||
"BusinessHoursSetup.ErrorIntersectingHours.ResetAction" = "Reset";
|
||||
|
||||
"BusinessHoursSetup.ErrorIntersectingDays.Text" = "Business hours are intersecting. Reset?";
|
||||
"BusinessHoursSetup.ErrorIntersectingDays.ResetAction" = "Reset";
|
||||
|
||||
"BusinessHoursSetup.DayOpen24h" = "Open 24 Hours";
|
||||
"BusinessHoursSetup.DayClosed" = "Closed";
|
||||
"BusinessHoursSetup.DaysSectionTitle" = "BUSINESS HOURS";
|
||||
|
||||
"BusinessHoursSetup.TimeZone" = "Time Zone";
|
||||
|
||||
"BusinessLocationSetup.Title" = "Location";
|
||||
"BusinessLocationSetup.Text" = "Display the location of your business on your account.";
|
||||
|
||||
"BusinessLocationSetup.AddressPlaceholder" = "Enter Address";
|
||||
"BusinessLocationSetup.SetLocationOnMap" = "Set Location on Map";
|
||||
"BusinessLocationSetup.DeleteLocation" = "Delete Location";
|
||||
|
||||
"BusinessLocationSetup.ErrorAddressEmpty.Text" = "Address can't be empty.";
|
||||
"BusinessLocationSetup.ErrorAddressEmpty.ResetAction" = "Delete";
|
||||
|
||||
"ChatbotSetup.Title" = "Chatbots";
|
||||
"ChatbotSetup.Text" = "Add a bot to your account to help you automatically process and respond to the messages you receive. [Learn More >]()";
|
||||
"ChatbotSetup.TextLink" = "https://telegram.org";
|
||||
|
||||
"ChatbotSetup.BotSearchPlaceholder" = "Bot Username";
|
||||
"ChatbotSetup.BotSectionFooter" = "Enter the username or URL of the Telegram bot that you want to automatically process your chats.";
|
||||
|
||||
"ChatbotSetup.RecipientsSectionHeader" = "CHATS ACCESSIBLE FOR THE BOT";
|
||||
|
||||
"ChatbotSetup.Recipients.ExcludedSectionFooter" = "Select chats or entire chat categories which the bot **WILL NOT** have access to.";
|
||||
"ChatbotSetup.Recipients.IncludedSectionFooter" = "Select chats or entire chat categories which the bot **WILL** have access to.";
|
||||
|
||||
"ChatbotSetup.PermissionsSectionHeader" = "BOT PERMISSIONS";
|
||||
"ChatbotSetup.PermissionsSectionFooter" = "The bot will be able to view all new incoming messages, but not the messages that had been sent before you added the bot.";
|
||||
"ChatbotSetup.Permission.ReplyToMessages" = "Reply to Messages";
|
||||
|
||||
"ChatbotSetup.BotAddAction" = "ADD";
|
||||
"ChatbotSetup.BotNotFoundStatus" = "Chatbot not found";
|
||||
|
@ -218,8 +218,7 @@ private final class AttachButtonComponent: CombinedComponent {
|
||||
imageName = ""
|
||||
imageFile = nil
|
||||
case .quickReply:
|
||||
//TODO:localize
|
||||
name = "Reply"
|
||||
name = strings.Attachment_Reply
|
||||
imageName = "Chat/Attach Menu/Reply"
|
||||
}
|
||||
|
||||
@ -1188,8 +1187,7 @@ final class AttachmentPanel: ASDisplayNode, UIScrollViewDelegate {
|
||||
case .standalone:
|
||||
accessibilityTitle = ""
|
||||
case .quickReply:
|
||||
//TODO:localize
|
||||
accessibilityTitle = "Reply"
|
||||
accessibilityTitle = self.presentationData.strings.Attachment_Reply
|
||||
}
|
||||
buttonView.isAccessibilityElement = true
|
||||
buttonView.accessibilityLabel = accessibilityTitle
|
||||
|
@ -462,7 +462,6 @@ private enum ChatListFilterPresetEntry: ItemListNodeEntry {
|
||||
arguments.expandSection(.exclude)
|
||||
})
|
||||
case let .tagColorHeader(name, color, isPremium):
|
||||
//TODO:localize
|
||||
var badge: String?
|
||||
var badgeStyle: ItemListSectionHeaderItem.BadgeStyle?
|
||||
var accessoryText: ItemListSectionHeaderAccessoryText?
|
||||
@ -474,12 +473,12 @@ private enum ChatListFilterPresetEntry: ItemListNodeEntry {
|
||||
foreground: color.main
|
||||
)
|
||||
} else {
|
||||
accessoryText = ItemListSectionHeaderAccessoryText(value: "NO TAG", color: .generic)
|
||||
accessoryText = ItemListSectionHeaderAccessoryText(value: presentationData.strings.ChatListFilter_TagLabelNoTag, color: .generic)
|
||||
}
|
||||
} else if color != nil {
|
||||
accessoryText = ItemListSectionHeaderAccessoryText(value: "PREMIUM EXPIRED", color: .generic)
|
||||
accessoryText = ItemListSectionHeaderAccessoryText(value: presentationData.strings.ChatListFilter_TagLabelPremiumExpired, color: .generic)
|
||||
}
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "FOLDER COLOR", badge: badge, badgeStyle: badgeStyle, accessoryText: accessoryText, sectionId: self.section)
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ChatListFilter_TagSectionTitle, badge: badge, badgeStyle: badgeStyle, accessoryText: accessoryText, sectionId: self.section)
|
||||
case let .tagColor(colors, color, isPremium):
|
||||
return PeerNameColorItem(
|
||||
theme: presentationData.theme,
|
||||
@ -498,8 +497,7 @@ private enum ChatListFilterPresetEntry: ItemListNodeEntry {
|
||||
sectionId: self.section
|
||||
)
|
||||
case .tagColorFooter:
|
||||
//TODO:localize
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("This color will be used for the folder's tag in the chat list"), sectionId: self.section)
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(presentationData.strings.ChatListFilter_TagSectionFooter), sectionId: self.section)
|
||||
case .inviteLinkHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ChatListFilter_SectionShare, badge: nil, sectionId: self.section)
|
||||
case let .inviteLinkCreate(hasLinks):
|
||||
@ -1580,14 +1578,15 @@ func chatListFilterPresetController(context: AccountContext, currentPreset initi
|
||||
}
|
||||
},
|
||||
openTagColorPremium: {
|
||||
//TODO:localize
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentControllerImpl?(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "anim_reorder", scale: 0.05, colors: [:], title: nil, text: "Subscribe to **Telegram Premium** to select folder color.", customUndoText: presentationData.strings.ChatListFolderSettings_SubscribeToMoveAllAction, timeout: nil), elevatedLayout: false, animateInAsReplacement: false, action: { action in
|
||||
if case .undo = action {
|
||||
pushControllerImpl?(PremiumIntroScreen(context: context, source: .folders))
|
||||
}
|
||||
return false
|
||||
}), nil)
|
||||
var replaceImpl: ((ViewController) -> Void)?
|
||||
let controller = context.sharedContext.makePremiumDemoController(context: context, subject: .folderTags, action: {
|
||||
let controller = context.sharedContext.makePremiumIntroController(context: context, source: .folderTags, forceDark: false, dismissed: nil)
|
||||
replaceImpl?(controller)
|
||||
})
|
||||
replaceImpl = { [weak controller] c in
|
||||
controller?.replace(with: c)
|
||||
}
|
||||
pushControllerImpl?(controller)
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -212,8 +212,7 @@ private enum ChatListFilterPresetListEntry: ItemListNodeEntry {
|
||||
case let .listFooter(text):
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(text), sectionId: self.section)
|
||||
case let .displayTags(value):
|
||||
//TODO:localize
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Show Folder Tags", value: value == true, enableInteractiveChanges: value != nil, enabled: true, displayLocked: value == nil, sectionId: self.section, style: .blocks, updated: { updatedValue in
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ChatListFilterList_ShowTags, value: value == true, enableInteractiveChanges: value != nil, enabled: true, displayLocked: value == nil, sectionId: self.section, style: .blocks, updated: { updatedValue in
|
||||
if value != nil {
|
||||
arguments.updateDisplayTags(updatedValue)
|
||||
} else {
|
||||
@ -223,8 +222,7 @@ private enum ChatListFilterPresetListEntry: ItemListNodeEntry {
|
||||
arguments.updateDisplayTagsLocked()
|
||||
}, tag: ChatListFilterPresetListEntryTag.displayTags)
|
||||
case .displayTagsFooter:
|
||||
//TODO:localize
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain("Display folder names for each chat in the chat list."), sectionId: self.section)
|
||||
return ItemListTextItem(presentationData: presentationData, text: .plain(presentationData.strings.ChatListFilterList_ShowTagsFooter), sectionId: self.section)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3066,8 +3066,7 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
var trailingTextBadgeLayoutAndApply: (TextNodeLayout, () -> TextNode)?
|
||||
if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData, customMessageListData.commandPrefix != nil, let messageCount = customMessageListData.messageCount, messageCount > 1 {
|
||||
let trailingText: String
|
||||
//TODO:localize
|
||||
trailingText = "+\(messageCount - 1) MORE"
|
||||
trailingText = item.presentationData.strings.ChatList_ItemMoreMessagesFormat(Int32(messageCount - 1))
|
||||
let trailingAttributedText = NSAttributedString(string: trailingText, font: Font.regular(12.0), textColor: theme.messageTextColor)
|
||||
let (layout, apply) = makeTrailingTextBadgeLayout(TextNodeLayoutArguments(attributedString: trailingAttributedText, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: rawContentWidth, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
|
||||
trailingTextBadgeLayoutAndApply = (layout, apply)
|
||||
@ -3210,10 +3209,9 @@ class ChatListItemNode: ItemListRevealOptionsItemNode {
|
||||
} else if case let .peer(peerData) = item.content, let customMessageListData = peerData.customMessageListData {
|
||||
peerLeftRevealOptions = []
|
||||
if customMessageListData.commandPrefix != nil {
|
||||
//TODO:localize
|
||||
peerRevealOptions = [
|
||||
ItemListRevealOption(key: RevealOptionKey.edit.rawValue, title: "Edit", icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.neutral2.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.neutral2.foregroundColor),
|
||||
ItemListRevealOption(key: RevealOptionKey.delete.rawValue, title: "Delete", icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.destructive.foregroundColor)
|
||||
ItemListRevealOption(key: RevealOptionKey.edit.rawValue, title: item.presentationData.strings.ChatList_ItemMenuEdit, icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.neutral2.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.neutral2.foregroundColor),
|
||||
ItemListRevealOption(key: RevealOptionKey.delete.rawValue, title: item.presentationData.strings.ChatList_ItemMenuDelete, icon: .none, color: item.presentationData.theme.list.itemDisclosureActions.destructive.fillColor, textColor: item.presentationData.theme.list.itemDisclosureActions.destructive.foregroundColor)
|
||||
]
|
||||
} else {
|
||||
peerRevealOptions = []
|
||||
|
@ -4130,16 +4130,14 @@ private func statusStringForPeerType(accountPeerId: EnginePeer.Id, strings: Pres
|
||||
if isContact {
|
||||
return (strings.ChatList_PeerTypeContact, false, false, nil)
|
||||
} else {
|
||||
//TODO:localize
|
||||
return ("non-contact", false, false, nil)
|
||||
return (strings.ChatList_PeerTypeNonContact, false, false, nil)
|
||||
}
|
||||
}
|
||||
} else if case .secretChat = peer {
|
||||
if isContact {
|
||||
return (strings.ChatList_PeerTypeContact, false, false, nil)
|
||||
} else {
|
||||
//TODO:localize
|
||||
return ("non-contact", false, false, nil)
|
||||
return (strings.ChatList_PeerTypeNonContact, false, false, nil)
|
||||
}
|
||||
} else if case .legacyGroup = peer {
|
||||
return (strings.ChatList_PeerTypeGroup, false, false, nil)
|
||||
|
@ -358,7 +358,7 @@ func _internal_applySentQuickReplyMessage(transaction: Transaction, shortcut: St
|
||||
var state = transaction.getPreferencesEntry(key: PreferencesKeys.shortcutMessages())?.get(QuickReplyMessageShortcutsState.self) ?? QuickReplyMessageShortcutsState(shortcuts: [])
|
||||
|
||||
if !state.shortcuts.contains(where: { $0.id == quickReplyId }) {
|
||||
state.shortcuts.insert(QuickReplyMessageShortcut(id: quickReplyId, shortcut: shortcut), at: 0)
|
||||
state.shortcuts.append(QuickReplyMessageShortcut(id: quickReplyId, shortcut: shortcut))
|
||||
transaction.setPreferencesEntry(key: PreferencesKeys.shortcutMessages(), value: PreferencesEntry(state))
|
||||
}
|
||||
}
|
||||
@ -778,19 +778,6 @@ func _internal_updateBusinessAwayMessage(account: Account, awayMessage: Telegram
|
||||
|> then(remoteApply)
|
||||
}
|
||||
|
||||
/*
|
||||
connectedBot flags:# can_reply:flags.0?true bot_id:long recipients:BusinessRecipients = ConnectedBot;
|
||||
|
||||
account.connectedBots connected_bots:Vector<ConnectedBot> users:Vector<User> = account.ConnectedBots;
|
||||
|
||||
---functions---
|
||||
|
||||
account.setConnectedBot flags:# can_reply:flags.0?true deleted:flags.1?true bot:InputUser recipients:InputBusinessRecipients = Updates;
|
||||
|
||||
account.getConnectedBots = account.ConnectedBots;
|
||||
|
||||
*/
|
||||
|
||||
public final class TelegramAccountConnectedBot: Codable, Equatable {
|
||||
public let id: PeerId
|
||||
public let recipients: TelegramBusinessRecipients
|
||||
|
@ -17,9 +17,9 @@ private func dayBusinessHoursText(presentationData: PresentationData, day: Teleg
|
||||
var businessHoursText: String = ""
|
||||
switch day {
|
||||
case .open:
|
||||
businessHoursText += "open 24 hours"
|
||||
businessHoursText += presentationData.strings.PeerInfo_BusinessHours_DayOpen24h
|
||||
case .closed:
|
||||
businessHoursText += "closed"
|
||||
businessHoursText += presentationData.strings.PeerInfo_BusinessHours_DayClosed
|
||||
case let .intervals(intervals):
|
||||
func clipMinutes(_ value: Int) -> Int {
|
||||
var value = value
|
||||
@ -216,22 +216,21 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
|
||||
for i in 0 ..< businessDays.count {
|
||||
let dayTitleValue: String
|
||||
//TODO:localize
|
||||
switch i {
|
||||
case 0:
|
||||
dayTitleValue = "Monday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Monday
|
||||
case 1:
|
||||
dayTitleValue = "Tuesday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Tuesday
|
||||
case 2:
|
||||
dayTitleValue = "Wednesday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Wednesday
|
||||
case 3:
|
||||
dayTitleValue = "Thursday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Thursday
|
||||
case 4:
|
||||
dayTitleValue = "Friday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Friday
|
||||
case 5:
|
||||
dayTitleValue = "Saturday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Saturday
|
||||
case 6:
|
||||
dayTitleValue = "Sunday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Sunday
|
||||
default:
|
||||
dayTitleValue = " "
|
||||
}
|
||||
@ -328,8 +327,7 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
}
|
||||
|
||||
let isOpen = self.cachedWeekMinuteSet.contains(currentWeekMinute)
|
||||
//TODO:localize
|
||||
let openStatusText = isOpen ? "Open" : "Closed"
|
||||
let openStatusText = isOpen ? presentationData.strings.PeerInfo_BusinessHours_StatusOpen : presentationData.strings.PeerInfo_BusinessHours_StatusClosed
|
||||
|
||||
var currentDayStatusText = currentDayIndex >= 0 && currentDayIndex < businessDays.count ? dayBusinessHoursText(presentationData: presentationData, day: businessDays[currentDayIndex], offsetMinutes: timezoneOffsetMinutes) : " "
|
||||
|
||||
@ -337,11 +335,10 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
for range in self.cachedWeekMinuteSet.rangeView {
|
||||
if range.lowerBound > currentWeekMinute {
|
||||
let openInMinutes = range.lowerBound - currentWeekMinute
|
||||
//TODO:localize
|
||||
if openInMinutes < 60 {
|
||||
currentDayStatusText = "Opens in \(openInMinutes) minutes"
|
||||
currentDayStatusText = presentationData.strings.PeerInfo_BusinessHours_StatusOpensInMinutes(Int32(openInMinutes))
|
||||
} else if openInMinutes < 6 * 60 {
|
||||
currentDayStatusText = "Opens in \(openInMinutes / 60) hours"
|
||||
currentDayStatusText = presentationData.strings.PeerInfo_BusinessHours_StatusOpensInHours(Int32(openInMinutes / 60))
|
||||
} else {
|
||||
let openDate = currentDate.addingTimeInterval(Double(openInMinutes * 60))
|
||||
let openTimestamp = Int32(openDate.timeIntervalSince1970) + Int32(currentCalendar.timeZone.secondsFromGMT() - TimeZone.current.secondsFromGMT())
|
||||
@ -360,7 +357,7 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
return PresentationStrings.FormattedString(string: presentationData.strings.Chat_MessageSeenTimestamp_YesterdayAt(value).string, ranges: [])
|
||||
}
|
||||
)).string
|
||||
currentDayStatusText = "opens \(dateText)"
|
||||
currentDayStatusText = presentationData.strings.PeerInfo_BusinessHours_StatusOpensOnDate(dateText).string
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -408,11 +405,10 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
self.timezoneSwitchButton = timezoneSwitchButton
|
||||
}
|
||||
let timezoneSwitchTitle: String
|
||||
//TODO:localize
|
||||
if self.displayLocalTimezone {
|
||||
timezoneSwitchTitle = "my time"
|
||||
timezoneSwitchTitle = presentationData.strings.PeerInfo_BusinessHours_TimezoneSwitchMy
|
||||
} else {
|
||||
timezoneSwitchTitle = "local time"
|
||||
timezoneSwitchTitle = presentationData.strings.PeerInfo_BusinessHours_TimezoneSwitchBusiness
|
||||
}
|
||||
timezoneSwitchButtonSize = timezoneSwitchButton.update(
|
||||
transition: .immediate,
|
||||
@ -510,22 +506,21 @@ private final class PeerInfoScreenBusinessHoursItemNode: PeerInfoScreenItemNode
|
||||
}
|
||||
|
||||
let dayTitleValue: String
|
||||
//TODO:localize
|
||||
switch i {
|
||||
case 0:
|
||||
dayTitleValue = "Monday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Monday
|
||||
case 1:
|
||||
dayTitleValue = "Tuesday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Tuesday
|
||||
case 2:
|
||||
dayTitleValue = "Wednesday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Wednesday
|
||||
case 3:
|
||||
dayTitleValue = "Thursday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Thursday
|
||||
case 4:
|
||||
dayTitleValue = "Friday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Friday
|
||||
case 5:
|
||||
dayTitleValue = "Saturday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Saturday
|
||||
case 6:
|
||||
dayTitleValue = "Sunday"
|
||||
dayTitleValue = presentationData.strings.Weekday_Sunday
|
||||
default:
|
||||
dayTitleValue = " "
|
||||
}
|
||||
|
@ -1167,8 +1167,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}
|
||||
|
||||
if let businessHours = cachedData.businessHours {
|
||||
//TODO:localize
|
||||
items[.peerInfo]!.append(PeerInfoScreenBusinessHoursItem(id: 300, label: "business hours", businessHours: businessHours, requestLayout: { animated in
|
||||
items[.peerInfo]!.append(PeerInfoScreenBusinessHoursItem(id: 300, label: presentationData.strings.PeerInfo_BusinessHours_Label, businessHours: businessHours, requestLayout: { animated in
|
||||
interaction.requestLayout(animated)
|
||||
}, longTapAction: { sourceNode, text in
|
||||
if !text.isEmpty {
|
||||
@ -1178,12 +1177,11 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}
|
||||
|
||||
if let businessLocation = cachedData.businessLocation {
|
||||
//TODO:localize
|
||||
if let coordinates = businessLocation.coordinates {
|
||||
let imageSignal = chatMapSnapshotImage(engine: context.engine, resource: MapSnapshotMediaResource(latitude: coordinates.latitude, longitude: coordinates.longitude, width: 90, height: 90))
|
||||
items[.peerInfo]!.append(PeerInfoScreenAddressItem(
|
||||
id: 301,
|
||||
label: "location",
|
||||
label: presentationData.strings.PeerInfo_Location_Label,
|
||||
text: businessLocation.address,
|
||||
imageSignal: imageSignal,
|
||||
action: {
|
||||
@ -1198,7 +1196,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
} else {
|
||||
items[.peerInfo]!.append(PeerInfoScreenAddressItem(
|
||||
id: 301,
|
||||
label: "location",
|
||||
label: presentationData.strings.PeerInfo_Location_Label,
|
||||
text: businessLocation.address,
|
||||
imageSignal: nil,
|
||||
action: nil,
|
||||
|
@ -141,7 +141,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
private var customScheduleStart: Date?
|
||||
private var customScheduleEnd: Date?
|
||||
|
||||
private var sendWhenOffline: Bool = false
|
||||
private var sendWhenOffline: Bool = true
|
||||
|
||||
private var hasAccessToAllChatsByDefault: Bool = true
|
||||
private var additionalPeerList = AdditionalPeerList(
|
||||
@ -195,11 +195,10 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
|
||||
if self.isOn {
|
||||
if !self.hasAccessToAllChatsByDefault && self.additionalPeerList.categories.isEmpty && self.additionalPeerList.peers.isEmpty {
|
||||
//TODO:localize
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "No recipients selected. Reset?", actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Cancel", action: {
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.BusinessMessageSetup_ErrorNoRecipients_Text, actions: [
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: "Reset", action: {
|
||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.BusinessMessageSetup_ErrorNoRecipients_ResetAction, action: {
|
||||
complete()
|
||||
})
|
||||
]), in: .window(.root))
|
||||
@ -208,28 +207,26 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
if case .away = component.mode, case .custom = self.schedule {
|
||||
//TODO:localize
|
||||
var errorText: String?
|
||||
if let customScheduleStart = self.customScheduleStart, let customScheduleEnd = self.customScheduleEnd {
|
||||
if customScheduleStart >= customScheduleEnd {
|
||||
errorText = "Custom schedule end time must be larger than start time."
|
||||
errorText = presentationData.strings.BusinessMessageSetup_ErrorScheduleEndTimeBeforeStartTime_Text
|
||||
}
|
||||
} else {
|
||||
if self.customScheduleStart == nil && self.customScheduleEnd == nil {
|
||||
errorText = "Custom schedule time is missing."
|
||||
errorText = presentationData.strings.BusinessMessageSetup_ErrorScheduleTimeMissing_Text
|
||||
} else if self.customScheduleStart == nil {
|
||||
errorText = "Custom schedule start time is missing."
|
||||
errorText = presentationData.strings.BusinessMessageSetup_ErrorScheduleStartTimeMissing_Text
|
||||
} else {
|
||||
errorText = "Custom schedule end time is missing."
|
||||
errorText = presentationData.strings.BusinessMessageSetup_ErrorScheduleEndTimeMissing_Text
|
||||
}
|
||||
}
|
||||
|
||||
if let errorText {
|
||||
//TODO:localize
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Cancel", action: {
|
||||
TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: "Reset", action: {
|
||||
TextAlertAction(type: .defaultAction, title: presentationData.strings.BusinessMessageSetup_ErrorScheduleTime_ResetAction, action: {
|
||||
complete()
|
||||
})
|
||||
]), in: .window(.root))
|
||||
@ -281,7 +278,6 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
if let customScheduleStart = self.customScheduleStart, let customScheduleEnd = self.customScheduleEnd {
|
||||
mappedSchedule = .custom(beginTimestamp: Int32(customScheduleStart.timeIntervalSince1970), endTimestamp: Int32(customScheduleEnd.timeIntervalSince1970))
|
||||
} else {
|
||||
//TODO:localize
|
||||
return false
|
||||
}
|
||||
}
|
||||
@ -335,7 +331,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
private func openAdditionalPeerListSetup() {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let enviroment = self.environment else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -351,19 +347,19 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
id: self.hasAccessToAllChatsByDefault ? AdditionalCategoryId.existingChats.rawValue : AdditionalCategoryId.newChats.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: self.hasAccessToAllChatsByDefault ? "Chat List/Filters/Chats" : "Chat List/Filters/NewChats"), color: .white), cornerRadius: 12.0, color: .purple),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: self.hasAccessToAllChatsByDefault ? "Chat List/Filters/Chats" : "Chat List/Filters/NewChats"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .purple),
|
||||
title: self.hasAccessToAllChatsByDefault ? "Existing Chats" : "New Chats"
|
||||
title: self.hasAccessToAllChatsByDefault ? enviroment.strings.BusinessMessageSetup_Recipients_CategoryExistingChats : enviroment.strings.BusinessMessageSetup_Recipients_CategoryNewChats
|
||||
),
|
||||
ChatListNodeAdditionalCategory(
|
||||
id: AdditionalCategoryId.contacts.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/Contact"), color: .white), cornerRadius: 12.0, color: .blue),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/Contact"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .blue),
|
||||
title: "Contacts"
|
||||
title: enviroment.strings.BusinessMessageSetup_Recipients_CategoryContacts
|
||||
),
|
||||
ChatListNodeAdditionalCategory(
|
||||
id: AdditionalCategoryId.nonContacts.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/User"), color: .white), cornerRadius: 12.0, color: .yellow),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/User"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .yellow),
|
||||
title: "Non-Contacts"
|
||||
title: enviroment.strings.BusinessMessageSetup_Recipients_CategoryNonContacts
|
||||
)
|
||||
]
|
||||
var selectedCategories = Set<Int>()
|
||||
@ -380,10 +376,9 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let controller = component.context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: component.context, mode: .chatSelection(ContactMultiselectionControllerMode.ChatSelection(
|
||||
title: self.hasAccessToAllChatsByDefault ? "Exclude Chats" : "Include Chats",
|
||||
searchPlaceholder: "Search chats",
|
||||
title: self.hasAccessToAllChatsByDefault ? enviroment.strings.BusinessMessageSetup_Recipients_ExcludeSearchTitle : enviroment.strings.BusinessMessageSetup_Recipients_IncludeSearchTitle,
|
||||
searchPlaceholder: enviroment.strings.ChatListFilter_AddChatsSearchPlaceholder,
|
||||
selectedChats: Set(self.additionalPeerList.peers.map(\.peer.id)),
|
||||
additionalCategories: ContactMultiselectionControllerAdditionalCategories(categories: additionalCategories, selectedCategories: selectedCategories),
|
||||
chatListFilters: nil,
|
||||
@ -687,11 +682,10 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: component.mode == .greeting ? "Greeting Message" : "Away Message", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: component.mode == .greeting ? environment.strings.BusinessMessageSetup_TitleGreetingMessage : environment.strings.BusinessMessageSetup_TitleAwayMessage, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
@ -736,8 +730,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
|
||||
contentHeight += 124.0
|
||||
|
||||
//TODO:localize
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(component.mode == .greeting ? "Greet customers when they message you the first time or after a period of no activity." : "Automatically reply with a message when you are away.", attributes: MarkdownAttributes(
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(component.mode == .greeting ? environment.strings.BusinessMessageSetup_TextGreetingMessage : environment.strings.BusinessMessageSetup_TextAwayMessage, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||
@ -746,7 +739,6 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
}), textAlignment: .center
|
||||
))
|
||||
|
||||
//TODO:localize
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
@ -789,7 +781,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: component.mode == .greeting ? "Send Greeting Message" : "Send Away Message",
|
||||
string: component.mode == .greeting ? environment.strings.BusinessMessageSetup_ToggleGreetingMessage : environment.strings.BusinessMessageSetup_ToggleAwayMessage,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -806,7 +798,6 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
action: nil
|
||||
))))
|
||||
|
||||
//TODO:localize
|
||||
let generalSectionSize = self.generalSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -830,7 +821,6 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
|
||||
var otherSectionsHeight: CGFloat = 0.0
|
||||
|
||||
//TODO:localize
|
||||
var messagesSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
if let currentShortcut = self.currentShortcut {
|
||||
if let accountPeer = self.accountPeer {
|
||||
@ -855,7 +845,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: component.mode == .greeting ? "Create a Greeting Message" : "Create an Away Message",
|
||||
string: component.mode == .greeting ? environment.strings.BusinessMessageSetup_CreateGreetingMessage : environment.strings.BusinessMessageSetup_CreateAwayMessage,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemAccentColor
|
||||
)),
|
||||
@ -881,7 +871,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: component.mode == .greeting ? "GREETING MESSAGE" : "AWAY MESSAGE",
|
||||
string: component.mode == .greeting ? environment.strings.BusinessMessageSetup_GreetingMessageSectionHeader : environment.strings.BusinessMessageSetup_AwayMessageSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -906,24 +896,23 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
otherSectionsHeight += sectionSpacing
|
||||
|
||||
if case .away = component.mode {
|
||||
//TODO:localize
|
||||
var scheduleSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
optionLoop: for i in 0 ..< 3 {
|
||||
let title: String
|
||||
let schedule: Schedule
|
||||
switch i {
|
||||
case 0:
|
||||
title = "Always Send"
|
||||
title = environment.strings.BusinessMessageSetup_ScheduleAlways
|
||||
schedule = .always
|
||||
case 1:
|
||||
if component.initialData.businessHours == nil {
|
||||
continue optionLoop
|
||||
}
|
||||
|
||||
title = "Outside of Business Hours"
|
||||
title = environment.strings.BusinessMessageSetup_ScheduleOutsideBusinessHours
|
||||
schedule = .outsideBusinessHours
|
||||
default:
|
||||
title = "Custom Schedule"
|
||||
title = environment.strings.BusinessMessageSetup_ScheduleCustom
|
||||
schedule = .custom
|
||||
}
|
||||
let isSelected = self.schedule == schedule
|
||||
@ -963,7 +952,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "SCHEDULE",
|
||||
string: environment.strings.BusinessMessageSetup_ScheduleSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -995,11 +984,11 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
let isStartTime: Bool
|
||||
switch i {
|
||||
case 0:
|
||||
title = "Start Time"
|
||||
title = environment.strings.BusinessMessageSetup_ScheduleStartTime
|
||||
itemDate = self.customScheduleStart
|
||||
isStartTime = true
|
||||
default:
|
||||
title = "End Time"
|
||||
title = environment.strings.BusinessMessageSetup_ScheduleEndTime
|
||||
itemDate = self.customScheduleEnd
|
||||
isStartTime = false
|
||||
}
|
||||
@ -1059,7 +1048,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
} else {
|
||||
icon = ListActionItemComponent.Icon(component: AnyComponentWithIdentity(id: 1, component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Set",
|
||||
string: environment.strings.BusinessMessageSetup_ScheduleTimePlaceholder,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemSecondaryTextColor
|
||||
)),
|
||||
@ -1126,7 +1115,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
header: nil,
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(
|
||||
text: "Don't send the away message if you've recently been online.",
|
||||
text: environment.strings.BusinessMessageSetup_SendWhenOfflineFooter,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
@ -1144,7 +1133,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Only if Offline",
|
||||
string: environment.strings.BusinessMessageSetup_SendWhenOffline,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -1182,15 +1171,14 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
otherSectionsHeight += sendWhenOfflineSectionSize.height
|
||||
otherSectionsHeight += sectionSpacing
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
|
||||
let accessSectionSize = self.accessSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "RECIPIENTS",
|
||||
string: environment.strings.BusinessMessageSetup_RecipientsSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1203,7 +1191,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "All 1-to-1 Chats Except...",
|
||||
string: environment.strings.BusinessMessageSetup_RecipientsOptionAllExcept,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -1233,7 +1221,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Only Selected Chats",
|
||||
string: environment.strings.BusinessMessageSetup_RecipientsOptionOnly,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -1281,7 +1269,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: self.hasAccessToAllChatsByDefault ? "Exclude Chats..." : "Select Chats...",
|
||||
string: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_AddExclude : environment.strings.BusinessMessageSetup_Recipients_AddInclude,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemAccentColor
|
||||
)),
|
||||
@ -1304,23 +1292,22 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
let title: String
|
||||
let icon: String
|
||||
let color: AvatarBackgroundColor
|
||||
//TODO:localize
|
||||
switch category {
|
||||
case .newChats:
|
||||
title = "New Chats"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryNewChats
|
||||
icon = "Chat List/Filters/NewChats"
|
||||
color = .purple
|
||||
case .existingChats:
|
||||
title = "Existing Chats"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryExistingChats
|
||||
icon = "Chat List/Filters/Chats"
|
||||
color = .purple
|
||||
case .contacts:
|
||||
title = "Contacts"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryContacts
|
||||
icon = "Chat List/Filters/Contact"
|
||||
color = .blue
|
||||
case .nonContacts:
|
||||
title = "Non-Contacts"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryNonContacts
|
||||
icon = "Chat List/Filters/User"
|
||||
color = .yellow
|
||||
}
|
||||
excludedSectionItems.append(AnyComponentWithIdentity(id: category, component: AnyComponent(PeerListItemComponent(
|
||||
@ -1354,7 +1341,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
sideInset: 0.0,
|
||||
title: peer.peer.displayTitle(strings: environment.strings, displayOrder: .firstLast),
|
||||
peer: peer.peer,
|
||||
subtitle: peer.isContact ? "contact" : "non-contact",
|
||||
subtitle: peer.isContact ? environment.strings.ChatList_PeerTypeContact : environment.strings.ChatList_PeerTypeNonContact,
|
||||
subtitleAccessory: .none,
|
||||
presence: nil,
|
||||
selectionState: .none,
|
||||
@ -1364,14 +1351,13 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
))))
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let excludedSectionSize = self.excludedSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: self.hasAccessToAllChatsByDefault ? "EXCLUDED CHATS" : "INCLUDED CHATS",
|
||||
string: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_ExcludedSectionHeader : environment.strings.BusinessMessageSetup_Recipients_IncludedSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1379,7 +1365,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(
|
||||
text: component.mode == .greeting ? "Choose chats or entire chat categories for sending a greeting message." : "Choose chats or entire chat categories for sending an away message.",
|
||||
text: component.mode == .greeting ? environment.strings.BusinessMessageSetup_Recipients_GreetingMessageFooter : environment.strings.BusinessMessageSetup_Recipients_AwayMessageFooter,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
@ -1428,7 +1414,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "PERIOD OF NO ACTIVITY",
|
||||
string: environment.strings.BusinessMessageSetup_InactivitySectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1436,7 +1422,7 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Choose how many days should pass after your last interaction with a recipient to send them the greeting in response to their message.",
|
||||
string: environment.strings.BusinessMessageSetup_InactivitySectionFooter,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -1445,12 +1431,9 @@ final class AutomaticBusinessMessageSetupScreenComponent: Component {
|
||||
items: [
|
||||
AnyComponentWithIdentity(id: 0, component: AnyComponent(ListItemSliderSelectorComponent(
|
||||
theme: environment.theme,
|
||||
values: [
|
||||
"7 days",
|
||||
"14 days",
|
||||
"21 days",
|
||||
"28 days"
|
||||
],
|
||||
values: valueList.map { item in
|
||||
return environment.strings.MessageTimer_Days(Int32(item))
|
||||
},
|
||||
selectedIndex: selectedInactivityIndex,
|
||||
selectedIndexUpdated: { [weak self] index in
|
||||
guard let self else {
|
||||
|
@ -75,7 +75,7 @@ final class QuickReplyEmptyStateComponent: Component {
|
||||
content: AnyComponentWithIdentity(
|
||||
id: AnyHashable(0),
|
||||
component: AnyComponent(ButtonTextContentComponent(
|
||||
text: "Add Quick Reply",
|
||||
text: component.strings.QuickReplies_EmptyState_AddButton,
|
||||
badge: 0,
|
||||
textColor: component.theme.list.itemCheckColors.foregroundColor,
|
||||
badgeBackground: component.theme.list.itemCheckColors.foregroundColor,
|
||||
@ -115,11 +115,10 @@ final class QuickReplyEmptyStateComponent: Component {
|
||||
containerSize: CGSize(width: 120.0, height: 120.0)
|
||||
)
|
||||
|
||||
//TODO:localize
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "No Quick Replies", font: Font.semibold(17.0), textColor: component.theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: component.strings.QuickReplies_EmptyState_Title, font: Font.semibold(17.0), textColor: component.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
@ -129,7 +128,7 @@ final class QuickReplyEmptyStateComponent: Component {
|
||||
let textSize = self.text.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Set up shortcuts with rich text and media to respond to messages faster.", font: Font.regular(15.0), textColor: component.theme.list.itemSecondaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: component.strings.QuickReplies_EmptyState_Text, font: Font.regular(15.0), textColor: component.theme.list.itemSecondaryTextColor)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 20,
|
||||
lineSpacing: 0.2
|
||||
|
@ -87,12 +87,11 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
func item(listNode: ContentListNode) -> ListViewItem {
|
||||
switch self {
|
||||
case .add:
|
||||
//TODO:localize
|
||||
return ItemListPeerActionItem(
|
||||
presentationData: ItemListPresentationData(listNode.presentationData),
|
||||
icon: PresentationResourcesItemList.plusIconImage(listNode.presentationData.theme),
|
||||
iconSignal: nil,
|
||||
title: "New Quick Reply",
|
||||
title: listNode.presentationData.strings.QuickReply_InlineCreateAction,
|
||||
additionalBadgeIcon: nil,
|
||||
alwaysPlain: true,
|
||||
hasSeparator: true,
|
||||
@ -525,7 +524,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func openQuickReplyChat(shortcut: String?, shortcutId: Int32?) {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -564,8 +563,8 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
var completion: ((String?) -> Void)?
|
||||
let alertController = quickReplyNameAlertController(
|
||||
context: component.context,
|
||||
text: "New Quick Reply",
|
||||
subtext: "Add a shortcut for your quick reply.",
|
||||
text: environment.strings.QuickReply_CreateShortcutTitle,
|
||||
subtext: environment.strings.QuickReply_CreateShortcutText,
|
||||
value: "",
|
||||
characterLimit: 32,
|
||||
apply: { value in
|
||||
@ -573,7 +572,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
}
|
||||
)
|
||||
completion = { [weak self, weak alertController] value in
|
||||
guard let self else {
|
||||
guard let self, let environment = self.environment else {
|
||||
alertController?.dismissAnimated()
|
||||
return
|
||||
}
|
||||
@ -585,7 +584,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
|
||||
if shortcutMessageList.items.contains(where: { $0.shortcut.lowercased() == value.lowercased() }) {
|
||||
if let contentNode = alertController?.contentNode as? QuickReplyNameAlertContentNode {
|
||||
contentNode.setErrorText(errorText: "Shortcut with that name already exists")
|
||||
contentNode.setErrorText(errorText: environment.strings.QuickReply_ShortcutExistsInlineError)
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -602,15 +601,15 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func openEditShortcut(id: Int32, currentValue: String) {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
|
||||
var completion: ((String?) -> Void)?
|
||||
let alertController = quickReplyNameAlertController(
|
||||
context: component.context,
|
||||
text: "Edit Shortcut",
|
||||
subtext: "Add a new name for your shortcut.",
|
||||
text: environment.strings.QuickReply_EditShortcutTitle,
|
||||
subtext: environment.strings.QuickReply_EditShortcutText,
|
||||
value: currentValue,
|
||||
characterLimit: 32,
|
||||
apply: { value in
|
||||
@ -618,7 +617,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
}
|
||||
)
|
||||
completion = { [weak self, weak alertController] value in
|
||||
guard let self, let component = self.component else {
|
||||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
alertController?.dismissAnimated()
|
||||
return
|
||||
}
|
||||
@ -634,7 +633,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
|
||||
if shortcutMessageList.items.contains(where: { $0.shortcut.lowercased() == value.lowercased() }) {
|
||||
if let contentNode = alertController?.contentNode as? QuickReplyNameAlertContentNode {
|
||||
contentNode.setErrorText(errorText: "Shortcut with that name already exists")
|
||||
contentNode.setErrorText(errorText: environment.strings.QuickReply_ShortcutExistsInlineError)
|
||||
}
|
||||
} else {
|
||||
component.context.engine.accountData.editMessageShortcut(id: id, shortcut: value)
|
||||
@ -665,8 +664,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
let actionSheet = ActionSheetController(presentationData: presentationData)
|
||||
var items: [ActionSheetItem] = []
|
||||
|
||||
//TODO:localize
|
||||
items.append(ActionSheetButtonItem(title: ids.count == 1 ? "Delete Quick Reply" : "Delete Quick Replies", color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
items.append(ActionSheetButtonItem(title: ids.count == 1 ? presentationData.strings.QuickReply_DeleteConfirmationSingle : presentationData.strings.QuickReply_DeleteConfirmationMultiple, color: .destructive, action: { [weak self, weak actionSheet] in
|
||||
actionSheet?.dismissAnimated()
|
||||
guard let self, let component = self.component else {
|
||||
return
|
||||
@ -732,10 +730,9 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
|
||||
let titleText: String
|
||||
if !self.selectedIds.isEmpty {
|
||||
//TODO:localize
|
||||
titleText = "\(self.selectedIds.count) Selected"
|
||||
titleText = strings.QuickReply_SelectedTitle(Int32(self.selectedIds.count))
|
||||
} else {
|
||||
titleText = "Quick Replies"
|
||||
titleText = strings.QuickReply_Title
|
||||
}
|
||||
|
||||
let closeTitle: String
|
||||
@ -762,7 +759,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
}
|
||||
))) : nil,
|
||||
rightButtons: rightButtons,
|
||||
backTitle: isModal ? nil : "Back",
|
||||
backTitle: isModal ? nil : strings.Common_Back,
|
||||
backPressed: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
@ -1060,12 +1057,7 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
self.selectionPanel = selectionPanel
|
||||
}
|
||||
|
||||
let buttonTitle: String
|
||||
if self.selectedIds.count == 1 {
|
||||
buttonTitle = "Delete 1 Quick Reply"
|
||||
} else {
|
||||
buttonTitle = "Delete \(self.selectedIds.count) Quick Replies"
|
||||
}
|
||||
let buttonTitle: String = environment.strings.QuickReply_DeleteAction(Int32(self.selectedIds.count))
|
||||
|
||||
let selectionPanelSize = selectionPanel.update(
|
||||
transition: selectionPanelTransition,
|
||||
@ -1098,7 +1090,6 @@ final class QuickReplySetupScreenComponent: Component {
|
||||
containerSize: availableSize
|
||||
)
|
||||
let selectionPanelFrame = CGRect(origin: CGPoint(x: 0.0, y: availableSize.height - selectionPanelSize.height), size: selectionPanelSize)
|
||||
print("selectionPanelFrame: \(selectionPanelFrame.minY)")
|
||||
listBottomInset = selectionPanelSize.height
|
||||
if let selectionPanelView = selectionPanel.view {
|
||||
var animateIn = false
|
||||
|
@ -117,7 +117,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let enviroment = self.environment else {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -126,11 +126,10 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
//TODO:localize
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "Business hours are intersecting. Reset?", actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Cancel", action: {
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: enviroment.strings.BusinessHoursSetup_ErrorIntersectingHours_Text, actions: [
|
||||
TextAlertAction(type: .genericAction, title: enviroment.strings.Common_Cancel, action: {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: "Reset", action: {
|
||||
TextAlertAction(type: .defaultAction, title: enviroment.strings.BusinessHoursSetup_ErrorIntersectingHours_ResetAction, action: {
|
||||
complete()
|
||||
})
|
||||
]), in: .window(.root))
|
||||
@ -258,23 +257,22 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let title: String
|
||||
switch component.dayIndex {
|
||||
case 0:
|
||||
title = "Monday"
|
||||
title = environment.strings.Weekday_Monday
|
||||
case 1:
|
||||
title = "Tuesday"
|
||||
title = environment.strings.Weekday_Tuesday
|
||||
case 2:
|
||||
title = "Wednesday"
|
||||
title = environment.strings.Weekday_Wednesday
|
||||
case 3:
|
||||
title = "Thursday"
|
||||
title = environment.strings.Weekday_Thursday
|
||||
case 4:
|
||||
title = "Friday"
|
||||
title = environment.strings.Weekday_Friday
|
||||
case 5:
|
||||
title = "Saturday"
|
||||
title = environment.strings.Weekday_Saturday
|
||||
case 6:
|
||||
title = "Sunday"
|
||||
title = environment.strings.Weekday_Sunday
|
||||
default:
|
||||
title = " "
|
||||
}
|
||||
@ -309,7 +307,6 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
contentHeight += environment.navigationHeight
|
||||
contentHeight += 16.0
|
||||
|
||||
//TODO:localize
|
||||
let generalSectionSize = self.generalSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -322,7 +319,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Open On This Day",
|
||||
string: environment.strings.BusinessHoursSetup_DaySwitch,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -381,7 +378,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: isOpenTime ? "Opening time" : "Closing Time",
|
||||
string: isOpenTime ? environment.strings.BusinessHoursSetup_DayIntervalStart : environment.strings.BusinessHoursSetup_DayIntervalEnd,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -420,7 +417,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Remove",
|
||||
string: environment.strings.BusinessHoursSetup_DayIntervalRemove,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemDestructiveColor
|
||||
)),
|
||||
@ -503,7 +500,6 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
canAddRanges = false
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let addSectionSize = self.addSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -511,7 +507,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
header: nil,
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Specify your working hours during the day.",
|
||||
string: environment.strings.BusinessHoursSetup_AddSectionFooter,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -523,7 +519,7 @@ final class BusinessDaySetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Add a Set of Hours",
|
||||
string: environment.strings.BusinessHoursSetup_AddAction,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemAccentColor
|
||||
)),
|
||||
|
@ -295,7 +295,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -306,11 +306,10 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
return true
|
||||
} catch _ {
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
//TODO:localize
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "Business hours are intersecting. Reset?", actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Cancel", action: {
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: environment.strings.BusinessHoursSetup_ErrorIntersectingDays_Text, actions: [
|
||||
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {
|
||||
}),
|
||||
TextAlertAction(type: .defaultAction, title: "Reset", action: { [weak self] in
|
||||
TextAlertAction(type: .defaultAction, title: environment.strings.BusinessHoursSetup_ErrorIntersectingDays_ResetAction, action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
}
|
||||
@ -409,11 +408,10 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Business Hours", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.BusinessHoursSetup_Title, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
@ -461,8 +459,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
|
||||
contentHeight += 126.0
|
||||
|
||||
//TODO:localize
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("Turn this on to show your opening hours schedule to your customers.", attributes: MarkdownAttributes(
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.BusinessHoursSetup_Text, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||
@ -471,7 +468,6 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
}), textAlignment: .center
|
||||
))
|
||||
|
||||
//TODO:localize
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
@ -508,7 +504,6 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
contentHeight += subtitleSize.height
|
||||
contentHeight += 27.0
|
||||
|
||||
//TODO:localize
|
||||
let generalSectionSize = self.generalSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -521,7 +516,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Show Business Hours",
|
||||
string: environment.strings.BusinessHoursSetup_MainToggle,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -559,22 +554,21 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
let dayIndex = daysSectionItems.count
|
||||
|
||||
let title: String
|
||||
//TODO:localize
|
||||
switch dayIndex {
|
||||
case 0:
|
||||
title = "Monday"
|
||||
title = environment.strings.Weekday_Monday
|
||||
case 1:
|
||||
title = "Tuesday"
|
||||
title = environment.strings.Weekday_Tuesday
|
||||
case 2:
|
||||
title = "Wednesday"
|
||||
title = environment.strings.Weekday_Wednesday
|
||||
case 3:
|
||||
title = "Thursday"
|
||||
title = environment.strings.Weekday_Thursday
|
||||
case 4:
|
||||
title = "Friday"
|
||||
title = environment.strings.Weekday_Friday
|
||||
case 5:
|
||||
title = "Saturday"
|
||||
title = environment.strings.Weekday_Saturday
|
||||
case 6:
|
||||
title = "Sunday"
|
||||
title = environment.strings.Weekday_Sunday
|
||||
default:
|
||||
title = " "
|
||||
}
|
||||
@ -593,17 +587,17 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
|
||||
if let ranges = self.daysState.days[dayIndex].ranges {
|
||||
if ranges.isEmpty {
|
||||
subtitle.append(NSAttributedString(string: "Open 24 Hours", font: subtitleFont, textColor: invalidIndices.contains(0) ? environment.theme.list.itemDestructiveColor : environment.theme.list.itemAccentColor))
|
||||
subtitle.append(NSAttributedString(string: environment.strings.BusinessHoursSetup_DayOpen24h, font: subtitleFont, textColor: invalidIndices.contains(0) ? environment.theme.list.itemDestructiveColor : environment.theme.list.itemAccentColor))
|
||||
} else {
|
||||
for i in 0 ..< ranges.count {
|
||||
let range = ranges[i]
|
||||
|
||||
let startHours = clipMinutes(range.startMinute) / 60
|
||||
let startMinutes = clipMinutes(range.startMinute) % 60
|
||||
let startText = stringForShortTimestamp(hours: Int32(startHours), minutes: Int32(startMinutes), dateTimeFormat: PresentationDateTimeFormat())
|
||||
let startText = stringForShortTimestamp(hours: Int32(startHours), minutes: Int32(startMinutes), dateTimeFormat: presentationData.dateTimeFormat)
|
||||
let endHours = clipMinutes(range.endMinute) / 60
|
||||
let endMinutes = clipMinutes(range.endMinute) % 60
|
||||
let endText = stringForShortTimestamp(hours: Int32(endHours), minutes: Int32(endMinutes), dateTimeFormat: PresentationDateTimeFormat())
|
||||
let endText = stringForShortTimestamp(hours: Int32(endHours), minutes: Int32(endMinutes), dateTimeFormat: presentationData.dateTimeFormat)
|
||||
|
||||
var rangeString = "\(startText)\u{00a0}- \(endText)"
|
||||
if i != ranges.count - 1 {
|
||||
@ -614,7 +608,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
subtitle.append(NSAttributedString(string: "Closed", font: subtitleFont, textColor: environment.theme.list.itemAccentColor))
|
||||
subtitle.append(NSAttributedString(string: environment.strings.BusinessHoursSetup_DayClosed, font: subtitleFont, textColor: environment.theme.list.itemAccentColor))
|
||||
}
|
||||
|
||||
daysSectionItems.append(AnyComponentWithIdentity(id: dayIndex, component: AnyComponent(ListActionItemComponent(
|
||||
@ -678,7 +672,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "BUSINESS HOURS",
|
||||
string: environment.strings.BusinessHoursSetup_DaysSectionTitle,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -712,8 +706,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
timezoneValueText = TimeZone(identifier: self.daysState.timezoneId)?.localizedName(for: .shortStandard, locale: Locale.current) ?? " "
|
||||
}
|
||||
} else {
|
||||
//TODO:localize
|
||||
timezoneValueText = "Loading..."
|
||||
timezoneValueText = "..."
|
||||
}
|
||||
|
||||
let timezoneSectionSize = self.timezoneSection.update(
|
||||
@ -727,7 +720,7 @@ final class BusinessHoursSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
title: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Time Zone", //TODO:localize
|
||||
string: environment.strings.BusinessHoursSetup_TimeZone,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
|
@ -118,7 +118,7 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
func attemptNavigation(complete: @escaping () -> Void) -> Bool {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return true
|
||||
}
|
||||
|
||||
@ -134,11 +134,10 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
|
||||
if businessLocation != nil && address.isEmpty {
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
//TODO:localize
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "Address can't be empty.", actions: [
|
||||
TextAlertAction(type: .genericAction, title: "Cancel", action: {
|
||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: environment.strings.BusinessLocationSetup_ErrorAddressEmpty_Text, actions: [
|
||||
TextAlertAction(type: .genericAction, title: environment.strings.Common_Cancel, action: {
|
||||
}),
|
||||
TextAlertAction(type: .destructiveAction, title: "Delete", action: {
|
||||
TextAlertAction(type: .destructiveAction, title: environment.strings.BusinessLocationSetup_ErrorAddressEmpty_ResetAction, action: {
|
||||
let _ = component.context.engine.accountData.updateAccountBusinessLocation(businessLocation: nil).startStandalone()
|
||||
|
||||
complete()
|
||||
@ -286,11 +285,10 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Location", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.BusinessLocationSetup_Title, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
@ -335,8 +333,7 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
|
||||
contentHeight += 129.0
|
||||
|
||||
//TODO:localize
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("Display the location of your business on your account.", attributes: MarkdownAttributes(
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.BusinessLocationSetup_Text, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||
@ -345,7 +342,6 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
}), textAlignment: .center
|
||||
))
|
||||
|
||||
//TODO:localize
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
@ -382,7 +378,6 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
contentHeight += subtitleSize.height
|
||||
contentHeight += 27.0
|
||||
|
||||
//TODO:localize
|
||||
var addressSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
addressSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListMultilineTextFieldItemComponent(
|
||||
externalState: self.addressTextInputState,
|
||||
@ -393,7 +388,7 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
resetText: self.resetAddressText.flatMap { resetAddressText in
|
||||
return ListMultilineTextFieldItemComponent.ResetText(value: resetAddressText)
|
||||
},
|
||||
placeholder: "Enter Address",
|
||||
placeholder: environment.strings.BusinessLocationSetup_AddressPlaceholder,
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
characterLimit: 64,
|
||||
@ -404,7 +399,6 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
))))
|
||||
self.resetAddressText = nil
|
||||
|
||||
//TODO:localize
|
||||
let addressSectionSize = self.addressSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -428,13 +422,12 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
contentHeight += sectionSpacing
|
||||
|
||||
var mapSectionItems: [AnyComponentWithIdentity<Empty>] = []
|
||||
//TODO:localize
|
||||
mapSectionItems.append(AnyComponentWithIdentity(id: 0, component: AnyComponent(ListActionItemComponent(
|
||||
theme: environment.theme,
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Set Location on Map",
|
||||
string: environment.strings.BusinessLocationSetup_SetLocationOnMap,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -471,7 +464,6 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
))))
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let mapSectionSize = self.mapSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -496,7 +488,6 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
var deleteSectionHeight: CGFloat = 0.0
|
||||
|
||||
deleteSectionHeight += sectionSpacing
|
||||
//TODO:localize
|
||||
let deleteSectionSize = self.deleteSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -509,7 +500,7 @@ final class BusinessLocationSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Delete Location",
|
||||
string: environment.strings.BusinessLocationSetup_DeleteLocation,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemDestructiveColor
|
||||
)),
|
||||
|
@ -108,12 +108,11 @@ final class ChatbotSearchResultItemComponent: Component {
|
||||
self.addButton = addButton
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
addButtonSize = addButton.update(
|
||||
transition: addButtonTransition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
content: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "ADD", font: Font.semibold(15.0), textColor: component.theme.list.itemCheckColors.foregroundColor))
|
||||
text: .plain(NSAttributedString(string: component.strings.ChatbotSetup_BotAddAction, font: Font.semibold(15.0), textColor: component.theme.list.itemCheckColors.foregroundColor))
|
||||
)),
|
||||
background: AnyComponent(RoundedRectangle(color: component.theme.list.itemCheckColors.fillColor, cornerRadius: nil)),
|
||||
effectAlignment: .center,
|
||||
@ -159,7 +158,6 @@ final class ChatbotSearchResultItemComponent: Component {
|
||||
self.removeButton = removeButton
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
removeButtonSize = removeButton.update(
|
||||
transition: removeButtonTransition,
|
||||
component: AnyComponent(PlainButtonComponent(
|
||||
@ -205,11 +203,11 @@ final class ChatbotSearchResultItemComponent: Component {
|
||||
case .searching, .notFound:
|
||||
isTextVisible = false
|
||||
titleValue = "AAAAAAAAA"
|
||||
subtitleValue = "bot" //TODO:localize
|
||||
subtitleValue = component.strings.Bot_GenericBotStatus
|
||||
case let .found(peer, _):
|
||||
isTextVisible = true
|
||||
titleValue = peer.displayTitle(strings: component.strings, displayOrder: .firstLast)
|
||||
subtitleValue = "bot"
|
||||
subtitleValue = component.strings.Bot_GenericBotStatus
|
||||
}
|
||||
|
||||
let titleSize = self.titleLabel.update(
|
||||
@ -298,11 +296,10 @@ final class ChatbotSearchResultItemComponent: Component {
|
||||
notFoundLabel = ComponentView()
|
||||
self.notFoundLabel = notFoundLabel
|
||||
}
|
||||
//TODO:localize
|
||||
let notFoundLabelSize = notFoundLabel.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Chatbot not found", font: Font.regular(13.0), textColor: component.theme.list.itemSecondaryTextColor))
|
||||
text: .plain(NSAttributedString(string: component.strings.ChatbotSetup_BotNotFoundStatus, font: Font.regular(13.0), textColor: component.theme.list.itemSecondaryTextColor))
|
||||
)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: maxTextWidth, height: 100.0)
|
||||
|
@ -296,7 +296,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
}
|
||||
|
||||
private func openAdditionalPeerListSetup() {
|
||||
guard let component = self.component else {
|
||||
guard let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
|
||||
@ -312,19 +312,19 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
id: self.hasAccessToAllChatsByDefault ? AdditionalCategoryId.existingChats.rawValue : AdditionalCategoryId.newChats.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: self.hasAccessToAllChatsByDefault ? "Chat List/Filters/Chats" : "Chat List/Filters/NewChats"), color: .white), cornerRadius: 12.0, color: .purple),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: self.hasAccessToAllChatsByDefault ? "Chat List/Filters/Chats" : "Chat List/Filters/NewChats"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .purple),
|
||||
title: self.hasAccessToAllChatsByDefault ? "Existing Chats" : "New Chats"
|
||||
title: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_CategoryExistingChats : environment.strings.BusinessMessageSetup_Recipients_CategoryNewChats
|
||||
),
|
||||
ChatListNodeAdditionalCategory(
|
||||
id: AdditionalCategoryId.contacts.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/Contact"), color: .white), cornerRadius: 12.0, color: .blue),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/Contact"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .blue),
|
||||
title: "Contacts"
|
||||
title: environment.strings.BusinessMessageSetup_Recipients_CategoryContacts
|
||||
),
|
||||
ChatListNodeAdditionalCategory(
|
||||
id: AdditionalCategoryId.nonContacts.rawValue,
|
||||
icon: generateAvatarImage(size: CGSize(width: 40.0, height: 40.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/User"), color: .white), cornerRadius: 12.0, color: .yellow),
|
||||
smallIcon: generateAvatarImage(size: CGSize(width: 22.0, height: 22.0), icon: generateTintedImage(image: UIImage(bundleImageName: "Chat List/Filters/User"), color: .white), iconScale: 0.6, cornerRadius: 6.0, circleCorners: true, color: .yellow),
|
||||
title: "Non-Contacts"
|
||||
title: environment.strings.BusinessMessageSetup_Recipients_CategoryNonContacts
|
||||
)
|
||||
]
|
||||
var selectedCategories = Set<Int>()
|
||||
@ -341,10 +341,9 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let controller = component.context.sharedContext.makeContactMultiselectionController(ContactMultiselectionControllerParams(context: component.context, mode: .chatSelection(ContactMultiselectionControllerMode.ChatSelection(
|
||||
title: self.hasAccessToAllChatsByDefault ? "Exclude Chats" : "Include Chats",
|
||||
searchPlaceholder: "Search chats",
|
||||
title: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_ExcludeSearchTitle : environment.strings.BusinessMessageSetup_Recipients_IncludeSearchTitle,
|
||||
searchPlaceholder: environment.strings.ChatListFilter_AddChatsSearchPlaceholder,
|
||||
selectedChats: Set(self.additionalPeerList.peers.map(\.peer.id)),
|
||||
additionalCategories: ContactMultiselectionControllerAdditionalCategories(categories: additionalCategories, selectedCategories: selectedCategories),
|
||||
chatListFilters: nil,
|
||||
@ -480,11 +479,10 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
//TODO:localize
|
||||
let navigationTitleSize = self.navigationTitle.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Chatbots", font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
text: .plain(NSAttributedString(string: environment.strings.ChatbotSetup_Title, font: Font.semibold(17.0), textColor: environment.theme.rootController.navigationBar.primaryTextColor)),
|
||||
horizontalAlignment: .center
|
||||
)),
|
||||
environment: {},
|
||||
@ -532,8 +530,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
|
||||
contentHeight += 129.0
|
||||
|
||||
//TODO:localize
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString("Add a bot to your account to help you automatically process and respond to the messages you receive. [Learn More >]()", attributes: MarkdownAttributes(
|
||||
let subtitleString = NSMutableAttributedString(attributedString: parseMarkdownIntoAttributedString(environment.strings.ChatbotSetup_Text, attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(15.0), textColor: environment.theme.list.freeTextColor),
|
||||
link: MarkdownAttributeSet(font: Font.regular(15.0), textColor: environment.theme.list.itemAccentColor),
|
||||
@ -548,7 +545,6 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
subtitleString.addAttribute(.attachment, value: chevronImage, range: NSRange(range, in: subtitleString.string))
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let subtitleSize = self.subtitle.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(BalancedTextComponent(
|
||||
@ -565,11 +561,10 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
}
|
||||
},
|
||||
tapAction: { [weak self] _, _ in
|
||||
guard let self, let component = self.component else {
|
||||
guard let self, let component = self.component, let environment = self.environment else {
|
||||
return
|
||||
}
|
||||
//TODO:localize
|
||||
component.context.sharedContext.applicationBindings.openUrl("https://telegram.org")
|
||||
component.context.sharedContext.applicationBindings.openUrl(environment.strings.ChatbotSetup_TextLink)
|
||||
}
|
||||
)),
|
||||
environment: {},
|
||||
@ -593,7 +588,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
theme: environment.theme,
|
||||
initialText: "",
|
||||
resetText: resetQueryText.flatMap { ListTextFieldItemComponent.ResetText(value: $0) },
|
||||
placeholder: "Bot Username",
|
||||
placeholder: environment.strings.ChatbotSetup_BotSearchPlaceholder,
|
||||
autocapitalizationType: .none,
|
||||
autocorrectionType: .no,
|
||||
updated: { [weak self] value in
|
||||
@ -649,7 +644,6 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
))))
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let nameSectionSize = self.nameSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
@ -657,7 +651,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
header: nil,
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Enter the username or URL of the Telegram bot that you want to automatically process your chats.",
|
||||
string: environment.strings.ChatbotSetup_BotSectionFooter,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -678,14 +672,13 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
contentHeight += nameSectionSize.height
|
||||
contentHeight += sectionSpacing
|
||||
|
||||
//TODO:localize
|
||||
let accessSectionSize = self.accessSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "CHATS ACCESSIBLE FOR THE BOT",
|
||||
string: environment.strings.ChatbotSetup_RecipientsSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -698,7 +691,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "All 1-to-1 Chats Except...",
|
||||
string: environment.strings.BusinessMessageSetup_RecipientsOptionAllExcept,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -728,7 +721,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Only Selected Chats",
|
||||
string: environment.strings.BusinessMessageSetup_RecipientsOptionOnly,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
@ -774,7 +767,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: self.hasAccessToAllChatsByDefault ? "Exclude Chats..." : "Select Chats...",
|
||||
string: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_AddExclude : environment.strings.BusinessMessageSetup_Recipients_AddInclude,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemAccentColor
|
||||
)),
|
||||
@ -797,23 +790,22 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
let title: String
|
||||
let icon: String
|
||||
let color: AvatarBackgroundColor
|
||||
//TODO:localize
|
||||
switch category {
|
||||
case .newChats:
|
||||
title = "New Chats"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryNewChats
|
||||
icon = "Chat List/Filters/NewChats"
|
||||
color = .purple
|
||||
case .existingChats:
|
||||
title = "Existing Chats"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryExistingChats
|
||||
icon = "Chat List/Filters/Chats"
|
||||
color = .purple
|
||||
case .contacts:
|
||||
title = "Contacts"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryContacts
|
||||
icon = "Chat List/Filters/Contact"
|
||||
color = .blue
|
||||
case .nonContacts:
|
||||
title = "Non-Contacts"
|
||||
icon = "Chat List/Filters/Contact"
|
||||
title = environment.strings.BusinessMessageSetup_Recipients_CategoryNonContacts
|
||||
icon = "Chat List/Filters/User"
|
||||
color = .yellow
|
||||
}
|
||||
excludedSectionItems.append(AnyComponentWithIdentity(id: category, component: AnyComponent(PeerListItemComponent(
|
||||
@ -847,7 +839,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
sideInset: 0.0,
|
||||
title: peer.peer.displayTitle(strings: environment.strings, displayOrder: .firstLast),
|
||||
peer: peer.peer,
|
||||
subtitle: peer.isContact ? "contact" : "non-contact",
|
||||
subtitle: peer.isContact ? environment.strings.ChatList_PeerTypeContact : environment.strings.ChatList_PeerTypeNonContact,
|
||||
subtitleAccessory: .none,
|
||||
presence: nil,
|
||||
selectionState: .none,
|
||||
@ -857,14 +849,13 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
))))
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let excludedSectionSize = self.excludedSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: self.hasAccessToAllChatsByDefault ? "EXCLUDED CHATS" : "INCLUDED CHATS",
|
||||
string: self.hasAccessToAllChatsByDefault ? environment.strings.BusinessMessageSetup_Recipients_ExcludedSectionHeader : environment.strings.BusinessMessageSetup_Recipients_IncludedSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -872,7 +863,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .markdown(
|
||||
text: self.hasAccessToAllChatsByDefault ? "Select chats or entire chat categories which the bot **WILL NOT** have access to." : "Select chats or entire chat categories which the bot **WILL** have access to.",
|
||||
text: self.hasAccessToAllChatsByDefault ? environment.strings.ChatbotSetup_Recipients_ExcludedSectionFooter : environment.strings.ChatbotSetup_Recipients_IncludedSectionFooter,
|
||||
attributes: MarkdownAttributes(
|
||||
body: MarkdownAttributeSet(font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
bold: MarkdownAttributeSet(font: Font.semibold(presentationData.listsFontSize.itemListBaseHeaderFontSize), textColor: environment.theme.list.freeTextColor),
|
||||
@ -899,14 +890,13 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
contentHeight += excludedSectionSize.height
|
||||
contentHeight += sectionSpacing
|
||||
|
||||
//TODO:localize
|
||||
let permissionsSectionSize = self.permissionsSection.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ListSectionComponent(
|
||||
theme: environment.theme,
|
||||
header: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "BOT PERMISSIONS",
|
||||
string: environment.strings.ChatbotSetup_PermissionsSectionHeader,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -914,7 +904,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
)),
|
||||
footer: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "The bot will be able to view all new incoming messages, but not the messages that had been sent before you added the bot.",
|
||||
string: environment.strings.ChatbotSetup_PermissionsSectionFooter,
|
||||
font: Font.regular(presentationData.listsFontSize.itemListBaseHeaderFontSize),
|
||||
textColor: environment.theme.list.freeTextColor
|
||||
)),
|
||||
@ -926,7 +916,7 @@ final class ChatbotSetupScreenComponent: Component {
|
||||
title: AnyComponent(VStack([
|
||||
AnyComponentWithIdentity(id: AnyHashable(0), component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(
|
||||
string: "Reply to Messages",
|
||||
string: environment.strings.ChatbotSetup_Permission_ReplyToMessages,
|
||||
font: Font.regular(presentationData.listsFontSize.baseDisplaySize),
|
||||
textColor: environment.theme.list.itemPrimaryTextColor
|
||||
)),
|
||||
|
@ -239,8 +239,7 @@ public final class QuickReplyNameAlertContentNode: AlertContentNode {
|
||||
self.subtext = subtext
|
||||
self.titleFont = titleFont
|
||||
|
||||
//TODO:localize
|
||||
self.inputFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: "Shortcut", characterLimit: characterLimit)
|
||||
self.inputFieldNode = PromptInputFieldNode(theme: ptheme, placeholder: strings.QuickReply_ShortcutPlaceholder, characterLimit: characterLimit)
|
||||
self.inputFieldNode.text = value ?? ""
|
||||
|
||||
self.actionNodesSeparator = ASDisplayNode()
|
||||
|
@ -39,8 +39,7 @@ public class TimezoneSelectionScreen: ViewController {
|
||||
|
||||
self.statusBar.statusBarStyle = self.presentationData.theme.rootController.statusBarStyle.style
|
||||
|
||||
//TODO:localize
|
||||
self.title = "Time Zone"
|
||||
self.title = self.presentationData.strings.TimeZoneSelection_Title
|
||||
|
||||
self.navigationItem.backBarButtonItem = UIBarButtonItem(title: self.presentationData.strings.Common_Back, style: .plain, target: nil, action: nil)
|
||||
|
||||
|
@ -94,8 +94,8 @@ public final class SliderComponent: Component {
|
||||
sliderView.minimumValue = 0.0
|
||||
sliderView.startValue = 0.0
|
||||
sliderView.disablesInteractiveTransitionGestureRecognizer = true
|
||||
sliderView.maximumValue = CGFloat(component.valueCount)
|
||||
sliderView.positionsCount = component.valueCount + 1
|
||||
sliderView.maximumValue = CGFloat(component.valueCount - 1)
|
||||
sliderView.positionsCount = component.valueCount
|
||||
sliderView.useLinesForPositions = true
|
||||
|
||||
sliderView.backgroundColor = nil
|
||||
|
@ -723,25 +723,24 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
switch customChatContents.kind {
|
||||
case let .quickReplyMessageInput(_, shortcutType):
|
||||
if let historyView = strongSelf.chatDisplayNode.historyNode.originalHistoryView, historyView.entries.isEmpty {
|
||||
//TODO:localize
|
||||
|
||||
let titleString: String
|
||||
let textString: String
|
||||
switch shortcutType {
|
||||
case .generic:
|
||||
titleString = "Remove Shortcut"
|
||||
textString = "You didn't create a quick reply message. Exiting will remove the shortcut."
|
||||
titleString = strongSelf.presentationData.strings.QuickReply_ChatRemoveGeneric_Title
|
||||
textString = strongSelf.presentationData.strings.QuickReply_ChatRemoveGeneric_Text
|
||||
case .greeting:
|
||||
titleString = "Remove Greeting Message"
|
||||
textString = "You didn't create a greeting message. Exiting will remove it."
|
||||
titleString = strongSelf.presentationData.strings.QuickReply_ChatRemoveGreetingMessage_Title
|
||||
textString = strongSelf.presentationData.strings.QuickReply_ChatRemoveGreetingMessage_Text
|
||||
case .away:
|
||||
titleString = "Remove Away Message"
|
||||
textString = "You didn't create an away message. Exiting will remove it."
|
||||
titleString = strongSelf.presentationData.strings.QuickReply_ChatRemoveAwayMessage_Title
|
||||
textString = strongSelf.presentationData.strings.QuickReply_ChatRemoveAwayMessage_Text
|
||||
}
|
||||
|
||||
strongSelf.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: strongSelf.presentationData), title: titleString, text: textString, actions: [
|
||||
TextAlertAction(type: .genericAction, title: strongSelf.presentationData.strings.Common_Cancel, action: {}),
|
||||
TextAlertAction(type: .defaultAction, title: "Remove", action: { [weak strongSelf] in
|
||||
TextAlertAction(type: .defaultAction, title: strongSelf.presentationData.strings.QuickReply_ChatRemoveGeneric_DeleteAction, action: { [weak strongSelf] in
|
||||
strongSelf?.dismiss()
|
||||
})
|
||||
]), in: .window(.root))
|
||||
@ -6204,7 +6203,6 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.reportIrrelvantGeoNoticePromise.set(.single(nil))
|
||||
self.titleDisposable.set(nil)
|
||||
|
||||
//TODO:localize
|
||||
if case let .customChatContents(customChatContents) = self.subject {
|
||||
switch customChatContents.kind {
|
||||
case let .quickReplyMessageInput(shortcut, shortcutType):
|
||||
@ -6212,13 +6210,13 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
case .generic:
|
||||
self.chatTitleView?.titleContent = .custom("\(shortcut)", nil, false)
|
||||
case .greeting:
|
||||
self.chatTitleView?.titleContent = .custom("Greeting Message", nil, false)
|
||||
self.chatTitleView?.titleContent = .custom(self.presentationData.strings.QuickReply_TitleGreetingMessage, nil, false)
|
||||
case .away:
|
||||
self.chatTitleView?.titleContent = .custom("Away Message", nil, false)
|
||||
self.chatTitleView?.titleContent = .custom(self.presentationData.strings.QuickReply_TitleAwayMessage, nil, false)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
self.chatTitleView?.titleContent = .custom("Messages", nil, false)
|
||||
self.chatTitleView?.titleContent = .custom(" ", nil, false)
|
||||
}
|
||||
|
||||
if !self.didSetChatLocationInfoReady {
|
||||
|
@ -11,13 +11,12 @@ import QuickReplyNameAlertController
|
||||
|
||||
extension ChatControllerImpl {
|
||||
func editChat() {
|
||||
//TODO:localize
|
||||
if case let .customChatContents(customChatContents) = self.subject, case let .quickReplyMessageInput(currentValue, shortcutType) = customChatContents.kind, case .generic = shortcutType {
|
||||
var completion: ((String?) -> Void)?
|
||||
let alertController = quickReplyNameAlertController(
|
||||
context: self.context,
|
||||
text: "Edit Shortcut",
|
||||
subtext: "Add a new name for your shortcut.",
|
||||
text: self.presentationData.strings.QuickReply_EditShortcutTitle,
|
||||
subtext: self.presentationData.strings.QuickReply_EditShortcutText,
|
||||
value: currentValue,
|
||||
characterLimit: 32,
|
||||
apply: { value in
|
||||
@ -45,7 +44,7 @@ extension ChatControllerImpl {
|
||||
|
||||
if shortcutMessageList.items.contains(where: { $0.shortcut.lowercased() == value.lowercased() }) {
|
||||
if let contentNode = alertController?.contentNode as? QuickReplyNameAlertContentNode {
|
||||
contentNode.setErrorText(errorText: "Shortcut with that name already exists")
|
||||
contentNode.setErrorText(errorText: self.presentationData.strings.QuickReply_ShortcutExistsInlineError)
|
||||
}
|
||||
} else {
|
||||
self.chatTitleView?.titleContent = .custom("\(value)", nil, false)
|
||||
|
@ -736,28 +736,25 @@ private final class ChatEmptyNodeCloudChatContent: ASDisplayNode, ChatEmptyNodeC
|
||||
switch shortcutType {
|
||||
case .generic:
|
||||
iconName = "Chat/Empty Chat/QuickReplies"
|
||||
//TODO:localize
|
||||
centerText = false
|
||||
titleString = "New Quick Reply"
|
||||
titleString = interfaceState.strings.Chat_EmptyState_QuickReply_Title
|
||||
strings = [
|
||||
"· Enter a message below that will be sent in chats when you type \"**/\(shortcut)\"**.",
|
||||
"· You can access Quick Replies in any chat by typing \"/\" or using the Attachment menu."
|
||||
interfaceState.strings.Chat_EmptyState_QuickReply_Text1(shortcut).string,
|
||||
interfaceState.strings.Chat_EmptyState_QuickReply_Text2
|
||||
]
|
||||
case .greeting:
|
||||
iconName = "Chat/Empty Chat/GreetingShortcut"
|
||||
//TODO:localize
|
||||
centerText = true
|
||||
titleString = "New Greeting Message"
|
||||
titleString = interfaceState.strings.EmptyState_GreetingMessage_Title
|
||||
strings = [
|
||||
"Create greetings that will be automatically sent to new customers"
|
||||
interfaceState.strings.EmptyState_GreetingMessage_Text
|
||||
]
|
||||
case .away:
|
||||
iconName = "Chat/Empty Chat/AwayShortcut"
|
||||
//TODO:localize
|
||||
centerText = true
|
||||
titleString = "New Away Message"
|
||||
titleString = interfaceState.strings.EmptyState_AwayMessage_Title
|
||||
strings = [
|
||||
"Add messages that are automatically sent when you are off."
|
||||
interfaceState.strings.EmptyState_AwayMessage_Text
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -243,8 +243,7 @@ private func updatedContextQueryResultStateForQuery(context: AccountContext, pee
|
||||
return false
|
||||
}
|
||||
var sortedCommands = filteredCommands.map(ChatInputTextCommand.command)
|
||||
if !shortcuts.isEmpty {
|
||||
sortedCommands.removeAll()
|
||||
if !shortcuts.isEmpty && sortedCommands.isEmpty {
|
||||
for shortcut in shortcuts {
|
||||
sortedCommands.append(.shortcut(shortcut))
|
||||
}
|
||||
|
@ -106,8 +106,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
||||
case .quickReplyMessageInput:
|
||||
displayCount = 20
|
||||
}
|
||||
//TODO:localize
|
||||
self.textNode.attributedText = NSAttributedString(string: "Limit of \(displayCount) messages reached", font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_QuickReplyMessageLimitReachedText(Int32(displayCount)), font: Font.regular(13.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||
}
|
||||
self.buttonNode.isUserInteractionEnabled = isUserInteractionEnabled
|
||||
|
||||
|
@ -1843,16 +1843,15 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
||||
}
|
||||
}
|
||||
if case let .customChatContents(customChatContents) = interfaceState.subject {
|
||||
//TODO:localize
|
||||
switch customChatContents.kind {
|
||||
case let .quickReplyMessageInput(_, shortcutType):
|
||||
switch shortcutType {
|
||||
case .generic:
|
||||
placeholder = "Add quick reply..."
|
||||
placeholder = interfaceState.strings.Chat_Placeholder_QuickReply
|
||||
case .greeting:
|
||||
placeholder = "Add greeting message..."
|
||||
placeholder = interfaceState.strings.Chat_Placeholder_GreetingMessage
|
||||
case .away:
|
||||
placeholder = "Add away message..."
|
||||
placeholder = interfaceState.strings.Chat_Placeholder_AwayMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -78,8 +78,7 @@ private struct CommandChatInputContextPanelEntry: Comparable, Identifiable {
|
||||
func item(context: AccountContext, presentationData: PresentationData, commandSelected: @escaping (ChatInputTextCommand, Bool) -> Void, openEditShortcuts: @escaping () -> Void) -> ListViewItem {
|
||||
switch self.content {
|
||||
case .editShortcuts:
|
||||
//TODO:localzie
|
||||
return VerticalListContextResultsChatInputPanelButtonItem(theme: presentationData.theme, style: .round, title: "Edit Quick Replies", pressed: {
|
||||
return VerticalListContextResultsChatInputPanelButtonItem(theme: presentationData.theme, style: .round, title: presentationData.strings.Chat_CommandList_EditQuickReplies, pressed: {
|
||||
openEditShortcuts()
|
||||
})
|
||||
case let .command(command):
|
||||
|
@ -285,8 +285,7 @@ final class EditAccessoryPanelNode: AccessoryPanelNode {
|
||||
|
||||
let titleString: String
|
||||
if let message, message.id.namespace == Namespaces.Message.QuickReplyCloud {
|
||||
//TODO:localize
|
||||
titleString = "Edit Quick Reply"
|
||||
titleString = self.strings.Conversation_EditingQuickReplyPanelTitle
|
||||
} else if canEditMedia {
|
||||
titleString = isPhoto ? self.strings.Conversation_EditingPhotoPanelTitle : self.strings.Conversation_EditingCaptionPanelTitle
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user