mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-04 05:26:48 +00:00
Various UI fixes
This commit is contained in:
parent
c3373cc263
commit
2bbbc85093
@ -234,7 +234,7 @@ public func callFeedbackController(sharedContext: SharedAccountContext, account:
|
|||||||
let signal = combineLatest(sharedContext.presentationData, statePromise.get())
|
let signal = combineLatest(sharedContext.presentationData, statePromise.get())
|
||||||
|> deliverOnMainQueue
|
|> deliverOnMainQueue
|
||||||
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<CallFeedbackControllerEntry>, CallFeedbackControllerEntry.ItemGenerationArguments)) in
|
|> map { presentationData, state -> (ItemListControllerState, (ItemListNodeState<CallFeedbackControllerEntry>, CallFeedbackControllerEntry.ItemGenerationArguments)) in
|
||||||
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .bold, enabled: true, action: {
|
let leftNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.Common_Cancel), style: .regular, enabled: true, action: {
|
||||||
dismissImpl?()
|
dismissImpl?()
|
||||||
})
|
})
|
||||||
let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.CallFeedback_Send), style: .bold, enabled: true, action: {
|
let rightNavigationButton = ItemListNavigationButton(content: .text(presentationData.strings.CallFeedback_Send), style: .bold, enabled: true, action: {
|
||||||
|
|||||||
@ -628,11 +628,11 @@ class CallListCallItemNode: ItemListRevealOptionsItemNode {
|
|||||||
infoIconRightInset -= 36.0
|
infoIconRightInset -= 36.0
|
||||||
}
|
}
|
||||||
|
|
||||||
transition.updateFrame(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset - 52.0, y: 8.0), size: CGSize(width: 40.0, height: 40.0)))
|
transition.updateFrame(node: self.avatarNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset - 52.0, y: 5.0), size: CGSize(width: 40.0, height: 40.0)))
|
||||||
|
|
||||||
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: 8.0), size: self.titleNode.bounds.size))
|
transition.updateFrame(node: self.titleNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: 6.0), size: self.titleNode.bounds.size))
|
||||||
|
|
||||||
transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: 30.0), size: self.statusNode.bounds.size))
|
transition.updateFrame(node: self.statusNode, frame: CGRect(origin: CGPoint(x: revealOffset + leftInset, y: 27.0), size: self.statusNode.bounds.size))
|
||||||
|
|
||||||
transition.updateFrame(node: self.dateNode, frame: CGRect(origin: CGPoint(x: editingOffset + revealOffset + self.bounds.size.width - dateRightInset - self.dateNode.bounds.size.width, y: self.dateNode.frame.minY), size: self.dateNode.bounds.size))
|
transition.updateFrame(node: self.dateNode, frame: CGRect(origin: CGPoint(x: editingOffset + revealOffset + self.bounds.size.width - dateRightInset - self.dateNode.bounds.size.width, y: self.dateNode.frame.minY), size: self.dateNode.bounds.size))
|
||||||
|
|
||||||
|
|||||||
@ -102,12 +102,13 @@ class ChatPlayingActivityContentNode: ChatTitleActivityContentNode {
|
|||||||
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||||
let size = self.textNode.updateLayout(constrainedSize)
|
let size = self.textNode.updateLayout(constrainedSize)
|
||||||
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
||||||
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
let originX: CGFloat
|
||||||
if case .center = alignment {
|
if case .center = alignment {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width / 2.0, y: size.height / 2.0)
|
originX = floorToScreenPixels((indicatorSize.width - size.width) / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width + size.width / 2.0, y: size.height / 2.0)
|
originX = indicatorSize.width
|
||||||
}
|
}
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: originX, y: 0.0), size: size)
|
||||||
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
||||||
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -74,12 +74,13 @@ class ChatRecordingVideoActivityContentNode: ChatTitleActivityContentNode {
|
|||||||
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||||
let size = self.textNode.updateLayout(constrainedSize)
|
let size = self.textNode.updateLayout(constrainedSize)
|
||||||
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
||||||
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
let originX: CGFloat
|
||||||
if case .center = alignment {
|
if case .center = alignment {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width / 2.0, y: size.height / 2.0)
|
originX = floorToScreenPixels((indicatorSize.width - size.width) / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width + size.width / 2.0, y: size.height / 2.0)
|
originX = indicatorSize.width
|
||||||
}
|
}
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: originX, y: 0.0), size: size)
|
||||||
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
||||||
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,12 +92,13 @@ class ChatRecordingVoiceActivityContentNode: ChatTitleActivityContentNode {
|
|||||||
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||||
let size = self.textNode.updateLayout(constrainedSize)
|
let size = self.textNode.updateLayout(constrainedSize)
|
||||||
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
||||||
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
let originX: CGFloat
|
||||||
if case .center = alignment {
|
if case .center = alignment {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width / 2.0, y: size.height / 2.0)
|
originX = floorToScreenPixels((indicatorSize.width - size.width) / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width + size.width / 2.0, y: size.height / 2.0)
|
originX = indicatorSize.width
|
||||||
}
|
}
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: originX, y: 0.0), size: size)
|
||||||
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
||||||
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,9 +8,15 @@ public enum ChatTitleActivityAnimationStyle {
|
|||||||
case slide
|
case slide
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum ChatTitleActivityInfoType {
|
||||||
|
case online
|
||||||
|
case lastSeenTime
|
||||||
|
case generic
|
||||||
|
}
|
||||||
|
|
||||||
public enum ChatTitleActivityNodeState: Equatable {
|
public enum ChatTitleActivityNodeState: Equatable {
|
||||||
case none
|
case none
|
||||||
case info(NSAttributedString)
|
case info(NSAttributedString, ChatTitleActivityInfoType)
|
||||||
case typingText(NSAttributedString, UIColor)
|
case typingText(NSAttributedString, UIColor)
|
||||||
case uploading(NSAttributedString, UIColor)
|
case uploading(NSAttributedString, UIColor)
|
||||||
case recordingVoice(NSAttributedString, UIColor)
|
case recordingVoice(NSAttributedString, UIColor)
|
||||||
@ -21,7 +27,7 @@ public enum ChatTitleActivityNodeState: Equatable {
|
|||||||
switch self {
|
switch self {
|
||||||
case .none:
|
case .none:
|
||||||
return nil
|
return nil
|
||||||
case let .info(text):
|
case let .info(text, _):
|
||||||
return ChatTitleActivityContentNode(text: text)
|
return ChatTitleActivityContentNode(text: text)
|
||||||
case let .typingText(text, color):
|
case let .typingText(text, color):
|
||||||
return ChatTypingActivityContentNode(text: text, color: color)
|
return ChatTypingActivityContentNode(text: text, color: color)
|
||||||
@ -37,7 +43,7 @@ public enum ChatTitleActivityNodeState: Equatable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var string: String? {
|
var string: String? {
|
||||||
if case let .info(text) = self {
|
if case let .info(text, _) = self {
|
||||||
return text.string
|
return text.string
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -76,6 +82,11 @@ class ChatTitleActivityNode: ASDisplayNode {
|
|||||||
self.addSubnode(contentNode)
|
self.addSubnode(contentNode)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
var animation = animation
|
||||||
|
if case let .info(_, fromType) = fromState, case let .info(_, toType) = state, fromType == toType {
|
||||||
|
animation = .none
|
||||||
|
}
|
||||||
|
|
||||||
self.contentNode = node
|
self.contentNode = node
|
||||||
if let contentNode = self.contentNode {
|
if let contentNode = self.contentNode {
|
||||||
self.addSubnode(contentNode)
|
self.addSubnode(contentNode)
|
||||||
|
|||||||
@ -301,21 +301,21 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
if let peer = peerViewMainPeer(peerView) {
|
if let peer = peerViewMainPeer(peerView) {
|
||||||
if peer.id == self.account.peerId {
|
if peer.id == self.account.peerId {
|
||||||
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else if let user = peer as? TelegramUser {
|
} else if let user = peer as? TelegramUser {
|
||||||
if user.id.namespace == Namespaces.Peer.CloudUser && user.id.id == 777000 {
|
if user.id.namespace == Namespaces.Peer.CloudUser && user.id.id == 777000 {
|
||||||
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else if user.flags.contains(.isSupport) {
|
} else if user.flags.contains(.isSupport) {
|
||||||
let statusText = self.strings.Bot_GenericSupportStatus
|
let statusText = self.strings.Bot_GenericSupportStatus
|
||||||
|
|
||||||
let string = NSAttributedString(string: statusText, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: statusText, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else if let _ = user.botInfo {
|
} else if let _ = user.botInfo {
|
||||||
let statusText = self.strings.Bot_GenericBotStatus
|
let statusText = self.strings.Bot_GenericBotStatus
|
||||||
|
|
||||||
let string = NSAttributedString(string: statusText, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: statusText, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else if let peer = peerViewMainPeer(peerView) {
|
} else if let peer = peerViewMainPeer(peerView) {
|
||||||
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
let timestamp = CFAbsoluteTimeGetCurrent() + NSTimeIntervalSince1970
|
||||||
let userPresence: TelegramUserPresence
|
let userPresence: TelegramUserPresence
|
||||||
@ -327,10 +327,10 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
}
|
}
|
||||||
let (string, activity) = stringAndActivityForUserPresence(strings: self.strings, dateTimeFormat: self.dateTimeFormat, presence: userPresence, relativeTo: Int32(timestamp))
|
let (string, activity) = stringAndActivityForUserPresence(strings: self.strings, dateTimeFormat: self.dateTimeFormat, presence: userPresence, relativeTo: Int32(timestamp))
|
||||||
let attributedString = NSAttributedString(string: string, font: Font.regular(13.0), textColor: activity ? self.theme.rootController.navigationBar.accentTextColor : self.theme.rootController.navigationBar.secondaryTextColor)
|
let attributedString = NSAttributedString(string: string, font: Font.regular(13.0), textColor: activity ? self.theme.rootController.navigationBar.accentTextColor : self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(attributedString)
|
state = .info(attributedString, activity ? .online : .lastSeenTime)
|
||||||
} else {
|
} else {
|
||||||
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: "", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
}
|
}
|
||||||
} else if let group = peer as? TelegramGroup {
|
} else if let group = peer as? TelegramGroup {
|
||||||
var onlineCount = 0
|
var onlineCount = 0
|
||||||
@ -353,10 +353,10 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
|
|
||||||
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(group.participantCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(group.participantCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
||||||
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else {
|
} else {
|
||||||
let string = NSAttributedString(string: strings.Conversation_StatusMembers(Int32(group.participantCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: strings.Conversation_StatusMembers(Int32(group.participantCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
}
|
}
|
||||||
} else if let channel = peer as? TelegramChannel {
|
} else if let channel = peer as? TelegramChannel {
|
||||||
if let cachedChannelData = peerView.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount {
|
if let cachedChannelData = peerView.cachedData as? CachedChannelData, let memberCount = cachedChannelData.participantsSummary.memberCount {
|
||||||
@ -367,14 +367,14 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
} else {
|
} else {
|
||||||
string = NSAttributedString(string: strings.Channel_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
string = NSAttributedString(string: strings.Channel_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
}
|
}
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else {
|
} else {
|
||||||
if case .group = channel.info, let onlineMemberCount = onlineMemberCount, onlineMemberCount > 1 {
|
if case .group = channel.info, let onlineMemberCount = onlineMemberCount, onlineMemberCount > 1 {
|
||||||
let string = NSMutableAttributedString()
|
let string = NSMutableAttributedString()
|
||||||
|
|
||||||
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(memberCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
string.append(NSAttributedString(string: "\(strings.Conversation_StatusMembers(Int32(memberCount))), ", font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
||||||
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineMemberCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
string.append(NSAttributedString(string: strings.Conversation_StatusOnline(Int32(onlineMemberCount)), font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor))
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
} else {
|
} else {
|
||||||
let membersString: String
|
let membersString: String
|
||||||
if case .group = channel.info {
|
if case .group = channel.info {
|
||||||
@ -383,17 +383,17 @@ final class ChatTitleView: UIView, NavigationBarTitleView {
|
|||||||
membersString = strings.Conversation_StatusSubscribers(memberCount)
|
membersString = strings.Conversation_StatusSubscribers(memberCount)
|
||||||
}
|
}
|
||||||
let string = NSAttributedString(string: membersString, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: membersString, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch channel.info {
|
switch channel.info {
|
||||||
case .group:
|
case .group:
|
||||||
let string = NSAttributedString(string: strings.Group_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: strings.Group_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
case .broadcast:
|
case .broadcast:
|
||||||
let string = NSAttributedString(string: strings.Channel_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
let string = NSAttributedString(string: strings.Channel_Status, font: Font.regular(13.0), textColor: self.theme.rootController.navigationBar.secondaryTextColor)
|
||||||
state = .info(string)
|
state = .info(string, .generic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,12 +109,13 @@ class ChatTypingActivityContentNode: ChatTitleActivityContentNode {
|
|||||||
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||||
let size = self.textNode.updateLayout(constrainedSize)
|
let size = self.textNode.updateLayout(constrainedSize)
|
||||||
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
||||||
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
let originX: CGFloat
|
||||||
if case .center = alignment {
|
if case .center = alignment {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width / 2.0, y: size.height / 2.0)
|
originX = floorToScreenPixels((indicatorSize.width - size.width) / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width + size.width / 2.0, y: size.height / 2.0)
|
originX = indicatorSize.width
|
||||||
}
|
}
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: originX, y: 0.0), size: size)
|
||||||
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: floorToScreenPixels((size.height - indicatorSize.height) / 2.0)), size: indicatorSize)
|
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: floorToScreenPixels((size.height - indicatorSize.height) / 2.0)), size: indicatorSize)
|
||||||
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,20 +47,18 @@ private class ChatUploadingActivityIndicatorNode: ChatTitleActivityIndicatorNode
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let origin = CGPoint(x: 11.0 / 2.0 - 1.0, y: 21.0 / 2.0 + 1.0)
|
let origin = CGPoint(x: 4.0 + UIScreenPixel, y: 7.0)
|
||||||
let size = CGSize(width: 26.0 / 2.0, height: 8.0 / 2.0)
|
let size = CGSize(width: 13.0, height: 4.0)
|
||||||
let radius: CGFloat = 1.25
|
let radius: CGFloat = 1.25
|
||||||
|
|
||||||
var dotsColor = parameters.color
|
var dotsColor = parameters.color.withAlphaComponent(0.3)
|
||||||
context.setFillColor(dotsColor.cgColor)
|
context.setFillColor(dotsColor.cgColor)
|
||||||
|
|
||||||
var path = UIBezierPath(roundedRect: CGRect(origin: origin, size: size), cornerRadius: radius)
|
var path = UIBezierPath(roundedRect: CGRect(origin: origin, size: size), cornerRadius: radius)
|
||||||
path.fill(with: .normal, alpha: 1.0)
|
path.fill(with: .normal, alpha: 1.0)
|
||||||
|
path.addClip()
|
||||||
|
|
||||||
dotsColor = parameters.color.withAlphaComponent(0.3)
|
let progress = interpolate(from: 0.0, to: size.width * 2.0, value: parameters.progress)
|
||||||
context.setFillColor(dotsColor.cgColor)
|
|
||||||
|
|
||||||
let progress = interpolate(from: 0.0, to: size.width, value: parameters.progress)
|
|
||||||
|
|
||||||
dotsColor = parameters.color
|
dotsColor = parameters.color
|
||||||
context.setFillColor(dotsColor.cgColor)
|
context.setFillColor(dotsColor.cgColor)
|
||||||
@ -84,12 +82,13 @@ class ChatUploadingActivityContentNode: ChatTitleActivityContentNode {
|
|||||||
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
override func updateLayout(_ constrainedSize: CGSize, alignment: NSTextAlignment) -> CGSize {
|
||||||
let size = self.textNode.updateLayout(constrainedSize)
|
let size = self.textNode.updateLayout(constrainedSize)
|
||||||
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
let indicatorSize = CGSize(width: 24.0, height: 16.0)
|
||||||
self.textNode.bounds = CGRect(origin: CGPoint(), size: size)
|
let originX: CGFloat
|
||||||
if case .center = alignment {
|
if case .center = alignment {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width / 2.0, y: size.height / 2.0)
|
originX = floorToScreenPixels((indicatorSize.width - size.width) / 2.0)
|
||||||
} else {
|
} else {
|
||||||
self.textNode.position = CGPoint(x: indicatorSize.width + size.width / 2.0, y: size.height / 2.0)
|
originX = indicatorSize.width
|
||||||
}
|
}
|
||||||
|
self.textNode.frame = CGRect(origin: CGPoint(x: originX, y: 0.0), size: size)
|
||||||
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
self.indicatorNode.frame = CGRect(origin: CGPoint(x: self.textNode.frame.minX - indicatorSize.width, y: 0.0), size: indicatorSize)
|
||||||
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
return CGSize(width: size.width + indicatorSize.width, height: size.height)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,7 @@ final class InstantPageController: ViewController {
|
|||||||
|
|
||||||
private var settings: InstantPagePresentationSettings?
|
private var settings: InstantPagePresentationSettings?
|
||||||
private var settingsDisposable: Disposable?
|
private var settingsDisposable: Disposable?
|
||||||
|
private var themeSettings: PresentationThemeSettings?
|
||||||
|
|
||||||
init(context: AccountContext, webPage: TelegramMediaWebpage, anchor: String? = nil) {
|
init(context: AccountContext, webPage: TelegramMediaWebpage, anchor: String? = nil) {
|
||||||
self.context = context
|
self.context = context
|
||||||
@ -45,7 +46,7 @@ final class InstantPageController: ViewController {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
self.settingsDisposable = (self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.instantPagePresentationSettings])
|
self.settingsDisposable = (self.context.sharedContext.accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.instantPagePresentationSettings, ApplicationSpecificSharedDataKeys.presentationThemeSettings])
|
||||||
|> deliverOnMainQueue).start(next: { [weak self] sharedData in
|
|> deliverOnMainQueue).start(next: { [weak self] sharedData in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
let settings: InstantPagePresentationSettings
|
let settings: InstantPagePresentationSettings
|
||||||
@ -54,7 +55,15 @@ final class InstantPageController: ViewController {
|
|||||||
} else {
|
} else {
|
||||||
settings = InstantPagePresentationSettings.defaultSettings
|
settings = InstantPagePresentationSettings.defaultSettings
|
||||||
}
|
}
|
||||||
|
let themeSettings: PresentationThemeSettings
|
||||||
|
if let current = sharedData.entries[ApplicationSpecificSharedDataKeys.presentationThemeSettings] as? PresentationThemeSettings {
|
||||||
|
themeSettings = current
|
||||||
|
} else {
|
||||||
|
themeSettings = PresentationThemeSettings.defaultSettings
|
||||||
|
}
|
||||||
|
|
||||||
strongSelf.settings = settings
|
strongSelf.settings = settings
|
||||||
|
strongSelf.themeSettings = themeSettings
|
||||||
if strongSelf.isNodeLoaded {
|
if strongSelf.isNodeLoaded {
|
||||||
strongSelf.controllerNode.update(settings: settings, strings: strongSelf.presentationData.strings)
|
strongSelf.controllerNode.update(settings: settings, strings: strongSelf.presentationData.strings)
|
||||||
}
|
}
|
||||||
@ -76,7 +85,7 @@ final class InstantPageController: ViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override public func loadDisplayNode() {
|
override public func loadDisplayNode() {
|
||||||
self.displayNode = InstantPageControllerNode(context: self.context, settings: self.settings, presentationTheme: self.presentationData.theme, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, statusBar: self.statusBar, getNavigationController: { [weak self] in
|
self.displayNode = InstantPageControllerNode(context: self.context, settings: self.settings, themeSettings: self.themeSettings, presentationTheme: self.presentationData.theme, strings: self.presentationData.strings, dateTimeFormat: self.presentationData.dateTimeFormat, statusBar: self.statusBar, getNavigationController: { [weak self] in
|
||||||
return self?.navigationController as? NavigationController
|
return self?.navigationController as? NavigationController
|
||||||
}, present: { [weak self] c, a in
|
}, present: { [weak self] c, a in
|
||||||
self?.present(c, in: .window(.root), with: a)
|
self?.present(c, in: .window(.root), with: a)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import SafariServices
|
|||||||
final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
||||||
private let context: AccountContext
|
private let context: AccountContext
|
||||||
private var settings: InstantPagePresentationSettings?
|
private var settings: InstantPagePresentationSettings?
|
||||||
|
private var themeSettings: PresentationThemeSettings?
|
||||||
private var presentationTheme: PresentationTheme
|
private var presentationTheme: PresentationTheme
|
||||||
private var strings: PresentationStrings
|
private var strings: PresentationStrings
|
||||||
private var dateTimeFormat: PresentationDateTimeFormat
|
private var dateTimeFormat: PresentationDateTimeFormat
|
||||||
@ -73,7 +74,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
return InstantPageStoredState(contentOffset: Double(self.scrollNode.view.contentOffset.y), details: details)
|
return InstantPageStoredState(contentOffset: Double(self.scrollNode.view.contentOffset.y), details: details)
|
||||||
}
|
}
|
||||||
|
|
||||||
init(context: AccountContext, settings: InstantPagePresentationSettings?, presentationTheme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, statusBar: StatusBar, getNavigationController: @escaping () -> NavigationController?, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, openPeer: @escaping (PeerId) -> Void, navigateBack: @escaping () -> Void) {
|
init(context: AccountContext, settings: InstantPagePresentationSettings?, themeSettings: PresentationThemeSettings?, presentationTheme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, statusBar: StatusBar, getNavigationController: @escaping () -> NavigationController?, present: @escaping (ViewController, Any?) -> Void, pushController: @escaping (ViewController) -> Void, openPeer: @escaping (PeerId) -> Void, navigateBack: @escaping () -> Void) {
|
||||||
self.context = context
|
self.context = context
|
||||||
self.presentationTheme = presentationTheme
|
self.presentationTheme = presentationTheme
|
||||||
self.dateTimeFormat = dateTimeFormat
|
self.dateTimeFormat = dateTimeFormat
|
||||||
@ -82,7 +83,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
let themeReferenceDate = Date()
|
let themeReferenceDate = Date()
|
||||||
self.themeReferenceDate = themeReferenceDate
|
self.themeReferenceDate = themeReferenceDate
|
||||||
self.theme = settings.flatMap { settings in
|
self.theme = settings.flatMap { settings in
|
||||||
return instantPageThemeForType(instantPageThemeTypeForSettingsAndTime(presentationTheme: presentationTheme, settings: settings, time: themeReferenceDate), settings: settings)
|
return instantPageThemeForType(instantPageThemeTypeForSettingsAndTime(themeSettings: themeSettings, settings: settings, time: themeReferenceDate), settings: settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
self.statusBar = statusBar
|
self.statusBar = statusBar
|
||||||
@ -159,7 +160,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.settings = settings
|
self.settings = settings
|
||||||
let themeType = instantPageThemeTypeForSettingsAndTime(presentationTheme: self.presentationTheme, settings: settings, time: self.themeReferenceDate)
|
let themeType = instantPageThemeTypeForSettingsAndTime(themeSettings: self.themeSettings, settings: settings, time: self.themeReferenceDate)
|
||||||
let theme = instantPageThemeForType(themeType, settings: settings)
|
let theme = instantPageThemeForType(themeType, settings: settings)
|
||||||
self.theme = theme
|
self.theme = theme
|
||||||
self.strings = strings
|
self.strings = strings
|
||||||
@ -1304,7 +1305,7 @@ final class InstantPageControllerNode: ASDisplayNode, UIScrollViewDelegate {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if self.settingsNode == nil {
|
if self.settingsNode == nil {
|
||||||
let settingsNode = InstantPageSettingsNode(strings: self.strings, settings: settings, currentThemeType: instantPageThemeTypeForSettingsAndTime(presentationTheme: self.presentationTheme, settings: settings, time: self.themeReferenceDate), applySettings: { [weak self] settings in
|
let settingsNode = InstantPageSettingsNode(strings: self.strings, settings: settings, currentThemeType: instantPageThemeTypeForSettingsAndTime(themeSettings: self.themeSettings, settings: settings, time: self.themeReferenceDate), applySettings: { [weak self] settings in
|
||||||
if let strongSelf = self {
|
if let strongSelf = self {
|
||||||
strongSelf.update(settings: settings, strings: strongSelf.strings)
|
strongSelf.update(settings: settings, strings: strongSelf.strings)
|
||||||
let _ = updateInstantPagePresentationSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { _ in
|
let _ = updateInstantPagePresentationSettingsInteractively(accountManager: strongSelf.context.sharedContext.accountManager, { _ in
|
||||||
|
|||||||
@ -274,14 +274,22 @@ private func fontSizeMultiplierForVariant(_ variant: InstantPagePresentationFont
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func instantPageThemeTypeForSettingsAndTime(presentationTheme: PresentationTheme, settings: InstantPagePresentationSettings, time: Date?) -> InstantPageThemeType {
|
func instantPageThemeTypeForSettingsAndTime(themeSettings: PresentationThemeSettings?, settings: InstantPagePresentationSettings, time: Date?) -> InstantPageThemeType {
|
||||||
if settings.autoNightMode {
|
if settings.autoNightMode {
|
||||||
switch settings.themeType {
|
switch settings.themeType {
|
||||||
case .light, .sepia, .gray:
|
case .light, .sepia, .gray:
|
||||||
var useDarkTheme = false
|
var useDarkTheme = false
|
||||||
if let time = time {
|
|
||||||
let calendar = Calendar.current
|
var fallback = true
|
||||||
let hour = calendar.component(.hour, from: time)
|
if let themeSettings = themeSettings {
|
||||||
|
if case .none = themeSettings.automaticThemeSwitchSetting.trigger {
|
||||||
|
} else {
|
||||||
|
fallback = false
|
||||||
|
useDarkTheme = automaticThemeShouldSwitchNow(themeSettings.automaticThemeSwitchSetting, currentTheme: themeSettings.theme)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if fallback, let time = time {
|
||||||
|
let hour = Calendar.current.component(.hour, from: time)
|
||||||
if hour <= 8 || hour >= 22 {
|
if hour <= 8 || hour >= 22 {
|
||||||
useDarkTheme = true
|
useDarkTheme = true
|
||||||
}
|
}
|
||||||
|
|||||||
@ -182,6 +182,16 @@ struct InviteContactsGroupSelectionState: Equatable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withSelectedContactId(_ contactId: String) -> InviteContactsGroupSelectionState {
|
||||||
|
var updatedIndices = self.selectedContactIndices
|
||||||
|
if let _ = updatedIndices[contactId] {
|
||||||
|
return self
|
||||||
|
} else {
|
||||||
|
updatedIndices[contactId] = self.nextSelectionIndex
|
||||||
|
return InviteContactsGroupSelectionState(selectedContactIndices: updatedIndices, nextSelectionIndex: self.nextSelectionIndex + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func withClearedSelection() -> InviteContactsGroupSelectionState {
|
func withClearedSelection() -> InviteContactsGroupSelectionState {
|
||||||
return InviteContactsGroupSelectionState(selectedContactIndices: [:], nextSelectionIndex: self.nextSelectionIndex)
|
return InviteContactsGroupSelectionState(selectedContactIndices: [:], nextSelectionIndex: self.nextSelectionIndex)
|
||||||
}
|
}
|
||||||
@ -519,7 +529,11 @@ final class InviteContactsControllerNode: ASDisplayNode {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.deviceContacts], openPeer: { _ in
|
self.searchDisplayController = SearchDisplayController(presentationData: self.presentationData, contentNode: ContactsSearchContainerNode(context: self.context, onlyWriteable: false, categories: [.deviceContacts], openPeer: { [weak self] peer in
|
||||||
|
if let strongSelf = self, case let .deviceContact(id, _) = peer {
|
||||||
|
strongSelf.selectionState = strongSelf.selectionState.withSelectedContactId(id)
|
||||||
|
strongSelf.requestDeactivateSearch?()
|
||||||
|
}
|
||||||
}), cancel: { [weak self] in
|
}), cancel: { [weak self] in
|
||||||
if let requestDeactivateSearch = self?.requestDeactivateSearch {
|
if let requestDeactivateSearch = self?.requestDeactivateSearch {
|
||||||
requestDeactivateSearch()
|
requestDeactivateSearch()
|
||||||
|
|||||||
@ -121,12 +121,15 @@ private enum ItemListRevealOptionAlignment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final class ItemListRevealOptionNode: ASDisplayNode {
|
private final class ItemListRevealOptionNode: ASDisplayNode {
|
||||||
|
private let highlightNode: ASDisplayNode
|
||||||
private let titleNode: ASTextNode
|
private let titleNode: ASTextNode
|
||||||
private let iconNode: ASImageNode?
|
private let iconNode: ASImageNode?
|
||||||
private let animationNode: ItemListRevealAnimationNode?
|
private let animationNode: ItemListRevealAnimationNode?
|
||||||
var alignment: ItemListRevealOptionAlignment?
|
var alignment: ItemListRevealOptionAlignment?
|
||||||
|
|
||||||
init(title: String, icon: ItemListRevealOptionIcon, color: UIColor, textColor: UIColor) {
|
init(title: String, icon: ItemListRevealOptionIcon, color: UIColor, textColor: UIColor) {
|
||||||
|
self.highlightNode = ASDisplayNode()
|
||||||
|
|
||||||
self.titleNode = ASTextNode()
|
self.titleNode = ASTextNode()
|
||||||
self.titleNode.attributedText = NSAttributedString(string: title, font: icon == .none ? titleFontWithoutIcon : titleFontWithIcon, textColor: textColor)
|
self.titleNode.attributedText = NSAttributedString(string: title, font: icon == .none ? titleFontWithoutIcon : titleFontWithIcon, textColor: textColor)
|
||||||
|
|
||||||
@ -156,9 +159,23 @@ private final class ItemListRevealOptionNode: ASDisplayNode {
|
|||||||
self.addSubnode(animationNode)
|
self.addSubnode(animationNode)
|
||||||
}
|
}
|
||||||
self.backgroundColor = color
|
self.backgroundColor = color
|
||||||
|
self.highlightNode.backgroundColor = color.withMultipliedBrightnessBy(0.9)
|
||||||
|
}
|
||||||
|
|
||||||
|
func setHighlighted(_ highlighted: Bool) {
|
||||||
|
if highlighted {
|
||||||
|
self.insertSubnode(self.highlightNode, at: 0)
|
||||||
|
self.highlightNode.layer.animate(from: 0.0 as NSNumber, to: 1.0 as NSNumber, keyPath: "opacity", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.3)
|
||||||
|
self.highlightNode.alpha = 1.0
|
||||||
|
} else {
|
||||||
|
self.highlightNode.removeFromSupernode()
|
||||||
|
self.highlightNode.alpha = 0.0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateLayout(baseSize: CGSize, alignment: ItemListRevealOptionAlignment, extendedWidth: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition, revealFactor: CGFloat) {
|
func updateLayout(baseSize: CGSize, alignment: ItemListRevealOptionAlignment, extendedWidth: CGFloat, sideInset: CGFloat, transition: ContainedViewLayoutTransition, revealFactor: CGFloat) {
|
||||||
|
self.highlightNode.frame = CGRect(origin: CGPoint(), size: baseSize)
|
||||||
|
|
||||||
var animateAdditive = false
|
var animateAdditive = false
|
||||||
if transition.isAnimated, self.alignment != alignment {
|
if transition.isAnimated, self.alignment != alignment {
|
||||||
animateAdditive = true
|
animateAdditive = true
|
||||||
@ -229,7 +246,22 @@ final class ItemListRevealOptionsNode: ASDisplayNode {
|
|||||||
override func didLoad() {
|
override func didLoad() {
|
||||||
super.didLoad()
|
super.didLoad()
|
||||||
|
|
||||||
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
let gestureRecognizer = TapLongTapOrDoubleTapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))
|
||||||
|
gestureRecognizer.highlight = { [weak self] location in
|
||||||
|
guard let strongSelf = self, let location = location else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for node in strongSelf.optionNodes {
|
||||||
|
if node.frame.contains(location) {
|
||||||
|
node.setHighlighted(true)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gestureRecognizer.tapActionAtPoint = { _ in
|
||||||
|
return .waitForSingleTap
|
||||||
|
}
|
||||||
|
self.view.addGestureRecognizer(gestureRecognizer)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setOptions(_ options: [ItemListRevealOption]) {
|
func setOptions(_ options: [ItemListRevealOption]) {
|
||||||
@ -302,15 +334,19 @@ final class ItemListRevealOptionsNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func tapGesture(_ recognizer: UITapGestureRecognizer) {
|
@objc func tapGesture(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
|
||||||
if case .ended = recognizer.state {
|
if case .ended = recognizer.state {
|
||||||
let location = recognizer.location(in: self.view)
|
let location = recognizer.location(in: self.view)
|
||||||
|
var selectedOption: Int?
|
||||||
for i in 0 ..< self.optionNodes.count {
|
for i in 0 ..< self.optionNodes.count {
|
||||||
|
self.optionNodes[i].setHighlighted(false)
|
||||||
if self.optionNodes[i].frame.contains(location) {
|
if self.optionNodes[i].frame.contains(location) {
|
||||||
self.optionSelected(self.options[i])
|
selectedOption = i
|
||||||
break
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if let selectedOption = selectedOption {
|
||||||
|
self.optionSelected(self.options[selectedOption])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1002,7 +1002,7 @@ public func chatMessagePhotoThumbnail(account: Account, photoReference: ImageMed
|
|||||||
}
|
}
|
||||||
|
|
||||||
public func chatMessageVideoThumbnail(account: Account, fileReference: FileMediaReference) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
public func chatMessageVideoThumbnail(account: Account, fileReference: FileMediaReference) -> Signal<(TransformImageArguments) -> DrawingContext?, NoError> {
|
||||||
let signal = chatMessageVideoDatas(postbox: account.postbox, fileReference: fileReference, thumbnailSize: true)
|
let signal = chatMessageVideoDatas(postbox: account.postbox, fileReference: fileReference, thumbnailSize: true, autoFetchFullSizeThumbnail: true)
|
||||||
|
|
||||||
return signal
|
return signal
|
||||||
|> map { (thumbnailData, fullSizeData, fullSizeComplete) in
|
|> map { (thumbnailData, fullSizeData, fullSizeComplete) in
|
||||||
@ -1055,16 +1055,20 @@ public func chatMessageVideoThumbnail(account: Account, fileReference: FileMedia
|
|||||||
|
|
||||||
var blurredThumbnailImage: UIImage?
|
var blurredThumbnailImage: UIImage?
|
||||||
if let thumbnailImage = thumbnailImage {
|
if let thumbnailImage = thumbnailImage {
|
||||||
let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height)
|
if max(thumbnailImage.width, thumbnailImage.height) > 200 {
|
||||||
let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0))
|
blurredThumbnailImage = UIImage(cgImage: thumbnailImage)
|
||||||
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
|
} else {
|
||||||
thumbnailContext.withFlippedContext { c in
|
let thumbnailSize = CGSize(width: thumbnailImage.width, height: thumbnailImage.height)
|
||||||
c.interpolationQuality = .none
|
let thumbnailContextSize = thumbnailSize.aspectFitted(CGSize(width: 150.0, height: 150.0))
|
||||||
c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
|
let thumbnailContext = DrawingContext(size: thumbnailContextSize, scale: 1.0)
|
||||||
|
thumbnailContext.withFlippedContext { c in
|
||||||
|
c.interpolationQuality = .none
|
||||||
|
c.draw(thumbnailImage, in: CGRect(origin: CGPoint(), size: thumbnailContextSize))
|
||||||
|
}
|
||||||
|
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
|
||||||
|
|
||||||
|
blurredThumbnailImage = thumbnailContext.generateImage()
|
||||||
}
|
}
|
||||||
telegramFastBlur(Int32(thumbnailContextSize.width), Int32(thumbnailContextSize.height), Int32(thumbnailContext.bytesPerRow), thumbnailContext.bytes)
|
|
||||||
|
|
||||||
blurredThumbnailImage = thumbnailContext.generateImage()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
context.withFlippedContext { c in
|
context.withFlippedContext { c in
|
||||||
|
|||||||
@ -286,7 +286,7 @@ private func roundTimeToDay(_ timestamp: Int32) -> Int32 {
|
|||||||
return Int32(components.hour! * 60 * 60 + components.minute! * 60 + components.second!)
|
return Int32(components.hour! * 60 * 60 + components.minute! * 60 + components.second!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func automaticThemeShouldSwitchNow(_ settings: AutomaticThemeSwitchSetting, currentTheme: PresentationThemeReference) -> Bool {
|
func automaticThemeShouldSwitchNow(_ settings: AutomaticThemeSwitchSetting, currentTheme: PresentationThemeReference) -> Bool {
|
||||||
switch currentTheme {
|
switch currentTheme {
|
||||||
case let .builtin(builtin):
|
case let .builtin(builtin):
|
||||||
switch builtin {
|
switch builtin {
|
||||||
|
|||||||
@ -159,7 +159,7 @@ class SearchBarPlaceholderNode: ASDisplayNode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc private func backgroundTap(_ recognizer: UITapGestureRecognizer) {
|
@objc private func backgroundTap(_ recognizer: TapLongTapOrDoubleTapGestureRecognizer) {
|
||||||
if case .ended = recognizer.state {
|
if case .ended = recognizer.state {
|
||||||
self.backgroundNode.layer.animate(from: (self.backgroundNode.backgroundColor ?? self.foregroundColor).cgColor, to: self.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.2, completion: { _ in
|
self.backgroundNode.layer.animate(from: (self.backgroundNode.backgroundColor ?? self.foregroundColor).cgColor, to: self.foregroundColor.cgColor, keyPath: "backgroundColor", timingFunction: kCAMediaTimingFunctionEaseInEaseOut, duration: 0.2, completion: { _ in
|
||||||
self.backgroundNode.backgroundColor = self.foregroundColor
|
self.backgroundNode.backgroundColor = self.foregroundColor
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user