mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Various fixes
This commit is contained in:
parent
b1ca18df4e
commit
6000760416
@ -8844,3 +8844,5 @@ Sorry for the inconvenience.";
|
|||||||
"EmojiInput.TrendingEmoji" = "TRENDING EMOJI";
|
"EmojiInput.TrendingEmoji" = "TRENDING EMOJI";
|
||||||
|
|
||||||
"Chat.PlaceholderTextNotAllowed" = "Text not allowed";
|
"Chat.PlaceholderTextNotAllowed" = "Text not allowed";
|
||||||
|
|
||||||
|
"CallList.DeleteAll" = "Delete All";
|
||||||
|
@ -39,7 +39,7 @@ private final class DeleteAllButtonNode: ASDisplayNode {
|
|||||||
self.buttonNode.addSubnode(self.titleNode)
|
self.buttonNode.addSubnode(self.titleNode)
|
||||||
self.contentNode.contentNode.addSubnode(self.buttonNode)
|
self.contentNode.contentNode.addSubnode(self.buttonNode)
|
||||||
|
|
||||||
self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.Notification_Exceptions_DeleteAll, font: Font.regular(17.0), textColor: presentationData.theme.rootController.navigationBar.accentTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: presentationData.strings.CallList_DeleteAll, font: Font.regular(17.0), textColor: presentationData.theme.rootController.navigationBar.accentTextColor)
|
||||||
|
|
||||||
//self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
//self.buttonNode.addTarget(self, action: #selector(self.buttonPressed), forControlEvents: .touchUpInside)
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ private final class LegacyComponentsGlobalsProviderImpl: NSObject, LegacyCompone
|
|||||||
switch type {
|
switch type {
|
||||||
case TGAudioSessionTypePlayAndRecord, TGAudioSessionTypePlayAndRecordHeadphones:
|
case TGAudioSessionTypePlayAndRecord, TGAudioSessionTypePlayAndRecordHeadphones:
|
||||||
if legacyContext.sharedContext.currentMediaInputSettings.with({ $0 }).pauseMusicOnRecording {
|
if legacyContext.sharedContext.currentMediaInputSettings.with({ $0 }).pauseMusicOnRecording {
|
||||||
convertedType = .record(speaker: false)
|
convertedType = .record(speaker: false, withOthers: false)
|
||||||
} else {
|
} else {
|
||||||
convertedType = .recordWithOthers
|
convertedType = .recordWithOthers
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,8 @@ private final class PremiumGiftScreenContentComponent: CombinedComponent {
|
|||||||
UIColor(rgb: 0x5A6EEE),
|
UIColor(rgb: 0x5A6EEE),
|
||||||
UIColor(rgb: 0x548DFF),
|
UIColor(rgb: 0x548DFF),
|
||||||
UIColor(rgb: 0x54A3FF),
|
UIColor(rgb: 0x54A3FF),
|
||||||
UIColor(rgb: 0x54bdff)
|
UIColor(rgb: 0x54bdff),
|
||||||
|
UIColor(rgb: 0x71c8ff)
|
||||||
]
|
]
|
||||||
|
|
||||||
i = 0
|
i = 0
|
||||||
|
@ -18,7 +18,7 @@ public enum ManagedAudioSessionType: Equatable {
|
|||||||
case ambient
|
case ambient
|
||||||
case play
|
case play
|
||||||
case playWithPossiblePortOverride
|
case playWithPossiblePortOverride
|
||||||
case record(speaker: Bool)
|
case record(speaker: Bool, withOthers: Bool)
|
||||||
case voiceCall
|
case voiceCall
|
||||||
case videoCall
|
case videoCall
|
||||||
case recordWithOthers
|
case recordWithOthers
|
||||||
@ -587,7 +587,14 @@ public final class ManagedAudioSession {
|
|||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
let lastIsRecordWithOthers = self.holders.last?.audioSessionType == .recordWithOthers
|
var lastIsRecordWithOthers = false
|
||||||
|
if let lastHolder = self.holders.last {
|
||||||
|
if case let .record(_, withOthers) = lastHolder.audioSessionType {
|
||||||
|
lastIsRecordWithOthers = withOthers
|
||||||
|
} else if case .recordWithOthers = lastHolder.audioSessionType {
|
||||||
|
lastIsRecordWithOthers = true
|
||||||
|
}
|
||||||
|
}
|
||||||
if !deactivating {
|
if !deactivating {
|
||||||
if let activeIndex = activeIndex {
|
if let activeIndex = activeIndex {
|
||||||
var deactivate = false
|
var deactivate = false
|
||||||
@ -896,13 +903,13 @@ public final class ManagedAudioSession {
|
|||||||
|
|
||||||
if resetToBuiltin {
|
if resetToBuiltin {
|
||||||
var updatedType = type
|
var updatedType = type
|
||||||
if case .record(false) = updatedType, self.isHeadsetPluggedInValue {
|
if case .record(false, let withOthers) = updatedType, self.isHeadsetPluggedInValue {
|
||||||
updatedType = .record(speaker: true)
|
updatedType = .record(speaker: true, withOthers: withOthers)
|
||||||
}
|
}
|
||||||
switch updatedType {
|
switch updatedType {
|
||||||
case .record(false):
|
case .record(false, _):
|
||||||
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
|
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
|
||||||
case .voiceCall, .playWithPossiblePortOverride, .record(true):
|
case .voiceCall, .playWithPossiblePortOverride, .record(true, _):
|
||||||
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
|
try AVAudioSession.sharedInstance().overrideOutputAudioPort(.none)
|
||||||
if let routes = AVAudioSession.sharedInstance().availableInputs {
|
if let routes = AVAudioSession.sharedInstance().availableInputs {
|
||||||
var alreadySet = false
|
var alreadySet = false
|
||||||
|
@ -356,11 +356,11 @@ public extension TelegramEngine {
|
|||||||
return EngineMessageReactionListContext(account: self.account, message: message, reaction: reaction)
|
return EngineMessageReactionListContext(account: self.account, message: message, reaction: reaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func translate(text: String, toLang: String) -> Signal<String?, NoError> {
|
public func translate(text: String, toLang: String) -> Signal<String?, TranslationError> {
|
||||||
return _internal_translate(network: self.account.network, text: text, toLang: toLang)
|
return _internal_translate(network: self.account.network, text: text, toLang: toLang)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func translateMessages(messageIds: [EngineMessage.Id], toLang: String) -> Signal<Void, NoError> {
|
public func translateMessages(messageIds: [EngineMessage.Id], toLang: String) -> Signal<Void, TranslationError> {
|
||||||
return _internal_translateMessages(account: self.account, messageIds: messageIds, toLang: toLang)
|
return _internal_translateMessages(account: self.account, messageIds: messageIds, toLang: toLang)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,19 +4,36 @@ import SwiftSignalKit
|
|||||||
import TelegramApi
|
import TelegramApi
|
||||||
import MtProtoKit
|
import MtProtoKit
|
||||||
|
|
||||||
func _internal_translate(network: Network, text: String, toLang: String) -> Signal<String?, NoError> {
|
public enum TranslationError {
|
||||||
|
case generic
|
||||||
|
case invalidMessageId
|
||||||
|
case textIsEmpty
|
||||||
|
case textTooLong
|
||||||
|
case invalidLanguage
|
||||||
|
case limitExceeded
|
||||||
|
}
|
||||||
|
|
||||||
|
func _internal_translate(network: Network, text: String, toLang: String) -> Signal<String?, TranslationError> {
|
||||||
var flags: Int32 = 0
|
var flags: Int32 = 0
|
||||||
flags |= (1 << 1)
|
flags |= (1 << 1)
|
||||||
|
|
||||||
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(text: text, entities: [])], toLang: toLang))
|
return network.request(Api.functions.messages.translateText(flags: flags, peer: nil, id: nil, text: [.textWithEntities(text: text, entities: [])], toLang: toLang))
|
||||||
|> map(Optional.init)
|
|> mapError { error -> TranslationError in
|
||||||
|> `catch` { _ -> Signal<Api.messages.TranslatedText?, NoError> in
|
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||||
return .single(nil)
|
return .limitExceeded
|
||||||
}
|
} else if error.errorDescription == "MSG_ID_INVALID" {
|
||||||
|> mapToSignal { result -> Signal<String?, NoError> in
|
return .invalidMessageId
|
||||||
guard let result = result else {
|
} else if error.errorDescription == "INPUT_TEXT_EMPTY" {
|
||||||
return .complete()
|
return .textIsEmpty
|
||||||
|
} else if error.errorDescription == "INPUT_TEXT_TOO_LONG" {
|
||||||
|
return .textTooLong
|
||||||
|
} else if error.errorDescription == "TO_LANG_INVALID" {
|
||||||
|
return .invalidLanguage
|
||||||
|
} else {
|
||||||
|
return .generic
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|> mapToSignal { result -> Signal<String?, TranslationError> in
|
||||||
switch result {
|
switch result {
|
||||||
case let .translateResult(results):
|
case let .translateResult(results):
|
||||||
if case let .textWithEntities(text, _) = results.first {
|
if case let .textWithEntities(text, _) = results.first {
|
||||||
@ -28,14 +45,15 @@ func _internal_translate(network: Network, text: String, toLang: String) -> Sign
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func _internal_translateMessages(account: Account, messageIds: [EngineMessage.Id], toLang: String) -> Signal<Void, NoError> {
|
func _internal_translateMessages(account: Account, messageIds: [EngineMessage.Id], toLang: String) -> Signal<Void, TranslationError> {
|
||||||
guard let peerId = messageIds.first?.peerId else {
|
guard let peerId = messageIds.first?.peerId else {
|
||||||
return .never()
|
return .never()
|
||||||
}
|
}
|
||||||
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
return account.postbox.transaction { transaction -> Api.InputPeer? in
|
||||||
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
return transaction.getPeer(peerId).flatMap(apiInputPeer)
|
||||||
}
|
}
|
||||||
|> mapToSignal { inputPeer -> Signal<Void, NoError> in
|
|> castError(TranslationError.self)
|
||||||
|
|> mapToSignal { inputPeer -> Signal<Void, TranslationError> in
|
||||||
guard let inputPeer = inputPeer else {
|
guard let inputPeer = inputPeer else {
|
||||||
return .never()
|
return .never()
|
||||||
}
|
}
|
||||||
@ -45,12 +63,23 @@ func _internal_translateMessages(account: Account, messageIds: [EngineMessage.Id
|
|||||||
|
|
||||||
let id: [Int32] = messageIds.map { $0.id }
|
let id: [Int32] = messageIds.map { $0.id }
|
||||||
return account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: toLang))
|
return account.network.request(Api.functions.messages.translateText(flags: flags, peer: inputPeer, id: id, text: nil, toLang: toLang))
|
||||||
|> map(Optional.init)
|
|> mapError { error -> TranslationError in
|
||||||
|> `catch` { _ -> Signal<Api.messages.TranslatedText?, NoError> in
|
if error.errorDescription.hasPrefix("FLOOD_WAIT") {
|
||||||
return .single(nil)
|
return .limitExceeded
|
||||||
|
} else if error.errorDescription == "MSG_ID_INVALID" {
|
||||||
|
return .invalidMessageId
|
||||||
|
} else if error.errorDescription == "INPUT_TEXT_EMPTY" {
|
||||||
|
return .textIsEmpty
|
||||||
|
} else if error.errorDescription == "INPUT_TEXT_TOO_LONG" {
|
||||||
|
return .textTooLong
|
||||||
|
} else if error.errorDescription == "TO_LANG_INVALID" {
|
||||||
|
return .invalidLanguage
|
||||||
|
} else {
|
||||||
|
return .generic
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|> mapToSignal { result -> Signal<Void, NoError> in
|
|> mapToSignal { result -> Signal<Void, TranslationError> in
|
||||||
guard let result = result, case let .translateResult(results) = result else {
|
guard case let .translateResult(results) = result else {
|
||||||
return .complete()
|
return .complete()
|
||||||
}
|
}
|
||||||
return account.postbox.transaction { transaction in
|
return account.postbox.transaction { transaction in
|
||||||
@ -71,6 +100,7 @@ func _internal_translateMessages(account: Account, messageIds: [EngineMessage.Id
|
|||||||
index += 1
|
index += 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|> castError(TranslationError.self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,25 @@ enum AvatarBackground: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isLight: Bool {
|
||||||
|
switch self {
|
||||||
|
case let .gradient(colors):
|
||||||
|
if colors.count == 1 {
|
||||||
|
return UIColor(rgb: colors.first!).lightness > 0.99
|
||||||
|
} else if colors.count == 2 {
|
||||||
|
return UIColor(rgb: colors.first!).lightness > 0.99 || UIColor(rgb: colors.last!).lightness > 0.99
|
||||||
|
} else {
|
||||||
|
var lightCount = 0
|
||||||
|
for color in colors {
|
||||||
|
if UIColor(rgb: color).lightness > 0.99 {
|
||||||
|
lightCount += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lightCount >= 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func generateImage(size: CGSize) -> UIImage {
|
func generateImage(size: CGSize) -> UIImage {
|
||||||
switch self {
|
switch self {
|
||||||
case let .gradient(colors):
|
case let .gradient(colors):
|
||||||
@ -313,31 +332,28 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let hasPremium = context.engine.data.subscribe(TelegramEngine.EngineData.Item.Peer.Peer(id: context.account.peerId))
|
|
||||||
|> map { peer -> Bool in
|
|
||||||
guard case let .user(user) = peer else {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return user.isPremium
|
|
||||||
}
|
|
||||||
|> distinctUntilChanged
|
|
||||||
|
|
||||||
let resultSignal = signal
|
let resultSignal = signal
|
||||||
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
|> mapToSignal { keywords -> Signal<[EmojiPagerContentComponent.ItemGroup], NoError> in
|
||||||
return combineLatest(
|
return combineLatest(
|
||||||
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000),
|
context.account.postbox.itemCollectionsView(orderedItemListCollectionIds: [], namespaces: [Namespaces.ItemCollection.CloudEmojiPacks], aroundIndex: nil, count: 10000000) |> take(1),
|
||||||
context.engine.stickers.availableReactions(),
|
combineLatest(keywords.map { context.engine.stickers.searchStickers(query: $0.emoticons)
|
||||||
hasPremium
|
|> map { items -> [FoundStickerItem] in
|
||||||
|
return items.items
|
||||||
|
}
|
||||||
|
})
|
||||||
)
|
)
|
||||||
|> take(1)
|
|> map { view, stickers -> [EmojiPagerContentComponent.ItemGroup] in
|
||||||
|> map { view, availableReactions, hasPremium -> [EmojiPagerContentComponent.ItemGroup] in
|
let hasPremium = true
|
||||||
var result: [(String, TelegramMediaFile?, String)] = []
|
|
||||||
|
|
||||||
|
var emoji: [(String, TelegramMediaFile?, String)] = []
|
||||||
|
|
||||||
|
var existingEmoticons = Set<String>()
|
||||||
var allEmoticons: [String: String] = [:]
|
var allEmoticons: [String: String] = [:]
|
||||||
for keyword in keywords {
|
for keyword in keywords {
|
||||||
for emoticon in keyword.emoticons {
|
for emoticon in keyword.emoticons {
|
||||||
allEmoticons[emoticon] = keyword.keyword
|
allEmoticons[emoticon] = keyword.keyword
|
||||||
|
existingEmoticons.insert(emoticon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,9 +366,9 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
case let .CustomEmoji(_, _, alt, _):
|
case let .CustomEmoji(_, _, alt, _):
|
||||||
if !item.file.isPremiumEmoji || hasPremium {
|
if !item.file.isPremiumEmoji || hasPremium {
|
||||||
if !alt.isEmpty, let keyword = allEmoticons[alt] {
|
if !alt.isEmpty, let keyword = allEmoticons[alt] {
|
||||||
result.append((alt, item.file, keyword))
|
emoji.append((alt, item.file, keyword))
|
||||||
} else if alt == query {
|
} else if alt == query {
|
||||||
result.append((alt, item.file, alt))
|
emoji.append((alt, item.file, alt))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
@ -361,10 +377,10 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var items: [EmojiPagerContentComponent.Item] = []
|
var emojiItems: [EmojiPagerContentComponent.Item] = []
|
||||||
|
|
||||||
var existingIds = Set<MediaId>()
|
var existingIds = Set<MediaId>()
|
||||||
for item in result {
|
for item in emoji {
|
||||||
if let itemFile = item.1 {
|
if let itemFile = item.1 {
|
||||||
if existingIds.contains(itemFile.fileId) {
|
if existingIds.contains(itemFile.fileId) {
|
||||||
continue
|
continue
|
||||||
@ -378,25 +394,71 @@ final class AvatarEditorScreenComponent: Component {
|
|||||||
icon: .none,
|
icon: .none,
|
||||||
tintMode: animationData.isTemplate ? .primary : .none
|
tintMode: animationData.isTemplate ? .primary : .none
|
||||||
)
|
)
|
||||||
items.append(item)
|
emojiItems.append(item)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return [EmojiPagerContentComponent.ItemGroup(
|
var stickerItems: [EmojiPagerContentComponent.Item] = []
|
||||||
supergroupId: "search",
|
for stickerResult in stickers {
|
||||||
groupId: "search",
|
for sticker in stickerResult {
|
||||||
title: nil,
|
if existingIds.contains(sticker.file.fileId) {
|
||||||
subtitle: nil,
|
continue
|
||||||
actionButtonTitle: nil,
|
}
|
||||||
isFeatured: false,
|
|
||||||
isPremiumLocked: false,
|
existingIds.insert(sticker.file.fileId)
|
||||||
isEmbedded: false,
|
let animationData = EntityKeyboardAnimationData(file: sticker.file)
|
||||||
hasClear: false,
|
let item = EmojiPagerContentComponent.Item(
|
||||||
collapsedLineCount: nil,
|
animationData: animationData,
|
||||||
displayPremiumBadges: false,
|
content: .animation(animationData),
|
||||||
headerItem: nil,
|
itemFile: sticker.file,
|
||||||
items: items
|
subgroupId: nil,
|
||||||
)]
|
icon: .none,
|
||||||
|
tintMode: .none
|
||||||
|
)
|
||||||
|
stickerItems.append(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result: [EmojiPagerContentComponent.ItemGroup] = []
|
||||||
|
if !emojiItems.isEmpty {
|
||||||
|
result.append(
|
||||||
|
EmojiPagerContentComponent.ItemGroup(
|
||||||
|
supergroupId: "search",
|
||||||
|
groupId: "emoji",
|
||||||
|
title: "Emoji",
|
||||||
|
subtitle: nil,
|
||||||
|
actionButtonTitle: nil,
|
||||||
|
isFeatured: false,
|
||||||
|
isPremiumLocked: false,
|
||||||
|
isEmbedded: false,
|
||||||
|
hasClear: false,
|
||||||
|
collapsedLineCount: nil,
|
||||||
|
displayPremiumBadges: false,
|
||||||
|
headerItem: nil,
|
||||||
|
items: emojiItems
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if !stickerItems.isEmpty {
|
||||||
|
result.append(
|
||||||
|
EmojiPagerContentComponent.ItemGroup(
|
||||||
|
supergroupId: "search",
|
||||||
|
groupId: "stickers",
|
||||||
|
title: "Stickers",
|
||||||
|
subtitle: nil,
|
||||||
|
actionButtonTitle: nil,
|
||||||
|
isFeatured: false,
|
||||||
|
isPremiumLocked: false,
|
||||||
|
isEmbedded: false,
|
||||||
|
hasClear: false,
|
||||||
|
collapsedLineCount: nil,
|
||||||
|
displayPremiumBadges: false,
|
||||||
|
headerItem: nil,
|
||||||
|
items: stickerItems
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,10 +395,10 @@ final class ManagedAudioRecorderContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let _ = self.audioUnit.swap(audioUnit)
|
let _ = self.audioUnit.swap(audioUnit)
|
||||||
|
|
||||||
if self.audioSessionDisposable == nil {
|
if self.audioSessionDisposable == nil {
|
||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
self.audioSessionDisposable = self.mediaManager.audioSession.push(audioSessionType: .record(speaker: self.beginWithTone), activate: { [weak self] state in
|
self.audioSessionDisposable = self.mediaManager.audioSession.push(audioSessionType: .record(speaker: self.beginWithTone, withOthers: false), activate: { [weak self] state in
|
||||||
queue.async {
|
queue.async {
|
||||||
if let strongSelf = self, !strongSelf.paused {
|
if let strongSelf = self, !strongSelf.paused {
|
||||||
strongSelf.hasAudioSession = true
|
strongSelf.hasAudioSession = true
|
||||||
|
@ -44,8 +44,6 @@ private struct GlobalControlOptions: OptionSet {
|
|||||||
static let seek = GlobalControlOptions(rawValue: 1 << 5)
|
static let seek = GlobalControlOptions(rawValue: 1 << 5)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var test: Double?
|
|
||||||
|
|
||||||
public final class MediaManagerImpl: NSObject, MediaManager {
|
public final class MediaManagerImpl: NSObject, MediaManager {
|
||||||
public static var globalAudioSession: ManagedAudioSession {
|
public static var globalAudioSession: ManagedAudioSession {
|
||||||
return sharedAudioSession
|
return sharedAudioSession
|
||||||
|
@ -144,6 +144,9 @@ public func translateMessageIds(context: AccountContext, messageIds: [EngineMess
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return context.engine.messages.translateMessages(messageIds: messageIdsToTranslate, toLang: toLang)
|
return context.engine.messages.translateMessages(messageIds: messageIdsToTranslate, toLang: toLang)
|
||||||
|
|> `catch` { _ -> Signal<Void, NoError> in
|
||||||
|
return .complete()
|
||||||
|
}
|
||||||
} |> switchToLatest
|
} |> switchToLatest
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user