mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-11-29 03:21:29 +00:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
d296fbf609
@ -10557,3 +10557,34 @@ Sorry for the inconvenience.";
|
|||||||
|
|
||||||
"Premium.Limits.RecommendedChannels" = "Similar Channels";
|
"Premium.Limits.RecommendedChannels" = "Similar Channels";
|
||||||
"Premium.Limits.RecommendedChannelsInfo" = "View up to 100 similar channels.";
|
"Premium.Limits.RecommendedChannelsInfo" = "View up to 100 similar channels.";
|
||||||
|
|
||||||
|
"ChannelBoost.CustomReactions" = "Custom Reactions";
|
||||||
|
"ChannelBoost.CustomReactionsText" = "Your channel needs to reach **Level %1$@** to add **%2$@** custom emoji as reactions.\n\nAsk your **Premium** subscribers to boost your channel with this link:";
|
||||||
|
|
||||||
|
"Settings.YourColor" = "Your Color";
|
||||||
|
|
||||||
|
"ChannelReactions.Reactions" = "Reactions";
|
||||||
|
"ChannelReactions.UnsavedChangesAlertTitle" = "Unsaved Changes";
|
||||||
|
"ChannelReactions.UnsavedChangesAlertText" = "You have changed the list of reactions. Apply changes?";
|
||||||
|
"ChannelReactions.UnsavedChangesAlertDiscard" = "Discard";
|
||||||
|
"ChannelReactions.UnsavedChangesAlertApply" = "Apply";
|
||||||
|
"ChannelReactions.ToastMaxReactionsReached" = "You can select at most 100 reactions.";
|
||||||
|
"ChannelReactions.ToastLevelBoostRequired" = "Your channel needs to reach **Level %1$@** to add **%2$@** custom emoji as reactions.**";
|
||||||
|
"ChannelReactions.GeneralInfoLabel" = "You can add emoji from any emoji pack as a reaction.";
|
||||||
|
"ChannelReactions.ReactionsSectionTitle" = "AVAILABLE REACTIONS";
|
||||||
|
"ChannelReactions.ReactionsInfoLabel" = "You can also [create your own]() emoji packs and use them.";
|
||||||
|
"ChannelReactions.SaveAction" = "Update Reactions";
|
||||||
|
"ChannelReactions.LevelRequiredLabel" = "Level %1$@ Required";
|
||||||
|
|
||||||
|
"ProfileColorSetup.ResetAction" = "Reset Profile Color";
|
||||||
|
"ProfileColorSetup.IconSectionTitle" = "ADD ICON TO PROFILE";
|
||||||
|
"ProfileColorSetup.AccountColorInfoLabel" = "Choose a color for your profile";
|
||||||
|
"ProfileColorSetup.ChannelColorInfoLabel" = "Choose a color for channel's profile";
|
||||||
|
"ProfileColorSetup.TitleName" = "Name";
|
||||||
|
"ProfileColorSetup.TitleProfile" = "Profile";
|
||||||
|
"ProfileColorSetup.TitleChannelColor" = "Set Channel Color";
|
||||||
|
"ProfileColorSetup.ToastAccountColorUpdated" = "Your color has been updated.";
|
||||||
|
|
||||||
|
"Chat.TopicIsClosedLabel" = "Topic \"%1$@\" is closed";
|
||||||
|
"Chat.InputPlaceholderReplyInTopic" = "Reply in %1$@";
|
||||||
|
"Chat.InputPlaceholderMessageInTopic" = "Message in %1$@";
|
||||||
|
|||||||
@ -1193,9 +1193,8 @@ private final class LimitSheetContent: CombinedComponent {
|
|||||||
titleText = strings.ChannelBoost_EnableColors
|
titleText = strings.ChannelBoost_EnableColors
|
||||||
string = strings.ChannelBoost_EnableColorsLevelText("\(premiumConfiguration.minChannelNameColorLevel)").string
|
string = strings.ChannelBoost_EnableColorsLevelText("\(premiumConfiguration.minChannelNameColorLevel)").string
|
||||||
case let .channelReactions(reactionCount):
|
case let .channelReactions(reactionCount):
|
||||||
//TODO:localize
|
titleText = strings.ChannelBoost_CustomReactions
|
||||||
titleText = "Custom Reactions"
|
string = strings.ChannelBoost_CustomReactionsText("\(reactionCount)", "\(reactionCount)").string
|
||||||
string = "Your channel needs to reach **Level \(reactionCount)** to add **\(reactionCount)** custom emoji as reactions.\n\nAsk your **Premium** subscribers to boost your channel with this link:"
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let storiesString = strings.ChannelBoost_StoriesPerDay(level)
|
let storiesString = strings.ChannelBoost_StoriesPerDay(level)
|
||||||
|
|||||||
@ -592,6 +592,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
backgroundColor: .clear,
|
backgroundColor: .clear,
|
||||||
separatorColor: strongSelf.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5),
|
separatorColor: strongSelf.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5),
|
||||||
hideTopPanel: hideTopPanel,
|
hideTopPanel: hideTopPanel,
|
||||||
|
disableTopPanel: strongSelf.alwaysAllowPremiumReactions,
|
||||||
hideTopPanelUpdated: { hideTopPanel, transition in
|
hideTopPanelUpdated: { hideTopPanel, transition in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
@ -1217,6 +1218,7 @@ public final class ReactionContextNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
backgroundColor: .clear,
|
backgroundColor: .clear,
|
||||||
separatorColor: self.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5),
|
separatorColor: self.presentationData.theme.list.itemPlainSeparatorColor.withMultipliedAlpha(0.5),
|
||||||
hideTopPanel: hideTopPanel,
|
hideTopPanel: hideTopPanel,
|
||||||
|
disableTopPanel: self.alwaysAllowPremiumReactions,
|
||||||
hideTopPanelUpdated: { [weak self] hideTopPanel, transition in
|
hideTopPanelUpdated: { [weak self] hideTopPanel, transition in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -408,8 +408,7 @@ private func themeSettingsControllerEntries(presentationData: PresentationData,
|
|||||||
|
|
||||||
let colors = nameColors.get(nameColor, dark: presentationData.theme.overallDarkAppearance)
|
let colors = nameColors.get(nameColor, dark: presentationData.theme.overallDarkAppearance)
|
||||||
let profileColors = profileColor.flatMap { nameColors.getProfile($0, dark: presentationData.theme.overallDarkAppearance, subject: .palette) }
|
let profileColors = profileColor.flatMap { nameColors.getProfile($0, dark: presentationData.theme.overallDarkAppearance, subject: .palette) }
|
||||||
//TODO:localize
|
entries.append(.nameColor(presentationData.theme, presentationData.strings.Settings_YourColor, accountPeer?.compactDisplayTitle ?? "", colors, profileColors))
|
||||||
entries.append(.nameColor(presentationData.theme, "Your Color", accountPeer?.compactDisplayTitle ?? "", colors, profileColors))
|
|
||||||
|
|
||||||
entries.append(.autoNight(presentationData.theme, strings.Appearance_NightTheme, presentationThemeSettings.automaticThemeSwitchSetting.force, !presentationData.autoNightModeTriggered || presentationThemeSettings.automaticThemeSwitchSetting.force))
|
entries.append(.autoNight(presentationData.theme, strings.Appearance_NightTheme, presentationThemeSettings.automaticThemeSwitchSetting.force, !presentationData.autoNightModeTriggered || presentationThemeSettings.automaticThemeSwitchSetting.force))
|
||||||
let autoNightMode: String
|
let autoNightMode: String
|
||||||
|
|||||||
@ -1496,32 +1496,61 @@ struct ChatRecentActionsEntry: Comparable, Identifiable {
|
|||||||
var text: String = ""
|
var text: String = ""
|
||||||
var entities: [MessageTextEntity] = []
|
var entities: [MessageTextEntity] = []
|
||||||
|
|
||||||
let rawText: PresentationStrings.FormattedString
|
|
||||||
switch updatedValue {
|
switch updatedValue {
|
||||||
case .all:
|
case .all:
|
||||||
rawText = self.presentationData.strings.Channel_AdminLog_ReactionsEnabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
|
let rawText = self.presentationData.strings.Channel_AdminLog_ReactionsEnabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
|
||||||
case let .limited(reactions):
|
appendAttributedText(text: rawText, generateEntities: { index in
|
||||||
let emojiString = reactions.compactMap({ reaction -> String? in
|
if index == 0, let author = author {
|
||||||
switch reaction {
|
return [.TextMention(peerId: author.id)]
|
||||||
case let .builtin(value):
|
} else if index == 1 {
|
||||||
return value
|
return [.Bold]
|
||||||
case .custom:
|
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
}).joined(separator: ", ")
|
return []
|
||||||
rawText = self.presentationData.strings.Channel_AdminLog_AllowedReactionsUpdated(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "", emojiString)
|
}, to: &text, entities: &entities)
|
||||||
case .empty:
|
case let .limited(reactions):
|
||||||
rawText = self.presentationData.strings.Channel_AdminLog_ReactionsDisabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
|
let authorTitle = author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? ""
|
||||||
}
|
let rawText = self.presentationData.strings.Channel_AdminLog_AllowedReactionsUpdated(authorTitle, "")
|
||||||
|
var previousIndex = 0
|
||||||
appendAttributedText(text: rawText, generateEntities: { index in
|
let nsText = rawText.string as NSString
|
||||||
if index == 0, let author = author {
|
for range in rawText.ranges.sorted(by: { $0.range.lowerBound < $1.range.lowerBound }) {
|
||||||
return [.TextMention(peerId: author.id)]
|
if range.range.lowerBound > previousIndex {
|
||||||
} else if index == 1 {
|
text.append(nsText.substring(with: NSRange(location: previousIndex, length: range.range.lowerBound - previousIndex)))
|
||||||
return [.Bold]
|
}
|
||||||
|
if range.index == 0 {
|
||||||
|
if let author {
|
||||||
|
entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (authorTitle as NSString).length, type: .TextMention(peerId: author.id)))
|
||||||
|
}
|
||||||
|
text.append(authorTitle)
|
||||||
|
} else if range.index == 1 {
|
||||||
|
for reaction in reactions {
|
||||||
|
let reactionText: String
|
||||||
|
switch reaction {
|
||||||
|
case let .builtin(value):
|
||||||
|
reactionText = value
|
||||||
|
text.append(reactionText)
|
||||||
|
case let .custom(fileId):
|
||||||
|
reactionText = "."
|
||||||
|
entities.append(MessageTextEntity(range: (text as NSString).length ..< (text as NSString).length + (reactionText as NSString).length, type: .CustomEmoji(stickerPack: nil, fileId: fileId)))
|
||||||
|
text.append(reactionText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
previousIndex = range.range.upperBound
|
||||||
}
|
}
|
||||||
return []
|
if nsText.length > previousIndex {
|
||||||
}, to: &text, entities: &entities)
|
text.append(nsText.substring(with: NSRange(location: previousIndex, length: nsText.length - previousIndex)))
|
||||||
|
}
|
||||||
|
case .empty:
|
||||||
|
let rawText = self.presentationData.strings.Channel_AdminLog_ReactionsDisabled(author.flatMap(EnginePeer.init)?.displayTitle(strings: self.presentationData.strings, displayOrder: self.presentationData.nameDisplayOrder) ?? "")
|
||||||
|
appendAttributedText(text: rawText, generateEntities: { index in
|
||||||
|
if index == 0, let author = author {
|
||||||
|
return [.TextMention(peerId: author.id)]
|
||||||
|
} else if index == 1 {
|
||||||
|
return [.Bold]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
}, to: &text, entities: &entities)
|
||||||
|
}
|
||||||
|
|
||||||
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
let action = TelegramMediaActionType.customText(text: text, entities: entities)
|
||||||
|
|
||||||
|
|||||||
@ -65,6 +65,7 @@ public final class EmojiStatusSelectionComponent: Component {
|
|||||||
public let backgroundColor: UIColor
|
public let backgroundColor: UIColor
|
||||||
public let separatorColor: UIColor
|
public let separatorColor: UIColor
|
||||||
public let hideTopPanel: Bool
|
public let hideTopPanel: Bool
|
||||||
|
public let disableTopPanel: Bool
|
||||||
public let hideTopPanelUpdated: (Bool, Transition) -> Void
|
public let hideTopPanelUpdated: (Bool, Transition) -> Void
|
||||||
|
|
||||||
public init(
|
public init(
|
||||||
@ -75,6 +76,7 @@ public final class EmojiStatusSelectionComponent: Component {
|
|||||||
backgroundColor: UIColor,
|
backgroundColor: UIColor,
|
||||||
separatorColor: UIColor,
|
separatorColor: UIColor,
|
||||||
hideTopPanel: Bool,
|
hideTopPanel: Bool,
|
||||||
|
disableTopPanel: Bool,
|
||||||
hideTopPanelUpdated: @escaping (Bool, Transition) -> Void
|
hideTopPanelUpdated: @escaping (Bool, Transition) -> Void
|
||||||
) {
|
) {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
@ -84,6 +86,7 @@ public final class EmojiStatusSelectionComponent: Component {
|
|||||||
self.backgroundColor = backgroundColor
|
self.backgroundColor = backgroundColor
|
||||||
self.separatorColor = separatorColor
|
self.separatorColor = separatorColor
|
||||||
self.hideTopPanel = hideTopPanel
|
self.hideTopPanel = hideTopPanel
|
||||||
|
self.disableTopPanel = disableTopPanel
|
||||||
self.hideTopPanelUpdated = hideTopPanelUpdated
|
self.hideTopPanelUpdated = hideTopPanelUpdated
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,6 +112,9 @@ public final class EmojiStatusSelectionComponent: Component {
|
|||||||
if lhs.hideTopPanel != rhs.hideTopPanel {
|
if lhs.hideTopPanel != rhs.hideTopPanel {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.disableTopPanel != rhs.disableTopPanel {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -193,7 +199,8 @@ public final class EmojiStatusSelectionComponent: Component {
|
|||||||
displayBottomPanel: false,
|
displayBottomPanel: false,
|
||||||
isExpanded: false,
|
isExpanded: false,
|
||||||
clipContentToTopPanel: false,
|
clipContentToTopPanel: false,
|
||||||
useExternalSearchContainer: false
|
useExternalSearchContainer: false,
|
||||||
|
hidePanels: component.disableTopPanel
|
||||||
)),
|
)),
|
||||||
environment: {},
|
environment: {},
|
||||||
containerSize: availableSize
|
containerSize: availableSize
|
||||||
@ -984,6 +991,7 @@ public final class EmojiStatusSelectionController: ViewController {
|
|||||||
backgroundColor: listBackgroundColor,
|
backgroundColor: listBackgroundColor,
|
||||||
separatorColor: separatorColor,
|
separatorColor: separatorColor,
|
||||||
hideTopPanel: self.isReactionSearchActive,
|
hideTopPanel: self.isReactionSearchActive,
|
||||||
|
disableTopPanel: false,
|
||||||
hideTopPanelUpdated: { [weak self] hideTopPanel, transition in
|
hideTopPanelUpdated: { [weak self] hideTopPanel, transition in
|
||||||
guard let strongSelf = self else {
|
guard let strongSelf = self else {
|
||||||
return
|
return
|
||||||
|
|||||||
@ -24,10 +24,12 @@ import AudioToolbox
|
|||||||
private final class ButtonSubtitleComponent: CombinedComponent {
|
private final class ButtonSubtitleComponent: CombinedComponent {
|
||||||
let count: Int
|
let count: Int
|
||||||
let theme: PresentationTheme
|
let theme: PresentationTheme
|
||||||
|
let strings: PresentationStrings
|
||||||
|
|
||||||
init(count: Int, theme: PresentationTheme) {
|
init(count: Int, theme: PresentationTheme, strings: PresentationStrings) {
|
||||||
self.count = count
|
self.count = count
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
self.strings = strings
|
||||||
}
|
}
|
||||||
|
|
||||||
static func ==(lhs: ButtonSubtitleComponent, rhs: ButtonSubtitleComponent) -> Bool {
|
static func ==(lhs: ButtonSubtitleComponent, rhs: ButtonSubtitleComponent) -> Bool {
|
||||||
@ -37,6 +39,9 @@ private final class ButtonSubtitleComponent: CombinedComponent {
|
|||||||
if lhs.theme !== rhs.theme {
|
if lhs.theme !== rhs.theme {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
if lhs.strings !== rhs.strings {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,11 +59,24 @@ private final class ButtonSubtitleComponent: CombinedComponent {
|
|||||||
availableSize: CGSize(width: 100.0, height: 100.0),
|
availableSize: CGSize(width: 100.0, height: 100.0),
|
||||||
transition: context.transition
|
transition: context.transition
|
||||||
)
|
)
|
||||||
//TODO:localize
|
|
||||||
var textItems: [AnimatedTextComponent.Item] = []
|
var textItems: [AnimatedTextComponent.Item] = []
|
||||||
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(0 as Int), content: .text("Level ")))
|
|
||||||
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(1 as Int), content: .number(context.component.count, minDigits: 1)))
|
let levelString = context.component.strings.ChannelReactions_LevelRequiredLabel("")
|
||||||
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(2 as Int), content: .text(" Required")))
|
var previousIndex = 0
|
||||||
|
let nsLevelString = levelString.string as NSString
|
||||||
|
for range in levelString.ranges.sorted(by: { $0.range.lowerBound < $1.range.lowerBound }) {
|
||||||
|
if range.range.lowerBound > previousIndex {
|
||||||
|
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(range.index), content: .text(nsLevelString.substring(with: NSRange(location: previousIndex, length: range.range.lowerBound - previousIndex)))))
|
||||||
|
}
|
||||||
|
if range.index == 0 {
|
||||||
|
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(range.index), content: .number(context.component.count, minDigits: 1)))
|
||||||
|
}
|
||||||
|
previousIndex = range.range.upperBound
|
||||||
|
}
|
||||||
|
if nsLevelString.length > previousIndex {
|
||||||
|
textItems.append(AnimatedTextComponent.Item(id: AnyHashable(100), content: .text(nsLevelString.substring(with: NSRange(location: previousIndex, length: nsLevelString.length - previousIndex)))))
|
||||||
|
}
|
||||||
|
|
||||||
let text = text.update(
|
let text = text.update(
|
||||||
component: AnimatedTextComponent(font: Font.medium(11.0), color: context.component.theme.list.itemCheckColors.foregroundColor.withMultipliedAlpha(0.7), items: textItems),
|
component: AnimatedTextComponent(font: Font.medium(11.0), color: context.component.theme.list.itemCheckColors.foregroundColor.withMultipliedAlpha(0.7), items: textItems),
|
||||||
availableSize: CGSize(width: context.availableSize.width - 20.0, height: 100.0),
|
availableSize: CGSize(width: context.availableSize.width - 20.0, height: 100.0),
|
||||||
@ -210,15 +228,14 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
self.applySettings(standalone: true)
|
self.applySettings(standalone: true)
|
||||||
} else {
|
} else {
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
//TODO:localize
|
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChannelReactions_UnsavedChangesAlertTitle, text: presentationData.strings.ChannelReactions_UnsavedChangesAlertText, actions: [
|
||||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: "Unsaved Changes", text: "You have changed the list of reactions. Apply changes?", actions: [
|
TextAlertAction(type: .genericAction, title: presentationData.strings.ChannelReactions_UnsavedChangesAlertDiscard, action: { [weak self] in
|
||||||
TextAlertAction(type: .genericAction, title: "Discard", action: { [weak self] in
|
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
self.environment?.controller()?.dismiss()
|
self.environment?.controller()?.dismiss()
|
||||||
}),
|
}),
|
||||||
TextAlertAction(type: .defaultAction, title: "Apply", action: { [weak self] in
|
TextAlertAction(type: .defaultAction, title: presentationData.strings.ChannelReactions_UnsavedChangesAlertApply, action: { [weak self] in
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -309,8 +326,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
self.displayPremiumScreen(reactionCount: customReactions.count)
|
self.displayPremiumScreen(reactionCount: customReactions.count)
|
||||||
case .generic:
|
case .generic:
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
//TODO:localize
|
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: presentationData.strings.Login_UnknownError, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
||||||
self.environment?.controller()?.present(standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: "An error occurred", actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {})]), in: .window(.root))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, completed: { [weak self] in
|
}, completed: { [weak self] in
|
||||||
@ -457,7 +473,6 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if enabledReactions.count >= 100 {
|
if enabledReactions.count >= 100 {
|
||||||
//TODO:localize
|
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
var animateAsReplacement = false
|
var animateAsReplacement = false
|
||||||
@ -466,7 +481,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
animateAsReplacement = true
|
animateAsReplacement = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let undoController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: "You can select at most 100 reactions.", timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
|
let undoController = UndoOverlayController(presentationData: presentationData, content: .info(title: nil, text: presentationData.strings.ChannelReactions_ToastMaxReactionsReached, timeout: nil, customUndoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
|
||||||
self.currentUndoController = undoController
|
self.currentUndoController = undoController
|
||||||
self.environment?.controller()?.present(undoController, in: .current)
|
self.environment?.controller()?.present(undoController, in: .current)
|
||||||
return
|
return
|
||||||
@ -490,7 +505,6 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
|
|
||||||
let nextCustomReactionCount = enabledCustomReactions.count + 1
|
let nextCustomReactionCount = enabledCustomReactions.count + 1
|
||||||
if nextCustomReactionCount > boostStatus.level {
|
if nextCustomReactionCount > boostStatus.level {
|
||||||
//TODO:localize
|
|
||||||
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = component.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
|
|
||||||
var animateAsReplacement = false
|
var animateAsReplacement = false
|
||||||
@ -499,7 +513,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
animateAsReplacement = true
|
animateAsReplacement = true
|
||||||
}
|
}
|
||||||
|
|
||||||
let undoController = UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: component.context, file: itemFile, loop: false, title: nil, text: "Your channel needs to reach **Level \(nextCustomReactionCount)** to add **\(nextCustomReactionCount)** custom emoji as reactions.**", undoText: nil, customAction: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
|
let undoController = UndoOverlayController(presentationData: presentationData, content: .customEmoji(context: component.context, file: itemFile, loop: false, title: nil, text: presentationData.strings.ChannelReactions_ToastLevelBoostRequired("\(nextCustomReactionCount)", "\(nextCustomReactionCount)").string, undoText: nil, customAction: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: animateAsReplacement, action: { _ in return false })
|
||||||
self.currentUndoController = undoController
|
self.currentUndoController = undoController
|
||||||
self.environment?.controller()?.present(undoController, in: .current)
|
self.environment?.controller()?.present(undoController, in: .current)
|
||||||
}
|
}
|
||||||
@ -632,12 +646,11 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
contentHeight += switchSize.height
|
contentHeight += switchSize.height
|
||||||
contentHeight += 7.0
|
contentHeight += 7.0
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
let switchInfoTextSize = self.switchInfoText.update(
|
let switchInfoTextSize = self.switchInfoText.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(
|
text: .plain(NSAttributedString(
|
||||||
string: "You can add emoji from any emoji pack as a reaction.",
|
string: environment.strings.ChannelReactions_GeneralInfoLabel,
|
||||||
font: Font.regular(13.0),
|
font: Font.regular(13.0),
|
||||||
textColor: environment.theme.list.freeTextColor
|
textColor: environment.theme.list.freeTextColor
|
||||||
)),
|
)),
|
||||||
@ -670,12 +683,11 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
animateIn = true
|
animateIn = true
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
let reactionsTitleTextSize = reactionsTitleText.update(
|
let reactionsTitleTextSize = reactionsTitleText.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
text: .plain(NSAttributedString(
|
text: .plain(NSAttributedString(
|
||||||
string: "AVAILABLE REACTIONS",
|
string: environment.strings.ChannelReactions_ReactionsSectionTitle,
|
||||||
font: Font.regular(13.0),
|
font: Font.regular(13.0),
|
||||||
textColor: environment.theme.list.freeTextColor
|
textColor: environment.theme.list.freeTextColor
|
||||||
)),
|
)),
|
||||||
@ -770,7 +782,6 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
self.reactionsInfoText = reactionsInfoText
|
self.reactionsInfoText = reactionsInfoText
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
let body = MarkdownAttributeSet(font: UIFont.systemFont(ofSize: 13.0), textColor: environment.theme.list.freeTextColor)
|
let body = MarkdownAttributeSet(font: UIFont.systemFont(ofSize: 13.0), textColor: environment.theme.list.freeTextColor)
|
||||||
let link = MarkdownAttributeSet(font: UIFont.systemFont(ofSize: 13.0), textColor: environment.theme.list.itemAccentColor, additionalAttributes: [:])
|
let link = MarkdownAttributeSet(font: UIFont.systemFont(ofSize: 13.0), textColor: environment.theme.list.itemAccentColor, additionalAttributes: [:])
|
||||||
let attributes = MarkdownAttributes(body: body, bold: body, link: link, linkAttribute: { contents in
|
let attributes = MarkdownAttributes(body: body, bold: body, link: link, linkAttribute: { contents in
|
||||||
@ -779,7 +790,7 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
let reactionsInfoTextSize = reactionsInfoText.update(
|
let reactionsInfoTextSize = reactionsInfoText.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(MultilineTextComponent(
|
component: AnyComponent(MultilineTextComponent(
|
||||||
text: .markdown(text: "You can also [create your own]() emoji packs and use them.", attributes: attributes),
|
text: .markdown(text: environment.strings.ChannelReactions_ReactionsInfoLabel, attributes: attributes),
|
||||||
maximumNumberOfLines: 0,
|
maximumNumberOfLines: 0,
|
||||||
highlightAction: { attributes in
|
highlightAction: { attributes in
|
||||||
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
if let _ = attributes[NSAttributedString.Key(rawValue: TelegramTextAttributes.URL)] {
|
||||||
@ -878,10 +889,9 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:localize
|
|
||||||
var buttonContents: [AnyComponentWithIdentity<Empty>] = []
|
var buttonContents: [AnyComponentWithIdentity<Empty>] = []
|
||||||
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
|
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(0 as Int), component: AnyComponent(
|
||||||
Text(text: "Update Reactions", font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
Text(text: environment.strings.ChannelReactions_SaveAction, font: Font.semibold(17.0), color: environment.theme.list.itemCheckColors.foregroundColor)
|
||||||
)))
|
)))
|
||||||
|
|
||||||
let customReactionCount = self.isEnabled ? enabledReactions.filter({ item in
|
let customReactionCount = self.isEnabled ? enabledReactions.filter({ item in
|
||||||
@ -894,10 +904,10 @@ final class PeerAllowedReactionsScreenComponent: Component {
|
|||||||
}).count : 0
|
}).count : 0
|
||||||
|
|
||||||
if let boostStatus = self.boostStatus, customReactionCount > boostStatus.level {
|
if let boostStatus = self.boostStatus, customReactionCount > boostStatus.level {
|
||||||
//TODO:localize
|
|
||||||
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(1 as Int), component: AnyComponent(ButtonSubtitleComponent(
|
buttonContents.append(AnyComponentWithIdentity(id: AnyHashable(1 as Int), component: AnyComponent(ButtonSubtitleComponent(
|
||||||
count: customReactionCount,
|
count: customReactionCount,
|
||||||
theme: environment.theme
|
theme: environment.theme,
|
||||||
|
strings: environment.strings
|
||||||
))))
|
))))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1120,8 +1130,7 @@ public class PeerAllowedReactionsScreen: ViewControllerComponentContainer {
|
|||||||
initialContent: initialContent
|
initialContent: initialContent
|
||||||
), navigationBarAppearance: .default, theme: .default)
|
), navigationBarAppearance: .default, theme: .default)
|
||||||
|
|
||||||
//TODO:localize
|
self.title = context.sharedContext.currentPresentationData.with({ $0 }).strings.ChannelReactions_Reactions
|
||||||
self.title = "Reactions"
|
|
||||||
|
|
||||||
self.scrollToTop = { [weak self] in
|
self.scrollToTop = { [weak self] in
|
||||||
guard let self, let componentView = self.node.hostView.componentView as? PeerAllowedReactionsScreenComponent.View else {
|
guard let self, let componentView = self.node.hostView.componentView as? PeerAllowedReactionsScreenComponent.View else {
|
||||||
|
|||||||
@ -1020,8 +1020,7 @@ private func settingsEditingItems(data: PeerInfoScreenData?, state: PeerInfoStat
|
|||||||
}
|
}
|
||||||
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colors)
|
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colors)
|
||||||
|
|
||||||
//TODO:localize
|
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), text: presentationData.strings.Settings_YourColor, icon: nil, action: {
|
||||||
items[.info]!.append(PeerInfoScreenDisclosureItem(id: ItemPeerColor, label: .image(colorImage, colorImage.size), text: "Your Color", icon: nil, action: {
|
|
||||||
interaction.editingOpenNameColorSetup()
|
interaction.editingOpenNameColorSetup()
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|||||||
@ -247,8 +247,7 @@ final class PeerNameColorProfilePreviewItemNode: ListViewItemNode {
|
|||||||
titleView.frame = titleFrame
|
titleView.frame = titleFrame
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO:localize
|
let subtitleString: String = item.strings.LastSeen_JustNow
|
||||||
let subtitleString: String = "last seen just now"
|
|
||||||
let subtitleSize = self.subtitle.update(
|
let subtitleSize = self.subtitle.update(
|
||||||
transition: .immediate,
|
transition: .immediate,
|
||||||
component: AnyComponent(Text(
|
component: AnyComponent(Text(
|
||||||
|
|||||||
@ -218,8 +218,7 @@ private enum PeerNameColorScreenEntry: ItemListNodeEntry {
|
|||||||
sectionId: self.section
|
sectionId: self.section
|
||||||
)
|
)
|
||||||
case .removeColor:
|
case .removeColor:
|
||||||
//TODO:localize
|
return ItemListActionItem(presentationData: presentationData, title: presentationData.strings.ProfileColorSetup_ResetAction, kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
||||||
return ItemListActionItem(presentationData: presentationData, title: "Reset Profile Color", kind: .generic, alignment: .natural, sectionId: self.section, style: .blocks, action: {
|
|
||||||
arguments.resetColor()
|
arguments.resetColor()
|
||||||
})
|
})
|
||||||
case let .colorDescription(text):
|
case let .colorDescription(text):
|
||||||
@ -390,15 +389,13 @@ private func peerNameColorScreenEntries(
|
|||||||
}
|
}
|
||||||
let emojiContent = emojiContent.withSelectedItems(selectedItems).withCustomTintColor(profileColors?.main ?? presentationData.theme.list.itemSecondaryTextColor)
|
let emojiContent = emojiContent.withSelectedItems(selectedItems).withCustomTintColor(profileColors?.main ?? presentationData.theme.list.itemSecondaryTextColor)
|
||||||
|
|
||||||
//TODO:localize
|
entries.append(.backgroundEmojiHeader(presentationData.strings.ProfileColorSetup_IconSectionTitle, (selectedProfileEmojiId != nil && selectedProfileEmojiId != 0) ? presentationData.strings.NameColor_BackgroundEmoji_Remove : nil))
|
||||||
entries.append(.backgroundEmojiHeader("ADD ICON TO PROFILE", (selectedProfileEmojiId != nil && selectedProfileEmojiId != 0) ? presentationData.strings.NameColor_BackgroundEmoji_Remove : nil))
|
|
||||||
entries.append(.backgroundEmoji(emojiContent, profileColors?.main ?? presentationData.theme.list.itemSecondaryTextColor, true, profileColor != nil))
|
entries.append(.backgroundEmoji(emojiContent, profileColors?.main ?? presentationData.theme.list.itemSecondaryTextColor, true, profileColor != nil))
|
||||||
} else {
|
} else {
|
||||||
//TODO:localize
|
|
||||||
if case .channel = peer {
|
if case .channel = peer {
|
||||||
entries.append(.colorDescription("Choose a color for channel's profile"))
|
entries.append(.colorDescription(presentationData.strings.ProfileColorSetup_ChannelColorInfoLabel))
|
||||||
} else {
|
} else {
|
||||||
entries.append(.colorDescription("Choose a color for your profile"))
|
entries.append(.colorDescription(presentationData.strings.ProfileColorSetup_AccountColorInfoLabel))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -701,10 +698,9 @@ public func PeerNameColorScreen(
|
|||||||
|
|
||||||
let title: ItemListControllerTitle
|
let title: ItemListControllerTitle
|
||||||
if case .user = peer {
|
if case .user = peer {
|
||||||
//TODO:localize
|
title = .sectionControl([presentationData.strings.ProfileColorSetup_TitleName, presentationData.strings.ProfileColorSetup_TitleProfile], state.selectedTabIndex)
|
||||||
title = .sectionControl(["Name", "Profile"], state.selectedTabIndex)
|
|
||||||
} else {
|
} else {
|
||||||
title = .text("Set Channel Color")
|
title = .text(presentationData.strings.ProfileColorSetup_TitleChannelColor)
|
||||||
}
|
}
|
||||||
|
|
||||||
let controllerState = ItemListControllerState(
|
let controllerState = ItemListControllerState(
|
||||||
@ -861,8 +857,7 @@ public func PeerNameColorScreen(
|
|||||||
|
|
||||||
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colorList)
|
let colorImage = generateSettingsMenuPeerColorsLabelIcon(colors: colorList)
|
||||||
|
|
||||||
//TODO:localize
|
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: colorImage, title: nil, text: presentationData.strings.ProfileColorSetup_ToastAccountColorUpdated, round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
|
||||||
let tipController = UndoOverlayController(presentationData: presentationData, content: .image(image: colorImage, title: nil, text: "Your color has been updated.", round: false, undoText: nil), elevatedLayout: false, position: .bottom, animateInAsReplacement: false, action: { _ in return false })
|
|
||||||
lastController.present(tipController, in: .window(.root))
|
lastController.present(tipController, in: .window(.root))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,8 +51,7 @@ final class ChatRestrictedInputPanelNode: ChatInputPanelNode {
|
|||||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelTopicClosedText, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelTopicClosedText, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||||
} else if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.flags.contains(.isForum), case .peer = interfaceState.chatLocation {
|
} else if let channel = interfaceState.renderedPeer?.peer as? TelegramChannel, channel.flags.contains(.isForum), case .peer = interfaceState.chatLocation {
|
||||||
if let replyMessage = interfaceState.replyMessage, let threadInfo = replyMessage.associatedThreadInfo {
|
if let replyMessage = interfaceState.replyMessage, let threadInfo = replyMessage.associatedThreadInfo {
|
||||||
//TODO:localize
|
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_TopicIsClosedLabel(threadInfo.title).string, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||||
self.textNode.attributedText = NSAttributedString(string: "Topic \"\(threadInfo.title)\" is closed", font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
|
||||||
} else {
|
} else {
|
||||||
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelForumModeReplyText, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
self.textNode.attributedText = NSAttributedString(string: interfaceState.strings.Chat_PanelForumModeReplyText, font: Font.regular(15.0), textColor: interfaceState.theme.chat.inputPanel.secondaryTextColor)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1774,11 +1774,9 @@ class ChatTextInputPanelNode: ChatInputPanelNode, ASEditableTextNodeDelegate, Ch
|
|||||||
}
|
}
|
||||||
} else if let channel = peer as? TelegramChannel, channel.isForum, let forumTopicData = interfaceState.forumTopicData {
|
} else if let channel = peer as? TelegramChannel, channel.isForum, let forumTopicData = interfaceState.forumTopicData {
|
||||||
if let replyMessage = interfaceState.replyMessage, let threadInfo = replyMessage.associatedThreadInfo {
|
if let replyMessage = interfaceState.replyMessage, let threadInfo = replyMessage.associatedThreadInfo {
|
||||||
//TODO:localize
|
placeholder = interfaceState.strings.Chat_InputPlaceholderReplyInTopic(threadInfo.title).string
|
||||||
placeholder = "Reply in \(threadInfo.title)"
|
|
||||||
} else {
|
} else {
|
||||||
//TODO:localize
|
placeholder = interfaceState.strings.Chat_InputPlaceholderMessageInTopic(forumTopicData.title).string
|
||||||
placeholder = "Message in \(forumTopicData.title)"
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
placeholder = interfaceState.strings.Conversation_InputTextPlaceholder
|
placeholder = interfaceState.strings.Conversation_InputTextPlaceholder
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user