mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-19 12:49:02 +00:00
Merge commit '4b0ee9a79ec9c3500cf1fb4d43dbd4689d2cbfae'
This commit is contained in:
commit
e72abb40a8
@ -2717,7 +2717,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, displayVideoUnmuteTip: { [weak self] location in
|
}, displayVideoUnmuteTip: { [weak self] location in
|
||||||
guard let strongSelf = self, let layout = strongSelf.validLayout else {
|
guard let strongSelf = self, let layout = strongSelf.validLayout, strongSelf.traceVisibility() && isTopmostChatController(strongSelf) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let deviceMetrics = DeviceMetrics.forScreenSize(layout.size)
|
let deviceMetrics = DeviceMetrics.forScreenSize(layout.size)
|
||||||
@ -2734,7 +2734,6 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
tooltipController.dismissed = { [weak tooltipController] in
|
tooltipController.dismissed = { [weak tooltipController] in
|
||||||
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.videoUnmuteTooltipController === tooltipController {
|
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.videoUnmuteTooltipController === tooltipController {
|
||||||
strongSelf.videoUnmuteTooltipController = nil
|
strongSelf.videoUnmuteTooltipController = nil
|
||||||
|
|
||||||
ApplicationSpecificNotice.setVolumeButtonToUnmute(accountManager: strongSelf.context.sharedContext.accountManager)
|
ApplicationSpecificNotice.setVolumeButtonToUnmute(accountManager: strongSelf.context.sharedContext.accountManager)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3266,7 +3265,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let shouldBeActive = combineLatest(MediaManager.globalAudioSession.isPlaybackActive(), self.chatDisplayNode.historyNode.hasVisiblePlayableItemNodes)
|
let shouldBeActive = combineLatest(MediaManager.globalAudioSession.isPlaybackActive() |> deliverOnMainQueue, self.chatDisplayNode.historyNode.hasVisiblePlayableItemNodes)
|
||||||
|> mapToSignal { [weak self] isPlaybackActive, hasVisiblePlayableItemNodes -> Signal<Bool, NoError> in
|
|> mapToSignal { [weak self] isPlaybackActive, hasVisiblePlayableItemNodes -> Signal<Bool, NoError> in
|
||||||
if hasVisiblePlayableItemNodes && !isPlaybackActive {
|
if hasVisiblePlayableItemNodes && !isPlaybackActive {
|
||||||
return Signal<Bool, NoError> { [weak self] subscriber in
|
return Signal<Bool, NoError> { [weak self] subscriber in
|
||||||
@ -3287,6 +3286,7 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
guard let strongSelf = self, strongSelf.traceVisibility() && isTopmostChatController(strongSelf) else {
|
guard let strongSelf = self, strongSelf.traceVisibility() && isTopmostChatController(strongSelf) else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
strongSelf.videoUnmuteTooltipController?.dismiss()
|
||||||
strongSelf.chatDisplayNode.playFirstMediaWithSound()
|
strongSelf.chatDisplayNode.playFirstMediaWithSound()
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -3506,6 +3506,9 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
|
override public func updateToInterfaceOrientation(_ orientation: UIInterfaceOrientation) {
|
||||||
|
guard let layout = self.validLayout, case .compact = layout.metrics.widthClass else {
|
||||||
|
return
|
||||||
|
}
|
||||||
let hasOverlayNodes = self.context.sharedContext.mediaManager.overlayMediaManager.controller?.hasNodes ?? false
|
let hasOverlayNodes = self.context.sharedContext.mediaManager.overlayMediaManager.controller?.hasNodes ?? false
|
||||||
if self.validLayout != nil && orientation.isLandscape && !hasOverlayNodes && self.traceVisibility() && isTopmostChatController(self) {
|
if self.validLayout != nil && orientation.isLandscape && !hasOverlayNodes && self.traceVisibility() && isTopmostChatController(self) {
|
||||||
self.chatDisplayNode.openCurrentPlayingWithSoundMedia()
|
self.chatDisplayNode.openCurrentPlayingWithSoundMedia()
|
||||||
|
|||||||
@ -413,9 +413,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
|
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
|
||||||
if display {
|
if display {
|
||||||
var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = []
|
var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = []
|
||||||
|
var skip = false
|
||||||
strongSelf.historyNode.forEachVisibleItemNode { itemNode in
|
strongSelf.historyNode.forEachVisibleItemNode { itemNode in
|
||||||
if let itemNode = itemNode as? ChatMessageItemView, let (_, _, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode {
|
if let itemNode = itemNode as? ChatMessageItemView, let (_, soundEnabled, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode {
|
||||||
if !isVideoMessage, case let .visible(fraction) = itemNode.visibility {
|
if soundEnabled {
|
||||||
|
skip = true
|
||||||
|
} else if !skip && !isVideoMessage, case let .visible(fraction) = itemNode.visibility {
|
||||||
nodes.insert((fraction, itemNode, node), at: 0)
|
nodes.insert((fraction, itemNode, node), at: 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1490,14 +1493,16 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
var hasUnconsumed = false
|
var hasUnconsumed = false
|
||||||
self.historyNode.forEachVisibleItemNode { itemNode in
|
self.historyNode.forEachVisibleItemNode { itemNode in
|
||||||
if let itemNode = itemNode as? ChatMessageItemView, let (action, _, _, isUnconsumed, _) = itemNode.playMediaWithSound() {
|
if let itemNode = itemNode as? ChatMessageItemView, let (action, _, _, isUnconsumed, _) = itemNode.playMediaWithSound() {
|
||||||
if case let .visible(fraction) = itemNode.visibility {
|
if case let .visible(fraction) = itemNode.visibility, fraction > 0.7 {
|
||||||
hasUnconsumed = isUnconsumed
|
|
||||||
actions.insert((fraction, isUnconsumed, action), at: 0)
|
actions.insert((fraction, isUnconsumed, action), at: 0)
|
||||||
|
if !hasUnconsumed && isUnconsumed {
|
||||||
|
hasUnconsumed = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (fraction, isUnconsumed, action) in actions {
|
for (_, isUnconsumed, action) in actions {
|
||||||
if fraction > 0.7 && (!hasUnconsumed || isUnconsumed) {
|
if (!hasUnconsumed || isUnconsumed) {
|
||||||
action()
|
action()
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -381,7 +381,16 @@ public class ChatListController: TelegramController, KeyShortcutResponder, UIVie
|
|||||||
guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else {
|
guard let strongSelf = self, let peer = peer, let chatPeer = peer.peers[peer.peerId], let mainPeer = peer.chatMainPeer else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let user = chatPeer as? TelegramUser, user.botInfo == nil {
|
|
||||||
|
var canRemoveGlobally = false
|
||||||
|
let limitsConfiguration = strongSelf.context.currentLimitsConfiguration.with { $0 }
|
||||||
|
if peer.peerId.namespace == Namespaces.Peer.CloudUser && peer.peerId != strongSelf.context.account.peerId {
|
||||||
|
if limitsConfiguration.maxMessageRevokeIntervalInPrivateChats == LimitsConfiguration.timeIntervalForever {
|
||||||
|
canRemoveGlobally = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let user = chatPeer as? TelegramUser, user.botInfo == nil, canRemoveGlobally {
|
||||||
strongSelf.maybeAskForPeerChatRemoval(peer: peer, completion: { _ in })
|
strongSelf.maybeAskForPeerChatRemoval(peer: peer, completion: { _ in })
|
||||||
} else {
|
} else {
|
||||||
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
|
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
|
||||||
|
|||||||
@ -89,7 +89,7 @@ class ChatListRecentPeersListItemNode: ListViewItemNode {
|
|||||||
let currentItem = self.item
|
let currentItem = self.item
|
||||||
|
|
||||||
return { [weak self] item, params, last in
|
return { [weak self] item, params, last in
|
||||||
let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 130.0), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0))
|
let nodeLayout = ListViewItemNodeLayout(contentSize: CGSize(width: params.width, height: 124.0), insets: UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 0.0))
|
||||||
|
|
||||||
return (nodeLayout, { [weak self] in
|
return (nodeLayout, { [weak self] in
|
||||||
var updatedTheme: PresentationTheme?
|
var updatedTheme: PresentationTheme?
|
||||||
|
|||||||
@ -184,7 +184,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
|||||||
badge = ContactsPeerItemBadge(count: peer.unreadCount, type: isMuted ? .inactive : .active)
|
badge = ContactsPeerItemBadge(count: peer.unreadCount, type: isMuted ? .inactive : .active)
|
||||||
}
|
}
|
||||||
|
|
||||||
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: context.account, peerMode: .generalSearch, peer: .peer(peer: primaryPeer, chatPeer: chatPeer), status: status, badge: badge, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: true, editing: false, revealed: hasRevealControls), index: nil, header: ChatListSearchItemHeader(type: .recentPeers, theme: theme, strings: strings, actionTitle: strings.WebSearch_RecentSectionClear.uppercased(), action: {
|
return ContactsPeerItem(theme: theme, strings: strings, sortOrder: nameSortOrder, displayOrder: nameDisplayOrder, account: context.account, peerMode: .generalSearch, peer: .peer(peer: primaryPeer, chatPeer: chatPeer), status: status, badge: badge, enabled: enabled, selection: .none, editing: ContactsPeerItemEditing(editable: true, editing: false, revealed: hasRevealControls), index: nil, header: ChatListSearchItemHeader(type: .recentPeers, theme: theme, strings: strings, actionTitle: strings.WebSearch_RecentSectionClear, action: {
|
||||||
clearRecentlySearchedPeers()
|
clearRecentlySearchedPeers()
|
||||||
}), action: { _ in
|
}), action: { _ in
|
||||||
if let chatPeer = peer.peer.peers[peer.peer.peerId] {
|
if let chatPeer = peer.peer.peers[peer.peer.peerId] {
|
||||||
|
|||||||
@ -22,7 +22,7 @@ final class ChatListSearchItemHeader: ListViewItemHeader {
|
|||||||
let actionTitle: String?
|
let actionTitle: String?
|
||||||
let action: (() -> Void)?
|
let action: (() -> Void)?
|
||||||
|
|
||||||
let height: CGFloat = 29.0
|
let height: CGFloat = 28.0
|
||||||
|
|
||||||
init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: (() -> Void)?) {
|
init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: (() -> Void)?) {
|
||||||
self.type = type
|
self.type = type
|
||||||
|
|||||||
@ -264,12 +264,12 @@ final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
override func calculateSizeThatFits(_ constrainedSize: CGSize) -> CGSize {
|
||||||
return CGSize(width: constrainedSize.width, height: 120.0)
|
return CGSize(width: constrainedSize.width, height: 114.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
|
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
|
||||||
self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 29.0))
|
self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 28.0))
|
||||||
self.sectionHeaderNode.updateLayout(size: CGSize(width: size.width, height: 29.0), leftInset: leftInset, rightInset: rightInset)
|
self.sectionHeaderNode.updateLayout(size: CGSize(width: size.width, height: 28.0), leftInset: leftInset, rightInset: rightInset)
|
||||||
|
|
||||||
var insets = UIEdgeInsets()
|
var insets = UIEdgeInsets()
|
||||||
insets.top += leftInset
|
insets.top += leftInset
|
||||||
@ -285,7 +285,7 @@ final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
|||||||
|
|
||||||
|
|
||||||
self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: 92.0, height: size.width)
|
self.listView.bounds = CGRect(x: 0.0, y: 0.0, width: 92.0, height: size.width)
|
||||||
self.listView.position = CGPoint(x: size.width / 2.0, y: 92.0 / 2.0 + 29.0)
|
self.listView.position = CGPoint(x: size.width / 2.0, y: 92.0 / 2.0 + 28.0)
|
||||||
self.listView.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: 92.0, height: size.width), insets: insets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
self.listView.transaction(deleteIndices: [], insertIndicesAndItems: [], updateIndicesAndItems: [], options: [.Synchronous], scrollToItem: nil, updateSizeAndInsets: ListViewUpdateSizeAndInsets(size: CGSize(width: 92.0, height: size.width), insets: insets, duration: 0.0, curve: .Default(duration: nil)), stationaryItemRange: nil, updateOpaqueState: nil, completion: { _ in })
|
||||||
self.itemCustomWidthValuePromise.set(itemCustomWidth)
|
self.itemCustomWidthValuePromise.set(itemCustomWidth)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -831,8 +831,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
||||||
forwardSource = currentForwardInfo.0
|
forwardSource = nil
|
||||||
forwardAuthorSignature = currentForwardInfo.1
|
forwardAuthorSignature = currentForwardInfo.0?.displayTitle
|
||||||
} else {
|
} else {
|
||||||
forwardSource = forwardInfo.author
|
forwardSource = forwardInfo.author
|
||||||
forwardAuthorSignature = forwardInfo.authorSignature
|
forwardAuthorSignature = forwardInfo.authorSignature
|
||||||
|
|||||||
@ -287,8 +287,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
||||||
forwardSource = currentForwardInfo.0
|
forwardSource = nil
|
||||||
forwardAuthorSignature = currentForwardInfo.1
|
forwardAuthorSignature = currentForwardInfo.0?.displayTitle
|
||||||
} else {
|
} else {
|
||||||
forwardSource = forwardInfo.author
|
forwardSource = forwardInfo.author
|
||||||
forwardAuthorSignature = forwardInfo.authorSignature
|
forwardAuthorSignature = forwardInfo.authorSignature
|
||||||
|
|||||||
@ -388,7 +388,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
updatedPlayerStatusSignal = videoNode.status
|
updatedPlayerStatusSignal = videoNode.status
|
||||||
|> mapToSignal { status -> Signal<MediaPlayerStatus?, NoError> in
|
|> mapToSignal { status -> Signal<MediaPlayerStatus?, NoError> in
|
||||||
if let status = status, case .buffering = status.status {
|
if let status = status, case .buffering = status.status {
|
||||||
return .single(status) |> delay(0.5, queue: Queue.mainQueue())
|
return .single(status) |> delay(0.75, queue: Queue.mainQueue())
|
||||||
} else {
|
} else {
|
||||||
return .single(status)
|
return .single(status)
|
||||||
}
|
}
|
||||||
@ -574,7 +574,11 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
state = .download(bubbleTheme.mediaOverlayControlForegroundColor)
|
state = .download(bubbleTheme.mediaOverlayControlForegroundColor)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if isBuffering ?? false {
|
var isLocal = false
|
||||||
|
if case .Local = status.fetchStatus {
|
||||||
|
isLocal = true
|
||||||
|
}
|
||||||
|
if (isBuffering ?? false) && !isLocal {
|
||||||
state = .progress(color: bubbleTheme.mediaOverlayControlForegroundColor, lineWidth: nil, value: nil, cancelEnabled: true)
|
state = .progress(color: bubbleTheme.mediaOverlayControlForegroundColor, lineWidth: nil, value: nil, cancelEnabled: true)
|
||||||
} else {
|
} else {
|
||||||
state = .none
|
state = .none
|
||||||
@ -747,11 +751,11 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
|
|
||||||
func playMediaWithSound() -> (action: () -> Void, soundEnabled: Bool, isVideoMessage: Bool, isUnread: Bool, badgeNode: ASDisplayNode?)? {
|
func playMediaWithSound() -> (action: () -> Void, soundEnabled: Bool, isVideoMessage: Bool, isUnread: Bool, badgeNode: ASDisplayNode?)? {
|
||||||
if let item = self.item {
|
if let item = self.item {
|
||||||
var notConsumed = false
|
var isUnconsumed = false
|
||||||
for attribute in item.message.attributes {
|
for attribute in item.message.attributes {
|
||||||
if let attribute = attribute as? ConsumableContentMessageAttribute {
|
if let attribute = attribute as? ConsumableContentMessageAttribute {
|
||||||
if !attribute.consumed {
|
if !attribute.consumed {
|
||||||
notConsumed = true
|
isUnconsumed = true
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
@ -778,7 +782,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}, false, true, !notConsumed, nil)
|
}, false, true, isUnconsumed, nil)
|
||||||
} else {
|
} else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,7 +84,6 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
private let titleNode: ImmediateTextNode
|
private let titleNode: ImmediateTextNode
|
||||||
private let titleLeftIconNode: ASImageNode
|
private let titleLeftIconNode: ASImageNode
|
||||||
private let titleRightIconNode: ASImageNode
|
private let titleRightIconNode: ASImageNode
|
||||||
|
|
||||||
private let activityNode: ChatTitleActivityNode
|
private let activityNode: ChatTitleActivityNode
|
||||||
|
|
||||||
private let button: HighlightTrackingButtonNode
|
private let button: HighlightTrackingButtonNode
|
||||||
@ -462,13 +461,21 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
if highlighted {
|
if highlighted {
|
||||||
strongSelf.titleNode.layer.removeAnimation(forKey: "opacity")
|
strongSelf.titleNode.layer.removeAnimation(forKey: "opacity")
|
||||||
strongSelf.activityNode.layer.removeAnimation(forKey: "opacity")
|
strongSelf.activityNode.layer.removeAnimation(forKey: "opacity")
|
||||||
|
strongSelf.titleLeftIconNode.layer.removeAnimation(forKey: "opacity")
|
||||||
|
strongSelf.titleRightIconNode.layer.removeAnimation(forKey: "opacity")
|
||||||
strongSelf.titleNode.alpha = 0.4
|
strongSelf.titleNode.alpha = 0.4
|
||||||
strongSelf.activityNode.alpha = 0.4
|
strongSelf.activityNode.alpha = 0.4
|
||||||
|
strongSelf.titleLeftIconNode.alpha = 0.4
|
||||||
|
strongSelf.titleRightIconNode.alpha = 0.4
|
||||||
} else {
|
} else {
|
||||||
strongSelf.titleNode.alpha = 1.0
|
strongSelf.titleNode.alpha = 1.0
|
||||||
strongSelf.activityNode.alpha = 1.0
|
strongSelf.activityNode.alpha = 1.0
|
||||||
|
strongSelf.titleLeftIconNode.alpha = 1.0
|
||||||
|
strongSelf.titleRightIconNode.alpha = 1.0
|
||||||
strongSelf.titleNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
strongSelf.titleNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||||
strongSelf.activityNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
strongSelf.activityNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||||
|
strongSelf.titleLeftIconNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||||
|
strongSelf.titleRightIconNode.layer.animateAlpha(from: 0.4, to: 1.0, duration: 0.2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -276,8 +276,10 @@ final class FFMpegMediaFrameSource: NSObject, MediaFrameSource {
|
|||||||
return MediaFrameSourceSeekResult(buffers: MediaPlaybackBuffers(audioBuffer: nil, videoBuffer: nil), extraDecodedVideoFrames: [], timestamp: timestamp)
|
return MediaFrameSourceSeekResult(buffers: MediaPlaybackBuffers(audioBuffer: nil, videoBuffer: nil), extraDecodedVideoFrames: [], timestamp: timestamp)
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
let _ = currentSemaphore.swap(nil)
|
||||||
subscriber.putCompletion()
|
subscriber.putCompletion()
|
||||||
} else {
|
} else {
|
||||||
|
let _ = currentSemaphore.swap(nil)
|
||||||
subscriber.putError(.generic)
|
subscriber.putError(.generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -84,7 +84,7 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
|||||||
}
|
}
|
||||||
if totalCount > maximumFetchSize {
|
if totalCount > maximumFetchSize {
|
||||||
context.readingError = true
|
context.readingError = true
|
||||||
return -1
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +111,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
|||||||
let _ = context.currentSemaphore.swap(nil)
|
let _ = context.currentSemaphore.swap(nil)
|
||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
if !completedRequest {
|
if !completedRequest {
|
||||||
return -1
|
context.readingError = true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -162,7 +163,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
|||||||
let _ = context.currentSemaphore.swap(nil)
|
let _ = context.currentSemaphore.swap(nil)
|
||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
if !completedRequest {
|
if !completedRequest {
|
||||||
return -1
|
context.readingError = true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -175,7 +177,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if context.closed {
|
if context.closed {
|
||||||
return -1
|
context.readingError = true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
return fetchedCount
|
return fetchedCount
|
||||||
}
|
}
|
||||||
@ -212,7 +215,8 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
|||||||
let _ = context.currentSemaphore.swap(nil)
|
let _ = context.currentSemaphore.swap(nil)
|
||||||
disposable.dispose()
|
disposable.dispose()
|
||||||
if !completedRequest {
|
if !completedRequest {
|
||||||
return -1
|
context.readingError = true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
resourceSize = resultSize
|
resourceSize = resultSize
|
||||||
}
|
}
|
||||||
@ -222,7 +226,7 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (whence & FFMPEG_AVSEEK_SIZE) != 0 {
|
if (whence & FFMPEG_AVSEEK_SIZE) != 0 {
|
||||||
result = Int64(resourceSize == Int(Int32.max - 1) ? -1 : resourceSize)
|
result = Int64(resourceSize == Int(Int32.max - 1) ? 0 : resourceSize)
|
||||||
} else {
|
} else {
|
||||||
context.readingOffset = Int(min(Int64(resourceSize), offset))
|
context.readingOffset = Int(min(Int64(resourceSize), offset))
|
||||||
|
|
||||||
@ -248,7 +252,8 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if context.closed {
|
if context.closed {
|
||||||
return -1
|
context.readingError = true
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@ -185,7 +185,11 @@ func readAlbumArtworkData(_ data: Data) -> ID3ArtworkResult {
|
|||||||
guard let value: UInt32 = stream.nextValue() else {
|
guard let value: UInt32 = stream.nextValue() else {
|
||||||
return .moreDataNeeded(tagSize)
|
return .moreDataNeeded(tagSize)
|
||||||
}
|
}
|
||||||
let frameSize = id3Tag.frameSize(Int32(CFSwapInt32HostToBig(value)))
|
let val = CFSwapInt32HostToBig(value)
|
||||||
|
if val > Int32.max {
|
||||||
|
return .notFound
|
||||||
|
}
|
||||||
|
let frameSize = id3Tag.frameSize(Int32(val))
|
||||||
let bytesLeft = frameSize - id3Tag.frameSizeOffset - 4
|
let bytesLeft = frameSize - id3Tag.frameSizeOffset - 4
|
||||||
|
|
||||||
if frameHeader == id3Tag.artworkHeader {
|
if frameHeader == id3Tag.artworkHeader {
|
||||||
@ -209,10 +213,11 @@ func readAlbumArtworkData(_ data: Data) -> ID3ArtworkResult {
|
|||||||
var data = Data(capacity: frameSize + 1024)
|
var data = Data(capacity: frameSize + 1024)
|
||||||
var previousByte: UInt8 = 0xff
|
var previousByte: UInt8 = 0xff
|
||||||
|
|
||||||
|
let limit = Int(Double(frameSize - offset) * 0.8)
|
||||||
for _ in 0 ..< frameSize - offset {
|
for _ in 0 ..< frameSize - offset {
|
||||||
if let byte: UInt8 = stream.nextValue() {
|
if let byte: UInt8 = stream.nextValue() {
|
||||||
data.append(byte)
|
data.append(byte)
|
||||||
if byte == 0xd9 && previousByte == 0xff {
|
if byte == 0xd9 && previousByte == 0xff && data.count > limit {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
previousByte = byte
|
previousByte = byte
|
||||||
|
|||||||
@ -2,6 +2,9 @@ import Foundation
|
|||||||
import AsyncDisplayKit
|
import AsyncDisplayKit
|
||||||
import Display
|
import Display
|
||||||
|
|
||||||
|
private let titleFont = Font.bold(13.0)
|
||||||
|
private let actionFont = Font.medium(13.0)
|
||||||
|
|
||||||
final class ListSectionHeaderNode: ASDisplayNode {
|
final class ListSectionHeaderNode: ASDisplayNode {
|
||||||
private let label: ImmediateTextNode
|
private let label: ImmediateTextNode
|
||||||
private var actionButton: HighlightableButtonNode?
|
private var actionButton: HighlightableButtonNode?
|
||||||
@ -11,7 +14,7 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
|
|
||||||
var title: String? {
|
var title: String? {
|
||||||
didSet {
|
didSet {
|
||||||
self.label.attributedText = NSAttributedString(string: self.title ?? "", font: Font.medium(12.0), textColor: self.theme.chatList.sectionHeaderTextColor)
|
self.label.attributedText = NSAttributedString(string: self.title ?? "", font: titleFont, textColor: self.theme.chatList.sectionHeaderTextColor)
|
||||||
|
|
||||||
if let (size, leftInset, rightInset) = self.validLayout {
|
if let (size, leftInset, rightInset) = self.validLayout {
|
||||||
self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset)
|
self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset)
|
||||||
@ -33,7 +36,7 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let action = self.action {
|
if let action = self.action {
|
||||||
self.actionButton?.setAttributedTitle(NSAttributedString(string: action, font: Font.medium(12.0), textColor: self.theme.chatList.sectionHeaderTextColor), for: [])
|
self.actionButton?.setAttributedTitle(NSAttributedString(string: action, font: actionFont, textColor: self.theme.chatList.sectionHeaderTextColor), for: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (size, leftInset, rightInset) = self.validLayout {
|
if let (size, leftInset, rightInset) = self.validLayout {
|
||||||
@ -61,11 +64,11 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
if self.theme !== theme {
|
if self.theme !== theme {
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
|
|
||||||
self.label.attributedText = NSAttributedString(string: self.title ?? "", font: Font.medium(12.0), textColor: self.theme.chatList.sectionHeaderTextColor)
|
self.label.attributedText = NSAttributedString(string: self.title ?? "", font: titleFont, textColor: self.theme.chatList.sectionHeaderTextColor)
|
||||||
|
|
||||||
self.backgroundColor = theme.chatList.sectionHeaderFillColor
|
self.backgroundColor = theme.chatList.sectionHeaderFillColor
|
||||||
if let action = self.action {
|
if let action = self.action {
|
||||||
self.actionButton?.setAttributedTitle(NSAttributedString(string: action, font: Font.medium(12.0), textColor: self.theme.chatList.sectionHeaderTextColor), for: [])
|
self.actionButton?.setAttributedTitle(NSAttributedString(string: action, font: actionFont, textColor: self.theme.chatList.sectionHeaderTextColor), for: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (size, leftInset, rightInset) = self.validLayout {
|
if let (size, leftInset, rightInset) = self.validLayout {
|
||||||
@ -77,11 +80,11 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
|||||||
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
|
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
|
||||||
self.validLayout = (size, leftInset, rightInset)
|
self.validLayout = (size, leftInset, rightInset)
|
||||||
let labelSize = self.label.updateLayout(CGSize(width: max(0.0, size.width - leftInset - rightInset - 18.0), height: size.height))
|
let labelSize = self.label.updateLayout(CGSize(width: max(0.0, size.width - leftInset - rightInset - 18.0), height: size.height))
|
||||||
self.label.frame = CGRect(origin: CGPoint(x: leftInset + 9.0, y: 7.0), size: labelSize)
|
self.label.frame = CGRect(origin: CGPoint(x: leftInset + 16.0, y: 6.0 + UIScreenPixel), size: labelSize)
|
||||||
|
|
||||||
if let actionButton = self.actionButton {
|
if let actionButton = self.actionButton {
|
||||||
let buttonSize = actionButton.measure(CGSize(width: size.width, height: size.height))
|
let buttonSize = actionButton.measure(CGSize(width: size.width, height: size.height))
|
||||||
actionButton.frame = CGRect(origin: CGPoint(x: size.width - rightInset - 9.0 - buttonSize.width, y: 7.0), size: buttonSize)
|
actionButton.frame = CGRect(origin: CGPoint(x: size.width - rightInset - 16.0 - buttonSize.width, y: 6.0 + UIScreenPixel), size: buttonSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -343,7 +343,7 @@ public final class ManagedAudioSession {
|
|||||||
let queue = self.queue
|
let queue = self.queue
|
||||||
return Signal { [weak self] subscriber in
|
return Signal { [weak self] subscriber in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
subscriber.putNext(strongSelf.currentTypeAndOutputMode?.0 == .play)
|
subscriber.putNext(strongSelf.currentTypeAndOutputMode?.0.isPlay ?? false)
|
||||||
|
|
||||||
let index = strongSelf.isPlaybackActiveSubscribers.add({ value in
|
let index = strongSelf.isPlaybackActiveSubscribers.add({ value in
|
||||||
subscriber.putNext(value)
|
subscriber.putNext(value)
|
||||||
@ -595,7 +595,7 @@ public final class ManagedAudioSession {
|
|||||||
self.deactivateTimer = nil
|
self.deactivateTimer = nil
|
||||||
|
|
||||||
let wasActive = self.currentTypeAndOutputMode != nil
|
let wasActive = self.currentTypeAndOutputMode != nil
|
||||||
let wasPlaybackActive = self.currentTypeAndOutputMode?.0 == .play
|
let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false
|
||||||
self.currentTypeAndOutputMode = nil
|
self.currentTypeAndOutputMode = nil
|
||||||
|
|
||||||
print("ManagedAudioSession setting active false")
|
print("ManagedAudioSession setting active false")
|
||||||
@ -624,7 +624,7 @@ public final class ManagedAudioSession {
|
|||||||
self.deactivateTimer = nil
|
self.deactivateTimer = nil
|
||||||
|
|
||||||
let wasActive = self.currentTypeAndOutputMode != nil
|
let wasActive = self.currentTypeAndOutputMode != nil
|
||||||
let wasPlaybackActive = self.currentTypeAndOutputMode?.0 == .play
|
let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false
|
||||||
|
|
||||||
if self.currentTypeAndOutputMode == nil || self.currentTypeAndOutputMode! != (type, outputMode) {
|
if self.currentTypeAndOutputMode == nil || self.currentTypeAndOutputMode! != (type, outputMode) {
|
||||||
self.currentTypeAndOutputMode = (type, outputMode)
|
self.currentTypeAndOutputMode = (type, outputMode)
|
||||||
|
|||||||
@ -380,9 +380,9 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
|||||||
|
|
||||||
private func updatePlayPauseButton(paused: Bool) {
|
private func updatePlayPauseButton(paused: Bool) {
|
||||||
if paused {
|
if paused {
|
||||||
self.playPauseButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Pause"), color: self.theme.list.itemPrimaryTextColor)
|
|
||||||
} else {
|
|
||||||
self.playPauseButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Play"), color: self.theme.list.itemPrimaryTextColor)
|
self.playPauseButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Play"), color: self.theme.list.itemPrimaryTextColor)
|
||||||
|
} else {
|
||||||
|
self.playPauseButton.icon = generateTintedImage(image: UIImage(bundleImageName: "GlobalMusicPlayer/Pause"), color: self.theme.list.itemPrimaryTextColor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -169,8 +169,8 @@ class PermissionInfoItemNode: ListViewItemNode {
|
|||||||
let currentItem = self.item
|
let currentItem = self.item
|
||||||
|
|
||||||
return { item, params, neighbors in
|
return { item, params, neighbors in
|
||||||
let leftInset: CGFloat = 16.0 + params.leftInset
|
let leftInset: CGFloat = 15.0 + params.leftInset
|
||||||
let rightInset: CGFloat = 16.0 + params.rightInset
|
let rightInset: CGFloat = 15.0 + params.rightInset
|
||||||
|
|
||||||
var updatedTheme: PresentationTheme?
|
var updatedTheme: PresentationTheme?
|
||||||
var updatedBadgeImage: UIImage?
|
var updatedBadgeImage: UIImage?
|
||||||
@ -296,11 +296,11 @@ class PermissionInfoItemNode: ListViewItemNode {
|
|||||||
strongSelf.closeButton.setImage(updatedCloseIcon, for: [])
|
strongSelf.closeButton.setImage(updatedCloseIcon, for: [])
|
||||||
}
|
}
|
||||||
|
|
||||||
strongSelf.badgeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 16.0), size: CGSize(width: badgeDiameter, height: badgeDiameter))
|
strongSelf.badgeNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 15.0), size: CGSize(width: badgeDiameter, height: badgeDiameter))
|
||||||
|
|
||||||
strongSelf.labelNode.frame = CGRect(origin: CGPoint(x: strongSelf.badgeNode.frame.midX - labelLayout.size.width / 2.0, y: strongSelf.badgeNode.frame.minY + 1.0), size: labelLayout.size)
|
strongSelf.labelNode.frame = CGRect(origin: CGPoint(x: strongSelf.badgeNode.frame.midX - labelLayout.size.width / 2.0, y: strongSelf.badgeNode.frame.minY + 1.0), size: labelLayout.size)
|
||||||
|
|
||||||
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: strongSelf.badgeNode.frame.maxX + 8.0, y: 16.0), size: titleLayout.size)
|
strongSelf.titleNode.frame = CGRect(origin: CGPoint(x: strongSelf.badgeNode.frame.maxX + 8.0, y: 15.0), size: titleLayout.size)
|
||||||
|
|
||||||
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + 9.0), size: textLayout.size)
|
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: leftInset, y: strongSelf.titleNode.frame.maxY + 9.0), size: textLayout.size)
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@ -473,7 +473,7 @@ class SearchBarNode: ASDisplayNode, UITextFieldDelegate {
|
|||||||
self.separatorNode.layer.animateFrame(from: initialSeparatorFrame, to: self.separatorNode.frame, duration: duration, timingFunction: timingFunction)
|
self.separatorNode.layer.animateFrame(from: initialSeparatorFrame, to: self.separatorNode.frame, duration: duration, timingFunction: timingFunction)
|
||||||
|
|
||||||
if let fromTextBackgroundColor = node.backgroundNode.backgroundColor, let toTextBackgroundColor = self.textBackgroundNode.backgroundColor {
|
if let fromTextBackgroundColor = node.backgroundNode.backgroundColor, let toTextBackgroundColor = self.textBackgroundNode.backgroundColor {
|
||||||
self.textBackgroundNode.layer.animate(from: fromTextBackgroundColor.cgColor, to: toTextBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: timingFunction, duration: duration * 0.5)
|
self.textBackgroundNode.layer.animate(from: fromTextBackgroundColor.cgColor, to: toTextBackgroundColor.cgColor, keyPath: "backgroundColor", timingFunction: timingFunction, duration: duration * 1.0)
|
||||||
}
|
}
|
||||||
self.textBackgroundNode.layer.animateFrame(from: initialTextBackgroundFrame, to: self.textBackgroundNode.frame, duration: duration, timingFunction: timingFunction)
|
self.textBackgroundNode.layer.animateFrame(from: initialTextBackgroundFrame, to: self.textBackgroundNode.frame, duration: duration, timingFunction: timingFunction)
|
||||||
|
|
||||||
|
|||||||
@ -113,7 +113,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
|
|||||||
return current
|
return current
|
||||||
} else {
|
} else {
|
||||||
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
let presentationData = self.context.sharedContext.currentPresentationData.with { $0 }
|
||||||
return NavigationBarSearchContentNode(theme: presentationData.theme, placeholder: presentationData.strings.Common_Search, activate: {
|
return NavigationBarSearchContentNode(theme: presentationData.theme, placeholder: presentationData.strings.Settings_Search, activate: {
|
||||||
updateActivated(true)
|
updateActivated(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -422,7 +422,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
|
|||||||
entries.append(.recent(i, recentSearchItems[i]))
|
entries.append(.recent(i, recentSearchItems[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear.uppercased(), action: {
|
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
|
||||||
clearRecentSettingsSearchItems(postbox: context.account.postbox)
|
clearRecentSettingsSearchItems(postbox: context.account.postbox)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -520,7 +520,7 @@ private func privacySearchableItems(context: AccountContext, privacySettings: Ac
|
|||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .privacy(8), title: strings.PrivacySettings_TwoStepAuth, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_TwoStepAuth), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
SettingsSearchableItem(id: .privacy(8), title: strings.PrivacySettings_TwoStepAuth, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_TwoStepAuth), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
||||||
present(.modal, twoStepVerificationUnlockSettingsController(context: context, mode: .access))
|
present(.push, twoStepVerificationUnlockSettingsController(context: context, mode: .access))
|
||||||
}),
|
}),
|
||||||
SettingsSearchableItem(id: .privacy(9), title: strings.PrivacySettings_AuthSessions, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
SettingsSearchableItem(id: .privacy(9), title: strings.PrivacySettings_AuthSessions, alternate: synonyms(strings.SettingsSearch_Synonyms_Privacy_AuthSessions), icon: icon, breadcrumbs: [strings.Settings_PrivacySettings], present: { context, _, present in
|
||||||
present(.push, recentSessionsController(context: context))
|
present(.push, recentSessionsController(context: context))
|
||||||
|
|||||||
@ -557,7 +557,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
|||||||
entries.append(.query(i, queries[i]))
|
entries.append(.query(i, queries[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear.uppercased(), action: {
|
let header = ChatListSearchItemHeader(type: .recentPeers, theme: presentationData.theme, strings: presentationData.strings, actionTitle: presentationData.strings.WebSearch_RecentSectionClear, action: {
|
||||||
_ = clearRecentWallpaperSearchQueries(postbox: strongSelf.context.account.postbox).start()
|
_ = clearRecentWallpaperSearchQueries(postbox: strongSelf.context.account.postbox).start()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@ -245,7 +245,7 @@ class WebSearchControllerNode: ASDisplayNode {
|
|||||||
entries.append(WebSearchRecentQueryEntry(index: i, query: queries[i]))
|
entries.append(WebSearchRecentQueryEntry(index: i, query: queries[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
let header = ChatListSearchItemHeader(type: .recentPeers, theme: interfaceState.presentationData.theme, strings:interfaceState.presentationData.strings, actionTitle: strings.WebSearch_RecentSectionClear.uppercased(), action: {
|
let header = ChatListSearchItemHeader(type: .recentPeers, theme: interfaceState.presentationData.theme, strings:interfaceState.presentationData.strings, actionTitle: strings.WebSearch_RecentSectionClear, action: {
|
||||||
_ = clearRecentWebSearchQueries(postbox: strongSelf.context.account.postbox).start()
|
_ = clearRecentWebSearchQueries(postbox: strongSelf.context.account.postbox).start()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user