mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-08-08 08:31:13 +00:00
Merge commit '72fce11e2d49d1ba0177f0c7482ea13e8a1bb068'
This commit is contained in:
commit
2f46baf863
@ -8700,9 +8700,11 @@ Sorry for the inconvenience.";
|
||||
"Conversation.HoldForAudioOnly" = "Hold to record audio.";
|
||||
"Conversation.HoldForVideoOnly" = "Hold to record video.";
|
||||
"Conversation.Translation.TranslateTo" = "Translate to %@";
|
||||
"Conversation.Translation.TranslateToOther" = "Translate to %@";
|
||||
"Conversation.Translation.ShowOriginal" = "Show Original";
|
||||
"Conversation.Translation.ChooseLanguage" = "Choose Another Language";
|
||||
"Conversation.Translation.DoNotTranslate" = "Do Not Translate %@";
|
||||
"Conversation.Translation.DoNotTranslateOther" = "Do Not Translate %@";
|
||||
"Conversation.Translation.Hide" = "Hide";
|
||||
"Conversation.Translation.AddedToDoNotTranslateText" = "**%@** is added to the Do Not Translate list.";
|
||||
"Conversation.Translation.TranslationBarHiddenChatText" = "Translation bar is now hidden for this chat.";
|
||||
@ -8720,7 +8722,7 @@ Sorry for the inconvenience.";
|
||||
"AvatarEditor.SetProfilePhoto" = "Set as Profile Photo";
|
||||
"AvatarEditor.SuggestProfilePhoto" = "Suggest as Profile Photo";
|
||||
"AvatarEditor.SetGroupPhoto" = "Set as Group Photo";
|
||||
"AvatarEditor.SetChannelPhoto" = "Set as Group Photo";
|
||||
"AvatarEditor.SetChannelPhoto" = "Set as Channel Photo";
|
||||
"AvatarEditor.Set" = "Set";
|
||||
|
||||
"Premium.UpgradeDescription" = "Your current **Telegram Premium** plan can be upgraded at a **discount**.";
|
||||
|
@ -78,8 +78,39 @@ public func generateRectsImage(color: UIColor, rects: [CGRect], inset: CGFloat,
|
||||
context.setBlendMode(.copy)
|
||||
|
||||
if useModernPathCalculation {
|
||||
var rects = rects.map { $0.insetBy(dx: -inset, dy: -inset).offsetBy(dx: -topLeft.x, dy: -topLeft.y) }
|
||||
if rects.count > 1 {
|
||||
if rects.count == 1 {
|
||||
let path = UIBezierPath(roundedRect: rects[0], cornerRadius: outerRadius).cgPath
|
||||
context.addPath(path)
|
||||
|
||||
if stroke {
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setLineWidth(2.0)
|
||||
context.strokePath()
|
||||
} else {
|
||||
context.fillPath()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var combinedRects: [[CGRect]] = []
|
||||
var currentRects: [CGRect] = []
|
||||
for rect in rects {
|
||||
if rect.width.isZero {
|
||||
if !currentRects.isEmpty {
|
||||
combinedRects.append(currentRects)
|
||||
}
|
||||
currentRects.removeAll()
|
||||
} else {
|
||||
currentRects.append(rect)
|
||||
}
|
||||
}
|
||||
if !currentRects.isEmpty {
|
||||
combinedRects.append(currentRects)
|
||||
}
|
||||
|
||||
for rects in combinedRects {
|
||||
var rects = rects.map { $0.insetBy(dx: -inset, dy: -inset).offsetBy(dx: -topLeft.x, dy: -topLeft.y) }
|
||||
|
||||
let minRadius: CGFloat = 2.0
|
||||
|
||||
for _ in 0 ..< rects.count * rects.count {
|
||||
@ -186,20 +217,8 @@ public func generateRectsImage(color: UIColor, rects: [CGRect], inset: CGFloat,
|
||||
} else {
|
||||
context.fillPath()
|
||||
}
|
||||
return
|
||||
} else {
|
||||
let path = UIBezierPath(roundedRect: rects[0], cornerRadius: outerRadius).cgPath
|
||||
context.addPath(path)
|
||||
|
||||
if stroke {
|
||||
context.setStrokeColor(color.cgColor)
|
||||
context.setLineWidth(2.0)
|
||||
context.strokePath()
|
||||
} else {
|
||||
context.fillPath()
|
||||
}
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
for i in 0 ..< rects.count {
|
||||
|
@ -182,7 +182,11 @@ private final class LegacyComponentsGlobalsProviderImpl: NSObject, LegacyCompone
|
||||
let convertedType: ManagedAudioSessionType
|
||||
switch type {
|
||||
case TGAudioSessionTypePlayAndRecord, TGAudioSessionTypePlayAndRecordHeadphones:
|
||||
convertedType = .recordWithOthers
|
||||
if legacyContext.sharedContext.currentMediaInputSettings.with({ $0 }).pauseMusicOnRecording {
|
||||
convertedType = .record(speaker: false)
|
||||
} else {
|
||||
convertedType = .recordWithOthers
|
||||
}
|
||||
default:
|
||||
convertedType = .play
|
||||
}
|
||||
|
@ -465,14 +465,22 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
||||
if let languages = translationSettings.ignoredLanguages {
|
||||
ignoredLanguages = languages
|
||||
} else {
|
||||
if let activeLanguageCode = activeLanguageCode, supportedTranslationLanguages.contains(activeLanguageCode) {
|
||||
ignoredLanguages = [activeLanguageCode]
|
||||
if let activeLanguage = activeLanguageCode, supportedTranslationLanguages.contains(activeLanguage) {
|
||||
ignoredLanguages = [activeLanguage]
|
||||
}
|
||||
let systemLanguage = systemLanguageCode()
|
||||
if !ignoredLanguages.contains(systemLanguage) {
|
||||
ignoredLanguages.append(systemLanguage)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
translateChats = isPremium
|
||||
if let activeLanguageCode = activeLanguageCode, supportedTranslationLanguages.contains(activeLanguageCode) {
|
||||
ignoredLanguages = [activeLanguageCode]
|
||||
if let activeLanguage = activeLanguageCode, supportedTranslationLanguages.contains(activeLanguage) {
|
||||
ignoredLanguages = [activeLanguage]
|
||||
}
|
||||
let systemLanguageCode = systemLanguageCode()
|
||||
if !ignoredLanguages.contains(systemLanguageCode) {
|
||||
ignoredLanguages.append(systemLanguageCode)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,7 +77,7 @@ private func translationSettingsControllerEntries(theme: PresentationTheme, stri
|
||||
if let ignoredLanguages = settings.ignoredLanguages {
|
||||
selectedLanguages = Set(ignoredLanguages)
|
||||
} else {
|
||||
selectedLanguages = Set([strings.baseLanguageCode])
|
||||
selectedLanguages = Set([strings.baseLanguageCode, systemLanguageCode()])
|
||||
}
|
||||
for (code, title, subtitle) in languages {
|
||||
entries.append(.language(index, theme, title, subtitle, selectedLanguages.contains(code), code))
|
||||
@ -100,6 +100,7 @@ public func translationSettingsController(context: AccountContext) -> ViewContro
|
||||
if value {
|
||||
if current.ignoredLanguages == nil {
|
||||
updatedIgnoredLanguages.append(interfaceLanguageCode)
|
||||
updatedIgnoredLanguages.append(systemLanguageCode())
|
||||
}
|
||||
if !updatedIgnoredLanguages.contains(code) {
|
||||
updatedIgnoredLanguages.append(code)
|
||||
|
@ -10083,6 +10083,12 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
guard let strongSelf = self, let peerId = strongSelf.chatLocation.peerId else {
|
||||
return
|
||||
}
|
||||
var langCode = langCode
|
||||
if langCode == "nb" {
|
||||
langCode = "nl"
|
||||
} else if langCode == "pt-br" {
|
||||
langCode = "pt"
|
||||
}
|
||||
let _ = updateChatTranslationStateInteractively(engine: strongSelf.context.engine, peerId: peerId, { current in
|
||||
return current?.withToLang(langCode).withIsEnabled(true)
|
||||
}).start()
|
||||
@ -10098,7 +10104,11 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
updated.ignoredLanguages = ignoredLanguages
|
||||
} else {
|
||||
updated.ignoredLanguages = [strongSelf.presentationData.strings.baseLanguageCode, langCode]
|
||||
var ignoredLanguages = Set<String>()
|
||||
ignoredLanguages.insert(strongSelf.presentationData.strings.baseLanguageCode)
|
||||
ignoredLanguages.insert(systemLanguageCode())
|
||||
ignoredLanguages.insert(langCode)
|
||||
updated.ignoredLanguages = Array(ignoredLanguages)
|
||||
}
|
||||
return updated
|
||||
}).start()
|
||||
|
@ -1096,7 +1096,17 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
var dismissedTranslationPanelNode: ChatTranslationPanelNode?
|
||||
var immediatelyLayoutTranslationPanelNodeAndAnimateAppearance = false
|
||||
var translationPanelHeight: CGFloat?
|
||||
|
||||
var hasTranslationPanel = false
|
||||
if let _ = self.chatPresentationInterfaceState.translationState {
|
||||
if case .overlay = self.chatPresentationInterfaceState.mode {
|
||||
} else if self.chatPresentationInterfaceState.renderedPeer?.peer?.restrictionText(platform: "ios", contentSettings: self.context.currentContentSettings.with { $0 }) != nil {
|
||||
} else if self.chatPresentationInterfaceState.search != nil {
|
||||
} else {
|
||||
hasTranslationPanel = true
|
||||
}
|
||||
}
|
||||
if hasTranslationPanel {
|
||||
let translationPanelNode: ChatTranslationPanelNode
|
||||
if let current = self.chatTranslationPanel {
|
||||
translationPanelNode = current
|
||||
|
@ -1295,6 +1295,11 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
var translateToLanguage: String?
|
||||
if let translationState, isPremium && translationState.isEnabled {
|
||||
translateToLanguage = translationState.toLang ?? presentationData.strings.baseLanguageCode
|
||||
if translateToLanguage == "nb" {
|
||||
translateToLanguage = "nl"
|
||||
} else if translateToLanguage == "pt-br" {
|
||||
translateToLanguage = "pt"
|
||||
}
|
||||
}
|
||||
|
||||
let associatedData = extractAssociatedData(chatLocation: chatLocation, view: view, automaticDownloadNetworkType: networkType, animatedEmojiStickers: animatedEmojiStickers, additionalAnimatedEmojiStickers: additionalAnimatedEmojiStickers, subject: subject, currentlyPlayingMessageId: currentlyPlayingMessageId, isCopyProtectionEnabled: isCopyProtectionEnabled, availableReactions: availableReactions, defaultReaction: defaultReaction, isPremium: isPremium, alwaysDisplayTranscribeButton: alwaysDisplayTranscribeButton, accountPeer: accountPeer, topicAuthorId: topicAuthorId, hasBots: chatHasBots, translateToLanguage: translateToLanguage)
|
||||
|
@ -635,8 +635,7 @@ class ChatMessageTextBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
guard let item = self.item else {
|
||||
return
|
||||
}
|
||||
let rects = self.textNode.textNode.rangeRects(in: NSRange(location: 0, length: self.textNode.textNode.cachedLayout?.attributedString?.length ?? 0))?.rects ?? []
|
||||
|
||||
let rects = self.textNode.textNode.rangeRects(in: NSRange(location: 0, length: self.textNode.textNode.cachedLayout?.attributedString?.length ?? 0))?.rects ?? []
|
||||
if isTranslating, !rects.isEmpty {
|
||||
let shimmeringNode: ShimmeringLinkNode
|
||||
if let current = self.shimmeringNode {
|
||||
|
@ -641,19 +641,7 @@ public func createChannelController(context: AccountContext, mode: CreateChannel
|
||||
guard let imageCompletion, let videoCompletion else {
|
||||
return
|
||||
}
|
||||
let peerType: AvatarEditorScreen.PeerType
|
||||
if case .legacyGroup = peer {
|
||||
peerType = .group
|
||||
} else if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
peerType = channel.flags.contains(.isForum) ? .forum : .group
|
||||
} else {
|
||||
peerType = .channel
|
||||
}
|
||||
} else {
|
||||
peerType = .user
|
||||
}
|
||||
let controller = AvatarEditorScreen(context: context, inputData: keyboardInputData.get(), peerType: peerType, markup: nil)
|
||||
let controller = AvatarEditorScreen(context: context, inputData: keyboardInputData.get(), peerType: .channel, markup: nil)
|
||||
controller.imageCompletion = imageCompletion
|
||||
controller.videoCompletion = videoCompletion
|
||||
pushControllerImpl?(controller)
|
||||
|
@ -965,19 +965,7 @@ public func createGroupControllerImpl(context: AccountContext, peerIds: [PeerId]
|
||||
guard let imageCompletion, let videoCompletion else {
|
||||
return
|
||||
}
|
||||
let peerType: AvatarEditorScreen.PeerType
|
||||
if case .legacyGroup = peer {
|
||||
peerType = .group
|
||||
} else if case let .channel(channel) = peer {
|
||||
if case .group = channel.info {
|
||||
peerType = channel.flags.contains(.isForum) ? .forum : .group
|
||||
} else {
|
||||
peerType = .channel
|
||||
}
|
||||
} else {
|
||||
peerType = .user
|
||||
}
|
||||
let controller = AvatarEditorScreen(context: context, inputData: keyboardInputData.get(), peerType: peerType, markup: nil)
|
||||
let controller = AvatarEditorScreen(context: context, inputData: keyboardInputData.get(), peerType: .group, markup: nil)
|
||||
controller.imageCompletion = imageCompletion
|
||||
controller.videoCompletion = videoCompletion
|
||||
pushImpl?(controller)
|
||||
|
@ -311,7 +311,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate {
|
||||
self.clipsToBounds = true
|
||||
|
||||
self.textFieldNode.textField.delegate = self
|
||||
self.textFieldNode.textField.addTarget(self, action: #selector(textFieldChanged(_:)), for: .editingChanged)
|
||||
self.textFieldNode.textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged)
|
||||
self.textFieldNode.textField.didDeleteBackwardWhileEmpty = { [weak self] in
|
||||
if let strongSelf = self {
|
||||
if let selectedTokenId = strongSelf.selectedTokenId {
|
||||
@ -518,7 +518,7 @@ final class EditableTokenListNode: ASDisplayNode, UITextFieldDelegate {
|
||||
for tokenNode in self.tokenNodes {
|
||||
let convertedPoint = self.view.convert(point, to: tokenNode.view)
|
||||
if tokenNode.bounds.contains(convertedPoint) {
|
||||
if tokenNode.isSelected && convertedPoint.x < 24.0 {
|
||||
if tokenNode.isSelected {
|
||||
self.deleteToken?(tokenNode.token.id)
|
||||
} else {
|
||||
self.updateSelectedTokenId(tokenNode.token.id, animated: true)
|
||||
|
@ -8,7 +8,7 @@ public struct MediaInputSettings: Codable, Equatable {
|
||||
public let pauseMusicOnRecording: Bool
|
||||
|
||||
public static var defaultSettings: MediaInputSettings {
|
||||
return MediaInputSettings(enableRaiseToSpeak: true, pauseMusicOnRecording: true)
|
||||
return MediaInputSettings(enableRaiseToSpeak: true, pauseMusicOnRecording: false)
|
||||
}
|
||||
|
||||
public init(enableRaiseToSpeak: Bool, pauseMusicOnRecording: Bool) {
|
||||
@ -20,7 +20,7 @@ public struct MediaInputSettings: Codable, Equatable {
|
||||
let container = try decoder.container(keyedBy: StringCodingKey.self)
|
||||
|
||||
self.enableRaiseToSpeak = (try container.decode(Int32.self, forKey: "enableRaiseToSpeak")) != 0
|
||||
self.pauseMusicOnRecording = (try container.decode(Int32.self, forKey: "pauseMusicOnRecording")) != 0
|
||||
self.pauseMusicOnRecording = (try container.decodeIfPresent(Int32.self, forKey: "pauseMusicOnRecording") ?? 0) != 0
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
|
@ -148,6 +148,9 @@ public func translateMessageIds(context: AccountContext, messageIds: [EngineMess
|
||||
}
|
||||
|
||||
public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id) -> Signal<ChatTranslationState?, NoError> {
|
||||
if peerId.id == PeerId.Id._internalFromInt64Value(777000) {
|
||||
return .single(nil)
|
||||
}
|
||||
if #available(iOS 12.0, *) {
|
||||
let baseLang = context.sharedContext.currentPresentationData.with { $0 }.strings.baseLanguageCode
|
||||
return context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.translationSettings])
|
||||
@ -160,8 +163,10 @@ public func chatTranslationState(context: AccountContext, peerId: EnginePeer.Id)
|
||||
var dontTranslateLanguages = Set<String>()
|
||||
if let ignoredLanguages = settings.ignoredLanguages {
|
||||
dontTranslateLanguages = Set(ignoredLanguages)
|
||||
} else {
|
||||
dontTranslateLanguages.insert(baseLang)
|
||||
dontTranslateLanguages.insert(systemLanguageCode())
|
||||
}
|
||||
dontTranslateLanguages.insert(baseLang)
|
||||
|
||||
return cachedChatTranslationState(engine: context.engine, peerId: peerId)
|
||||
|> mapToSignal { cached in
|
||||
|
@ -178,3 +178,11 @@ public func canTranslateText(context: AccountContext, text: String, showTranslat
|
||||
return (false, nil)
|
||||
}
|
||||
}
|
||||
|
||||
public func systemLanguageCode() -> String {
|
||||
if let systemLanguage = Locale.preferredLanguages.first {
|
||||
let language = systemLanguage.components(separatedBy: "-").first ?? systemLanguage
|
||||
return language
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@ -1001,11 +1001,16 @@ public class TranslateScreen: ViewController {
|
||||
}
|
||||
|
||||
var toLanguage = toLanguage ?? baseLanguageCode
|
||||
|
||||
if toLanguage == fromLanguage {
|
||||
toLanguage = "en"
|
||||
}
|
||||
|
||||
if toLanguage == "nb" {
|
||||
toLanguage = "nl"
|
||||
} else if toLanguage == "pt-br" {
|
||||
toLanguage = "pt"
|
||||
}
|
||||
|
||||
var copyTranslationImpl: ((String) -> Void)?
|
||||
var changeLanguageImpl: ((String, String, @escaping (String, String) -> Void) -> Void)?
|
||||
var expandImpl: (() -> Void)?
|
||||
|
Loading…
x
Reference in New Issue
Block a user