Added votes tooltips on polls

Added track switching on panel swipes
This commit is contained in:
Ilya Laktyushin 2019-04-06 23:48:24 +04:00
parent 6c5a7dbcfe
commit 8fbcfd0e88
16 changed files with 754 additions and 698 deletions

View File

@ -108,7 +108,7 @@ final class ChatBotInfoItemNode: ListViewItemNode {
break
case .ignore:
return .fail
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .call, .openMessage, .timecode:
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .call, .openMessage, .timecode, .tooltip:
return .waitForSingleTap
}
}

View File

@ -115,6 +115,17 @@ enum ChatItemGalleryFooterContentTapAction {
case ignore
}
class CaptionScrollWrapperNode: ASDisplayNode {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if result == self.view, let subnode = self.subnodes?.first {
return subnode.hitTest(self.view.convert(point, to: subnode.view), with: event)
} else {
return result
}
}
}
final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScrollViewDelegate {
private let context: AccountContext
private var theme: PresentationTheme
@ -124,7 +135,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
private let deleteButton: UIButton
private let actionButton: UIButton
private let maskNode: ASDisplayNode
private let scrollWrapperNode: ASDisplayNode
private let scrollWrapperNode: CaptionScrollWrapperNode
private let scrollNode: ASScrollNode
private let textNode: ImmediateTextNode
@ -230,7 +241,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
self.deleteButton.setImage(deleteImage, for: [.normal])
self.actionButton.setImage(actionImage, for: [.normal])
self.scrollWrapperNode = ASDisplayNode()
self.scrollWrapperNode = CaptionScrollWrapperNode()
self.scrollWrapperNode.clipsToBounds = true
self.scrollNode = ASScrollNode()
@ -338,16 +349,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
override func didLoad() {
super.didLoad()
self.scrollNode.view.delegate = self
if let maskImage = captionMaskImage {
let mask = CALayer()
mask.contents = maskImage.cgImage
mask.contentsScale = maskImage.scale
//mask.contentsCenter = CGRect(x: max(corners.topLeft.radius, corners.bottomLeft.radius) / maskImage.size.width, y: max(corners.topLeft.radius, corners.topRight.radius) / maskImage.size.height, width: (maskImage.size.width - max(corners.topLeft.radius, corners.bottomLeft.radius) - max(corners.topRight.radius, corners.bottomRight.radius)) / maskImage.size.width, height: (maskImage.size.height - max(corners.topLeft.radius, corners.topRight.radius) - max(corners.bottomLeft.radius, corners.bottomRight.radius)) / maskImage.size.height)
//self.scrollWrapperNode.layer.mask = mask
//self.scrollWrapperNode.layer.mask?.frame = self.scrollWrapperNode.bounds
}
self.scrollNode.view.showsVerticalScrollIndicator = false
}
private func actionForAttributes(_ attributes: [NSAttributedStringKey: Any]) -> GalleryControllerInteractionTapAction? {
@ -488,19 +490,10 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
self.requestLayout?(.immediate)
}
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let result = super.hitTest(point, with: event)
if self.scrollWrapperNode.frame.contains(point) {
return self.scrollNode.view
} else {
return result
}
}
override func updateLayout(size: CGSize, metrics: LayoutMetrics, leftInset: CGFloat, rightInset: CGFloat, bottomInset: CGFloat, contentInset: CGFloat, transition: ContainedViewLayoutTransition) -> CGFloat {
let width = size.width
var bottomInset = bottomInset
if bottomInset < 30.0 {
if !bottomInset.isZero && bottomInset < 30.0 {
bottomInset -= 7.0
}
var panelHeight: CGFloat = 44.0 + bottomInset
@ -546,8 +539,7 @@ final class ChatItemGalleryFooterContentNode: GalleryFooterContentNode, UIScroll
panelHeight = max(0.0, panelHeight + visibleTextPanelHeight + textOffset)
if self.scrollNode.view.isScrollEnabled {
if self.scrollWrapperNode.layer.mask == nil {
let maskImage = captionMaskImage!
if self.scrollWrapperNode.layer.mask == nil, let maskImage = captionMaskImage {
let maskLayer = CALayer()
maskLayer.contents = maskImage.cgImage
maskLayer.contentsScale = maskImage.scale

View File

@ -74,6 +74,7 @@ enum ChatMessageBubbleContentTapAction {
case call(PeerId)
case openMessage
case timecode(Double, String)
case tooltip(String, ASDisplayNode?, CGRect?)
case ignore
}

View File

@ -257,7 +257,7 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
break
case .ignore:
return .fail
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .call, .openMessage, .timecode:
case .url, .peerMention, .textMention, .botCommand, .hashtag, .instantPage, .wallpaper, .call, .openMessage, .timecode, .tooltip:
return .waitForSingleTap
}
}
@ -1761,6 +1761,12 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
item.controllerInteraction.seekToTimecode(mediaMessage, timecode, forceOpen)
}
break loop
case let .tooltip(text, node, rect):
foundTapAction = true
if let item = self.item {
let _ = item.controllerInteraction.displayMessageTooltip(item.message.id, text, node, rect)
}
break loop
}
}
if !foundTapAction {
@ -1819,6 +1825,8 @@ class ChatMessageBubbleItemNode: ChatMessageItemView {
item.controllerInteraction.longTap(.timecode(timecode, text), mediaMessage)
}
break loop
case .tooltip:
break
}
}
if !foundTapAction, let tapMessage = tapMessage {

View File

@ -681,7 +681,7 @@ class ChatMessageInstantVideoItemNode: ChatMessageItemView {
let offset: CGFloat = incoming ? 42.0 : 0.0
if let selectionNode = self.selectionNode {
selectionNode.updateSelected(selected, animated: false)
selectionNode.updateSelected(selected, animated: animated)
selectionNode.frame = CGRect(origin: CGPoint(x: -offset, y: 0.0), size: CGSize(width: self.contentBounds.size.width, height: self.contentBounds.size.height))
self.subnodeTransform = CATransform3DMakeTranslation(offset, 0.0, 0.0);
} else {

View File

@ -301,6 +301,7 @@ private func generatePercentageAnimationImages(presentationData: ChatPresentatio
private struct ChatMessagePollOptionResult: Equatable {
let normalized: CGFloat
let percent: Int
let count: Int32
}
private final class ChatMessagePollOptionNode: ASDisplayNode {
@ -314,7 +315,7 @@ private final class ChatMessagePollOptionNode: ASDisplayNode {
private let resultBarNode: ASImageNode
var option: TelegramMediaPollOption?
private var currentResult: ChatMessagePollOptionResult?
public private(set) var currentResult: ChatMessagePollOptionResult?
var pressed: (() -> Void)?
override init() {
@ -727,12 +728,12 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
var optionResult: ChatMessagePollOptionResult?
if let count = optionVoterCount[i] {
if maxOptionVoterCount != 0 && totalVoterCount != 0 {
optionResult = ChatMessagePollOptionResult(normalized: CGFloat(count) / CGFloat(maxOptionVoterCount), percent: optionVoterCounts[i])
optionResult = ChatMessagePollOptionResult(normalized: CGFloat(count) / CGFloat(maxOptionVoterCount), percent: optionVoterCounts[i], count: count)
} else if poll.isClosed {
optionResult = ChatMessagePollOptionResult(normalized: 0, percent: 0)
optionResult = ChatMessagePollOptionResult(normalized: 0, percent: 0, count: 0)
}
} else if poll.isClosed {
optionResult = ChatMessagePollOptionResult(normalized: 0, percent: 0)
optionResult = ChatMessagePollOptionResult(normalized: 0, percent: 0, count: 0)
}
let result = makeLayout(item.context.account.peerId, item.presentationData, item.message, option, optionResult, constrainedSize.width - layoutConstants.bubble.borderInset * 2.0)
boundingSize.width = max(boundingSize.width, result.minimumWidth + layoutConstants.bubble.borderInset * 2.0)
@ -922,55 +923,21 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
}
} else {
for optionNode in self.optionNodes {
if optionNode.isUserInteractionEnabled {
if optionNode.frame.contains(point) {
if optionNode.frame.contains(point) {
if optionNode.isUserInteractionEnabled {
return .ignore
} else if let result = optionNode.currentResult, let item = self.item {
let string: String
if result.count == 0 {
string = item.presentationData.strings.MessagePoll_NoVotes
} else {
string = item.presentationData.strings.MessagePoll_VotedCount(result.count)
}
return .tooltip(string, optionNode, optionNode.bounds.offsetBy(dx: 0.0, dy: 10.0))
}
}
}
return .none
}
}
override func updateTouchesAtPoint(_ point: CGPoint?) {
if let item = self.item {
/*var rects: [CGRect]?
if let point = point {
let textNodeFrame = self.textNode.frame
if let (index, attributes) = self.textNode.attributesAtPoint(CGPoint(x: point.x - textNodeFrame.minX, y: point.y - textNodeFrame.minY)) {
let possibleNames: [String] = [
TelegramTextAttributes.URL,
TelegramTextAttributes.PeerMention,
TelegramTextAttributes.PeerTextMention,
TelegramTextAttributes.BotCommand,
TelegramTextAttributes.Hashtag
]
for name in possibleNames {
if let _ = attributes[NSAttributedStringKey(rawValue: name)] {
rects = self.textNode.attributeRects(name: name, at: index)
break
}
}
}
}
if let rects = rects {
let linkHighlightingNode: LinkHighlightingNode
if let current = self.linkHighlightingNode {
linkHighlightingNode = current
} else {
linkHighlightingNode = LinkHighlightingNode(color: item.message.effectivelyIncoming(item.account.peerId) ? item.presentationData.theme.theme.chat.bubble.incomingLinkHighlightColor : item.presentationData.theme.theme.chat.bubble.outgoingLinkHighlightColor)
self.linkHighlightingNode = linkHighlightingNode
self.insertSubnode(linkHighlightingNode, belowSubnode: self.textNode)
}
linkHighlightingNode.frame = self.textNode.frame
linkHighlightingNode.updateRects(rects)
} else if let linkHighlightingNode = self.linkHighlightingNode {
self.linkHighlightingNode = nil
linkHighlightingNode.layer.animateAlpha(from: 1.0, to: 0.0, duration: 0.18, removeOnCompletion: false, completion: { [weak linkHighlightingNode] _ in
linkHighlightingNode?.removeFromSupernode()
})
}*/
}
}
}

View File

@ -674,7 +674,7 @@ class ChatMessageStickerItemNode: ChatMessageItemView {
let offset: CGFloat = incoming ? 42.0 : 0.0
if let selectionNode = self.selectionNode {
selectionNode.updateSelected(selected, animated: false)
selectionNode.updateSelected(selected, animated: animated)
selectionNode.frame = CGRect(origin: CGPoint(x: -offset, y: 0.0), size: CGSize(width: self.contentBounds.size.width, height: self.contentBounds.size.height))
self.subnodeTransform = CATransform3DMakeTranslation(offset, 0.0, 0.0);
} else {

View File

@ -7,15 +7,135 @@ import TelegramCore
private let titleFont = Font.regular(12.0)
private let subtitleFont = Font.regular(10.0)
final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
private class MediaHeaderItemNode: ASDisplayNode {
private let titleNode: TextNode
private let subtitleNode: TextNode
override init() {
self.titleNode = TextNode()
self.titleNode.isUserInteractionEnabled = false
self.titleNode.displaysAsynchronously = false
self.subtitleNode = TextNode()
self.subtitleNode.isUserInteractionEnabled = false
self.subtitleNode.displaysAsynchronously = false
super.init()
self.isUserInteractionEnabled = false
self.addSubnode(self.titleNode)
self.addSubnode(self.subtitleNode)
}
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, theme: PresentationTheme, strings: PresentationStrings, dateTimeFormat: PresentationDateTimeFormat, playbackItem: SharedMediaPlaylistItem?, transition: ContainedViewLayoutTransition) -> (NSAttributedString?, NSAttributedString?, Bool) {
var rateButtonHidden = false
var titleString: NSAttributedString?
var subtitleString: NSAttributedString?
if let playbackItem = playbackItem, let displayData = playbackItem.displayData {
switch displayData {
case let .music(title, performer, _):
rateButtonHidden = true
let titleText: String = title ?? "Unknown Track"
let subtitleText: String = performer ?? "Unknown Artist"
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: theme.rootController.navigationBar.secondaryTextColor)
case let .voice(author, peer):
rateButtonHidden = false
let titleText: String = author?.displayTitle ?? ""
let subtitleText: String
if let peer = peer {
if peer is TelegramGroup || peer is TelegramChannel {
subtitleText = peer.displayTitle
} else {
subtitleText = strings.MusicPlayer_VoiceNote
}
} else {
subtitleText = strings.MusicPlayer_VoiceNote
}
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: theme.rootController.navigationBar.secondaryTextColor)
case let .instantVideo(author, peer, timestamp):
rateButtonHidden = false
let titleText: String = author?.displayTitle ?? ""
var subtitleText: String
if let peer = peer {
if peer is TelegramGroup || peer is TelegramChannel {
subtitleText = peer.displayTitle
} else {
subtitleText = strings.Message_VideoMessage
}
} else {
subtitleText = strings.Message_VideoMessage
}
if titleText == subtitleText {
subtitleText = humanReadableStringForTimestamp(strings: strings, dateTimeFormat: dateTimeFormat, timestamp: timestamp)
}
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: theme.rootController.navigationBar.secondaryTextColor)
}
}
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
var titleSideInset: CGFloat = 12.0
if !rateButtonHidden {
titleSideInset += 52.0
}
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: size.width - titleSideInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: size.width - titleSideInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let _ = titleApply()
let _ = subtitleApply()
let minimizedTitleOffset: CGFloat = subtitleString == nil ? 6.0 : 0.0
let minimizedTitleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleLayout.size.width) / 2.0), y: 4.0 + minimizedTitleOffset), size: titleLayout.size)
let minimizedSubtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleLayout.size.width) / 2.0), y: 20.0), size: subtitleLayout.size)
transition.updateFrame(node: self.titleNode, frame: minimizedTitleFrame)
transition.updateFrame(node: self.subtitleNode, frame: minimizedSubtitleFrame)
return (titleString, subtitleString, rateButtonHidden)
}
}
private func generateMaskImage(color: UIColor) -> UIImage? {
return generateImage(CGSize(width: 12.0, height: 2.0), opaque: false, rotatedContext: { size, context in
let bounds = CGRect(origin: CGPoint(), size: size)
context.clear(bounds)
let gradientColors = [color.cgColor, color.withAlphaComponent(0.0).cgColor] as CFArray
var locations: [CGFloat] = [0.0, 1.0]
let colorSpace = CGColorSpaceCreateDeviceRGB()
let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: 0.0), end: CGPoint(x: 12.0, y: 0.0), options: CGGradientDrawingOptions())
})
}
final class MediaNavigationAccessoryHeaderNode: ASDisplayNode, UIScrollViewDelegate {
static let minimizedHeight: CGFloat = 37.0
private var theme: PresentationTheme
private var strings: PresentationStrings
private var dateTimeFormat: PresentationDateTimeFormat
private let titleNode: TextNode
private let subtitleNode: TextNode
private let scrollNode: ASScrollNode
private var initialContentOffset: CGFloat?
private let leftMaskNode: ASImageNode
private let rightMaskNode: ASImageNode
private let currentItemNode: MediaHeaderItemNode
private let previousItemNode: MediaHeaderItemNode
private let nextItemNode: MediaHeaderItemNode
private let closeButton: HighlightableButtonNode
private let actionButton: HighlightTrackingButtonNode
@ -42,6 +162,8 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
var close: (() -> Void)?
var toggleRate: (() -> Void)?
var togglePlayPause: (() -> Void)?
var playPrevious: (() -> Void)?
var playNext: (() -> Void)?
var voiceBaseRate: AudioPlaybackRate? = nil {
didSet {
@ -69,9 +191,9 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
}
}
var playbackItem: SharedMediaPlaylistItem? {
var playbackItems: (SharedMediaPlaylistItem?, SharedMediaPlaylistItem?, SharedMediaPlaylistItem?)? {
didSet {
if !arePlaylistItemsEqual(self.playbackItem, oldValue), let layout = validLayout {
if !arePlaylistItemsEqual(self.playbackItems?.0, oldValue?.0) || !arePlaylistItemsEqual(self.playbackItems?.1, oldValue?.1) || !arePlaylistItemsEqual(self.playbackItems?.2, oldValue?.2), let layout = validLayout {
self.updateLayout(size: layout.0, leftInset: layout.1, rightInset: layout.2, transition: .immediate)
}
}
@ -82,12 +204,20 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
self.strings = presentationData.strings
self.dateTimeFormat = presentationData.dateTimeFormat
self.titleNode = TextNode()
self.titleNode.isUserInteractionEnabled = false
self.titleNode.displaysAsynchronously = false
self.subtitleNode = TextNode()
self.subtitleNode.isUserInteractionEnabled = false
self.subtitleNode.displaysAsynchronously = false
self.scrollNode = ASScrollNode()
self.currentItemNode = MediaHeaderItemNode()
self.previousItemNode = MediaHeaderItemNode()
self.nextItemNode = MediaHeaderItemNode()
self.leftMaskNode = ASImageNode()
self.leftMaskNode.contentMode = .scaleToFill
self.rightMaskNode = ASImageNode()
self.rightMaskNode.contentMode = .scaleToFill
let maskImage = generateMaskImage(color: self.theme.rootController.navigationBar.backgroundColor)
self.leftMaskNode.image = maskImage
self.rightMaskNode.image = maskImage
self.closeButton = HighlightableButtonNode()
self.closeButton.accessibilityLabel = "Stop playback"
@ -132,8 +262,13 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
self.clipsToBounds = true
self.addSubnode(self.titleNode)
self.addSubnode(self.subtitleNode)
self.addSubnode(self.scrollNode)
self.scrollNode.addSubnode(self.currentItemNode)
self.scrollNode.addSubnode(self.previousItemNode)
self.scrollNode.addSubnode(self.nextItemNode)
self.addSubnode(self.leftMaskNode)
self.addSubnode(self.rightMaskNode)
self.addSubnode(self.closeButton)
self.addSubnode(self.rateButton)
@ -205,6 +340,13 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
override func didLoad() {
super.didLoad()
self.view.disablesInteractiveTransitionGestureRecognizer = true
self.scrollNode.view.alwaysBounceHorizontal = true
self.scrollNode.view.delegate = self
self.scrollNode.view.isPagingEnabled = true
self.scrollNode.view.showsHorizontalScrollIndicator = false
self.scrollNode.view.showsVerticalScrollIndicator = false
let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:)))
self.tapRecognizer = tapRecognizer
self.view.addGestureRecognizer(tapRecognizer)
@ -215,6 +357,10 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
self.strings = presentationData.strings
self.dateTimeFormat = presentationData.dateTimeFormat
let maskImage = generateMaskImage(color: self.theme.rootController.navigationBar.backgroundColor)
self.leftMaskNode.image = maskImage
self.rightMaskNode.image = maskImage
self.closeButton.setImage(PresentationResourcesRootController.navigationPlayerCloseButton(self.theme), for: [])
self.actionPlayNode.image = PresentationResourcesRootController.navigationPlayerPlayIcon(self.theme)
self.actionPauseNode.image = PresentationResourcesRootController.navigationPlayerPauseIcon(self.theme)
@ -234,92 +380,75 @@ final class MediaNavigationAccessoryHeaderNode: ASDisplayNode {
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
self.changeTrack()
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
guard !decelerate else {
return
}
self.changeTrack()
}
private func changeTrack() {
guard let initialContentOffset = self.initialContentOffset else {
return
}
if self.scrollNode.view.contentOffset.x < initialContentOffset {
self.playPrevious?()
} else if self.scrollNode.view.contentOffset.x > initialContentOffset {
self.playNext?()
}
}
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {
self.validLayout = (size, leftInset, rightInset)
let minHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight
var titleString: NSAttributedString?
var subtitleString: NSAttributedString?
if let playbackItem = self.playbackItem, let displayData = playbackItem.displayData {
switch displayData {
case let .music(title, performer, _):
self.rateButton.isHidden = true
let titleText: String = title ?? "Unknown Track"
let subtitleText: String = performer ?? "Unknown Artist"
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: self.theme.rootController.navigationBar.secondaryTextColor)
case let .voice(author, peer):
self.rateButton.isHidden = false
let titleText: String = author?.displayTitle ?? ""
let subtitleText: String
if let peer = peer {
if peer is TelegramGroup || peer is TelegramChannel {
subtitleText = peer.displayTitle
} else {
subtitleText = self.strings.MusicPlayer_VoiceNote
}
} else {
subtitleText = self.strings.MusicPlayer_VoiceNote
}
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: self.theme.rootController.navigationBar.secondaryTextColor)
case let .instantVideo(author, peer, timestamp):
self.rateButton.isHidden = false
let titleText: String = author?.displayTitle ?? ""
var subtitleText: String
if let peer = peer {
if peer is TelegramGroup || peer is TelegramChannel {
subtitleText = peer.displayTitle
} else {
subtitleText = self.strings.Message_VideoMessage
}
} else {
subtitleText = self.strings.Message_VideoMessage
}
if titleText == subtitleText {
subtitleText = humanReadableStringForTimestamp(strings: self.strings, dateTimeFormat: self.dateTimeFormat, timestamp: timestamp)
}
titleString = NSAttributedString(string: titleText, font: titleFont, textColor: self.theme.rootController.navigationBar.primaryTextColor)
subtitleString = NSAttributedString(string: subtitleText, font: subtitleFont, textColor: self.theme.rootController.navigationBar.secondaryTextColor)
}
}
let makeTitleLayout = TextNode.asyncLayout(self.titleNode)
let makeSubtitleLayout = TextNode.asyncLayout(self.subtitleNode)
var titleSideInset: CGFloat = 80.0
if !self.rateButton.isHidden {
titleSideInset += 52.0
}
let (titleLayout, titleApply) = makeTitleLayout(TextNodeLayoutArguments(attributedString: titleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: size.width - titleSideInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let (subtitleLayout, subtitleApply) = makeSubtitleLayout(TextNodeLayoutArguments(attributedString: subtitleString, backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .middle, constrainedSize: CGSize(width: size.width - titleSideInset, height: 100.0), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))
let inset: CGFloat = 40.0 + leftInset
let constrainedSize = CGSize(width: size.width - inset * 2.0, height: size.height)
let (titleString, subtitleString, rateButtonHidden) = self.currentItemNode.updateLayout(size: constrainedSize, leftInset: leftInset, rightInset: rightInset, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, playbackItem: self.playbackItems?.0, transition: transition)
self.accessibilityAreaNode.accessibilityLabel = "\(titleString?.string ?? ""). \(subtitleString?.string ?? "")"
self.rateButton.isHidden = rateButtonHidden
let _ = titleApply()
let _ = subtitleApply()
let _ = self.previousItemNode.updateLayout(size: constrainedSize, leftInset: 0.0, rightInset: 0.0, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, playbackItem: self.playbackItems?.1, transition: transition)
let _ = self.nextItemNode.updateLayout(size: constrainedSize, leftInset: 0.0, rightInset: 0.0, theme: self.theme, strings: self.strings, dateTimeFormat: self.dateTimeFormat, playbackItem: self.playbackItems?.2, transition: transition)
let minimizedTitleOffset: CGFloat = subtitleString == nil ? 6.0 : 0.0
let constrainedBounds = CGRect(origin: CGPoint(), size: constrainedSize)
transition.updateFrame(node: self.scrollNode, frame: constrainedBounds.offsetBy(dx: inset, dy: 0.0))
let minimizedTitleFrame = CGRect(origin: CGPoint(x: floor((size.width - titleLayout.size.width) / 2.0), y: 4.0 + minimizedTitleOffset), size: titleLayout.size)
let minimizedSubtitleFrame = CGRect(origin: CGPoint(x: floor((size.width - subtitleLayout.size.width) / 2.0), y: 20.0), size: subtitleLayout.size)
var contentSize = constrainedSize
var contentOffset: CGFloat = 0.0
if self.playbackItems?.1 != nil {
contentSize.width += constrainedSize.width
contentOffset = constrainedSize.width
}
if self.playbackItems?.2 != nil {
contentSize.width += constrainedSize.width
}
transition.updateFrame(node: self.titleNode, frame: minimizedTitleFrame)
transition.updateFrame(node: self.subtitleNode, frame: minimizedSubtitleFrame)
self.previousItemNode.frame = constrainedBounds.offsetBy(dx: contentOffset - constrainedSize.width, dy: 0.0)
self.currentItemNode.frame = constrainedBounds.offsetBy(dx: contentOffset, dy: 0.0)
self.nextItemNode.frame = constrainedBounds.offsetBy(dx: contentOffset + constrainedSize.width, dy: 0.0)
self.leftMaskNode.frame = CGRect(x: inset, y: 0.0, width: 12.0, height: minHeight)
self.rightMaskNode.transform = CATransform3DMakeScale(-1.0, 1.0, 1.0)
self.rightMaskNode.frame = CGRect(x: size.width - inset - 12.0, y: 0.0, width: 12.0, height: minHeight)
self.scrollNode.view.contentSize = contentSize
self.scrollNode.view.contentOffset = CGPoint(x: contentOffset, y: 0.0)
self.initialContentOffset = contentOffset
let bounds = CGRect(origin: CGPoint(), size: size)
let closeButtonSize = self.closeButton.measure(CGSize(width: 100.0, height: 100.0))
transition.updateFrame(node: self.closeButton, frame: CGRect(origin: CGPoint(x: bounds.size.width - 44.0 - rightInset, y: 0.0), size: CGSize(width: 44.0, height: minHeight)))
let rateButtonSize = CGSize(width: 24.0, height: minHeight)
transition.updateFrame(node: self.rateButton, frame: CGRect(origin: CGPoint(x: bounds.size.width - 18.0 - closeButtonSize.width - 18.0 - rateButtonSize.width - rightInset, y: 0.0), size: rateButtonSize))
transition.updateFrame(node: self.actionPlayNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
transition.updateFrame(node: self.actionPauseNode, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
transition.updateFrame(node: self.actionButton, frame: CGRect(origin: CGPoint(x: leftInset, y: minimizedTitleFrame.minY - 4.0), size: CGSize(width: 40.0, height: 37.0)))
transition.updateFrame(node: self.actionButton, frame: CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: 40.0, height: 37.0)))
transition.updateFrame(node: self.scrubbingNode, frame: CGRect(origin: CGPoint(x: 0.0, y: 37.0 - 2.0), size: CGSize(width: size.width, height: 2.0)))
transition.updateFrame(node: self.separatorNode, frame: CGRect(origin: CGPoint(x: 0.0, y: minHeight - UIScreenPixel), size: CGSize(width: size.width, height: UIScreenPixel)))

View File

@ -10,6 +10,8 @@ final class MediaNavigationAccessoryPanel: ASDisplayNode {
var toggleRate: (() -> Void)?
var togglePlayPause: (() -> Void)?
var tapAction: (() -> Void)?
var playPrevious: (() -> Void)?
var playNext: (() -> Void)?
init(context: AccountContext) {
self.containerNode = MediaNavigationAccessoryContainerNode(context: context)
@ -18,24 +20,34 @@ final class MediaNavigationAccessoryPanel: ASDisplayNode {
self.addSubnode(self.containerNode)
containerNode.headerNode.close = { [weak self] in
self.containerNode.headerNode.close = { [weak self] in
if let strongSelf = self, let close = strongSelf.close {
close()
}
}
containerNode.headerNode.toggleRate = { [weak self] in
self.containerNode.headerNode.toggleRate = { [weak self] in
self?.toggleRate?()
}
containerNode.headerNode.togglePlayPause = { [weak self] in
self.containerNode.headerNode.togglePlayPause = { [weak self] in
if let strongSelf = self, let togglePlayPause = strongSelf.togglePlayPause {
togglePlayPause()
}
}
containerNode.headerNode.tapAction = { [weak self] in
self.containerNode.headerNode.tapAction = { [weak self] in
if let strongSelf = self, let tapAction = strongSelf.tapAction {
tapAction()
}
}
self.containerNode.headerNode.playPrevious = { [weak self] in
if let strongSelf = self, let playPrevious = strongSelf.playPrevious {
playPrevious()
}
}
self.containerNode.headerNode.playNext = { [weak self] in
if let strongSelf = self, let playNext = strongSelf.playNext {
playNext()
}
}
}
func updateLayout(size: CGSize, leftInset: CGFloat, rightInset: CGFloat, transition: ContainedViewLayoutTransition) {

View File

@ -16,51 +16,14 @@ public struct ParsedSecureIdUrl {
}
public func parseProxyUrl(_ url: URL) -> ProxyServerSettings? {
guard let query = url.query, url.scheme == "tg" else {
guard let proxy = parseProxyUrl(url.absoluteString) else {
return nil
}
if url.host == "socks" || url.host == "proxy" {
if let components = URLComponents(string: "/?" + query) {
var server: String?
var port: String?
var user: String?
var pass: String?
var secret: String?
if let queryItems = components.queryItems {
for queryItem in queryItems {
if let value = queryItem.value {
if queryItem.name == "server" || queryItem.name == "proxy" {
server = value
} else if queryItem.name == "port" {
port = value
} else if queryItem.name == "user" {
user = value
} else if queryItem.name == "pass" {
pass = value
} else if queryItem.name == "secret" {
secret = value
}
}
}
}
if let server = server, !server.isEmpty, let port = port, let portValue = Int32(port), let _ = Int32(port) {
let connection: ProxyServerConnection
if let secret = secret {
let data = dataWithHexString(secret)
if data.count == 16 || (data.count == 17 && MTSocksProxySettings.secretSupportsExtendedPadding(data)) {
connection = .mtp(secret: data)
} else {
return nil
}
} else {
connection = .socks5(username: user, password: pass)
}
return ProxyServerSettings(host: server, port: portValue, connection: connection)
}
}
if let secret = proxy.secret, secret.count == 16 || (secret.count == 17 && MTSocksProxySettings.secretSupportsExtendedPadding(secret)) {
return ProxyServerSettings(host: proxy.host, port: proxy.port, connection: .mtp(secret: secret))
} else {
return ProxyServerSettings(host: proxy.host, port: proxy.port, connection: .socks5(username: proxy.username, password: proxy.password))
}
return nil
}
public func parseSecureIdUrl(_ url: URL) -> ParsedSecureIdUrl? {

View File

@ -3676,526 +3676,526 @@ public final class PresentationStrings {
public var Channel_Setup_TypePublicHelp: String { return self._s[3283]! }
public var Passport_Identity_EditInternalPassport: String { return self._s[3284]! }
public var PhotoEditor_Skip: String { return self._s[3285]! }
public func ForwardedMessages(_ value: Int32) -> String {
public func LastSeen_HoursAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[0 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_StatusMembers(_ value: Int32) -> String {
public func Notifications_Exceptions(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[1 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Passport_Scans(_ value: Int32) -> String {
public func Map_ETAHours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[2 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Weeks(_ value: Int32) -> String {
public func SharedMedia_Generic(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[3 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_RemoveMaskCount(_ value: Int32) -> String {
public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[4 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteExpires_Minutes(_ value: Int32) -> String {
public func AttachmentMenu_SendVideo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[5 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, stringValue)
public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[6 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[7 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MessageTimer_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func AttachmentMenu_SendItem(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortDays(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func ForwardedContacts(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteFor_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[8 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func Chat_DeleteMessagesConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_SharePhoto(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Watch_UserInfo_Mute(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func ForwardedStickers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Photo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Months(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortHours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, stringValue)
}
public func AttachmentMenu_SendGif(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedGifs(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Link(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ChatList_SelectedChats(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LastSeen_HoursAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MessageTimer_ShortSeconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func Call_Seconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Contacts_ImportersCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedAudios(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LastSeen_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Map_ETAHours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Map_ETAMinutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_StickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MuteExpires_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_AddMaskCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func ForwardedPhotos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Invitation_Members(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreSelfExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue)
}
public func QuickSend_Photos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_ShortSeconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue)
}
public func InviteText_ContactsCountText(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteFor_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_ShareItem(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue)
}
public func CreatePoll_AddMoreOptions(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedVideos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, _0, _1)
}
public func ChatList_DeleteConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func GroupInfo_ParticipantCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_AddStickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_RemoveStickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func Notification_GameScoreSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LiveLocationUpdated_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func AttachmentMenu_SendPhoto(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[9 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedLocations(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[10 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func SharedMedia_Video(_ value: Int32) -> String {
public func Watch_UserInfo_Mute(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[11 * 6 + Int(form.rawValue)]!, stringValue)
}
public func UserCount(_ value: Int32) -> String {
public func Notification_GameScoreSelfSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[12 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Generic(_ value: Int32) -> String {
public func SharedMedia_Link(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[13 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedPolls(_ value: Int32) -> String {
public func ServiceMessage_GameScoreExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortWeeks(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteExpires_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, stringValue)
}
public func AttachmentMenu_SendVideo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[14 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedVideoMessages(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[15 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessagePoll_VotedCount(_ value: Int32) -> String {
public func Contacts_ImportersCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[16 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreExtended(_ value: Int32) -> String {
public func ServiceMessage_GameScoreSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[17 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_Exceptions(_ value: Int32) -> String {
public func InviteText_ContactsCountText(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[18 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_Minutes(_ value: Int32) -> String {
public func ForwardedAuthorsOthers(_ selector: Int32, _ _0: String, _ _1: String) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[19 * 6 + Int(form.rawValue)]!, _0, _1)
}
public func PUSH_CHANNEL_MESSAGE_VIDEOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[20 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func ForwardedContacts(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Years(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedFiles(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_StatusOnline(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue)
}
public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Seconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LiveLocation_MenuChatsCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_ShortMinutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_File(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[21 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGE_ROUNDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, _2, _1, _3)
return String(format: self._ps[22 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func CreatePoll_AddMoreOptions(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[23 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreSelfExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[24 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Watch_LastSeen_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[25 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_ShareVideo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue)
return String(format: self._ps[26 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_StatusSubscribers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue)
public func PUSH_MESSAGE_FWDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[27 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MessageTimer_ShortMinutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[28 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[29 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortWeeks(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[30 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedPolls(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[31 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PasscodeSettings_FailedAttempts(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[32 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Watch_LastSeen_HoursAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[33 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGE_VIDEOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[34 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func StickerPack_RemoveStickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[35 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PrivacyLastSeenSettings_AddUsers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[36 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_StickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[37 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[38 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_AddMaskCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[39 * 6 + Int(form.rawValue)]!, stringValue)
}
public func UserCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[40 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGES(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[41 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func PUSH_CHAT_MESSAGE_FWDS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[42 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func AttachmentMenu_SendPhoto(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[43 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_StatusOnline(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[44 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[45 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MuteFor_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[46 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGE_PHOTOS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[47 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func Call_ShortSeconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[48 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHAT_MESSAGE_PHOTOS(_ selector: Int32, _ _2: String, _ _1: String, _ _3: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[49 * 6 + Int(form.rawValue)]!, _2, _1, _3)
}
public func PUSH_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[50 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func Invitation_Members(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[51 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[52 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ServiceMessage_GameScoreSelfSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[53 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedFiles(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[54 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LiveLocation_MenuChatsCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[55 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedGifs(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[56 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Passport_Scans(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[57 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortDays(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[58 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_ShareItem(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[59 * 6 + Int(form.rawValue)]!, stringValue)
}
public func LastSeen_MinutesAgo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[60 * 6 + Int(form.rawValue)]!, stringValue)
}
public func DialogList_LiveLocationChatsCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[61 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedVideos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[62 * 6 + Int(form.rawValue)]!, stringValue)
}
public func QuickSend_Photos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[63 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Forward_ConfirmMultipleFiles(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[64 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteExpires_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[65 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[66 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreSimple(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[67 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortSeconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[68 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_ShortMinutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[69 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_StatusSubscribers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[70 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ChatList_SelectedChats(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[71 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[72 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteExpires_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[73 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[74 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_AddStickerCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[75 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Seconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[76 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Wallpaper_DeleteConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[77 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Map_ETAMinutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[78 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Media_SharePhoto(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[79 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notifications_ExceptionMuteExpires_Minutes(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[80 * 6 + Int(form.rawValue)]!, stringValue)
}
public func GroupInfo_ParticipantCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[81 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedMessages(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[82 * 6 + Int(form.rawValue)]!, stringValue)
}
public func StickerPack_RemoveMaskCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[83 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteFor_Hours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[84 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_MESSAGE_ROUNDS(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[85 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func MessagePoll_VotedCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[86 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_File(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[87 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Call_Seconds(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[88 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_ShortHours(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[89 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Years(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[90 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_DeleteItemsConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[91 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Conversation_LiveLocationMembersCount(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[92 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedStickers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[93 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MuteExpires_Days(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[94 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[95 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Weeks(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[96 * 6 + Int(form.rawValue)]!, stringValue)
}
public func MessageTimer_Months(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[97 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ChatList_DeleteConfirmation(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[98 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedPhotos(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[99 * 6 + Int(form.rawValue)]!, stringValue)
}
public func PUSH_CHANNEL_MESSAGES(_ selector: Int32, _ _1: String, _ _2: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, selector)
return String(format: self._ps[100 * 6 + Int(form.rawValue)]!, _1, _2)
}
public func Conversation_StatusMembers(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[101 * 6 + Int(form.rawValue)]!, stringValue)
}
public func AttachmentMenu_SendItem(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[102 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Video(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[103 * 6 + Int(form.rawValue)]!, stringValue)
}
public func SharedMedia_Photo(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[104 * 6 + Int(form.rawValue)]!, stringValue)
}
public func ForwardedAudios(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[105 * 6 + Int(form.rawValue)]!, stringValue)
}
public func AttachmentMenu_SendGif(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[106 * 6 + Int(form.rawValue)]!, stringValue)
}
public func Notification_GameScoreSelfSimple(_ value: Int32) -> String {
public func ServiceMessage_GameScoreSelfExtended(_ value: Int32) -> String {
let form = presentationStringsPluralizationForm(self.lc, value)
let stringValue = presentationStringsFormattedNumber(value, self.groupingSeparator)
return String(format: self._ps[107 * 6 + Int(form.rawValue)]!, stringValue)

View File

@ -207,15 +207,19 @@ final class SharedMediaPlayerItemPlaybackState: Equatable {
let playlistId: SharedMediaPlaylistId
let playlistLocation: SharedMediaPlaylistLocation
let item: SharedMediaPlaylistItem
let previousItem: SharedMediaPlaylistItem?
let nextItem: SharedMediaPlaylistItem?
let status: MediaPlayerStatus
let order: MusicPlaybackSettingsOrder
let looping: MusicPlaybackSettingsLooping
let playerIndex: Int32
init(playlistId: SharedMediaPlaylistId, playlistLocation: SharedMediaPlaylistLocation, item: SharedMediaPlaylistItem, status: MediaPlayerStatus, order: MusicPlaybackSettingsOrder, looping: MusicPlaybackSettingsLooping, playerIndex: Int32) {
init(playlistId: SharedMediaPlaylistId, playlistLocation: SharedMediaPlaylistLocation, item: SharedMediaPlaylistItem, previousItem: SharedMediaPlaylistItem?, nextItem: SharedMediaPlaylistItem?, status: MediaPlayerStatus, order: MusicPlaybackSettingsOrder, looping: MusicPlaybackSettingsLooping, playerIndex: Int32) {
self.playlistId = playlistId
self.playlistLocation = playlistLocation
self.item = item
self.previousItem = previousItem
self.nextItem = nextItem
self.status = status
self.order = order
self.looping = looping
@ -229,6 +233,12 @@ final class SharedMediaPlayerItemPlaybackState: Equatable {
if !arePlaylistItemsEqual(lhs.item, rhs.item) {
return false
}
if !arePlaylistItemsEqual(lhs.previousItem, rhs.previousItem) {
return false
}
if !arePlaylistItemsEqual(lhs.nextItem, rhs.nextItem) {
return false
}
if lhs.status != rhs.status {
return false
}
@ -544,7 +554,6 @@ final class SharedMediaPlayer {
node.setSoundEnabled(false)
}
}
//strongSelf.playbackItem?.seek(0.0)
strongSelf.playedToEnd?()
}
}
@ -559,7 +568,7 @@ final class SharedMediaPlayer {
if let playbackItem = strongSelf.playbackItem, let item = state.item {
strongSelf.playbackStateValue.set(playbackItem.playbackStatus
|> map { itemStatus in
return .item(SharedMediaPlayerItemPlaybackState(playlistId: playlistId, playlistLocation: playlistLocation, item: item, status: itemStatus, order: state.order, looping: state.looping, playerIndex: playerIndex))
return .item(SharedMediaPlayerItemPlaybackState(playlistId: playlistId, playlistLocation: playlistLocation, item: item, previousItem: state.previousItem, nextItem: state.nextItem, status: itemStatus, order: state.order, looping: state.looping, playerIndex: playerIndex))
})
strongSelf.markItemAsPlayedDisposable.set((playbackItem.playbackStatus
|> filter { status in

View File

@ -55,7 +55,7 @@ public class TelegramController: ViewController {
private var mediaStatusDisposable: Disposable?
private var locationBroadcastDisposable: Disposable?
private(set) var playlistStateAndType: (SharedMediaPlaylistItem, MusicPlaybackSettingsOrder, MediaManagerPlayerType, Account)?
private(set) var playlistStateAndType: (SharedMediaPlaylistItem, SharedMediaPlaylistItem?, SharedMediaPlaylistItem?, MusicPlaybackSettingsOrder, MediaManagerPlayerType, Account)?
var tempVoicePlaylistEnded: (() -> Void)?
var tempVoicePlaylistItemChanged: ((SharedMediaPlaylistItem?, SharedMediaPlaylistItem?) -> Void)?
@ -124,9 +124,11 @@ public class TelegramController: ViewController {
return
}
if !arePlaylistItemsEqual(strongSelf.playlistStateAndType?.0, playlistStateAndType?.1.item) ||
strongSelf.playlistStateAndType?.1 != playlistStateAndType?.1.order || strongSelf.playlistStateAndType?.2 != playlistStateAndType?.2 {
!arePlaylistItemsEqual(strongSelf.playlistStateAndType?.1, playlistStateAndType?.1.previousItem) ||
!arePlaylistItemsEqual(strongSelf.playlistStateAndType?.2, playlistStateAndType?.1.nextItem) ||
strongSelf.playlistStateAndType?.3 != playlistStateAndType?.1.order || strongSelf.playlistStateAndType?.4 != playlistStateAndType?.2 {
var previousVoiceItem: SharedMediaPlaylistItem?
if let playlistStateAndType = strongSelf.playlistStateAndType, playlistStateAndType.2 == .voice {
if let playlistStateAndType = strongSelf.playlistStateAndType, playlistStateAndType.4 == .voice {
previousVoiceItem = playlistStateAndType.0
}
@ -137,10 +139,10 @@ public class TelegramController: ViewController {
strongSelf.tempVoicePlaylistItemChanged?(previousVoiceItem, updatedVoiceItem)
if let playlistStateAndType = playlistStateAndType {
strongSelf.playlistStateAndType = (playlistStateAndType.1.item, playlistStateAndType.1.order, playlistStateAndType.2, playlistStateAndType.0)
strongSelf.playlistStateAndType = (playlistStateAndType.1.item, playlistStateAndType.1.previousItem, playlistStateAndType.1.nextItem, playlistStateAndType.1.order, playlistStateAndType.2, playlistStateAndType.0)
} else {
var voiceEnded = false
if strongSelf.playlistStateAndType?.2 == .voice {
if strongSelf.playlistStateAndType?.4 == .voice {
voiceEnded = true
}
strongSelf.playlistStateAndType = nil
@ -417,13 +419,13 @@ public class TelegramController: ViewController {
mediaAccessoryPanelHidden = size != layout.metrics.widthClass
}
if let (item, _, type, _) = self.playlistStateAndType, !mediaAccessoryPanelHidden {
if let (item, previousItem, nextItem, _, type, _) = self.playlistStateAndType, !mediaAccessoryPanelHidden {
let panelHeight = MediaNavigationAccessoryHeaderNode.minimizedHeight
let panelFrame = CGRect(origin: CGPoint(x: 0.0, y: navigationHeight.isZero ? -panelHeight : (navigationHeight + additionalHeight + UIScreenPixel)), size: CGSize(width: layout.size.width, height: panelHeight))
if let (mediaAccessoryPanel, mediaType) = self.mediaAccessoryPanel, mediaType == type {
transition.updateFrame(layer: mediaAccessoryPanel.layer, frame: panelFrame)
mediaAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: transition)
mediaAccessoryPanel.containerNode.headerNode.playbackItem = item
mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, previousItem, nextItem)
let delayedStatus = self.context.sharedContext.mediaManager.globalMediaPlayerState
|> mapToSignal { value -> Signal<(Account, SharedMediaPlayerItemPlaybackStateOrLoading, MediaManagerPlayerType)?, NoError> in
@ -461,7 +463,7 @@ public class TelegramController: ViewController {
let mediaAccessoryPanel = MediaNavigationAccessoryPanel(context: self.context)
mediaAccessoryPanel.containerNode.headerNode.displayScrubber = type != .voice
mediaAccessoryPanel.close = { [weak self] in
if let strongSelf = self, let (_, _, type, _) = strongSelf.playlistStateAndType {
if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType {
strongSelf.context.sharedContext.mediaManager.setPlaylist(nil, type: type)
}
}
@ -486,19 +488,29 @@ public class TelegramController: ViewController {
return nextRate
}
|> deliverOnMainQueue).start(next: { baseRate in
guard let strongSelf = self, let (_, _, type, _) = strongSelf.playlistStateAndType else {
guard let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType else {
return
}
strongSelf.context.sharedContext.mediaManager.playlistControl(.setBaseRate(baseRate), type: type)
})
}
mediaAccessoryPanel.togglePlayPause = { [weak self] in
if let strongSelf = self, let (_, _, type, _) = strongSelf.playlistStateAndType {
if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType {
strongSelf.context.sharedContext.mediaManager.playlistControl(.playback(.togglePlayPause), type: type)
}
}
mediaAccessoryPanel.playPrevious = { [weak self] in
if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType {
strongSelf.context.sharedContext.mediaManager.playlistControl(.next, type: type)
}
}
mediaAccessoryPanel.playNext = { [weak self] in
if let strongSelf = self, let (_, _, _, _, type, _) = strongSelf.playlistStateAndType {
strongSelf.context.sharedContext.mediaManager.playlistControl(.previous, type: type)
}
}
mediaAccessoryPanel.tapAction = { [weak self] in
guard let strongSelf = self, let navigationController = strongSelf.navigationController as? NavigationController, let (state, order, type, account) = strongSelf.playlistStateAndType else {
guard let strongSelf = self, let _ = strongSelf.navigationController as? NavigationController, let (state, _, _, order, type, account) = strongSelf.playlistStateAndType else {
return
}
if let id = state.id as? PeerMessagesMediaPlaylistItemId {
@ -580,7 +592,7 @@ public class TelegramController: ViewController {
}
self.mediaAccessoryPanel = (mediaAccessoryPanel, type)
mediaAccessoryPanel.updateLayout(size: panelFrame.size, leftInset: layout.safeInsets.left, rightInset: layout.safeInsets.right, transition: .immediate)
mediaAccessoryPanel.containerNode.headerNode.playbackItem = item
mediaAccessoryPanel.containerNode.headerNode.playbackItems = (item, previousItem, nextItem)
mediaAccessoryPanel.containerNode.headerNode.playbackStatus = self.context.sharedContext.mediaManager.globalMediaPlayerState
|> map { state -> MediaPlayerStatus in
if let stateOrLoading = state?.1, case let .state(state) = stateOrLoading {

View File

@ -83,44 +83,6 @@ public final class TelegramRootController: NavigationController {
self.accountSettingsController = accountSettingsController
self.rootTabController = tabBarController
self.pushViewController(tabBarController, animated: false)
// guard let controller = self.viewControllers.last as? ViewController else {
// return
// }
//
// DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1.0) {
// let wrapperNode = ASDisplayNode()
// let bounds = controller.displayNode.bounds
// wrapperNode.frame = bounds
// wrapperNode.backgroundColor = .gray
// //controller.displayNode.addSubnode(wrapperNode)
//
// let label = TGMarqLabel(frame: CGRect())
// label.textColor = .white
// label.font = Font.regular(28.0)
// label.scrollDuration = 15.0
// label.fadeLength = 25.0
// label.trailingBuffer = 60.0
// label.animationDelay = 2.0
// label.text = "Lorem ipsum dolor sir amet, consecteur"
// label.sizeToFit()
// label.frame = CGRect(x: bounds.width / 2.0 - 100.0, y: 100.0, width: 200.0, height: label.frame.height)
// //wrapperNode.view.addSubview(label)
//
// let data = testLineChartData()
// let node = LineChartContainerNode(data: data)
// node.frame = CGRect(x: 0.0, y: 100.0, width: bounds.width, height: 280.0)
// node.updateLayout(size: node.frame.size)
// wrapperNode.addSubnode(node)
//
// self.wNode = wrapperNode
//
// let gesture = UITapGestureRecognizer(target: self, action: #selector(self.closeIt))
// wrapperNode.view.addGestureRecognizer(gesture)
// }
}
@objc func closeIt() {

View File

@ -641,6 +641,7 @@ final class UniversalVideoGalleryItemNode: ZoomableContentGalleryItemNode {
videoNode.seek(0.0)
videoNode.play()
} else {
self.hideStatusNodeUntilCentrality = false
videoNode.playOnceWithSound(playAndRecord: false, seek: seek, actionAtEnd: .stop)
}
}