mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-15 21:45:19 +00:00
Localization
This commit is contained in:
parent
aa3ce6132d
commit
295ba9541b
@ -9411,6 +9411,9 @@ Sorry for the inconvenience.";
|
||||
"StoryFeed.TooltipStoryLimitValue_any" = "%d stories";
|
||||
"StoryFeed.TooltipStoryLimit" = "You can't post more than **%@** stories in **24 hours**.";
|
||||
|
||||
"StoryFeed.MyStory" = "My Story";
|
||||
"StoryFeed.MyUploading" = "Uploading...";
|
||||
|
||||
"MediaPicker.AddImage" = "Add Image";
|
||||
|
||||
"Premium.Stories" = "Story Posting";
|
||||
@ -9429,3 +9432,105 @@ Sorry for the inconvenience.";
|
||||
|
||||
"Settings.MyStories" = "My Stories";
|
||||
"Settings.StoriesArchive" = "Stories Archive";
|
||||
|
||||
"ArchiveSettings.Title" = "Archive Settings";
|
||||
|
||||
"ArchiveSettings.UnmutedChatsHeader" = "UNMUTED CHATS";
|
||||
"ArchiveSettings.UnmutedChatsFooter" = "Keep archived chats in the Archive even if they are unmuted and get a new message.";
|
||||
"ArchiveSettings.FolderChatsHeader" = "CHATS FROM FOLDERS";
|
||||
"ArchiveSettings.FolderChatsFooter" = "Keep archived chats from folders in the Archive even if they are unmuted and get a new message.";
|
||||
|
||||
"ArchiveSettings.UnknownChatsHeader" = "NEW CHATS FROM UNKNOWN USERS";
|
||||
"ArchiveSettings.UnknownChatsFooter" = "Automatically archive and mute new private chats, groups and channels from non-contacts.";
|
||||
|
||||
"ArchiveSettings.KeepArchived" = "Always Keep Archived";
|
||||
"ArchiveSettings.TooltipPremiumRequired" = "This setting is available only to the subscribers of [Telegram Premium]().";
|
||||
|
||||
"NotificationSettings.Stories.ShowAll" = "Show All Notifications";
|
||||
"NotificationSettings.Stories.ShowImportant" = "Show Important Notifications";
|
||||
"NotificationSettings.Stories.ShowImportantFooter" = "Always on for top 5 contacts.";
|
||||
"NotificationSettings.Stories.DisplayAuthorName" = "Display Author Name";
|
||||
|
||||
"NotificationSettings.Stories.AutomaticValue" = "%@ (automatic)";
|
||||
"NotificationSettings.Stories.CompactShowName" = "Show name";
|
||||
"NotificationSettings.Stories.CompactHideName" = "Hide name";
|
||||
|
||||
"Notifications.StoriesTitle" = "Stories";
|
||||
|
||||
"Message.Story" = "Story";
|
||||
|
||||
"Notification.Exceptions.StoriesHeader" = "STORY NOTIFICATIONS";
|
||||
"Notification.Exceptions.StoriesDisplayAuthorName" = "DISPLAY AUTHOR NAME";
|
||||
|
||||
"StorageManagement.SectionStories" = "Stories";
|
||||
|
||||
"PeerInfo.PaneStories" = "Stories";
|
||||
|
||||
"Story.TooltipExpired" = "This story is no longer available";
|
||||
|
||||
"Chat.ReplyExpiredStory" = "Expired story";
|
||||
"Chat.ReplyStory" = "Story";
|
||||
|
||||
"Chat.StoryMentionAction" = "View Story";
|
||||
|
||||
"StoryList.ContextSaveToGallery" = "Save to Gallery";
|
||||
"StoryList.ContextShowArchive" = "Show Archive";
|
||||
|
||||
"StoryList.TooltipStoriesDeleted_1" = "1 story deleted.";
|
||||
"StoryList.TooltipStoriesDeleted_any" = "%d stories deleted.";
|
||||
|
||||
"Story.TooltipSaving" = "Saving";
|
||||
"Story.TooltipSaved" = "Saved";
|
||||
|
||||
"StoryList.SaveToProfile" = "Save to Profile";
|
||||
"StoryList.TooltipStoriesSavedToProfile_1" = "Story saved to your profile";
|
||||
"StoryList.TooltipStoriesSavedToProfile_any" = "%d stories saved to your profile.";
|
||||
"StoryList.TooltipStoriesSavedToProfileText" = "Saved stories can be viewed by others on your profile until you remove them.";
|
||||
|
||||
"StoryList.TitleSaved" = "My Stories";
|
||||
"StoryList.TitleArchive" = "Stories Archive";
|
||||
"StoryList.SubtitleSelected_1" = "1 story selected";
|
||||
"StoryList.SubtitleSelected_any" = "%d stories selected";
|
||||
|
||||
"StoryList.SubtitleSaved_1" = "1 saved story";
|
||||
"StoryList.SubtitleSaved_any" = "%d saved stories";
|
||||
|
||||
"StoryList.SubtitleCount_1" = "1 story";
|
||||
"StoryList.SubtitleCount_any" = "%d stories";
|
||||
|
||||
"StoryList.ArchiveDescription" = "Only you can see archived stories unless you choose to save them to your profile.";
|
||||
|
||||
"StoryList.SavedEmptyState.Title" = "No saved stories";
|
||||
"StoryList.SavedEmptyState.Text" = "Open the Archive to select stories you\nwant to be displayed in your profile.";
|
||||
"StoryList.ArchivedEmptyState.Title" = "No Archived Stories";
|
||||
"StoryList.ArchivedEmptyState.Text" = "Upload a new story to view it here";
|
||||
"StoryList.SavedEmptyAction" = "Open Archive";
|
||||
|
||||
"ArchiveInfo.Title" = "This is Your Archive";
|
||||
|
||||
"ArchiveInfo.TextKeepArchivedUnmuted" = "Archived chats will remain in the Archive when you receive a new message. [Tap to change >]()";
|
||||
"ArchiveInfo.TextKeepArchivedDefault" = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change >]()";
|
||||
|
||||
"ArchiveInfo.ChatsTitle" = "Archived Chats";
|
||||
"ArchiveInfo.ChatsText" = "Move any chat into your Archive and back by swiping on it.";
|
||||
"ArchiveInfo.HideTitle" = "Hiding Archive";
|
||||
"ArchiveInfo.HideText" = "Hide the Archive from your Main screen by swiping on it.";
|
||||
"ArchiveInfo.StoriesTitle" = "Stories";
|
||||
"ArchiveInfo.StoriesText" = "Archive Stories from your contacts separately from chats with them.";
|
||||
"ArchiveInfo.CloseAction" = "Got it";
|
||||
|
||||
"Story.HeaderYourStory" = "Your story";
|
||||
"Story.HeaderEdited" = "edited";
|
||||
"Story.CaptionShowMore" = "Show more";
|
||||
|
||||
"Story.UnsupportedText" = "This story is not supported by\nyour version of Telegram.";
|
||||
"Story.UnsupportedAction" = "Update Telegram";
|
||||
|
||||
"Story.ScreenshotBlockedTitle" = "Screenshot Blocked";
|
||||
"Story.ScreenshotBlockedText" = "The story you tried to take a\nscreenshot of is protected from\ncopying by its creator.";
|
||||
|
||||
"Story.Footer.NoViews" = "No views";
|
||||
"Story.Footer.Views_1" = "1 view";
|
||||
"Story.Footer.Views_any" = "%d views";
|
||||
|
||||
"Story.Footer.Uploading" = "Uploading...";
|
||||
|
@ -2576,7 +2576,7 @@ public class ChatListControllerImpl: TelegramBaseController, ChatListController
|
||||
text = self.presentationData.strings.StoryFeed_TooltipPremiumPosting
|
||||
} else if reachedCountLimit {
|
||||
let valueText = self.presentationData.strings.StoryFeed_TooltipStoryLimitValue(Int32(storiesCountLimit))
|
||||
text = self.presentationData.strings.StoryFeed_TooltipStoryLimit
|
||||
text = self.presentationData.strings.StoryFeed_TooltipStoryLimit(valueText).string
|
||||
} else {
|
||||
text = ""
|
||||
}
|
||||
|
@ -303,7 +303,7 @@ public func chatListItemStrings(strings: PresentationStrings, nameDisplayOrder:
|
||||
messageText = strings.Conversation_StoryMentionTextOutgoing(peer.compactDisplayTitle).string
|
||||
}
|
||||
} else {
|
||||
messageText = strongs.Notification_Story
|
||||
messageText = strings.Notification_Story
|
||||
}
|
||||
default:
|
||||
break
|
||||
|
@ -68,7 +68,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: presentationData.strings.StoryFeed.TooltipNotifyOn(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil),
|
||||
], title: nil, text: presentationData.strings.StoryFeed_TooltipNotifyOn(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil),
|
||||
elevatedLayout: false,
|
||||
animateInAsReplacement: false,
|
||||
action: { _ in return false }
|
||||
@ -82,7 +82,7 @@ func contactContextMenuItems(context: AccountContext, peerId: EnginePeer.Id, con
|
||||
"Bottom.Group 1.Fill 1": iconColor,
|
||||
"EXAMPLE.Group 1.Fill 1": iconColor,
|
||||
"Line.Group 1.Stroke 1": iconColor
|
||||
], title: nil, text: presentationData.strings.StoryFeed.TooltipNotifyOff(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)), customUndoText: nil, timeout: nil),
|
||||
], title: nil, text: presentationData.strings.StoryFeed_TooltipNotifyOff(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string, customUndoText: nil, timeout: nil),
|
||||
elevatedLayout: false,
|
||||
animateInAsReplacement: false,
|
||||
action: { _ in return false }
|
||||
|
@ -391,7 +391,6 @@ private func contactListNodeEntries(accountPeer: EnginePeer?, peers: [ContactLis
|
||||
}
|
||||
|
||||
if addHeader {
|
||||
//TODO:localize
|
||||
commonHeader = ChatListSearchItemHeader(type: .text(strings.Contacts_SortedByPresence.uppercased(), AnyHashable(1)), theme: theme, strings: strings, actionTitle: nil, action: nil)
|
||||
}
|
||||
|
||||
|
@ -1265,6 +1265,7 @@ public final class PeerInfoAvatarListContainerNode: ASDisplayNode {
|
||||
transition: indicatorTransition,
|
||||
component: AnyComponent(StorySetIndicatorComponent(
|
||||
context: self.context,
|
||||
strings: self.context.sharedContext.currentPresentationData.with({ $0 }).strings,
|
||||
peer: storyParams.peer,
|
||||
items: storyParams.items,
|
||||
hasUnseen: storyParams.hasUnseen,
|
||||
|
@ -85,34 +85,33 @@ private enum ArchiveSettingsControllerEntry: ItemListNodeEntry {
|
||||
|
||||
func item(presentationData: ItemListPresentationData, arguments: Any) -> ListViewItem {
|
||||
let arguments = arguments as! ArchiveSettingsControllerArguments
|
||||
//TODO:localize
|
||||
switch self {
|
||||
case .unmutedHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "UNMUTED CHATS", sectionId: self.section)
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnmutedChatsHeader, sectionId: self.section)
|
||||
case let .unmutedValue(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateUnmuted(value)
|
||||
})
|
||||
case .unmutedFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown("Keep archived chats in the Archive even if they are unmuted and get a new message."), sectionId: self.section)
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnmutedChatsFooter), sectionId: self.section)
|
||||
case .foldersHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "CHATS FROM FOLDERS", sectionId: self.section)
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_FolderChatsHeader, sectionId: self.section)
|
||||
case let .foldersValue(value):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: value, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateFolders(value)
|
||||
})
|
||||
case .foldersFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown("Keep archived chats from folders in the Archive even if they are unmuted and get a new message."), sectionId: self.section)
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_FolderChatsFooter), sectionId: self.section)
|
||||
case .unknownHeader:
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: "NEW CHATS FROM UNKNOWN USERS", sectionId: self.section)
|
||||
return ItemListSectionHeaderItem(presentationData: presentationData, text: presentationData.strings.ArchiveSettings_UnknownChatsHeader, sectionId: self.section)
|
||||
case let .unknownValue(isOn, isLocked):
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: "Always Keep Archived", value: isOn, enableInteractiveChanges: !isLocked, enabled: true, displayLocked: isLocked, sectionId: self.section, style: .blocks, updated: { value in
|
||||
return ItemListSwitchItem(presentationData: presentationData, title: presentationData.strings.ArchiveSettings_KeepArchived, value: isOn, enableInteractiveChanges: !isLocked, enabled: true, displayLocked: isLocked, sectionId: self.section, style: .blocks, updated: { value in
|
||||
arguments.updateUnknown(value)
|
||||
}, activatedWhileDisabled: {
|
||||
arguments.updateUnknown(nil)
|
||||
})
|
||||
case .unknownFooter:
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown("Automatically archive and mute new private chats, groups and channels from non-contacts."), sectionId: self.section)
|
||||
return ItemListTextItem(presentationData: presentationData, text: .markdown(presentationData.strings.ArchiveSettings_UnknownChatsFooter), sectionId: self.section)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,7 +162,8 @@ public func archiveSettingsController(context: AccountContext) -> ViewController
|
||||
if let value {
|
||||
let _ = context.engine.privacy.updateAccountAutoArchiveChats(value: value).start()
|
||||
} else {
|
||||
presentUndoImpl?(.premiumPaywall(title: nil, text: "This setting is available only to the subscribers of [Telegram Premium]().", customUndoText: nil, timeout: nil, linkAction: { _ in
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
presentUndoImpl?(.premiumPaywall(title: nil, text: presentationData.strings.ArchiveSettings_TooltipPremiumRequired, customUndoText: nil, timeout: nil, linkAction: { _ in
|
||||
presentPremiumImpl?()
|
||||
}))
|
||||
}
|
||||
@ -181,8 +181,7 @@ public func archiveSettingsController(context: AccountContext) -> ViewController
|
||||
let isPremium = accountPeer?.isPremium ?? false
|
||||
let isPremiumDisabled = PremiumConfiguration.with(appConfiguration: appConfiguration).isPremiumDisabled
|
||||
|
||||
//TODO:localize
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text("Archive Settings"), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(presentationData.strings.ArchiveSettings_Title), leftNavigationButton: nil, rightNavigationButton: nil, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back))
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: archiveSettingsControllerEntries(
|
||||
presentationData: presentationData,
|
||||
settings: settings,
|
||||
|
@ -345,17 +345,16 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
|
||||
importantEnabled = true
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
entries.append(.enable(presentationData.theme, "Show All Notifications", allEnabled))
|
||||
entries.append(.enable(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowAll, allEnabled))
|
||||
if !allEnabled {
|
||||
entries.append(.enableImportant(presentationData.theme, "Show Important Notifications", importantEnabled))
|
||||
entries.append(.importantInfo(presentationData.theme, "Always on for top 5 contacts."))
|
||||
entries.append(.enableImportant(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowImportant, importantEnabled))
|
||||
entries.append(.importantInfo(presentationData.theme, presentationData.strings.NotificationSettings_Stories_ShowImportantFooter))
|
||||
}
|
||||
|
||||
if notificationSettings.enabled || !notificationExceptions.isEmpty {
|
||||
entries.append(.optionsHeader(presentationData.theme, presentationData.strings.Notifications_Options.uppercased()))
|
||||
|
||||
entries.append(.previews(presentationData.theme, "Display Author Name", notificationSettings.storySettings.hideSender != .hide))
|
||||
entries.append(.previews(presentationData.theme, presentationData.strings.NotificationSettings_Stories_DisplayAuthorName, notificationSettings.storySettings.hideSender != .hide))
|
||||
entries.append(.sound(presentationData.theme, presentationData.strings.Notifications_MessageNotificationsSound, localizedPeerNotificationSoundString(strings: presentationData.strings, notificationSoundList: notificationSoundList, sound: filteredGlobalSound(notificationSettings.storySettings.sound)), filteredGlobalSound(notificationSettings.storySettings.sound)))
|
||||
}
|
||||
} else {
|
||||
@ -413,8 +412,7 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
|
||||
var title: String = ""
|
||||
|
||||
if automaticSet.contains(value.peer.id) {
|
||||
//TODO:localize
|
||||
title = "\(presentationData.strings.Notification_Exceptions_AlwaysOn) (automatic)"
|
||||
title = presentationData.strings.NotificationSettings_Stories_AutomaticValue(presentationData.strings.Notification_Exceptions_AlwaysOn).string
|
||||
canRemove = false
|
||||
} else {
|
||||
if case .stories = category {
|
||||
@ -443,11 +441,10 @@ private func notificationsPeerCategoryEntries(category: NotificationsPeerCategor
|
||||
if !title.isEmpty {
|
||||
title += ", "
|
||||
}
|
||||
//TODO:localize
|
||||
if case .show = value.settings.storySettings.hideSender {
|
||||
title += "Show Name"
|
||||
title += presentationData.strings.NotificationSettings_Stories_CompactShowName
|
||||
} else {
|
||||
title += "Hide Name"
|
||||
title += presentationData.strings.NotificationSettings_Stories_CompactHideName
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1068,8 +1065,7 @@ public func notificationsPeerCategoryController(context: AccountContext, categor
|
||||
case .channel:
|
||||
title = presentationData.strings.Notifications_ChannelsTitle
|
||||
case .stories:
|
||||
//TODO:localize
|
||||
title = "Stories"
|
||||
title = presentationData.strings.Notifications_StoriesTitle
|
||||
}
|
||||
let controllerState = ItemListControllerState(presentationData: ItemListPresentationData(presentationData), title: .text(title), leftNavigationButton: leftNavigationButton, rightNavigationButton: rightNavigationButton, backNavigationButton: ItemListBackButton(title: presentationData.strings.Common_Back), animateChanges: true)
|
||||
let listState = ItemListNodeState(presentationData: ItemListPresentationData(presentationData), entries: entries, style: .blocks, ensureVisibleItemTag: focusOnItemTag, initialScrollToItem: scrollToItem)
|
||||
|
@ -396,8 +396,7 @@ public func stringForMediaKind(_ kind: MessageContentKind, strings: Presentation
|
||||
case let .invoice(text):
|
||||
return (NSAttributedString(string: text), true)
|
||||
case .story:
|
||||
//TODO:localize
|
||||
return (NSAttributedString(string: "Story"), true)
|
||||
return (NSAttributedString(string: strings.Message_Story), true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,7 +283,6 @@ public final class ChatListNavigationBar: Component {
|
||||
placeholder = component.strings.Common_Search
|
||||
compactPlaceholder = component.strings.Common_Search
|
||||
|
||||
//TODO:localize
|
||||
searchContentNode = NavigationBarSearchContentNode(
|
||||
theme: component.theme,
|
||||
placeholder: placeholder,
|
||||
|
@ -726,8 +726,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
|
||||
|
||||
if isStories == nil || isStories == true {
|
||||
if case .user = peer {
|
||||
//TODO:localize
|
||||
entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: "STORY NOTIFICATIONS"))
|
||||
entries.append(.storyNotificationsHeader(index: index, theme: presentationData.theme, title: presentationData.strings.Notification_Exceptions_StoriesHeader))
|
||||
index += 1
|
||||
entries.append(.storyNotifications(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesMuted == .alwaysOn))
|
||||
index += 1
|
||||
@ -735,7 +734,7 @@ private func notificationPeerExceptionEntries(presentationData: PresentationData
|
||||
index += 1
|
||||
|
||||
if state.storiesMuted != .alwaysOff {
|
||||
entries.append(.displayPreviewsHeader(index: index, theme: presentationData.theme, title: "DISPLAY AUTHOR NAME"))
|
||||
entries.append(.displayPreviewsHeader(index: index, theme: presentationData.theme, title: presentationData.strings.Notification_Exceptions_StoriesDisplayAuthorName))
|
||||
index += 1
|
||||
entries.append(.showSender(index: index, theme: presentationData.theme, strings: presentationData.strings, value: .alwaysOn, selected: state.storiesHideSender == .alwaysOn))
|
||||
index += 1
|
||||
|
@ -88,9 +88,7 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
let strings = presentationData.strings
|
||||
|
||||
if self.selectedCount != 0 {
|
||||
//TODO:localize
|
||||
//TODO:update icon
|
||||
items.append(.action(ContextMenuActionItem(text: "Save to Photos", icon: { theme in
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.StoryList_ContextSaveToGallery, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
a(.default)
|
||||
@ -113,16 +111,10 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
let _ = component.context.engine.messages.deleteStories(ids: Array(paneNode.selectedIds)).start()
|
||||
|
||||
//TODO:localize
|
||||
let text: String
|
||||
if paneNode.selectedIds.count == 1 {
|
||||
text = "1 story deleted."
|
||||
} else {
|
||||
text = "\(paneNode.selectedIds.count) stories deleted."
|
||||
}
|
||||
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: environment.theme)
|
||||
let text: String = presentationData.strings.StoryList_TooltipStoriesDeleted(Int32(paneNode.selectedIds.count))
|
||||
|
||||
environment.controller()?.present(UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .info(title: nil, text: text, timeout: nil),
|
||||
@ -163,8 +155,7 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
|
||||
if component.peerId == component.context.account.peerId, case .saved = component.scope {
|
||||
var ignoreNextActions = false
|
||||
//TODO:localize
|
||||
items.append(.action(ContextMenuActionItem(text: "Show Archive", icon: { theme in
|
||||
items.append(.action(ContextMenuActionItem(text: presentationData.strings.StoryList_ContextShowArchive, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/StoryArchive"), color: theme.contextMenu.primaryColor)
|
||||
}, action: { [weak self] _, a in
|
||||
if ignoreNextActions {
|
||||
@ -305,8 +296,8 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
return
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let saveScreen = SaveProgressScreen(context: component.context, content: .progress("Saving", 0.0))
|
||||
let strings = (component.context.sharedContext.currentPresentationData.with { $0 }).strings
|
||||
let saveScreen = SaveProgressScreen(context: component.context, content: .progress(strings.Story_TooltipSaving, 0.0))
|
||||
self.environment?.controller()?.present(saveScreen, in: .current)
|
||||
|
||||
let valueNorm: Float = 1.0 / Float(sortedItems.count)
|
||||
@ -330,12 +321,12 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
guard let saveScreen else {
|
||||
return
|
||||
}
|
||||
saveScreen.content = .progress("Saving", progress)
|
||||
saveScreen.content = .progress(strings.Story_TooltipSaving, progress)
|
||||
}, completed: { [weak saveScreen] in
|
||||
guard let saveScreen else {
|
||||
return
|
||||
}
|
||||
saveScreen.content = .completion("Saved")
|
||||
saveScreen.content = .completion(strings.Story_TooltipSaved)
|
||||
Queue.mainQueue().after(3.0, { [weak saveScreen] in
|
||||
saveScreen?.dismiss()
|
||||
})
|
||||
@ -376,12 +367,11 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
self.selectionPanel = selectionPanel
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let selectionPanelSize = selectionPanel.update(
|
||||
transition: selectionPanelTransition,
|
||||
component: AnyComponent(BottomButtonPanelComponent(
|
||||
theme: environment.theme,
|
||||
title: "Save to Profile",
|
||||
title: environment.strings.StoryList_SaveToProfile,
|
||||
label: nil,
|
||||
isEnabled: true,
|
||||
insets: UIEdgeInsets(top: 0.0, left: sideInset, bottom: environment.safeInsets.bottom, right: sideInset),
|
||||
@ -395,18 +385,12 @@ final class PeerInfoStoryGridScreenComponent: Component {
|
||||
|
||||
let _ = component.context.engine.messages.updateStoriesArePinned(ids: paneNode.selectedItems, isPinned: true).start()
|
||||
|
||||
//TODO:localize
|
||||
let title: String
|
||||
if paneNode.selectedIds.count == 1 {
|
||||
title = "Story saved to your profile"
|
||||
} else {
|
||||
title = "\(paneNode.selectedIds.count) saved to your profile"
|
||||
}
|
||||
|
||||
let presentationData = component.context.sharedContext.currentPresentationData.with({ $0 }).withUpdated(theme: environment.theme)
|
||||
|
||||
let title: String = presentationData.strings.StoryList_TooltipStoriesSavedToProfile(Int32(paneNode.selectedIds.count))
|
||||
environment.controller()?.present(UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
content: .info(title: title, text: "Saved stories can be viewed by others on your profile until you remove them.", timeout: nil),
|
||||
content: .info(title: title, text: presentationData.strings.StoryList_TooltipStoriesSavedToProfileText, timeout: nil),
|
||||
elevatedLayout: false,
|
||||
animateInAsReplacement: false,
|
||||
action: { _ in return false }
|
||||
@ -596,7 +580,8 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer {
|
||||
}
|
||||
|
||||
func updateTitle() {
|
||||
//TODO:localize
|
||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||
|
||||
switch self.scope {
|
||||
case .saved:
|
||||
guard let componentView = self.node.hostView.componentView as? PeerInfoStoryGridScreenComponent.View else {
|
||||
@ -608,16 +593,16 @@ public class PeerInfoStoryGridScreen: ViewControllerComponentContainer {
|
||||
} else {
|
||||
title = nil
|
||||
}
|
||||
self.titleView?.titleContent = .custom("My Stories", title, false)
|
||||
self.titleView?.titleContent = .custom(presentationData.strings.StoryList_TitleSaved, title, false)
|
||||
case .archive:
|
||||
guard let componentView = self.node.hostView.componentView as? PeerInfoStoryGridScreenComponent.View else {
|
||||
return
|
||||
}
|
||||
let title: String
|
||||
if componentView.selectedCount != 0 {
|
||||
title = "\(componentView.selectedCount) Selected"
|
||||
title = presentationData.strings.StoryList_SubtitleSelected(Int32(componentView.selectedCount))
|
||||
} else {
|
||||
title = "Stories Archive"
|
||||
title = presentationData.strings.StoryList_TitleArchive
|
||||
}
|
||||
self.titleView?.titleContent = .custom(title, nil, false)
|
||||
}
|
||||
|
@ -1560,17 +1560,11 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
let title: String
|
||||
if state.totalCount == 0 {
|
||||
title = ""
|
||||
} else if state.totalCount == 1 {
|
||||
if self.isSaved {
|
||||
title = "1 saved story"
|
||||
} else {
|
||||
title = "1 story"
|
||||
}
|
||||
} else {
|
||||
if self.isSaved {
|
||||
title = "\(state.totalCount) saved stories"
|
||||
title = self.presentationData.strings.StoryList_SubtitleSaved(Int32(state.totalCount))
|
||||
} else {
|
||||
title = "\(state.totalCount) stories"
|
||||
title = self.presentationData.strings.StoryList_SubtitleCount(Int32(state.totalCount))
|
||||
}
|
||||
}
|
||||
self.statusPromise.set(.single(PeerInfoStatusData(text: title, isActivity: false, key: .stories)))
|
||||
@ -1607,8 +1601,7 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
|
||||
var headerText: String?
|
||||
if strongSelf.isArchive && !mappedItems.isEmpty {
|
||||
//TODO:localize
|
||||
headerText = "Only you can see archived stories unless you choose to save them to your profile."
|
||||
headerText = strongSelf.presentationData.strings.StoryList_ArchiveDescription
|
||||
}
|
||||
|
||||
let items = SparseItemGrid.Items(
|
||||
@ -1914,16 +1907,15 @@ public final class PeerInfoStoryPaneNode: ASDisplayNode, PeerInfoPaneNode, UIScr
|
||||
emptyStateView = ComponentView()
|
||||
self.emptyStateView = emptyStateView
|
||||
}
|
||||
//TODO:localize
|
||||
let emptyStateSize = emptyStateView.update(
|
||||
transition: emptyStateTransition,
|
||||
component: AnyComponent(EmptyStateIndicatorComponent(
|
||||
context: self.context,
|
||||
theme: presentationData.theme,
|
||||
animationName: "StoryListEmpty",
|
||||
title: self.isArchive ? "No Archived Stories" : "No saved stories",
|
||||
text: self.isArchive ? "Upload a new story to view it here" : "Open the Archive to select stories you\nwant to be displayed in your profile.",
|
||||
actionTitle: self.isArchive ? nil : "Open Archive",
|
||||
title: self.isArchive ? presentationData.strings.StoryList_ArchivedEmptyState_Title : presentationData.strings.StoryList_SavedEmptyState_Title,
|
||||
text: self.isArchive ? presentationData.strings.StoryList_ArchivedEmptyState_Text : presentationData.strings.StoryList_SavedEmptyState_Text,
|
||||
actionTitle: self.isArchive ? nil : presentationData.strings.StoryList_SavedEmptyAction,
|
||||
action: { [weak self] in
|
||||
guard let self else {
|
||||
return
|
||||
|
@ -128,12 +128,11 @@ public final class ArchiveInfoContentComponent: Component {
|
||||
contentHeight += 15.0
|
||||
|
||||
let titleString = NSMutableAttributedString()
|
||||
titleString.append(NSAttributedString(string: "This is Your Archive", font: Font.semibold(19.0), textColor: component.theme.list.itemPrimaryTextColor))
|
||||
titleString.append(NSAttributedString(string: component.strings.ArchiveInfo_Title, font: Font.semibold(19.0), textColor: component.theme.list.itemPrimaryTextColor))
|
||||
let imageAttachment = NSTextAttachment()
|
||||
imageAttachment.image = self.iconBackground.image
|
||||
titleString.append(NSAttributedString(attachment: imageAttachment))
|
||||
|
||||
//TODO:localize
|
||||
let titleSize = self.title.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
@ -153,11 +152,10 @@ public final class ArchiveInfoContentComponent: Component {
|
||||
contentHeight += 16.0
|
||||
|
||||
let text: String
|
||||
//TODO:localize
|
||||
if component.settings.keepArchivedUnmuted {
|
||||
text = "Archived chats will remain in the Archive when you receive a new message. [Tap to change >]()"
|
||||
text = component.strings.ArchiveInfo_TextKeepArchivedUnmuted
|
||||
} else {
|
||||
text = "When you receive a new message, muted chats will remain in the Archive, while unmuted chats will be moved to Chats. [Tap to change >]()"
|
||||
text = component.strings.ArchiveInfo_TextKeepArchivedDefault
|
||||
}
|
||||
|
||||
let mainText = NSMutableAttributedString()
|
||||
@ -229,18 +227,18 @@ public final class ArchiveInfoContentComponent: Component {
|
||||
let itemDescs: [ItemDesc] = [
|
||||
ItemDesc(
|
||||
icon: "Chat List/Archive/IconArchived",
|
||||
title: "Archived Chats",
|
||||
text: "Move any chat into your Archive and back by swiping on it."
|
||||
title: component.strings.ArchiveInfo_ChatsTitle,
|
||||
text: component.strings.ArchiveInfo_ChatsText
|
||||
),
|
||||
ItemDesc(
|
||||
icon: "Chat List/Archive/IconHide",
|
||||
title: "Hiding Archive",
|
||||
text: "Hide the Archive from your Main screen by swiping on it."
|
||||
title: component.strings.ArchiveInfo_HideTitle,
|
||||
text: component.strings.ArchiveInfo_HideText
|
||||
),
|
||||
ItemDesc(
|
||||
icon: "Chat List/Archive/IconStories",
|
||||
title: "Stories",
|
||||
text: "Archive Stories from your contacts separately from chats with them."
|
||||
title: component.strings.ArchiveInfo_StoriesTitle,
|
||||
text: component.strings.ArchiveInfo_StoriesText
|
||||
)
|
||||
]
|
||||
for i in 0 ..< itemDescs.count {
|
||||
|
@ -76,7 +76,6 @@ private final class ArchiveInfoSheetContentComponent: Component {
|
||||
contentHeight += contentSize.height
|
||||
contentHeight += 30.0
|
||||
|
||||
//TODO:localize
|
||||
let buttonSize = self.button.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(ButtonComponent(
|
||||
@ -86,7 +85,7 @@ private final class ArchiveInfoSheetContentComponent: Component {
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.8)
|
||||
),
|
||||
content: AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
|
||||
Text(text: "Got it", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||
Text(text: environment.strings.ArchiveInfo_CloseAction, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||
)),
|
||||
isEnabled: true,
|
||||
displaysProgress: false,
|
||||
|
@ -310,8 +310,7 @@ final class StorageUsageScreenComponent: Component {
|
||||
case .misc:
|
||||
return strings.StorageManagement_SectionMiscellaneous
|
||||
case .stories:
|
||||
//TODO:localize
|
||||
return "Stories"
|
||||
return strings.StorageManagement_SectionStories
|
||||
}
|
||||
}
|
||||
|
||||
@ -1810,8 +1809,7 @@ final class StorageUsageScreenComponent: Component {
|
||||
mappedCategory = .groups
|
||||
case 3:
|
||||
iconName = "Settings/Menu/Stories"
|
||||
//TODO:localized
|
||||
title = "Stories"
|
||||
title = environment.strings.Notifications_Stories
|
||||
mappedCategory = .stories
|
||||
default:
|
||||
iconName = "Settings/Menu/Channels"
|
||||
|
@ -6,6 +6,7 @@ import AccountContext
|
||||
import TelegramCore
|
||||
import TelegramStringFormatting
|
||||
import MultilineTextComponent
|
||||
import TelegramPresentationData
|
||||
|
||||
final class StoryAuthorInfoComponent: Component {
|
||||
struct Counters: Equatable {
|
||||
@ -14,13 +15,15 @@ final class StoryAuthorInfoComponent: Component {
|
||||
}
|
||||
|
||||
let context: AccountContext
|
||||
let strings: PresentationStrings
|
||||
let peer: EnginePeer?
|
||||
let timestamp: Int32
|
||||
let counters: Counters?
|
||||
let isEdited: Bool
|
||||
|
||||
init(context: AccountContext, peer: EnginePeer?, timestamp: Int32, counters: Counters?, isEdited: Bool) {
|
||||
init(context: AccountContext, strings: PresentationStrings, peer: EnginePeer?, timestamp: Int32, counters: Counters?, isEdited: Bool) {
|
||||
self.context = context
|
||||
self.strings = strings
|
||||
self.peer = peer
|
||||
self.timestamp = timestamp
|
||||
self.counters = counters
|
||||
@ -31,6 +34,9 @@ final class StoryAuthorInfoComponent: Component {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.peer != rhs.peer {
|
||||
return false
|
||||
}
|
||||
@ -75,8 +81,7 @@ final class StoryAuthorInfoComponent: Component {
|
||||
|
||||
let title: String
|
||||
if component.peer?.id == component.context.account.peerId {
|
||||
//TODO:localize
|
||||
title = "Your story"
|
||||
title = component.strings.Story_HeaderYourStory
|
||||
} else {
|
||||
title = component.peer?.debugDisplayTitle ?? ""
|
||||
}
|
||||
@ -86,7 +91,7 @@ final class StoryAuthorInfoComponent: Component {
|
||||
|
||||
if component.isEdited {
|
||||
subtitle.append(" • ")
|
||||
subtitle.append("edited")
|
||||
subtitle.append(component.strings.Story_HeaderEdited)
|
||||
}
|
||||
|
||||
let titleSize = self.title.update(
|
||||
|
@ -9,6 +9,7 @@ import TextNodeWithEntities
|
||||
import TextFormat
|
||||
import InvisibleInkDustNode
|
||||
import UrlEscaping
|
||||
import TelegramPresentationData
|
||||
|
||||
final class StoryContentCaptionComponent: Component {
|
||||
enum Action {
|
||||
@ -41,6 +42,7 @@ final class StoryContentCaptionComponent: Component {
|
||||
|
||||
let externalState: ExternalState
|
||||
let context: AccountContext
|
||||
let strings: PresentationStrings
|
||||
let text: String
|
||||
let entities: [MessageTextEntity]
|
||||
let entityFiles: [EngineMedia.Id: TelegramMediaFile]
|
||||
@ -50,6 +52,7 @@ final class StoryContentCaptionComponent: Component {
|
||||
init(
|
||||
externalState: ExternalState,
|
||||
context: AccountContext,
|
||||
strings: PresentationStrings,
|
||||
text: String,
|
||||
entities: [MessageTextEntity],
|
||||
entityFiles: [EngineMedia.Id: TelegramMediaFile],
|
||||
@ -58,6 +61,7 @@ final class StoryContentCaptionComponent: Component {
|
||||
) {
|
||||
self.externalState = externalState
|
||||
self.context = context
|
||||
self.strings = strings
|
||||
self.text = text
|
||||
self.entities = entities
|
||||
self.entityFiles = entityFiles
|
||||
@ -72,6 +76,9 @@ final class StoryContentCaptionComponent: Component {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.text != rhs.text {
|
||||
return false
|
||||
}
|
||||
@ -425,9 +432,8 @@ final class StoryContentCaptionComponent: Component {
|
||||
|
||||
let truncationToken = NSMutableAttributedString()
|
||||
truncationToken.append(NSAttributedString(string: "\u{2026} ", font: Font.regular(16.0), textColor: .white))
|
||||
truncationToken.append(NSAttributedString(string: "Show more", font: Font.semibold(16.0), textColor: .white))
|
||||
truncationToken.append(NSAttributedString(string: component.strings.Story_CaptionShowMore, font: Font.semibold(16.0), textColor: .white))
|
||||
|
||||
//TODO:localize
|
||||
let collapsedTextLayout = TextNodeWithEntities.asyncLayout(self.collapsedText.textNode)(TextNodeLayoutArguments(
|
||||
attributedString: attributedText,
|
||||
maximumNumberOfLines: 3,
|
||||
|
@ -592,11 +592,10 @@ final class StoryItemContentComponent: Component {
|
||||
self.unsupportedButton = unsupportedButton
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let unsupportedTextSize = unsupportedText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "This story is not supported by\nyour version of Telegram.", font: Font.regular(17.0), textColor: .white)),
|
||||
text: .plain(NSAttributedString(string: component.strings.Story_UnsupportedText, font: Font.regular(17.0), textColor: .white)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
@ -611,7 +610,7 @@ final class StoryItemContentComponent: Component {
|
||||
foreground: environment.theme.list.itemCheckColors.foregroundColor,
|
||||
pressedColor: environment.theme.list.itemCheckColors.fillColor.withMultipliedAlpha(0.7)
|
||||
),
|
||||
content: AnyComponentWithIdentity(id: AnyHashable(""), component: AnyComponent(Text(text: "Update Telegram", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor
|
||||
content: AnyComponentWithIdentity(id: AnyHashable(""), component: AnyComponent(Text(text: component.strings.Story_UnsupportedAction, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor
|
||||
))),
|
||||
isEnabled: true,
|
||||
displaysProgress: false,
|
||||
@ -655,7 +654,10 @@ final class StoryItemContentComponent: Component {
|
||||
self.updateProgressMode(update: false)
|
||||
|
||||
if reloadMedia && synchronousLoad {
|
||||
let _ = startTime
|
||||
#if DEBUG
|
||||
print("\(CFAbsoluteTimeGetCurrent()) Synchronous: \((CFAbsoluteTimeGetCurrent() - startTime) * 1000.0) ms")
|
||||
#endif
|
||||
}
|
||||
|
||||
if !self.contentLoaded {
|
||||
|
@ -34,11 +34,6 @@ final class StoryItemImageView: UIView {
|
||||
super.init(frame: frame)
|
||||
|
||||
self.addSubview(self.contentView)
|
||||
#if DEBUG
|
||||
if "".isEmpty {
|
||||
self.contentView.isHidden = true
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
@ -292,11 +287,10 @@ final class CaptureProtectedInfoComponent: Component {
|
||||
environment: {},
|
||||
containerSize: availableSize
|
||||
)
|
||||
//TODO:localize
|
||||
let titleSize = self.title.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "Screenshot Blocked", font: Font.semibold(20.0), textColor: .white)),
|
||||
text: .plain(NSAttributedString(string: component.strings.Story_ScreenshotBlockedTitle, font: Font.semibold(20.0), textColor: .white)),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
@ -306,7 +300,7 @@ final class CaptureProtectedInfoComponent: Component {
|
||||
let textSize = self.text.update(
|
||||
transition: transition,
|
||||
component: AnyComponent(MultilineTextComponent(
|
||||
text: .plain(NSAttributedString(string: "The story you tried to take a\nscreenshot of is protected from\ncopying by its creator.", font: Font.regular(17.0), textColor: UIColor(white: 1.0, alpha: 0.6))),
|
||||
text: .plain(NSAttributedString(string: component.strings.Story_ScreenshotBlockedText, font: Font.regular(17.0), textColor: UIColor(white: 1.0, alpha: 0.6))),
|
||||
horizontalAlignment: .center,
|
||||
maximumNumberOfLines: 0
|
||||
)),
|
||||
|
@ -2541,6 +2541,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
|
||||
let centerInfoComponent = AnyComponent(StoryAuthorInfoComponent(
|
||||
context: component.context,
|
||||
strings: component.strings,
|
||||
peer: component.slice.peer,
|
||||
timestamp: component.slice.item.storyItem.timestamp,
|
||||
counters: counters,
|
||||
@ -2679,6 +2680,7 @@ public final class StoryItemSetContainerComponent: Component {
|
||||
component: AnyComponent(StoryContentCaptionComponent(
|
||||
externalState: captionItem.externalState,
|
||||
context: component.context,
|
||||
strings: component.strings,
|
||||
text: component.slice.item.storyItem.text,
|
||||
entities: component.slice.item.storyItem.entities,
|
||||
entityFiles: component.slice.item.entityFiles,
|
||||
|
@ -685,6 +685,7 @@ final class StoryItemSetViewListComponent: Component {
|
||||
transition: transition,
|
||||
component: AnyComponent(StoryFooterPanelComponent(
|
||||
context: component.context,
|
||||
strings: component.strings,
|
||||
storyItem: component.storyItem,
|
||||
externalViews: externalViews,
|
||||
expandFraction: dismissFraction,
|
||||
|
@ -10,9 +10,11 @@ import TelegramCore
|
||||
import MoreHeaderButton
|
||||
import SemanticStatusNode
|
||||
import SwiftSignalKit
|
||||
import TelegramPresentationData
|
||||
|
||||
public final class StoryFooterPanelComponent: Component {
|
||||
public let context: AccountContext
|
||||
public let strings: PresentationStrings
|
||||
public let storyItem: EngineStoryItem?
|
||||
public let externalViews: EngineStoryItem.Views?
|
||||
public let expandFraction: CGFloat
|
||||
@ -22,6 +24,7 @@ public final class StoryFooterPanelComponent: Component {
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
strings: PresentationStrings,
|
||||
storyItem: EngineStoryItem?,
|
||||
externalViews: EngineStoryItem.Views?,
|
||||
expandFraction: CGFloat,
|
||||
@ -30,6 +33,7 @@ public final class StoryFooterPanelComponent: Component {
|
||||
moreAction: @escaping (UIView, ContextGesture?) -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.strings = strings
|
||||
self.storyItem = storyItem
|
||||
self.externalViews = externalViews
|
||||
self.expandViewStats = expandViewStats
|
||||
@ -42,6 +46,9 @@ public final class StoryFooterPanelComponent: Component {
|
||||
if lhs.context !== rhs.context {
|
||||
return false
|
||||
}
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.storyItem != rhs.storyItem {
|
||||
return false
|
||||
}
|
||||
@ -200,10 +207,9 @@ public final class StoryFooterPanelComponent: Component {
|
||||
|
||||
statusNode.transitionToState(.progress(value: CGFloat(max(0.08, self.uploadProgress)), cancelEnabled: true, appearance: SemanticStatusNodeState.ProgressAppearance(inset: 0.0, lineWidth: 2.0)))
|
||||
|
||||
//TODO:localize
|
||||
let uploadingTextSize = uploadingText.update(
|
||||
transition: .immediate,
|
||||
component: AnyComponent(Text(text: "Uploading...", font: Font.regular(15.0), color: .white)),
|
||||
component: AnyComponent(Text(text: component.strings.Story_Footer_Uploading, font: Font.regular(15.0), color: .white)),
|
||||
environment: {},
|
||||
containerSize: CGSize(width: 200.0, height: 100.0)
|
||||
)
|
||||
@ -260,11 +266,9 @@ public final class StoryFooterPanelComponent: Component {
|
||||
|
||||
let viewsText: String
|
||||
if viewCount == 0 {
|
||||
viewsText = "No Views"
|
||||
} else if viewCount == 1 {
|
||||
viewsText = "1 view"
|
||||
viewsText = component.strings.Story_Footer_NoViews
|
||||
} else {
|
||||
viewsText = "\(viewCount) views"
|
||||
viewsText = component.strings.Story_Footer_Views(Int32(viewCount))
|
||||
}
|
||||
|
||||
self.viewStatsButton.isEnabled = viewCount != 0
|
||||
|
@ -778,13 +778,12 @@ public final class StoryPeerListItemComponent: Component {
|
||||
Transition.immediate.setShapeLayerPath(layer: self.indicatorShapeSeenLayer, path: calculateMergingCircleShape(center: indicatorCenter, leftCenter: mappedLeftCenter, rightCenter: mappedRightCenter, radius: indicatorRadius - indicatorLineUnseenWidth * 0.5, totalCount: component.totalCount, unseenCount: component.unseenCount, isSeen: true, segmentFraction: component.expandedAlphaFraction))
|
||||
Transition.immediate.setShapeLayerPath(layer: self.indicatorShapeUnseenLayer, path: calculateMergingCircleShape(center: indicatorCenter, leftCenter: mappedLeftCenter, rightCenter: mappedRightCenter, radius: indicatorRadius - indicatorLineUnseenWidth * 0.5, totalCount: component.totalCount, unseenCount: component.unseenCount, isSeen: false, segmentFraction: component.expandedAlphaFraction))
|
||||
|
||||
//TODO:localize
|
||||
let titleString: String
|
||||
if component.peer.id == component.context.account.peerId {
|
||||
if let ringAnimation = component.ringAnimation, case .progress = ringAnimation {
|
||||
titleString = "Uploading..."
|
||||
titleString = component.strings.StoryFeed_MyUploading
|
||||
} else {
|
||||
titleString = "My story"
|
||||
titleString = component.strings.StoryFeed_MyStory
|
||||
}
|
||||
} else {
|
||||
titleString = component.peer.compactDisplayTitle.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
|
@ -89,6 +89,7 @@ private final class ShapeImageView: UIView {
|
||||
|
||||
public final class StorySetIndicatorComponent: Component {
|
||||
public let context: AccountContext
|
||||
public let strings: PresentationStrings
|
||||
public let peer: EnginePeer
|
||||
public let items: [EngineStoryItem]
|
||||
public let hasUnseen: Bool
|
||||
@ -99,6 +100,7 @@ public final class StorySetIndicatorComponent: Component {
|
||||
|
||||
public init(
|
||||
context: AccountContext,
|
||||
strings: PresentationStrings,
|
||||
peer: EnginePeer,
|
||||
items: [EngineStoryItem],
|
||||
hasUnseen: Bool,
|
||||
@ -108,6 +110,7 @@ public final class StorySetIndicatorComponent: Component {
|
||||
action: @escaping () -> Void
|
||||
) {
|
||||
self.context = context
|
||||
self.strings = strings
|
||||
self.peer = peer
|
||||
self.items = items
|
||||
self.hasUnseen = hasUnseen
|
||||
@ -118,6 +121,9 @@ public final class StorySetIndicatorComponent: Component {
|
||||
}
|
||||
|
||||
public static func ==(lhs: StorySetIndicatorComponent, rhs: StorySetIndicatorComponent) -> Bool {
|
||||
if lhs.strings !== rhs.strings {
|
||||
return false
|
||||
}
|
||||
if lhs.items != rhs.items {
|
||||
return false
|
||||
}
|
||||
@ -378,14 +384,11 @@ public final class StorySetIndicatorComponent: Component {
|
||||
self.imageView.setNeedsDisplay()
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
let textValue: String
|
||||
if component.totalCount == 0 {
|
||||
textValue = ""
|
||||
} else if component.totalCount == 1 {
|
||||
textValue = "1 story"
|
||||
} else {
|
||||
textValue = "\(component.totalCount) stories"
|
||||
textValue = component.strings.Story_Footer_Views(Int32(component.totalCount))
|
||||
}
|
||||
let textSize = self.text.update(
|
||||
transition: .immediate,
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "smoothGradient 0.4.png",
|
||||
"filename" : "smoothGradient 0.6.png",
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB |
BIN
submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.6.png
vendored
Normal file
BIN
submodules/TelegramUI/Images.xcassets/Stories/PanelGradient.imageset/smoothGradient 0.6.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
@ -4524,8 +4524,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
return
|
||||
}
|
||||
if let story = message.associatedStories[storyId], story.data.isEmpty {
|
||||
//TODO:localize
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: "This story is no longer available", timeout: nil), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
self.present(UndoOverlayController(presentationData: self.presentationData, content: .info(title: nil, text: self.presentationData.strings.Story_TooltipExpired, timeout: nil), elevatedLayout: false, action: { _ in return true }), in: .current)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -137,15 +137,14 @@ public class ChatMessageReplyInfoNode: ASDisplayNode {
|
||||
} else {
|
||||
titleString = arguments.strings.User_DeletedAccount
|
||||
}
|
||||
//TODO:localize
|
||||
isText = false
|
||||
if let storyItem = arguments.parentMessage.associatedStories[story], storyItem.data.isEmpty {
|
||||
isExpiredStory = true
|
||||
textString = NSAttributedString(string: "Expired story")
|
||||
textString = NSAttributedString(string: arguments.strings.Chat_ReplyExpiredStory)
|
||||
isMedia = false
|
||||
} else {
|
||||
isStory = true
|
||||
textString = NSAttributedString(string: "Story")
|
||||
textString = NSAttributedString(string: arguments.strings.Chat_ReplyStory)
|
||||
isMedia = true
|
||||
}
|
||||
} else {
|
||||
|
@ -194,9 +194,7 @@ class ChatMessageStoryMentionContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: text, backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
//TODO:localize
|
||||
|
||||
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: "View Story", font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
let (buttonTitleLayout, buttonTitleApply) = makeButtonTitleLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Chat_StoryMentionAction, font: Font.semibold(15.0), textColor: primaryTextColor, paragraphAlignment: .center), backgroundColor: nil, maximumNumberOfLines: 0, truncationType: .end, constrainedSize: CGSize(width: width - 32.0, height: CGFloat.greatestFiniteMagnitude), alignment: .center, cutout: nil, insets: UIEdgeInsets()))
|
||||
|
||||
let backgroundSize = CGSize(width: width, height: subtitleLayout.size.height + 186.0)
|
||||
|
||||
|
@ -833,12 +833,11 @@ func openResolvedUrlImpl(_ resolvedUrl: ResolvedUrl, context: AccountContext, ur
|
||||
navigationController?.pushViewController(storyContainerScreen)
|
||||
})
|
||||
} else {
|
||||
//TODO:localize
|
||||
var elevatedLayout = true
|
||||
if case .chat = urlContext {
|
||||
elevatedLayout = false
|
||||
}
|
||||
present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "story_expired", scale: 0.066, colors: [:], title: nil, text: "This story does not exist", customUndoText: nil, timeout: nil), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in
|
||||
present(UndoOverlayController(presentationData: presentationData, content: .universal(animation: "story_expired", scale: 0.066, colors: [:], title: nil, text: presentationData.strings.Story_TooltipExpired, customUndoText: nil, timeout: nil), elevatedLayout: elevatedLayout, animateInAsReplacement: false, action: { _ in
|
||||
return true
|
||||
}), nil)
|
||||
}
|
||||
|
@ -956,8 +956,7 @@ final class PeerInfoPaneContainerNode: ASDisplayNode, UIGestureRecognizerDelegat
|
||||
let title: String
|
||||
switch key {
|
||||
case .stories:
|
||||
//TODO:localize
|
||||
title = "Stories"
|
||||
title = presentationData.strings.PeerInfo_PaneStories
|
||||
case .media:
|
||||
title = presentationData.strings.PeerInfo_PaneMedia
|
||||
case .files:
|
||||
|
@ -792,8 +792,7 @@ private func settingsItems(data: PeerInfoScreenData?, context: AccountContext, p
|
||||
}
|
||||
}
|
||||
|
||||
//TODO:localize
|
||||
items[.stories]!.append(PeerInfoScreenDisclosureItem(id: 0, text: "My Stories", icon: PresentationResourcesSettings.stories, action: {
|
||||
items[.stories]!.append(PeerInfoScreenDisclosureItem(id: 0, text: presentationData.strings.Settings_MyStories, icon: PresentationResourcesSettings.stories, action: {
|
||||
interaction.openSettings(.stories)
|
||||
}))
|
||||
|
||||
|
@ -141,8 +141,7 @@ final class WebpagePreviewAccessoryPanelNode: AccessoryPanelNode {
|
||||
} else if content.type == "video" {
|
||||
text = stringForMediaKind(.video, strings: self.strings).0.string
|
||||
} else if content.type == "telegram_story" {
|
||||
//TODO:localize
|
||||
text = "Story"
|
||||
text = stringForMediaKind(.story, strings: self.strings).0.string
|
||||
} else if let _ = content.image {
|
||||
text = stringForMediaKind(.image, strings: self.strings).0.string
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user