mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Merge commit 'f6ff9b86d0e76184cdc047b8d3856ce0aefe545b'
# Conflicts: # submodules/TelegramUI/Sources/ChatController.swift
This commit is contained in:
commit
bc5e989351
@ -8911,8 +8911,9 @@ Sorry for the inconvenience.";
|
||||
|
||||
"ChatList.EmptyChatListWithArchive" = "All of your chats are archived.";
|
||||
|
||||
"Conversation.AudioRateTooltip15X" = "Audio will play at 1.5X speed.";
|
||||
"Conversation.AudioRateTooltip15X" = "Audio will play at 1.5x speed.";
|
||||
"Conversation.AudioRateOptionsTooltip" = "Long tap for more speed values.";
|
||||
"Conversation.AudioRateTooltipCustom" = "Audio will play at %@x speed.";
|
||||
|
||||
"ImportStickerPack.EmojiCount_1" = "%@ Emoji";
|
||||
"ImportStickerPack.EmojiCount_any" = "%@ Emojis";
|
||||
@ -8936,3 +8937,5 @@ Sorry for the inconvenience.";
|
||||
"ChatList.ReadAll" = "Read All";
|
||||
|
||||
"ChatList.ClearSavedMessagesConfirmation" = "Are you sure you want to delete all your saved messages?";
|
||||
|
||||
"Conversation.Translation.Settings" = "Settings";
|
||||
|
@ -751,6 +751,7 @@ public protocol SharedAccountContext: AnyObject {
|
||||
var immediateExperimentalUISettings: ExperimentalUISettings { get }
|
||||
var currentInAppNotificationSettings: Atomic<InAppNotificationSettings> { get }
|
||||
var currentMediaInputSettings: Atomic<MediaInputSettings> { get }
|
||||
var currentStickerSettings: Atomic<StickerSettings> { get }
|
||||
|
||||
var energyUsageSettings: EnergyUsageSettings { get }
|
||||
|
||||
|
@ -2715,7 +2715,7 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
strongSelf.context.sharedContext.mediaManager.setPlaylist(nil, type: type, control: SharedMediaPlayerControlAction.playback(.pause))
|
||||
}
|
||||
}
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, fromMenu in
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, changeType in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -2756,10 +2756,25 @@ final class ChatListSearchListPaneNode: ASDisplayNode, ChatListSearchPaneNode {
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipSpeedUp
|
||||
rate = 2.0
|
||||
} else {
|
||||
text = nil
|
||||
rate = nil
|
||||
let value = String(format: "%0.1f", baseRate.doubleValue)
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipCustom(value).string
|
||||
if case let .sliderCommit(previousValue, newValue) = changeType {
|
||||
if newValue > previousValue {
|
||||
rate = .infinity
|
||||
} else if newValue < previousValue {
|
||||
rate = -.infinity
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
}
|
||||
if let rate, let text, !fromMenu {
|
||||
var showTooltip = true
|
||||
if case .sliderChange = changeType {
|
||||
showTooltip = false
|
||||
}
|
||||
if let rate, let text, showTooltip {
|
||||
controller.present(
|
||||
UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
|
@ -615,16 +615,8 @@ final class ChatImageGalleryItemNode: ZoomableContentGalleryItemNode {
|
||||
|
||||
func setFile(context: AccountContext, userLocation: MediaResourceUserLocation, fileReference: FileMediaReference) {
|
||||
if self.contextAndMedia == nil || !self.contextAndMedia!.1.media.isEqual(to: fileReference.media) {
|
||||
if var largestSize = fileReference.media.dimensions {
|
||||
var displaySize = largestSize.cgSize.dividedByScreenScale()
|
||||
if let previewDimensions = largestImageRepresentation(fileReference.media.previewRepresentations)?.dimensions {
|
||||
let previewAspect = CGFloat(previewDimensions.width) / CGFloat(previewDimensions.height)
|
||||
let aspect = displaySize.width / displaySize.height
|
||||
if abs(previewAspect - 1.0 / aspect) < 0.1 {
|
||||
displaySize = CGSize(width: displaySize.height, height: displaySize.width)
|
||||
largestSize = PixelDimensions(width: largestSize.height, height: largestSize.width)
|
||||
}
|
||||
}
|
||||
if let largestSize = fileReference.media.dimensions {
|
||||
let displaySize = largestSize.cgSize.dividedByScreenScale()
|
||||
self.imageNode.asyncLayout()(TransformImageArguments(corners: ImageCorners(), imageSize: displaySize, boundingSize: displaySize, intrinsicInsets: UIEdgeInsets()))()
|
||||
|
||||
/*if largestSize.width > 2600 || largestSize.height > 2600 {
|
||||
|
@ -1904,19 +1904,23 @@ public func channelVisibilityController(context: AccountContext, updatedPresenta
|
||||
|
||||
}
|
||||
|
||||
_ = (ApplicationSpecificNotice.getSetPublicChannelLink(accountManager: context.sharedContext.accountManager) |> deliverOnMainQueue).start(next: { showAlert in
|
||||
if showAlert {
|
||||
let text: String
|
||||
if case .broadcast = peer.info {
|
||||
text = presentationData.strings.Channel_Edit_PrivatePublicLinkAlert
|
||||
if !updatedAddressNameValue.isEmpty {
|
||||
_ = (ApplicationSpecificNotice.getSetPublicChannelLink(accountManager: context.sharedContext.accountManager) |> deliverOnMainQueue).start(next: { showAlert in
|
||||
if showAlert {
|
||||
let text: String
|
||||
if case .broadcast = peer.info {
|
||||
text = presentationData.strings.Channel_Edit_PrivatePublicLinkAlert
|
||||
} else {
|
||||
text = presentationData.strings.Group_Edit_PrivatePublicLinkAlert
|
||||
}
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: invokeAction)]), nil)
|
||||
} else {
|
||||
text = presentationData.strings.Group_Edit_PrivatePublicLinkAlert
|
||||
invokeAction()
|
||||
}
|
||||
presentControllerImpl?(textAlertController(context: context, updatedPresentationData: updatedPresentationData, title: nil, text: text, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_Cancel, action: {}), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_OK, action: invokeAction)]), nil)
|
||||
} else {
|
||||
invokeAction()
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
invokeAction()
|
||||
}
|
||||
} else {
|
||||
switch mode {
|
||||
case .initialSetup:
|
||||
|
@ -465,8 +465,15 @@ final class LocalizationListControllerNode: ViewControllerTracingNode {
|
||||
if let languages = translationSettings.ignoredLanguages {
|
||||
ignoredLanguages = languages
|
||||
} else {
|
||||
if let activeLanguage = activeLanguageCode, supportedTranslationLanguages.contains(activeLanguage) {
|
||||
ignoredLanguages = [activeLanguage]
|
||||
|
||||
if var activeLanguage = activeLanguageCode {
|
||||
let rawSuffix = "-raw"
|
||||
if activeLanguage.hasSuffix(rawSuffix) {
|
||||
activeLanguage = String(activeLanguage.dropLast(rawSuffix.count))
|
||||
}
|
||||
if supportedTranslationLanguages.contains(activeLanguage) {
|
||||
ignoredLanguages = [activeLanguage]
|
||||
}
|
||||
}
|
||||
let systemLanguages = systemLanguageCodes()
|
||||
for systemLanguage in systemLanguages {
|
||||
|
@ -77,13 +77,17 @@ private func translationSettingsControllerEntries(theme: PresentationTheme, stri
|
||||
if let ignoredLanguages = settings.ignoredLanguages {
|
||||
selectedLanguages = Set(ignoredLanguages)
|
||||
} else {
|
||||
var langCode = strings.baseLanguageCode
|
||||
if langCode == "nb" {
|
||||
langCode = "no"
|
||||
} else if langCode == "pt-br" {
|
||||
langCode = "pt"
|
||||
var activeLanguage = strings.baseLanguageCode
|
||||
let rawSuffix = "-raw"
|
||||
if activeLanguage.hasSuffix(rawSuffix) {
|
||||
activeLanguage = String(activeLanguage.dropLast(rawSuffix.count))
|
||||
}
|
||||
selectedLanguages = Set([langCode])
|
||||
if activeLanguage == "nb" {
|
||||
activeLanguage = "no"
|
||||
} else if activeLanguage == "pt-br" {
|
||||
activeLanguage = "pt"
|
||||
}
|
||||
selectedLanguages = Set([activeLanguage])
|
||||
for language in systemLanguageCodes() {
|
||||
selectedLanguages.insert(language)
|
||||
}
|
||||
@ -114,7 +118,11 @@ public func translationSettingsController(context: AccountContext) -> ViewContro
|
||||
let actionsDisposable = DisposableSet()
|
||||
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
let interfaceLanguageCode = presentationData.strings.baseLanguageCode
|
||||
var interfaceLanguageCode = presentationData.strings.baseLanguageCode
|
||||
let rawSuffix = "-raw"
|
||||
if interfaceLanguageCode.hasSuffix(rawSuffix) {
|
||||
interfaceLanguageCode = String(interfaceLanguageCode.dropLast(rawSuffix.count))
|
||||
}
|
||||
|
||||
let arguments = TranslationSettingsControllerArguments(context: context, updateLanguageSelected: { code, value in
|
||||
let _ = updateTranslationSettingsInteractively(accountManager: context.sharedContext.accountManager, { current in
|
||||
@ -185,7 +193,12 @@ public func translationSettingsController(context: AccountContext) -> ViewContro
|
||||
if let ignoredLanguages = settings.ignoredLanguages {
|
||||
selectedLanguages = Set(ignoredLanguages)
|
||||
} else {
|
||||
selectedLanguages = Set([presentationData.strings.baseLanguageCode])
|
||||
var activeLanguage = presentationData.strings.baseLanguageCode
|
||||
let rawSuffix = "-raw"
|
||||
if activeLanguage.hasSuffix(rawSuffix) {
|
||||
activeLanguage = String(activeLanguage.dropLast(rawSuffix.count))
|
||||
}
|
||||
selectedLanguages = Set([activeLanguage])
|
||||
for language in systemLanguageCodes() {
|
||||
selectedLanguages.insert(language)
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
|
||||
public var tapAction: (() -> Void)?
|
||||
public var close: (() -> Void)?
|
||||
public var setRate: ((AudioPlaybackRate, Bool) -> Void)?
|
||||
public var setRate: ((AudioPlaybackRate, MediaNavigationAccessoryPanel.ChangeType) -> Void)?
|
||||
public var togglePlayPause: (() -> Void)?
|
||||
public var playPrevious: (() -> Void)?
|
||||
public var playNext: (() -> Void)?
|
||||
@ -500,7 +500,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
} else {
|
||||
nextRate = .x2
|
||||
}
|
||||
self.setRate?(nextRate, false)
|
||||
self.setRate?(nextRate, .preset)
|
||||
|
||||
let frame = self.rateButton.view.convert(self.rateButton.bounds, to: nil)
|
||||
|
||||
@ -527,8 +527,10 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
private func contextMenuSpeedItems(dismiss: @escaping () -> Void) -> Signal<[ContextMenuItem], NoError> {
|
||||
var items: [ContextMenuItem] = []
|
||||
|
||||
items.append(.custom(SliderContextItem(minValue: 0.5, maxValue: 2.5, value: self.playbackBaseRate?.doubleValue ?? 1.0, valueChanged: { [weak self] newValue, finished in
|
||||
self?.setRate?(AudioPlaybackRate(newValue), true)
|
||||
let previousValue = self.playbackBaseRate?.doubleValue ?? 1.0
|
||||
items.append(.custom(SliderContextItem(minValue: 0.5, maxValue: 2.5, value: previousValue, valueChanged: { [weak self] newValue, finished in
|
||||
let type: MediaNavigationAccessoryPanel.ChangeType = finished ? .sliderCommit(previousValue, newValue) : .sliderChange
|
||||
self?.setRate?(AudioPlaybackRate(newValue), type)
|
||||
if finished {
|
||||
dismiss()
|
||||
}
|
||||
@ -547,7 +549,7 @@ public final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollVi
|
||||
}, action: { [weak self] _, f in
|
||||
f(.default)
|
||||
|
||||
self?.setRate?(rate, true)
|
||||
self?.setRate?(rate, .preset)
|
||||
})))
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,14 @@ import TelegramPresentationData
|
||||
public final class MediaNavigationAccessoryPanel: ASDisplayNode {
|
||||
public let containerNode: MediaNavigationAccessoryContainerNode
|
||||
|
||||
public enum ChangeType {
|
||||
case preset
|
||||
case sliderChange
|
||||
case sliderCommit(CGFloat, CGFloat)
|
||||
}
|
||||
|
||||
public var close: (() -> Void)?
|
||||
public var setRate: ((AudioPlaybackRate, Bool) -> Void)?
|
||||
public var setRate: ((AudioPlaybackRate, ChangeType) -> Void)?
|
||||
public var togglePlayPause: (() -> Void)?
|
||||
public var tapAction: (() -> Void)?
|
||||
public var playPrevious: (() -> Void)?
|
||||
@ -34,8 +40,8 @@ public final class MediaNavigationAccessoryPanel: ASDisplayNode {
|
||||
close()
|
||||
}
|
||||
}
|
||||
self.containerNode.headerNode.setRate = { [weak self] rate, fromMenu in
|
||||
self?.setRate?(rate, fromMenu)
|
||||
self.containerNode.headerNode.setRate = { [weak self] rate, type in
|
||||
self?.setRate?(rate, type)
|
||||
}
|
||||
self.containerNode.headerNode.togglePlayPause = { [weak self] in
|
||||
if let strongSelf = self, let togglePlayPause = strongSelf.togglePlayPause {
|
||||
|
@ -669,7 +669,7 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
strongSelf.context.sharedContext.mediaManager.setPlaylist(nil, type: type, control: SharedMediaPlayerControlAction.playback(.pause))
|
||||
}
|
||||
}
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, fromMenu in
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, changeType in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -709,10 +709,25 @@ open class TelegramBaseController: ViewController, KeyShortcutResponder {
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipSpeedUp
|
||||
rate = 2.0
|
||||
} else {
|
||||
text = nil
|
||||
rate = nil
|
||||
let value = String(format: "%0.1f", baseRate.doubleValue)
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipCustom(value).string
|
||||
if case let .sliderCommit(previousValue, newValue) = changeType {
|
||||
if newValue > previousValue {
|
||||
rate = .infinity
|
||||
} else if newValue < previousValue {
|
||||
rate = -.infinity
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
}
|
||||
if let rate, let text, !fromMenu {
|
||||
var showTooltip = true
|
||||
if case .sliderChange = changeType {
|
||||
showTooltip = false
|
||||
}
|
||||
if let rate, let text, showTooltip {
|
||||
strongSelf.present(
|
||||
UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
|
@ -218,15 +218,17 @@ public final class InitialPresentationDataAndSettings {
|
||||
public let callListSettings: CallListSettings
|
||||
public let inAppNotificationSettings: InAppNotificationSettings
|
||||
public let mediaInputSettings: MediaInputSettings
|
||||
public let stickerSettings: StickerSettings
|
||||
public let experimentalUISettings: ExperimentalUISettings
|
||||
|
||||
public init(presentationData: PresentationData, automaticMediaDownloadSettings: MediaAutoDownloadSettings, autodownloadSettings: AutodownloadSettings, callListSettings: CallListSettings, inAppNotificationSettings: InAppNotificationSettings, mediaInputSettings: MediaInputSettings, experimentalUISettings: ExperimentalUISettings) {
|
||||
public init(presentationData: PresentationData, automaticMediaDownloadSettings: MediaAutoDownloadSettings, autodownloadSettings: AutodownloadSettings, callListSettings: CallListSettings, inAppNotificationSettings: InAppNotificationSettings, mediaInputSettings: MediaInputSettings, stickerSettings: StickerSettings, experimentalUISettings: ExperimentalUISettings) {
|
||||
self.presentationData = presentationData
|
||||
self.automaticMediaDownloadSettings = automaticMediaDownloadSettings
|
||||
self.autodownloadSettings = autodownloadSettings
|
||||
self.callListSettings = callListSettings
|
||||
self.inAppNotificationSettings = inAppNotificationSettings
|
||||
self.mediaInputSettings = mediaInputSettings
|
||||
self.stickerSettings = stickerSettings
|
||||
self.experimentalUISettings = experimentalUISettings
|
||||
}
|
||||
}
|
||||
@ -242,6 +244,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
var mediaInputSettings: PreferencesEntry?
|
||||
var experimentalUISettings: PreferencesEntry?
|
||||
var contactSynchronizationSettings: PreferencesEntry?
|
||||
var stickerSettings: PreferencesEntry?
|
||||
|
||||
init(
|
||||
localizationSettings: PreferencesEntry?,
|
||||
@ -252,7 +255,8 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
inAppNotificationSettings: PreferencesEntry?,
|
||||
mediaInputSettings: PreferencesEntry?,
|
||||
experimentalUISettings: PreferencesEntry?,
|
||||
contactSynchronizationSettings: PreferencesEntry?
|
||||
contactSynchronizationSettings: PreferencesEntry?,
|
||||
stickerSettings: PreferencesEntry?
|
||||
) {
|
||||
self.localizationSettings = localizationSettings
|
||||
self.presentationThemeSettings = presentationThemeSettings
|
||||
@ -263,6 +267,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
self.mediaInputSettings = mediaInputSettings
|
||||
self.experimentalUISettings = experimentalUISettings
|
||||
self.contactSynchronizationSettings = contactSynchronizationSettings
|
||||
self.stickerSettings = stickerSettings
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,6 +281,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
let mediaInputSettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.mediaInputSettings)
|
||||
let experimentalUISettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.experimentalUISettings)
|
||||
let contactSynchronizationSettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.contactSynchronizationSettings)
|
||||
let stickerSettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.stickerSettings)
|
||||
|
||||
return InternalData(
|
||||
localizationSettings: localizationSettings,
|
||||
@ -286,7 +292,8 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
inAppNotificationSettings: inAppNotificationSettings,
|
||||
mediaInputSettings: mediaInputSettings,
|
||||
experimentalUISettings: experimentalUISettings,
|
||||
contactSynchronizationSettings: contactSynchronizationSettings
|
||||
contactSynchronizationSettings: contactSynchronizationSettings,
|
||||
stickerSettings: stickerSettings
|
||||
)
|
||||
}
|
||||
|> deliverOn(Queue(name: "PresentationData-Load", qos: .userInteractive))
|
||||
@ -340,6 +347,13 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
mediaInputSettings = MediaInputSettings.defaultSettings
|
||||
}
|
||||
|
||||
let stickerSettings: StickerSettings
|
||||
if let value = internalData.stickerSettings?.get(StickerSettings.self) {
|
||||
stickerSettings = value
|
||||
} else {
|
||||
stickerSettings = StickerSettings.defaultSettings
|
||||
}
|
||||
|
||||
let experimentalUISettings: ExperimentalUISettings = internalData.experimentalUISettings?.get(ExperimentalUISettings.self) ?? ExperimentalUISettings.defaultSettings
|
||||
|
||||
let contactSettings: ContactSynchronizationSettings = internalData.contactSynchronizationSettings?.get(ContactSynchronizationSettings.self) ?? ContactSynchronizationSettings.defaultSettings
|
||||
@ -385,7 +399,7 @@ public func currentPresentationDataAndSettings(accountManager: AccountManager<Te
|
||||
|
||||
let chatBubbleCorners = PresentationChatBubbleCorners(mainRadius: CGFloat(themeSettings.chatBubbleSettings.mainRadius), auxiliaryRadius: CGFloat(themeSettings.chatBubbleSettings.auxiliaryRadius), mergeBubbleCorners: themeSettings.chatBubbleSettings.mergeBubbleCorners)
|
||||
|
||||
return InitialPresentationDataAndSettings(presentationData: PresentationData(strings: stringsValue, theme: theme, autoNightModeTriggered: autoNightModeTriggered, chatWallpaper: effectiveChatWallpaper, chatFontSize: chatFontSize, chatBubbleCorners: chatBubbleCorners, listsFontSize: listsFontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, reduceMotion: themeSettings.reduceMotion, largeEmoji: themeSettings.largeEmoji), automaticMediaDownloadSettings: automaticMediaDownloadSettings, autodownloadSettings: autodownloadSettings, callListSettings: callListSettings, inAppNotificationSettings: inAppNotificationSettings, mediaInputSettings: mediaInputSettings, experimentalUISettings: experimentalUISettings)
|
||||
return InitialPresentationDataAndSettings(presentationData: PresentationData(strings: stringsValue, theme: theme, autoNightModeTriggered: autoNightModeTriggered, chatWallpaper: effectiveChatWallpaper, chatFontSize: chatFontSize, chatBubbleCorners: chatBubbleCorners, listsFontSize: listsFontSize, dateTimeFormat: dateTimeFormat, nameDisplayOrder: nameDisplayOrder, nameSortOrder: nameSortOrder, reduceMotion: themeSettings.reduceMotion, largeEmoji: themeSettings.largeEmoji), automaticMediaDownloadSettings: automaticMediaDownloadSettings, autodownloadSettings: autodownloadSettings, callListSettings: callListSettings, inAppNotificationSettings: inAppNotificationSettings, mediaInputSettings: mediaInputSettings, stickerSettings: stickerSettings, experimentalUISettings: experimentalUISettings)
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -4255,6 +4255,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
}
|
||||
if case .user = peerType {
|
||||
let _ = context.engine.peers.sendBotRequestedPeer(messageId: messageId, buttonId: buttonId, requestedPeerId: peer.id).start()
|
||||
controller?.dismiss()
|
||||
} else {
|
||||
var isChannel = false
|
||||
if let channel = peer as? TelegramChannel, case .broadcast = channel.info {
|
||||
@ -10117,7 +10118,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
let locale = Locale(identifier: languageCode)
|
||||
let fromLanguage: String = locale.localizedString(forLanguageCode: langCode) ?? ""
|
||||
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/Translate"), color: .white)!, title: nil, text: presentationData.strings.Conversation_Translation_AddedToDoNotTranslateText(fromLanguage).string, round: false, undoText: "Settings"), elevatedLayout: false, animateInAsReplacement: false, action: { [weak self] action in
|
||||
strongSelf.present(UndoOverlayController(presentationData: presentationData, content: .image(image: generateTintedImage(image: UIImage(bundleImageName: "Chat/Title Panels/Translate"), color: .white)!, title: nil, text: presentationData.strings.Conversation_Translation_AddedToDoNotTranslateText(fromLanguage).string, round: false, undoText: presentationData.strings.Conversation_Translation_Settings), elevatedLayout: false, animateInAsReplacement: false, action: { [weak self] action in
|
||||
if case .undo = action, let strongSelf = self {
|
||||
let controller = translationSettingsController(context: strongSelf.context)
|
||||
controller.navigationPresentation = .modal
|
||||
@ -15633,7 +15634,7 @@ public final class ChatControllerImpl: TelegramBaseController, ChatController, G
|
||||
self.dismiss()
|
||||
|
||||
let navigateToLocation: NavigateToChatControllerParams.Location
|
||||
if let threadId = messages.first?.threadId {
|
||||
if let message = messages.first, let threadId = message.threadId, threadId != 1 || (message.peers[message.id.peerId] as? TelegramChannel)?.flags.contains(.isForum) == true {
|
||||
navigateToLocation = .replyThread(ChatReplyThreadMessage(messageId: MessageId(peerId: peer.id, namespace: Namespaces.Message.Cloud, id: Int32(clamping: threadId)), channelMessageId: nil, isChannelPost: false, isForumPost: true, maxMessage: nil, maxReadIncomingMessageId: nil, maxReadOutgoingMessageId: nil, unreadCount: 0, initialFilledHoles: IndexSet(), initialAnchor: .automatic, isNotAvailable: false))
|
||||
} else {
|
||||
navigateToLocation = .peer(peer)
|
||||
|
@ -1114,9 +1114,8 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
}
|
||||
}
|
||||
|
||||
let isCopyProtected = chatPresentationInterfaceState.copyProtectionEnabled || message.isCopyProtected()
|
||||
if !messageText.isEmpty || (resourceAvailable && isImage) || diceEmoji != nil {
|
||||
let isCopyProtected = chatPresentationInterfaceState.copyProtectionEnabled || message.isCopyProtected()
|
||||
|
||||
if !isExpired {
|
||||
if !isPoll {
|
||||
if !isCopyProtected {
|
||||
@ -1223,35 +1222,35 @@ func contextMenuForChatPresentationInterfaceState(chatPresentationInterfaceState
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
if resourceAvailable, !message.containsSecretMedia, !chatPresentationInterfaceState.copyProtectionEnabled, !message.isCopyProtected() {
|
||||
var mediaReference: AnyMediaReference?
|
||||
var isVideo = false
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
|
||||
mediaReference = ImageMediaReference.standalone(media: image).abstract
|
||||
break
|
||||
} else if let file = media as? TelegramMediaFile, file.isVideo {
|
||||
mediaReference = FileMediaReference.standalone(media: file).abstract
|
||||
isVideo = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if let mediaReference = mediaReference {
|
||||
actions.append(.action(ContextMenuActionItem(text: isVideo ? chatPresentationInterfaceState.strings.Gallery_SaveVideo : chatPresentationInterfaceState.strings.Gallery_SaveImage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
let _ = (saveToCameraRoll(context: context, postbox: context.account.postbox, userLocation: .peer(message.id.peerId), mediaReference: mediaReference)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .mediaSaved(text: isVideo ? presentationData.strings.Gallery_VideoSaved : presentationData.strings.Gallery_ImageSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return true }), nil)
|
||||
}
|
||||
})
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
|
||||
if resourceAvailable, !message.containsSecretMedia && !isCopyProtected {
|
||||
var mediaReference: AnyMediaReference?
|
||||
var isVideo = false
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage, let _ = largestImageRepresentation(image.representations) {
|
||||
mediaReference = ImageMediaReference.standalone(media: image).abstract
|
||||
break
|
||||
} else if let file = media as? TelegramMediaFile, file.isVideo {
|
||||
mediaReference = FileMediaReference.standalone(media: file).abstract
|
||||
isVideo = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if let mediaReference = mediaReference {
|
||||
actions.append(.action(ContextMenuActionItem(text: isVideo ? chatPresentationInterfaceState.strings.Gallery_SaveVideo : chatPresentationInterfaceState.strings.Gallery_SaveImage, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Save"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
let _ = (saveToCameraRoll(context: context, postbox: context.account.postbox, userLocation: .peer(message.id.peerId), mediaReference: mediaReference)
|
||||
|> deliverOnMainQueue).start(completed: {
|
||||
Queue.mainQueue().after(0.2) {
|
||||
let presentationData = context.sharedContext.currentPresentationData.with { $0 }
|
||||
controllerInteraction.presentControllerInCurrent(UndoOverlayController(presentationData: presentationData, content: .mediaSaved(text: isVideo ? presentationData.strings.Gallery_VideoSaved : presentationData.strings.Gallery_ImageSaved), elevatedLayout: false, animateInAsReplacement: false, action: { _ in return true }), nil)
|
||||
}
|
||||
})
|
||||
f(.default)
|
||||
})))
|
||||
}
|
||||
}
|
||||
|
||||
var downloadableMediaResourceInfos: [String] = []
|
||||
|
@ -1034,7 +1034,10 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
|
||||
if item.associatedData.isCopyProtectionEnabled || item.message.isCopyProtected() {
|
||||
needsShareButton = false
|
||||
if hasCommentButton(item: item) {
|
||||
} else {
|
||||
needsShareButton = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,10 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
let textFixedFont = Font.regular(fontSize)
|
||||
let textBlockQuoteFont = Font.regular(fontSize)
|
||||
|
||||
let incoming = message.effectivelyIncoming(context.account.peerId)
|
||||
var incoming = message.effectivelyIncoming(context.account.peerId)
|
||||
if case .forwardedMessages = associatedData.subject {
|
||||
incoming = false
|
||||
}
|
||||
|
||||
var horizontalInsets = UIEdgeInsets(top: 0.0, left: 10.0, bottom: 0.0, right: 10.0)
|
||||
if displayLine {
|
||||
@ -517,7 +520,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
if !skipStandardStatus {
|
||||
if message.effectivelyIncoming(context.account.peerId) {
|
||||
if incoming {
|
||||
if isImage {
|
||||
imageStatusType = .ImageIncoming
|
||||
} else {
|
||||
@ -609,7 +612,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
let automaticDownload = shouldDownloadMediaAutomatically(settings: automaticDownloadSettings, peerType: associatedData.automaticDownloadPeerType, networkType: associatedData.automaticDownloadNetworkType, authorPeerId: message.author?.id, contactsPeerIds: associatedData.contactsPeerIds, media: file)
|
||||
|
||||
let statusType: ChatMessageDateAndStatusType
|
||||
if message.effectivelyIncoming(context.account.peerId) {
|
||||
if incoming {
|
||||
statusType = .BubbleIncoming
|
||||
} else {
|
||||
if message.flags.contains(.Failed) {
|
||||
@ -633,7 +636,7 @@ final class ChatMessageAttachedContentNode: ASDisplayNode {
|
||||
forcedIsEdited: false,
|
||||
file: file,
|
||||
automaticDownload: automaticDownload,
|
||||
incoming: message.effectivelyIncoming(context.account.peerId),
|
||||
incoming: incoming,
|
||||
isRecentActions: false,
|
||||
forcedResourceStatus: associatedData.forcedResourceStatus,
|
||||
dateAndStatusType: statusType,
|
||||
|
@ -53,7 +53,7 @@ private final class ChatMessageBubbleClippingNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
|
||||
private func hasCommentButton(item: ChatMessageItem) -> Bool {
|
||||
func hasCommentButton(item: ChatMessageItem) -> Bool {
|
||||
let firstMessage = item.content.firstMessage
|
||||
|
||||
var hasDiscussion = false
|
||||
@ -4541,6 +4541,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView, ChatMessagePreviewItemNode
|
||||
for contentNode in self.contentNodes {
|
||||
if let contentNode = contentNode as? ChatMessageFileBubbleContentNode {
|
||||
return contentNode.interactiveFileNode.hasExpandedAudioTranscription
|
||||
} else if let contentNode = contentNode as? ChatMessageInstantVideoBubbleContentNode {
|
||||
return contentNode.hasExpandedAudioTranscription
|
||||
}
|
||||
}
|
||||
return false
|
||||
|
@ -88,10 +88,15 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
var selectedContact: TelegramMediaContact?
|
||||
for media in item.message.media {
|
||||
if let media = media as? TelegramMediaContact {
|
||||
selectedContact = media
|
||||
selectedContact = media;
|
||||
}
|
||||
}
|
||||
|
||||
var incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
if case .forwardedMessages = item.associatedData.subject {
|
||||
incoming = false
|
||||
}
|
||||
|
||||
var titleString: NSAttributedString?
|
||||
var textString: NSAttributedString?
|
||||
var updatedContactInfo: String?
|
||||
@ -149,8 +154,8 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
updatedContactInfo = info
|
||||
|
||||
titleString = NSAttributedString(string: displayName, font: titleFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor : item.presentationData.theme.theme.chat.message.outgoing.accentTextColor)
|
||||
textString = NSAttributedString(string: info, font: textFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
titleString = NSAttributedString(string: displayName, font: titleFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.accentTextColor : item.presentationData.theme.theme.chat.message.outgoing.accentTextColor)
|
||||
textString = NSAttributedString(string: info, font: textFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
} else {
|
||||
updatedContactInfo = nil
|
||||
}
|
||||
@ -193,7 +198,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
let statusType: ChatMessageDateAndStatusType?
|
||||
switch position {
|
||||
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
if incoming {
|
||||
statusType = .BubbleIncoming
|
||||
} else {
|
||||
if item.message.flags.contains(.Failed) {
|
||||
@ -242,7 +247,7 @@ class ChatMessageContactBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
let titleColor: UIColor
|
||||
let titleHighlightedColor: UIColor
|
||||
let avatarPlaceholderColor: UIColor
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
if incoming {
|
||||
buttonImage = PresentationResourcesChat.chatMessageAttachedContentButtonIncoming(item.presentationData.theme.theme)!
|
||||
buttonHighlightedImage = PresentationResourcesChat.chatMessageAttachedContentHighlightedButtonIncoming(item.presentationData.theme.theme)!
|
||||
titleColor = item.presentationData.theme.theme.chat.message.incoming.accentTextColor
|
||||
|
@ -102,7 +102,10 @@ class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
let incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
var incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
if case .forwardedMessages = item.associatedData.subject {
|
||||
incoming = false
|
||||
}
|
||||
let statusType: ChatMessageDateAndStatusType?
|
||||
switch preparePosition {
|
||||
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
||||
@ -135,7 +138,7 @@ class ChatMessageFileBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
forcedIsEdited: item.isItemEdited,
|
||||
file: selectedFile!,
|
||||
automaticDownload: automaticDownload,
|
||||
incoming: item.message.effectivelyIncoming(item.context.account.peerId),
|
||||
incoming: incoming,
|
||||
isRecentActions: item.associatedData.isRecentActions,
|
||||
forcedResourceStatus: item.associatedData.forcedResourceStatus,
|
||||
dateAndStatusType: statusType,
|
||||
|
@ -23,6 +23,14 @@ class ChatMessageInstantVideoBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
|
||||
private var audioTranscriptionState: AudioTranscriptionButtonComponent.TranscriptionState = .collapsed
|
||||
|
||||
var hasExpandedAudioTranscription: Bool {
|
||||
if case .expanded = self.audioTranscriptionState {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
override var visibility: ListViewItemNodeVisibility {
|
||||
didSet {
|
||||
var wasVisible = false
|
||||
|
@ -88,6 +88,11 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
|
||||
var incoming = item.message.effectivelyIncoming(item.context.account.peerId)
|
||||
if case .forwardedMessages = item.associatedData.subject {
|
||||
incoming = false
|
||||
}
|
||||
|
||||
let bubbleInsets: UIEdgeInsets
|
||||
if case .color = item.presentationData.theme.wallpaper {
|
||||
bubbleInsets = UIEdgeInsets()
|
||||
@ -106,12 +111,12 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
imageSize = CGSize(width: fitWidth, height: floor(fitWidth * 0.5))
|
||||
|
||||
if let venue = selectedMedia.venue {
|
||||
titleString = NSAttributedString(string: venue.title, font: titleFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
titleString = NSAttributedString(string: venue.title, font: titleFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
if let address = venue.address, !address.isEmpty {
|
||||
textString = NSAttributedString(string: address, font: textFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor)
|
||||
textString = NSAttributedString(string: address, font: textFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor)
|
||||
}
|
||||
} else {
|
||||
textString = NSAttributedString(string: " ", font: textFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor)
|
||||
textString = NSAttributedString(string: " ", font: textFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor)
|
||||
}
|
||||
} else {
|
||||
let fitWidth: CGFloat = min(constrainedSize.width, layoutConstants.image.maxDimensions.width)
|
||||
@ -120,7 +125,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
|
||||
if selectedMedia.liveBroadcastingTimeout != nil {
|
||||
titleString = NSAttributedString(string: item.presentationData.strings.Message_LiveLocation, font: liveTitleFont, textColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
titleString = NSAttributedString(string: item.presentationData.strings.Message_LiveLocation, font: liveTitleFont, textColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.primaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.primaryTextColor)
|
||||
}
|
||||
} else {
|
||||
imageSize = CGSize(width: 75.0, height: 75.0)
|
||||
@ -211,7 +216,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
switch position {
|
||||
case .linear(_, .None), .linear(_, .Neighbour(true, _, _)):
|
||||
if selectedMedia?.venue != nil || activeLiveBroadcastingTimeout != nil {
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
if incoming {
|
||||
statusType = .BubbleIncoming
|
||||
} else {
|
||||
if item.message.flags.contains(.Failed) {
|
||||
@ -223,7 +228,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if item.message.effectivelyIncoming(item.context.account.peerId) {
|
||||
if incoming {
|
||||
statusType = .ImageIncoming
|
||||
} else {
|
||||
if item.message.flags.contains(.Failed) {
|
||||
@ -283,7 +288,7 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
}
|
||||
|
||||
return (contentWidth, { boundingWidth in
|
||||
let arguments = TransformImageArguments(corners: imageCorners, imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor)
|
||||
let arguments = TransformImageArguments(corners: imageCorners, imageSize: imageSize, boundingSize: imageSize, intrinsicInsets: UIEdgeInsets(), emptyColor: incoming ? item.presentationData.theme.theme.chat.message.incoming.mediaPlaceholderColor : item.presentationData.theme.theme.chat.message.outgoing.mediaPlaceholderColor)
|
||||
|
||||
let imageLayoutSize = CGSize(width: imageSize.width + bubbleInsets.left + bubbleInsets.right, height: imageSize.height + bubbleInsets.top + bubbleInsets.bottom)
|
||||
|
||||
@ -379,8 +384,8 @@ class ChatMessageMapBubbleContentNode: ChatMessageBubbleContentNode {
|
||||
let timerSize = CGSize(width: 28.0, height: 28.0)
|
||||
strongSelf.liveTimerNode?.frame = CGRect(origin: CGPoint(x: floor(imageFrame.maxX - 10.0 - timerSize.width), y: floor(imageFrame.maxY + 11.0)), size: timerSize)
|
||||
|
||||
let timerForegroundColor: UIColor = item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.accentControlColor : item.presentationData.theme.theme.chat.message.outgoing.accentControlColor
|
||||
let timerTextColor: UIColor = item.message.effectivelyIncoming(item.context.account.peerId) ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor
|
||||
let timerForegroundColor: UIColor = incoming ? item.presentationData.theme.theme.chat.message.incoming.accentControlColor : item.presentationData.theme.theme.chat.message.outgoing.accentControlColor
|
||||
let timerTextColor: UIColor = incoming ? item.presentationData.theme.theme.chat.message.incoming.secondaryTextColor : item.presentationData.theme.theme.chat.message.outgoing.secondaryTextColor
|
||||
strongSelf.liveTimerNode?.update(backgroundColor: timerForegroundColor.withAlphaComponent(0.4), foregroundColor: timerForegroundColor, textColor: timerTextColor, beginTimestamp: Double(item.message.timestamp), timeout: Double(activeLiveBroadcastingTimeout), strings: item.presentationData.strings)
|
||||
|
||||
if strongSelf.liveTextNode == nil {
|
||||
|
@ -505,7 +505,10 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
|
||||
}
|
||||
|
||||
if item.associatedData.isCopyProtectionEnabled || item.message.isCopyProtected() {
|
||||
needsShareButton = false
|
||||
if hasCommentButton(item: item) {
|
||||
} else {
|
||||
needsShareButton = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -262,7 +262,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
strongSelf.context.sharedContext.mediaManager.setPlaylist(nil, type: type, control: SharedMediaPlayerControlAction.playback(.pause))
|
||||
}
|
||||
}
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, fromMenu in
|
||||
mediaAccessoryPanel.setRate = { [weak self] rate, changeType in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
@ -289,7 +289,7 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
|
||||
let presentationData = strongSelf.context.sharedContext.currentPresentationData.with { $0 }
|
||||
let text: String?
|
||||
let rate: CGFloat?
|
||||
@ -303,10 +303,25 @@ final class PeerInfoListPaneNode: ASDisplayNode, PeerInfoPaneNode {
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipSpeedUp
|
||||
rate = 2.0
|
||||
} else {
|
||||
text = nil
|
||||
rate = nil
|
||||
let value = String(format: "%0.1f", baseRate.doubleValue)
|
||||
text = presentationData.strings.Conversation_AudioRateTooltipCustom(value).string
|
||||
if case let .sliderCommit(previousValue, newValue) = changeType {
|
||||
if newValue > previousValue {
|
||||
rate = .infinity
|
||||
} else if newValue < previousValue {
|
||||
rate = -.infinity
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
} else {
|
||||
rate = nil
|
||||
}
|
||||
}
|
||||
if let rate, let text, !fromMenu {
|
||||
var showTooltip = true
|
||||
if case .sliderChange = changeType {
|
||||
showTooltip = false
|
||||
}
|
||||
if let rate, let text, showTooltip {
|
||||
controller.present(
|
||||
UndoOverlayController(
|
||||
presentationData: presentationData,
|
||||
|
@ -1112,7 +1112,7 @@ private func infoItems(data: PeerInfoScreenData?, context: AccountContext, prese
|
||||
}))
|
||||
}
|
||||
|
||||
if user.botInfo != nil, !user.isVerified {
|
||||
if user.botInfo != nil {
|
||||
items[.peerInfo]!.append(PeerInfoScreenActionItem(id: 6, text: presentationData.strings.ReportPeer_Report, action: {
|
||||
interaction.openReport(.default)
|
||||
}))
|
||||
|
@ -161,6 +161,9 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
public let currentMediaInputSettings: Atomic<MediaInputSettings>
|
||||
private var mediaInputSettingsDisposable: Disposable?
|
||||
|
||||
public let currentStickerSettings: Atomic<StickerSettings>
|
||||
private var stickerSettingsDisposable: Disposable?
|
||||
|
||||
private let automaticMediaDownloadSettingsDisposable = MetaDisposable()
|
||||
|
||||
private var immediateExperimentalUISettingsValue = Atomic<ExperimentalUISettings>(value: ExperimentalUISettings.defaultSettings)
|
||||
@ -237,6 +240,7 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
self.currentAutomaticMediaDownloadSettings = initialPresentationDataAndSettings.automaticMediaDownloadSettings
|
||||
self.currentAutodownloadSettings = Atomic(value: initialPresentationDataAndSettings.autodownloadSettings)
|
||||
self.currentMediaInputSettings = Atomic(value: initialPresentationDataAndSettings.mediaInputSettings)
|
||||
self.currentStickerSettings = Atomic(value: initialPresentationDataAndSettings.stickerSettings)
|
||||
self.currentInAppNotificationSettings = Atomic(value: initialPresentationDataAndSettings.inAppNotificationSettings)
|
||||
|
||||
if automaticEnergyUsageShouldBeOnNow(settings: self.currentAutomaticMediaDownloadSettings) {
|
||||
@ -354,6 +358,15 @@ public final class SharedAccountContextImpl: SharedAccountContext {
|
||||
}
|
||||
})
|
||||
|
||||
self.stickerSettingsDisposable = (self.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.stickerSettings])
|
||||
|> deliverOnMainQueue).start(next: { [weak self] sharedData in
|
||||
if let strongSelf = self {
|
||||
if let settings = sharedData.entries[ApplicationSpecificSharedDataKeys.stickerSettings]?.get(StickerSettings.self) {
|
||||
let _ = strongSelf.currentStickerSettings.swap(settings)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
let immediateExperimentalUISettingsValue = self.immediateExperimentalUISettingsValue
|
||||
let _ = immediateExperimentalUISettingsValue.swap(initialPresentationDataAndSettings.experimentalUISettings)
|
||||
self.experimentalUISettingsDisposable = (self.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.experimentalUISettings])
|
||||
|
@ -546,7 +546,11 @@ final class UndoOverlayControllerNode: ViewControllerTracingNode {
|
||||
self.iconCheckNode = nil
|
||||
|
||||
let animationName: String
|
||||
if rate == 1.5 {
|
||||
if rate == .infinity {
|
||||
animationName = "anim_voicefast"
|
||||
} else if rate == -.infinity {
|
||||
animationName = "anim_voiceslow"
|
||||
} else if rate == 1.5 {
|
||||
animationName = "anim_voice1_5x"
|
||||
} else if rate == 2.0 {
|
||||
animationName = "anim_voice2x"
|
||||
|
@ -962,7 +962,8 @@ public func resolveUrlImpl(context: AccountContext, peerId: PeerId?, url: String
|
||||
for scheme in schemes {
|
||||
let basePrefix = scheme + basePath + "/"
|
||||
var url = url
|
||||
if (url.lowercased().hasPrefix(scheme) && (url.lowercased().hasSuffix(".\(basePath)") || url.lowercased().contains(".\(basePath)/"))) {
|
||||
let lowercasedUrl = url.lowercased()
|
||||
if (lowercasedUrl.hasPrefix(scheme) && (lowercasedUrl.hasSuffix(".\(basePath)") || lowercasedUrl.contains(".\(basePath)/") || lowercasedUrl.contains(".\(basePath)?"))) {
|
||||
url = basePrefix + String(url[scheme.endIndex...]).replacingOccurrences(of: ".\(basePath)/", with: "").replacingOccurrences(of: ".\(basePath)", with: "")
|
||||
}
|
||||
if url.lowercased().hasPrefix(basePrefix) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user