Fix RTL in polls

Fix percentages in polls
This commit is contained in:
Peter 2018-12-19 18:28:36 +03:00
parent ea4b62939b
commit 3302f0ab4f
4 changed files with 63 additions and 12 deletions

View File

@ -400,7 +400,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
var activePoll: TelegramMediaPoll? var activePoll: TelegramMediaPoll?
for media in message.media { for media in message.media {
if let poll = media as? TelegramMediaPoll, !poll.isClosed { if let poll = media as? TelegramMediaPoll, !poll.isClosed, message.id.namespace == Namespaces.Message.Cloud, poll.pollId.namespace == Namespaces.Media.CloudPoll {
activePoll = poll activePoll = poll
} }
} }
@ -429,8 +429,34 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
interfaceInteraction.unpinMessage() interfaceInteraction.unpinMessage()
}))) })))
} }
}
if let _ = activePoll, messages[0].forwardInfo == nil, !messages[0].flags.contains(.Incoming) { if let _ = activePoll, messages[0].forwardInfo == nil {
var canStopPoll = false
if !messages[0].flags.contains(.Incoming) {
canStopPoll = true
} else {
var hasEditRights = false
if messages[0].id.namespace == Namespaces.Message.Cloud {
if message.id.peerId.namespace == Namespaces.Peer.SecretChat {
hasEditRights = false
} else if let author = message.author, author.id == account.peerId {
hasEditRights = true
} else if message.author?.id == message.id.peerId, let peer = message.peers[message.id.peerId] {
if let peer = peer as? TelegramChannel, case .broadcast = peer.info {
if peer.hasAdminRights(.canEditMessages) {
hasEditRights = true
}
}
}
}
if hasEditRights {
canStopPoll = true
}
}
if canStopPoll {
actions.append(.sheet(ChatMessageContextMenuSheetAction(color: .accent, title: chatPresentationInterfaceState.strings.Conversation_StopPoll, action: { actions.append(.sheet(ChatMessageContextMenuSheetAction(color: .accent, title: chatPresentationInterfaceState.strings.Conversation_StopPoll, action: {
interfaceInteraction.requestStopPollInMessage(messages[0].id) interfaceInteraction.requestStopPollInMessage(messages[0].id)
}))) })))

View File

@ -203,13 +203,13 @@ private final class ChatMessagePollOptionRadioNode: ASDisplayNode {
} }
} }
private let percentageFont = Font.bold(14.0) private let percentageFont = Font.bold(14.5)
private func generatePercentageImage(presentationData: ChatPresentationData, incoming: Bool, value: CGFloat) -> UIImage { private func generatePercentageImage(presentationData: ChatPresentationData, incoming: Bool, value: CGFloat) -> UIImage {
return generateImage(CGSize(width: 42.0, height: 20.0), rotatedContext: { size, context in return generateImage(CGSize(width: 42.0, height: 20.0), rotatedContext: { size, context in
UIGraphicsPushContext(context) UIGraphicsPushContext(context)
context.clear(CGRect(origin: CGPoint(), size: size)) context.clear(CGRect(origin: CGPoint(), size: size))
let percents = Int(value * 100.0) let percents = Int(round(value * 100.0))
let string = NSAttributedString(string: "\(percents)%", font: percentageFont, textColor: incoming ? presentationData.theme.theme.chat.bubble.incomingPrimaryTextColor : presentationData.theme.theme.chat.bubble.outgoingPrimaryTextColor, paragraphAlignment: .right) let string = NSAttributedString(string: "\(percents)%", font: percentageFont, textColor: incoming ? presentationData.theme.theme.chat.bubble.incomingPrimaryTextColor : presentationData.theme.theme.chat.bubble.outgoingPrimaryTextColor, paragraphAlignment: .right)
string.draw(in: CGRect(origin: CGPoint(x: 0.0, y: 2.0), size: size)) string.draw(in: CGRect(origin: CGPoint(x: 0.0, y: 2.0), size: size))
UIGraphicsPopContext() UIGraphicsPopContext()
@ -300,7 +300,7 @@ private final class ChatMessagePollOptionNode: ASDisplayNode {
return { accountPeerId, presentationData, message, option, optionResult, constrainedWidth in return { accountPeerId, presentationData, message, option, optionResult, constrainedWidth in
let leftInset: CGFloat = 50.0 let leftInset: CGFloat = 50.0
let rightInset: CGFloat = 18.0 let rightInset: CGFloat = 12.0
let incoming = message.effectivelyIncoming(accountPeerId) let incoming = message.effectivelyIncoming(accountPeerId)
@ -336,7 +336,11 @@ private final class ChatMessagePollOptionNode: ASDisplayNode {
node.addSubnode(titleNode) node.addSubnode(titleNode)
titleNode.isUserInteractionEnabled = false titleNode.isUserInteractionEnabled = false
} }
if titleLayout.hasRTL {
titleNode.frame = CGRect(origin: CGPoint(x: width - rightInset - titleLayout.size.width, y: 11.0), size: titleLayout.size)
} else {
titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 11.0), size: titleLayout.size) titleNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 11.0), size: titleLayout.size)
}
if shouldHaveRadioNode { if shouldHaveRadioNode {
let radioNode: ChatMessagePollOptionRadioNode let radioNode: ChatMessagePollOptionRadioNode
@ -368,11 +372,12 @@ private final class ChatMessagePollOptionNode: ASDisplayNode {
if let image = node.percentageImage { if let image = node.percentageImage {
node.percentageNode.frame = CGRect(origin: CGPoint(x: leftInset - 7.0 - image.size.width, y: 12.0), size: image.size) node.percentageNode.frame = CGRect(origin: CGPoint(x: leftInset - 7.0 - image.size.width, y: 12.0), size: image.size)
if animated, let optionResult = optionResult { if animated, let optionResult = optionResult {
let images = generatePercentageAnimationImages(presentationData: presentationData, incoming: incoming, from: previousResult?.absolute ?? 0.0, to: optionResult.absolute, duration: 0.4) let percentageDuration = 0.27
let images = generatePercentageAnimationImages(presentationData: presentationData, incoming: incoming, from: previousResult?.absolute ?? 0.0, to: optionResult.absolute, duration: percentageDuration)
if !images.isEmpty { if !images.isEmpty {
let animation = CAKeyframeAnimation(keyPath: "contents") let animation = CAKeyframeAnimation(keyPath: "contents")
animation.values = images.map { $0.cgImage! } animation.values = images.map { $0.cgImage! }
animation.duration = 0.4 * UIView.animationDurationFactor() animation.duration = percentageDuration * UIView.animationDurationFactor()
animation.calculationMode = kCAAnimationDiscrete animation.calculationMode = kCAAnimationDiscrete
node.percentageNode.layer.add(animation, forKey: "image") node.percentageNode.layer.add(animation, forKey: "image")
} }
@ -776,7 +781,11 @@ class ChatMessagePollBubbleContentNode: ChatMessageBubbleContentNode {
strongSelf.statusNode.removeFromSupernode() strongSelf.statusNode.removeFromSupernode()
} }
if textLayout.hasRTL {
strongSelf.textNode.frame = CGRect(origin: CGPoint(x: resultSize.width - textFrame.size.width - textInsets.left - layoutConstants.text.bubbleInsets.right, y: textFrame.origin.y), size: textFrame.size)
} else {
strongSelf.textNode.frame = textFrame strongSelf.textNode.frame = textFrame
}
strongSelf.typeNode.frame = CGRect(origin: CGPoint(x: textFrame.minX, y: textFrame.maxY + titleTypeSpacing), size: typeLayout.size) strongSelf.typeNode.frame = CGRect(origin: CGPoint(x: textFrame.minX, y: textFrame.maxY + titleTypeSpacing), size: typeLayout.size)
let _ = votersApply() let _ = votersApply()

View File

@ -101,7 +101,7 @@ func legacyAttachmentMenu(account: Account, peer: Peer, editMediaOptions: Messag
})! })!
itemViews.append(locationItem) itemViews.append(locationItem)
if !(peer is TelegramSecretChat) && canSendMessagesToPeer(peer) { if (peer is TelegramGroup || peer is TelegramChannel) && canSendMessagesToPeer(peer) {
let pollItem = TGMenuSheetButtonItemView(title: strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in let pollItem = TGMenuSheetButtonItemView(title: strings.AttachmentMenu_Poll, type: TGMenuSheetButtonTypeDefault, action: { [weak controller] in
controller?.dismiss(animated: true) controller?.dismiss(animated: true)
openPoll() openPoll()

View File

@ -79,7 +79,7 @@ private struct CollectableExternalShareItem {
let mediaReference: AnyMediaReference? let mediaReference: AnyMediaReference?
} }
private func collectExternalShareItems(postbox: Postbox, collectableItems: [CollectableExternalShareItem]) -> Signal<ExternalShareItemsState, NoError> { private func collectExternalShareItems(strings: PresentationStrings, postbox: Postbox, collectableItems: [CollectableExternalShareItem]) -> Signal<ExternalShareItemsState, NoError> {
var signals: [Signal<ExternalShareItemStatus, NoError>] = [] var signals: [Signal<ExternalShareItemStatus, NoError>] = []
for item in collectableItems { for item in collectableItems {
if let mediaReference = item.mediaReference, let file = mediaReference.media as? TelegramMediaFile { if let mediaReference = item.mediaReference, let file = mediaReference.media as? TelegramMediaFile {
@ -135,6 +135,19 @@ private func collectExternalShareItems(postbox: Postbox, collectableItems: [Coll
} }
} }
}) })
} else if let mediaReference = item.mediaReference, let poll = mediaReference.media as? TelegramMediaPoll {
var text = "📊 \(poll.text)"
text.append("\n\(strings.MessagePoll_LabelAnonymous)")
for option in poll.options {
text.append("\n\(option.text)")
}
let totalVoters = poll.results.totalVoters ?? 0
if totalVoters == 0 {
text.append("\n\(strings.MessagePoll_NoVotes)")
} else {
text.append("\n\(strings.MessagePoll_VotedCount(totalVoters))")
}
signals.append(.single(.done(.text(text))))
} }
if let url = item.url, let parsedUrl = URL(string: url) { if let url = item.url, let parsedUrl = URL(string: url) {
if signals.isEmpty { if signals.isEmpty {
@ -454,6 +467,9 @@ public final class ShareController: ViewController {
selectedMedia = image selectedMedia = image
} }
} }
case let _ as TelegramMediaPoll:
selectedMedia = media
break loop
default: default:
break break
} }
@ -468,7 +484,7 @@ public final class ShareController: ViewController {
case .fromExternal: case .fromExternal:
break break
} }
return (collectExternalShareItems(postbox: strongSelf.account.postbox, collectableItems: collectableItems) |> deliverOnMainQueue) |> map { state in return (collectExternalShareItems(strings: strongSelf.presentationData.strings, postbox: strongSelf.account.postbox, collectableItems: collectableItems) |> deliverOnMainQueue) |> map { state in
switch state { switch state {
case .progress: case .progress:
return .preparing return .preparing