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
|
||||
guard let strongSelf = self, let layout = strongSelf.validLayout else {
|
||||
guard let strongSelf = self, let layout = strongSelf.validLayout, strongSelf.traceVisibility() && isTopmostChatController(strongSelf) else {
|
||||
return
|
||||
}
|
||||
let deviceMetrics = DeviceMetrics.forScreenSize(layout.size)
|
||||
@ -2734,7 +2734,6 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
||||
tooltipController.dismissed = { [weak tooltipController] in
|
||||
if let strongSelf = self, let tooltipController = tooltipController, strongSelf.videoUnmuteTooltipController === tooltipController {
|
||||
strongSelf.videoUnmuteTooltipController = nil
|
||||
|
||||
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
|
||||
if hasVisiblePlayableItemNodes && !isPlaybackActive {
|
||||
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 {
|
||||
return
|
||||
}
|
||||
strongSelf.videoUnmuteTooltipController?.dismiss()
|
||||
strongSelf.chatDisplayNode.playFirstMediaWithSound()
|
||||
})
|
||||
|
||||
@ -3506,6 +3506,9 @@ public final class ChatController: TelegramController, KeyShortcutResponder, Gal
|
||||
}
|
||||
|
||||
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
|
||||
if self.validLayout != nil && orientation.isLandscape && !hasOverlayNodes && self.traceVisibility() && isTopmostChatController(self) {
|
||||
self.chatDisplayNode.openCurrentPlayingWithSoundMedia()
|
||||
|
||||
@ -413,9 +413,12 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
if let strongSelf = self, let interfaceInteraction = strongSelf.interfaceInteraction {
|
||||
if display {
|
||||
var nodes: [(CGFloat, ChatMessageItemView, ASDisplayNode)] = []
|
||||
var skip = false
|
||||
strongSelf.historyNode.forEachVisibleItemNode { itemNode in
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let (_, _, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode {
|
||||
if !isVideoMessage, case let .visible(fraction) = itemNode.visibility {
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let (_, soundEnabled, isVideoMessage, _, badgeNode) = itemNode.playMediaWithSound(), let node = badgeNode {
|
||||
if soundEnabled {
|
||||
skip = true
|
||||
} else if !skip && !isVideoMessage, case let .visible(fraction) = itemNode.visibility {
|
||||
nodes.insert((fraction, itemNode, node), at: 0)
|
||||
}
|
||||
}
|
||||
@ -1490,14 +1493,16 @@ class ChatControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||
var hasUnconsumed = false
|
||||
self.historyNode.forEachVisibleItemNode { itemNode in
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let (action, _, _, isUnconsumed, _) = itemNode.playMediaWithSound() {
|
||||
if case let .visible(fraction) = itemNode.visibility {
|
||||
hasUnconsumed = isUnconsumed
|
||||
if case let .visible(fraction) = itemNode.visibility, fraction > 0.7 {
|
||||
actions.insert((fraction, isUnconsumed, action), at: 0)
|
||||
if !hasUnconsumed && isUnconsumed {
|
||||
hasUnconsumed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
for (fraction, isUnconsumed, action) in actions {
|
||||
if fraction > 0.7 && (!hasUnconsumed || isUnconsumed) {
|
||||
}
|
||||
for (_, isUnconsumed, action) in actions {
|
||||
if (!hasUnconsumed || isUnconsumed) {
|
||||
action()
|
||||
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 {
|
||||
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 })
|
||||
} else {
|
||||
let actionSheet = ActionSheetController(presentationTheme: strongSelf.presentationData.theme)
|
||||
|
||||
@ -89,7 +89,7 @@ class ChatListRecentPeersListItemNode: ListViewItemNode {
|
||||
let currentItem = self.item
|
||||
|
||||
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
|
||||
var updatedTheme: PresentationTheme?
|
||||
|
||||
@ -184,7 +184,7 @@ private enum ChatListRecentEntry: Comparable, Identifiable {
|
||||
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()
|
||||
}), action: { _ in
|
||||
if let chatPeer = peer.peer.peers[peer.peer.peerId] {
|
||||
|
||||
@ -22,7 +22,7 @@ final class ChatListSearchItemHeader: ListViewItemHeader {
|
||||
let actionTitle: String?
|
||||
let action: (() -> Void)?
|
||||
|
||||
let height: CGFloat = 29.0
|
||||
let height: CGFloat = 28.0
|
||||
|
||||
init(type: ChatListSearchItemHeaderType, theme: PresentationTheme, strings: PresentationStrings, actionTitle: String?, action: (() -> Void)?) {
|
||||
self.type = type
|
||||
|
||||
@ -264,12 +264,12 @@ final class ChatListSearchRecentPeersNode: ASDisplayNode {
|
||||
}
|
||||
|
||||
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) {
|
||||
self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 29.0))
|
||||
self.sectionHeaderNode.updateLayout(size: CGSize(width: size.width, height: 29.0), leftInset: leftInset, rightInset: rightInset)
|
||||
self.sectionHeaderNode.frame = CGRect(origin: CGPoint(), size: CGSize(width: size.width, height: 28.0))
|
||||
self.sectionHeaderNode.updateLayout(size: CGSize(width: size.width, height: 28.0), leftInset: leftInset, rightInset: rightInset)
|
||||
|
||||
var insets = UIEdgeInsets()
|
||||
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.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.itemCustomWidthValuePromise.set(itemCustomWidth)
|
||||
}
|
||||
|
||||
@ -831,8 +831,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
|
||||
}
|
||||
} else {
|
||||
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
||||
forwardSource = currentForwardInfo.0
|
||||
forwardAuthorSignature = currentForwardInfo.1
|
||||
forwardSource = nil
|
||||
forwardAuthorSignature = currentForwardInfo.0?.displayTitle
|
||||
} else {
|
||||
forwardSource = forwardInfo.author
|
||||
forwardAuthorSignature = forwardInfo.authorSignature
|
||||
|
||||
@ -287,8 +287,8 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
|
||||
}
|
||||
} else {
|
||||
if let currentForwardInfo = currentForwardInfo, forwardInfo.author == nil && currentForwardInfo.0 != nil {
|
||||
forwardSource = currentForwardInfo.0
|
||||
forwardAuthorSignature = currentForwardInfo.1
|
||||
forwardSource = nil
|
||||
forwardAuthorSignature = currentForwardInfo.0?.displayTitle
|
||||
} else {
|
||||
forwardSource = forwardInfo.author
|
||||
forwardAuthorSignature = forwardInfo.authorSignature
|
||||
|
||||
@ -388,7 +388,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
updatedPlayerStatusSignal = videoNode.status
|
||||
|> mapToSignal { status -> Signal<MediaPlayerStatus?, NoError> in
|
||||
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 {
|
||||
return .single(status)
|
||||
}
|
||||
@ -574,7 +574,11 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
state = .download(bubbleTheme.mediaOverlayControlForegroundColor)
|
||||
}
|
||||
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)
|
||||
} else {
|
||||
state = .none
|
||||
@ -747,11 +751,11 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
|
||||
func playMediaWithSound() -> (action: () -> Void, soundEnabled: Bool, isVideoMessage: Bool, isUnread: Bool, badgeNode: ASDisplayNode?)? {
|
||||
if let item = self.item {
|
||||
var notConsumed = false
|
||||
var isUnconsumed = false
|
||||
for attribute in item.message.attributes {
|
||||
if let attribute = attribute as? ConsumableContentMessageAttribute {
|
||||
if !attribute.consumed {
|
||||
notConsumed = true
|
||||
isUnconsumed = true
|
||||
}
|
||||
break
|
||||
}
|
||||
@ -778,7 +782,7 @@ class ChatMessageInteractiveInstantVideoNode: ASDisplayNode {
|
||||
}
|
||||
})
|
||||
}
|
||||
}, false, true, !notConsumed, nil)
|
||||
}, false, true, isUnconsumed, nil)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -84,7 +84,6 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||
private let titleNode: ImmediateTextNode
|
||||
private let titleLeftIconNode: ASImageNode
|
||||
private let titleRightIconNode: ASImageNode
|
||||
|
||||
private let activityNode: ChatTitleActivityNode
|
||||
|
||||
private let button: HighlightTrackingButtonNode
|
||||
@ -462,13 +461,21 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
||||
if highlighted {
|
||||
strongSelf.titleNode.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.activityNode.alpha = 0.4
|
||||
strongSelf.titleLeftIconNode.alpha = 0.4
|
||||
strongSelf.titleRightIconNode.alpha = 0.4
|
||||
} else {
|
||||
strongSelf.titleNode.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.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)
|
||||
}
|
||||
}))
|
||||
let _ = currentSemaphore.swap(nil)
|
||||
subscriber.putCompletion()
|
||||
} else {
|
||||
let _ = currentSemaphore.swap(nil)
|
||||
subscriber.putError(.generic)
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
||||
}
|
||||
if totalCount > maximumFetchSize {
|
||||
context.readingError = true
|
||||
return -1
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
@ -111,7 +111,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
||||
let _ = context.currentSemaphore.swap(nil)
|
||||
disposable.dispose()
|
||||
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)
|
||||
disposable.dispose()
|
||||
if !completedRequest {
|
||||
return -1
|
||||
context.readingError = true
|
||||
return 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -175,7 +177,8 @@ private func readPacketCallback(userData: UnsafeMutableRawPointer?, buffer: Unsa
|
||||
}
|
||||
|
||||
if context.closed {
|
||||
return -1
|
||||
context.readingError = true
|
||||
return 0
|
||||
}
|
||||
return fetchedCount
|
||||
}
|
||||
@ -212,7 +215,8 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
||||
let _ = context.currentSemaphore.swap(nil)
|
||||
disposable.dispose()
|
||||
if !completedRequest {
|
||||
return -1
|
||||
context.readingError = true
|
||||
return 0
|
||||
}
|
||||
resourceSize = resultSize
|
||||
}
|
||||
@ -222,7 +226,7 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
||||
}
|
||||
|
||||
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 {
|
||||
context.readingOffset = Int(min(Int64(resourceSize), offset))
|
||||
|
||||
@ -248,7 +252,8 @@ private func seekCallback(userData: UnsafeMutableRawPointer?, offset: Int64, whe
|
||||
}
|
||||
|
||||
if context.closed {
|
||||
return -1
|
||||
context.readingError = true
|
||||
return 0
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@ -185,7 +185,11 @@ func readAlbumArtworkData(_ data: Data) -> ID3ArtworkResult {
|
||||
guard let value: UInt32 = stream.nextValue() else {
|
||||
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
|
||||
|
||||
if frameHeader == id3Tag.artworkHeader {
|
||||
@ -209,10 +213,11 @@ func readAlbumArtworkData(_ data: Data) -> ID3ArtworkResult {
|
||||
var data = Data(capacity: frameSize + 1024)
|
||||
var previousByte: UInt8 = 0xff
|
||||
|
||||
let limit = Int(Double(frameSize - offset) * 0.8)
|
||||
for _ in 0 ..< frameSize - offset {
|
||||
if let byte: UInt8 = stream.nextValue() {
|
||||
data.append(byte)
|
||||
if byte == 0xd9 && previousByte == 0xff {
|
||||
if byte == 0xd9 && previousByte == 0xff && data.count > limit {
|
||||
break
|
||||
}
|
||||
previousByte = byte
|
||||
|
||||
@ -2,6 +2,9 @@ import Foundation
|
||||
import AsyncDisplayKit
|
||||
import Display
|
||||
|
||||
private let titleFont = Font.bold(13.0)
|
||||
private let actionFont = Font.medium(13.0)
|
||||
|
||||
final class ListSectionHeaderNode: ASDisplayNode {
|
||||
private let label: ImmediateTextNode
|
||||
private var actionButton: HighlightableButtonNode?
|
||||
@ -11,7 +14,7 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
||||
|
||||
var title: String? {
|
||||
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 {
|
||||
self.updateLayout(size: size, leftInset: leftInset, rightInset: rightInset)
|
||||
@ -33,7 +36,7 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
||||
}
|
||||
}
|
||||
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 {
|
||||
@ -61,11 +64,11 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
||||
if 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
|
||||
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 {
|
||||
@ -77,11 +80,11 @@ final class ListSectionHeaderNode: ASDisplayNode {
|
||||
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat) {
|
||||
self.validLayout = (size, leftInset, rightInset)
|
||||
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 {
|
||||
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
|
||||
return Signal { [weak self] subscriber in
|
||||
if let strongSelf = self {
|
||||
subscriber.putNext(strongSelf.currentTypeAndOutputMode?.0 == .play)
|
||||
subscriber.putNext(strongSelf.currentTypeAndOutputMode?.0.isPlay ?? false)
|
||||
|
||||
let index = strongSelf.isPlaybackActiveSubscribers.add({ value in
|
||||
subscriber.putNext(value)
|
||||
@ -595,7 +595,7 @@ public final class ManagedAudioSession {
|
||||
self.deactivateTimer = nil
|
||||
|
||||
let wasActive = self.currentTypeAndOutputMode != nil
|
||||
let wasPlaybackActive = self.currentTypeAndOutputMode?.0 == .play
|
||||
let wasPlaybackActive = self.currentTypeAndOutputMode?.0.isPlay ?? false
|
||||
self.currentTypeAndOutputMode = nil
|
||||
|
||||
print("ManagedAudioSession setting active false")
|
||||
@ -624,7 +624,7 @@ public final class ManagedAudioSession {
|
||||
self.deactivateTimer = 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) {
|
||||
self.currentTypeAndOutputMode = (type, outputMode)
|
||||
|
||||
@ -380,9 +380,9 @@ final class OverlayPlayerControlsNode: ASDisplayNode {
|
||||
|
||||
private func updatePlayPauseButton(paused: Bool) {
|
||||
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)
|
||||
} 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
|
||||
|
||||
return { item, params, neighbors in
|
||||
let leftInset: CGFloat = 16.0 + params.leftInset
|
||||
let rightInset: CGFloat = 16.0 + params.rightInset
|
||||
let leftInset: CGFloat = 15.0 + params.leftInset
|
||||
let rightInset: CGFloat = 15.0 + params.rightInset
|
||||
|
||||
var updatedTheme: PresentationTheme?
|
||||
var updatedBadgeImage: UIImage?
|
||||
@ -296,11 +296,11 @@ class PermissionInfoItemNode: ListViewItemNode {
|
||||
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.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)
|
||||
|
||||
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@ -113,7 +113,7 @@ final class SettingsSearchItem: ItemListControllerSearch {
|
||||
return current
|
||||
} else {
|
||||
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)
|
||||
})
|
||||
}
|
||||
@ -422,7 +422,7 @@ private final class SettingsSearchContainerNode: SearchDisplayControllerContentN
|
||||
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)
|
||||
})
|
||||
|
||||
|
||||
@ -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
|
||||
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
|
||||
present(.push, recentSessionsController(context: context))
|
||||
|
||||
@ -557,7 +557,7 @@ final class ThemeGridSearchContentNode: SearchDisplayControllerContentNode {
|
||||
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()
|
||||
})
|
||||
|
||||
|
||||
@ -245,7 +245,7 @@ class WebSearchControllerNode: ASDisplayNode {
|
||||
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()
|
||||
})
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user