mirror of
https://github.com/TelegramMessenger/Telegram-iOS.git
synced 2026-07-06 03:33:41 +02:00
Merge branch 'master' of gitlab.com:peter-iakovlev/telegram-ios
This commit is contained in:
commit
67945eb5a7
42 changed files with 1320 additions and 1442 deletions
|
|
@ -5474,3 +5474,5 @@ Any member of this group will be able to see messages in the channel.";
|
|||
"SetupUsername.ChangeLinkWarningGroup" = "Warning, if you change the short link to your group, it will loose its verified status. You will need to send a new application to @verification_bot";
|
||||
|
||||
"MuteFor.Forever" = "Mute Forever";
|
||||
|
||||
"Conversation.Dice" = "Send a 🎲 emoji to any chat to get a random number from Telegram.";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import UIKit
|
|||
|
||||
enum BaseConstants {
|
||||
static let defaultRange: ClosedRange<CGFloat> = 0...1
|
||||
static let minimumAxisYLabelsDistance: CGFloat = 90
|
||||
static let minimumAxisYLabelsDistance: CGFloat = 85
|
||||
static let monthDayDateFormatter = DateFormatter.utc(format: "MMM d")
|
||||
static let timeDateFormatter = DateFormatter.utc(format: "HH:mm")
|
||||
static let headerFullRangeFormatter: DateFormatter = {
|
||||
|
|
|
|||
|
|
@ -269,16 +269,20 @@ class GeneralChartComponentController: ChartThemeContainer {
|
|||
|
||||
var numberOfOffsetsPerItem = ditance / approximateNumberOfChartValues
|
||||
var multiplier: CGFloat = 1.0
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
}
|
||||
}
|
||||
var dividor: CGFloat = 1.0
|
||||
var maximumNumberOfDecimals = 2
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
}
|
||||
}
|
||||
|
||||
var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
|
||||
|
|
|
|||
|
|
@ -107,6 +107,8 @@ public class BaseLinesChartController: BaseChartController {
|
|||
color: component.color,
|
||||
visible: actualChartVisibility[index])
|
||||
}
|
||||
let total = actualChartsCollection.chartValues.enumerated().map { $0.element.values[pointIndex] }.reduce(0, +)
|
||||
|
||||
let dateString: String
|
||||
if isZoomed {
|
||||
dateString = BaseConstants.timeDateFormatter.string(from: closestDate)
|
||||
|
|
@ -114,7 +116,7 @@ public class BaseLinesChartController: BaseChartController {
|
|||
dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
|
||||
}
|
||||
let viewModel = ChartDetailsViewModel(title: dateString,
|
||||
showArrow: self.isZoomable && !self.isZoomed,
|
||||
showArrow: total > 0 && self.isZoomable && !self.isZoomed,
|
||||
showPrefixes: false,
|
||||
values: values,
|
||||
totalValue: nil,
|
||||
|
|
@ -194,16 +196,20 @@ public class BaseLinesChartController: BaseChartController {
|
|||
|
||||
var numberOfOffsetsPerItem = distance / approximateNumberOfChartValues
|
||||
var multiplier: CGFloat = 1.0
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
}
|
||||
}
|
||||
var dividor: CGFloat = 1.0
|
||||
var maximumNumberOfDecimals = 2
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
}
|
||||
}
|
||||
|
||||
var base: CGFloat = BaseConstants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ public class GeneralLinesChartController: BaseLinesChartController {
|
|||
self.prevoiusHorizontalStrideInterval = -1
|
||||
self.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange
|
||||
self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange
|
||||
self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero,
|
||||
self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero,
|
||||
color: $0.color)}
|
||||
|
||||
let chartRange: ClosedRange<CGFloat>
|
||||
|
|
@ -133,7 +133,7 @@ public class GeneralLinesChartController: BaseLinesChartController {
|
|||
super.chartInteractionDidBegin(point: point)
|
||||
|
||||
self.lineBulletsRenderer.bullets = chartLines.compactMap { chart in
|
||||
return LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], color: chart.color)
|
||||
return LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], offset: .zero, color: chart.color)
|
||||
}
|
||||
self.lineBulletsRenderer.isEnabled = true
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public class TwoAxisLinesChartController: BaseLinesChartController {
|
|||
controller.verticalScalesRenderer.labelsColor = chart.color
|
||||
controller.totalVerticalRange = LinesChartRenderer.LineData.verticalRange(lines: chartLines) ?? Constants.defaultRange
|
||||
self.totalHorizontalRange = LinesChartRenderer.LineData.horizontalRange(lines: chartLines) ?? Constants.defaultRange
|
||||
controller.lineBulletsRenderer.bullets = chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero,
|
||||
controller.lineBulletsRenderer.bullets = chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero,
|
||||
color: $0.color) }
|
||||
controller.previewLinesRenderer.setup(horizontalRange: self.totalHorizontalRange, animated: animated)
|
||||
controller.previewLinesRenderer.setup(verticalRange: controller.totalVerticalRange, animated: animated)
|
||||
|
|
@ -161,7 +161,7 @@ public class TwoAxisLinesChartController: BaseLinesChartController {
|
|||
|
||||
for graphController in graphControllers {
|
||||
graphController.lineBulletsRenderer.bullets = graphController.chartLines.map { chart in
|
||||
LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], color: chart.color)
|
||||
LineBulletsRenderer.Bullet(coordinate: chart.points[minIndex], offset: .zero, color: chart.color)
|
||||
}
|
||||
graphController.lineBulletsRenderer.isEnabled = true
|
||||
}
|
||||
|
|
@ -246,16 +246,20 @@ public class TwoAxisLinesChartController: BaseLinesChartController {
|
|||
var numberOfOffsetsPerItem = verticalRange.distance / approximateNumberOfChartValues
|
||||
|
||||
var multiplier: CGFloat = 1.0
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
}
|
||||
}
|
||||
var dividor: CGFloat = 1.0
|
||||
var maximumNumberOfDecimals = 2
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
}
|
||||
}
|
||||
|
||||
let generalBase = Constants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
super.willAppear(animated: animated)
|
||||
|
||||
updatePreviewRangeClosure?(currentChartHorizontalRangeFraction, animated)
|
||||
setConponentsVisible(visible: true, animated: animated)
|
||||
setComponentsVisible(visible: true, animated: animated)
|
||||
updateHorizontalLimitLabels(animated: animated, forceUpdate: true)
|
||||
}
|
||||
|
||||
|
|
@ -111,10 +111,10 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
|
||||
func prepareAppearanceAnimation(horizontalRnage: ClosedRange<CGFloat>) {
|
||||
setupMainChart(horizontalRange: horizontalRnage, animated: false)
|
||||
setConponentsVisible(visible: false, animated: false)
|
||||
setComponentsVisible(visible: false, animated: false)
|
||||
}
|
||||
|
||||
func setConponentsVisible(visible: Bool, animated: Bool) {
|
||||
func setComponentsVisible(visible: Bool, animated: Bool) {
|
||||
mainBarsRenderer.setVisible(visible, animated: animated)
|
||||
horizontalScalesRenderer.setVisible(visible, animated: animated)
|
||||
verticalScalesRenderer.setVisible(visible, animated: animated)
|
||||
|
|
@ -183,6 +183,9 @@ class BarsComponentController: GeneralChartComponentController {
|
|||
var viewModel = super.chartDetailsViewModel(closestDate: closestDate, pointIndex: pointIndex)
|
||||
let visibleChartValues = self.visibleChartValues
|
||||
let totalSumm: CGFloat = visibleChartValues.map { CGFloat($0.values[pointIndex]) }.reduce(0, +)
|
||||
viewModel.hideAction = { [weak self] in
|
||||
self?.hideDetailsView(animated: true)
|
||||
}
|
||||
if !self.step {
|
||||
viewModel.totalValue = ChartDetailsViewModel.Value(prefix: nil,
|
||||
title: "Total",
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ class LinesComponentController: GeneralChartComponentController {
|
|||
let (chartLines, totalHorizontalRange, totalVerticalRange) = LinesChartRenderer.LineData.initialComponents(chartsCollection: chartsCollection)
|
||||
self.chartLines = chartLines
|
||||
|
||||
self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero,
|
||||
self.lineBulletsRenderer.bullets = self.chartLines.map { LineBulletsRenderer.Bullet(coordinate: $0.points.first ?? .zero, offset: .zero,
|
||||
color: $0.color)}
|
||||
|
||||
super.initialize(chartsCollection: chartsCollection,
|
||||
|
|
@ -190,7 +190,7 @@ class LinesComponentController: GeneralChartComponentController {
|
|||
lineBulletsRenderer.isEnabled = true
|
||||
lineBulletsRenderer.setVisible(true, animated: animted)
|
||||
lineBulletsRenderer.bullets = chartLines.compactMap { chart in
|
||||
return LineBulletsRenderer.Bullet(coordinate: chart.points[dataIndex], color: chart.color)
|
||||
return LineBulletsRenderer.Bullet(coordinate: chart.points[dataIndex], offset: .zero, color: chart.color)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController {
|
|||
for i in 0 ..< chartBars.locations.count {
|
||||
let location = chartBars.locations[i]
|
||||
let value = component.values[i]
|
||||
bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), color: component.color))
|
||||
bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), offset: .zero, color: component.color))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -155,13 +155,17 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController {
|
|||
let chartInteractionWasBegin = isChartInteractionBegun
|
||||
super.chartInteractionDidBegin(point: point)
|
||||
|
||||
var barOffset: CGFloat = 0.0
|
||||
for graphController in graphControllers {
|
||||
|
||||
var bullets: [LineBulletsRenderer.Bullet] = []
|
||||
if let component = graphController.chartBars.components.first {
|
||||
let location = graphController.chartBars.locations[minIndex]
|
||||
let value = component.values[minIndex]
|
||||
bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), color: component.color))
|
||||
|
||||
let offset = -(graphController.mainBarsRenderer.transform(toChartCoordinateHorizontal: horizontalRange.lowerBound + graphController.barsWidth, chartFrame: chartFrame) - chartFrame.minX) / 2.0
|
||||
barOffset = offset
|
||||
|
||||
bullets.append(LineBulletsRenderer.Bullet(coordinate: CGPoint(x: location, y: value), offset: CGPoint(x: offset, y: 0.0), color: component.color))
|
||||
}
|
||||
graphController.lineBulletsRenderer.bullets = bullets
|
||||
graphController.lineBulletsRenderer.isEnabled = true
|
||||
|
|
@ -173,6 +177,7 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController {
|
|||
self.setDetailsChartVisibleClosure?(true, true)
|
||||
self.setDetailsViewPositionClosure?(detailsViewPosition)
|
||||
self.verticalLineRenderer.values = [chartValue]
|
||||
self.verticalLineRenderer.offset = barOffset
|
||||
}
|
||||
|
||||
public override var currentChartHorizontalRangeFraction: ClosedRange<CGFloat> {
|
||||
|
|
@ -245,18 +250,22 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController {
|
|||
var numberOfOffsetsPerItem = verticalRange.distance / approximateNumberOfChartValues
|
||||
|
||||
var multiplier: CGFloat = 1.0
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem > 10 {
|
||||
numberOfOffsetsPerItem /= 10
|
||||
multiplier *= 10
|
||||
}
|
||||
}
|
||||
var dividor: CGFloat = 1.0
|
||||
var maximumNumberOfDecimals = 2
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
if numberOfOffsetsPerItem > 0 {
|
||||
while numberOfOffsetsPerItem < 1 {
|
||||
numberOfOffsetsPerItem *= 10
|
||||
dividor *= 10
|
||||
maximumNumberOfDecimals += 1
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let generalBase = Constants.verticalBaseAnchors.first { numberOfOffsetsPerItem > $0 } ?? BaseConstants.defaultVerticalBaseAnchor
|
||||
let base = generalBase * multiplier / dividor
|
||||
|
||||
|
|
|
|||
|
|
@ -197,9 +197,7 @@ class BarChartRenderer: BaseChartRenderer {
|
|||
leftX = rightX
|
||||
barIndex += 1
|
||||
}
|
||||
|
||||
let colorOffset = Double((1.0 - (1.0 - generalUnselectedAlpha) * selectedIndexAnimator.current) * chartsAlpha)
|
||||
|
||||
|
||||
for (index, component) in bars.components.enumerated().reversed() {
|
||||
if maxValues[index] < optimizationLevel {
|
||||
continue
|
||||
|
|
@ -209,7 +207,7 @@ class BarChartRenderer: BaseChartRenderer {
|
|||
context.setLineWidth(self.lineWidth)
|
||||
context.setStrokeColor(GColor.valueBetween(start: backgroundColorAnimator.current.color,
|
||||
end: component.color,
|
||||
offset: colorOffset).cgColor)
|
||||
offset: 1.0).cgColor)
|
||||
context.beginPath()
|
||||
context.addLines(between: backgroundPaths[index])
|
||||
context.strokePath()
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ class BaseChartRenderer: ChartViewRenderer {
|
|||
lazy var horizontalRange = AnimationController<ClosedRange<CGFloat>>(current: 0...1, refreshClosure: refreshClosure)
|
||||
lazy var verticalRange = AnimationController<ClosedRange<CGFloat>>(current: 0...1, refreshClosure: refreshClosure)
|
||||
|
||||
func setup(verticalRange: ClosedRange<CGFloat>, animated: Bool, timeFunction: TimeFunction? = nil) {
|
||||
func setup(verticalRange: ClosedRange<CGFloat>, animated: Bool, timeFunction: TimeFunction? = nil) {
|
||||
guard self.verticalRange.end != verticalRange else {
|
||||
self.verticalRange.timeFunction = timeFunction ?? .linear
|
||||
return
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import UIKit
|
|||
class LineBulletsRenderer: BaseChartRenderer {
|
||||
struct Bullet {
|
||||
var coordinate: CGPoint
|
||||
var offset: CGPoint
|
||||
var color: GColor
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +57,8 @@ class LineBulletsRenderer: BaseChartRenderer {
|
|||
let alpha = alphaAnimators[index].current
|
||||
if alpha == 0 { continue }
|
||||
|
||||
let centerX = transform(toChartCoordinateHorizontal: bullet.coordinate.x, chartFrame: chartFrame)
|
||||
let centerY = transform(toChartCoordinateVertical: bullet.coordinate.y, chartFrame: chartFrame)
|
||||
let centerX = transform(toChartCoordinateHorizontal: bullet.coordinate.x, chartFrame: chartFrame) + bullet.offset.x
|
||||
let centerY = transform(toChartCoordinateVertical: bullet.coordinate.y, chartFrame: chartFrame) + bullet.offset.y
|
||||
context.setFillColor(innerColorAnimator.current.color.withAlphaComponent(alpha).cgColor)
|
||||
context.setStrokeColor(bullet.color.withAlphaComponent(alpha).cgColor)
|
||||
context.setLineWidth(linesWidth)
|
||||
|
|
|
|||
|
|
@ -59,6 +59,9 @@ class LinesChartRenderer: BaseChartRenderer {
|
|||
if chartsAlpha == 0 { return }
|
||||
let range = renderRange(bounds: bounds, chartFrame: chartFrame)
|
||||
|
||||
let spacing: CGFloat = 1.0
|
||||
context.clip(to: CGRect(origin: CGPoint(x: 0.0, y: chartFrame.minY - spacing), size: CGSize(width: chartFrame.width + chartFrame.origin.x * 2.0, height: chartFrame.height + spacing * 2.0)))
|
||||
|
||||
for (index, toLine) in toLines.enumerated() {
|
||||
let alpha = linesAlphaAnimators[index].current * chartsAlpha
|
||||
if alpha == 0 { continue }
|
||||
|
|
@ -434,6 +437,8 @@ class LinesChartRenderer: BaseChartRenderer {
|
|||
}
|
||||
context.setAlpha(1.0)
|
||||
}
|
||||
|
||||
context.resetClip()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -496,6 +501,11 @@ extension LinesChartRenderer.LineData {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if vMin == vMax {
|
||||
return 0...vMax * 2.0
|
||||
}
|
||||
|
||||
return vMin...vMax
|
||||
} else {
|
||||
guard let firstPoint = lines.first?.points.first else { return nil }
|
||||
|
|
@ -507,6 +517,11 @@ extension LinesChartRenderer.LineData {
|
|||
vMax = max(vMax, point.y)
|
||||
}
|
||||
}
|
||||
|
||||
if vMin == vMax {
|
||||
return 0...vMax * 2.0
|
||||
}
|
||||
|
||||
return vMin...vMax
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ class VerticalLinesRenderer: BaseChartRenderer {
|
|||
setNeedsDisplay()
|
||||
}
|
||||
}
|
||||
var offset: CGFloat = 0.0
|
||||
private var alphaAnimators: [AnimationController<CGFloat>] = []
|
||||
|
||||
var linesColor: GColor = .black
|
||||
|
|
@ -39,7 +40,7 @@ class VerticalLinesRenderer: BaseChartRenderer {
|
|||
if alpha == 0 { continue }
|
||||
|
||||
context.setStrokeColor(linesColor.withAlphaComponent(linesColor.alphaValue * alpha).cgColor)
|
||||
let pointX = transform(toChartCoordinateHorizontal: value, chartFrame: chartFrame)
|
||||
let pointX = transform(toChartCoordinateHorizontal: value, chartFrame: chartFrame) + offset
|
||||
context.strokeLineSegments(between: [CGPoint(x: pointX, y: chartFrame.minY),
|
||||
CGPoint(x: pointX, y: chartFrame.maxY)])
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
}
|
||||
}
|
||||
var horizontalLinesWidth: CGFloat = GView.oneDevicePixel
|
||||
var lavelsAsisOffset: CGFloat = 6
|
||||
var labelsAxisOffset: CGFloat = 6
|
||||
var labelsColor: GColor = .black {
|
||||
didSet {
|
||||
setNeedsDisplay()
|
||||
|
|
@ -100,6 +100,9 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
if generalAlpha == 0 { return }
|
||||
let labelColorAlpha = labelsColor.alphaValue
|
||||
|
||||
let spacing: CGFloat = 1.0
|
||||
context.clip(to: CGRect(origin: CGPoint(x: 0.0, y: chartFrame.minY - spacing), size: CGSize(width: chartFrame.width + chartFrame.origin.x * 2.0, height: chartFrame.height + spacing * 2.0)))
|
||||
|
||||
func drawLines(_ labels: [LinesChartLabel], alpha: CGFloat) {
|
||||
var lineSegments: [CGPoint] = []
|
||||
let x0 = chartFrame.minX
|
||||
|
|
@ -109,8 +112,10 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
|
||||
for lineInfo in labels {
|
||||
let y = transform(toChartCoordinateVertical: lineInfo.value, chartFrame: chartFrame).roundedUpToPixelGrid()
|
||||
lineSegments.append(CGPoint(x: x0, y: y))
|
||||
lineSegments.append(CGPoint(x: x1, y: y))
|
||||
if y < chartFrame.maxY - 2.0 {
|
||||
lineSegments.append(CGPoint(x: x0, y: y))
|
||||
lineSegments.append(CGPoint(x: x1, y: y))
|
||||
}
|
||||
}
|
||||
context.strokeLineSegments(between: lineSegments)
|
||||
}
|
||||
|
|
@ -118,18 +123,14 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
func drawVerticalLabels(_ labels: [LinesChartLabel], attributes: [NSAttributedString.Key: Any]) {
|
||||
if isRightAligned {
|
||||
for label in labels {
|
||||
let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - lavelsAsisOffset
|
||||
|
||||
|
||||
|
||||
|
||||
let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - labelsAxisOffset
|
||||
let attributedString = NSAttributedString(string: label.text, attributes: attributes)
|
||||
let textNode = LabelNode.layoutText(attributedString, bounds.size)
|
||||
textNode.1.draw(CGRect(origin: CGPoint(x:chartFrame.maxX - textNode.0.size.width, y: y), size: textNode.0.size), in: context, backingScaleFactor: deviceScale)
|
||||
}
|
||||
} else {
|
||||
for label in labels {
|
||||
let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - lavelsAsisOffset
|
||||
let y = transform(toChartCoordinateVertical: label.value, chartFrame: chartFrame) - labelsFont.pointSize - labelsAxisOffset
|
||||
let attributedString = NSAttributedString(string: label.text, attributes: attributes)
|
||||
let textNode = LabelNode.layoutText(attributedString, bounds.size)
|
||||
textNode.1.draw(CGRect(origin: CGPoint(x:chartFrame.minX, y: y), size: textNode.0.size), in: context, backingScaleFactor: deviceScale)
|
||||
|
|
@ -164,5 +165,7 @@ class VerticalScalesRenderer: BaseChartRenderer {
|
|||
attributes: [.foregroundColor: labelsColor.withAlphaComponent(animatedLabesAndLines.alphaAnimator.current * labelColorAlpha * generalAlpha),
|
||||
.font: labelsFont])
|
||||
}
|
||||
|
||||
context.resetClip()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ enum TimeFunction {
|
|||
return time / duration
|
||||
case .easeIn:
|
||||
return (pow(2, 10 * (time / duration - 1)) - 0.0009765625) * 1.0009775171065499
|
||||
|
||||
case .easeOut:
|
||||
return (-pow(2, -10 * time / duration)) + 1 * 1.0009775171065499
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ public extension TimeInterval {
|
|||
static let hour: TimeInterval = 60 * 60
|
||||
static let day: TimeInterval = 60 * 60 * 24
|
||||
static let osXDuration: TimeInterval = 0.25
|
||||
static let expandAnimationDuration: TimeInterval = 0.4
|
||||
static let expandAnimationDuration: TimeInterval = 0.25
|
||||
static var animationDurationMultipler: Double = 1.0
|
||||
|
||||
static var defaultDuration: TimeInterval {
|
||||
|
|
|
|||
|
|
@ -29,12 +29,11 @@ extension GColor {
|
|||
|
||||
convenience init?(hexString: String) {
|
||||
let r, g, b, a: CGFloat
|
||||
|
||||
let components = hexString.components(separatedBy: "#")
|
||||
if let name = components.first, !name.isEmpty {
|
||||
switch name.lowercased() {
|
||||
case "red":
|
||||
self.init(hexString: "#ff2d55")
|
||||
self.init(hexString: "#ff3b30")
|
||||
return
|
||||
case "green":
|
||||
self.init(hexString: "#34c759")
|
||||
|
|
@ -43,13 +42,13 @@ extension GColor {
|
|||
self.init(hexString: "#007aff")
|
||||
return
|
||||
case "golden":
|
||||
self.init(hexString: "#ff9500")
|
||||
self.init(hexString: "#ffcc00")
|
||||
return
|
||||
case "yellow":
|
||||
self.init(hexString: "#ffcc00")
|
||||
return
|
||||
case "lightgreen":
|
||||
self.init(hexString: "#8fcf39")
|
||||
self.init(hexString: "#7ED321")
|
||||
return
|
||||
case "lightblue":
|
||||
self.init(hexString: "#5ac8fa")
|
||||
|
|
@ -58,16 +57,19 @@ extension GColor {
|
|||
self.init(hexString: "#35afdc")
|
||||
return
|
||||
case "orange":
|
||||
self.init(hexString: "#fd7a32")
|
||||
self.init(hexString: "#ff9500")
|
||||
return
|
||||
case "violet":
|
||||
self.init(hexString: "#9968f7")
|
||||
self.init(hexString: "#af52de")
|
||||
return
|
||||
case "emerald":
|
||||
self.init(hexString: "#37cca3")
|
||||
self.init(hexString: "#50e3c2")
|
||||
return
|
||||
case "pink":
|
||||
self.init(hexString: "#ff4f79")
|
||||
self.init(hexString: "#ff2d55")
|
||||
return
|
||||
case "indigo":
|
||||
self.init(hexString: "#5e5ce6")
|
||||
return
|
||||
default:
|
||||
break
|
||||
|
|
|
|||
|
|
@ -30,9 +30,7 @@ public protocol ChartThemeContainer {
|
|||
public class ChartTheme {
|
||||
public let chartTitleColor: GColor
|
||||
public let actionButtonColor: GColor
|
||||
public let tableBackgroundColor: GColor
|
||||
public let chartBackgroundColor: GColor
|
||||
public let tableSeparatorColor: GColor
|
||||
public let chartLabelsColor: GColor
|
||||
public let chartHelperLinesColor: GColor
|
||||
public let chartStrongLinesColor: GColor
|
||||
|
|
@ -40,17 +38,15 @@ public class ChartTheme {
|
|||
public let chartDetailsTextColor: GColor
|
||||
public let chartDetailsArrowColor: GColor
|
||||
public let chartDetailsViewColor: GColor
|
||||
public let descriptionActionColor: GColor
|
||||
public let rangeViewFrameColor: GColor
|
||||
public let rangeViewTintColor: GColor
|
||||
public let rangeViewFrameColor: GColor
|
||||
public let rangeViewMarkerColor: GColor
|
||||
public let rangeCropImage: GImage?
|
||||
|
||||
public init(chartTitleColor: GColor, actionButtonColor: GColor, tableBackgroundColor: GColor, chartBackgroundColor: GColor, tableSeparatorColor: GColor, chartLabelsColor: GColor, chartHelperLinesColor: GColor, chartStrongLinesColor: GColor, barChartStrongLinesColor: GColor, chartDetailsTextColor: GColor, chartDetailsArrowColor: GColor, chartDetailsViewColor: GColor, descriptionActionColor: GColor, rangeViewFrameColor: GColor, rangeViewTintColor: GColor, rangeViewMarkerColor: GColor) {
|
||||
public init(chartTitleColor: GColor, actionButtonColor: GColor, chartBackgroundColor: GColor, chartLabelsColor: GColor, chartHelperLinesColor: GColor, chartStrongLinesColor: GColor, barChartStrongLinesColor: GColor, chartDetailsTextColor: GColor, chartDetailsArrowColor: GColor, chartDetailsViewColor: GColor, rangeViewFrameColor: GColor, rangeViewTintColor: GColor, rangeViewMarkerColor: GColor, rangeCropImage: GImage?) {
|
||||
self.chartTitleColor = chartTitleColor
|
||||
self.actionButtonColor = actionButtonColor
|
||||
self.tableBackgroundColor = tableBackgroundColor
|
||||
self.chartBackgroundColor = chartBackgroundColor
|
||||
self.tableSeparatorColor = tableSeparatorColor
|
||||
self.chartLabelsColor = chartLabelsColor
|
||||
self.chartHelperLinesColor = chartHelperLinesColor
|
||||
self.chartStrongLinesColor = chartStrongLinesColor
|
||||
|
|
@ -58,147 +54,14 @@ public class ChartTheme {
|
|||
self.chartDetailsTextColor = chartDetailsTextColor
|
||||
self.chartDetailsArrowColor = chartDetailsArrowColor
|
||||
self.chartDetailsViewColor = chartDetailsViewColor
|
||||
self.descriptionActionColor = descriptionActionColor
|
||||
self.rangeViewFrameColor = rangeViewFrameColor
|
||||
self.rangeViewTintColor = rangeViewTintColor
|
||||
self.rangeViewMarkerColor = rangeViewMarkerColor
|
||||
self.rangeCropImage = rangeCropImage
|
||||
}
|
||||
|
||||
public static var defaultDayTheme = ChartTheme(chartTitleColor: GColor.black, actionButtonColor: GColor(red: 53/255.0, green: 120/255.0, blue: 246/255.0, alpha: 1.0), tableBackgroundColor: GColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 1.0), chartBackgroundColor: GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0), tableSeparatorColor: GColor(red: 200/255.0, green: 199/255.0, blue: 204/255.0, alpha: 1.0), chartLabelsColor: GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.5), chartHelperLinesColor: GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.1), chartStrongLinesColor: GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.35), barChartStrongLinesColor: GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.2), chartDetailsTextColor: GColor(red: 109/255.0, green: 109/255.0, blue: 114/255.0, alpha: 1.0), chartDetailsArrowColor: GColor(red: 197/255.0, green: 199/255.0, blue: 205/255.0, alpha: 1.0), chartDetailsViewColor: GColor(red: 245/255.0, green: 245/255.0, blue: 251/255.0, alpha: 1.0), descriptionActionColor: GColor(red: 1/255.0, green: 125/255.0, blue: 229/255.0, alpha: 1.0), rangeViewFrameColor: GColor(red: 202/255.0, green: 212/255.0, blue: 222/255.0, alpha: 1.0), rangeViewTintColor: GColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 0.5), rangeViewMarkerColor: GColor.white)
|
||||
public static var defaultDayTheme = ChartTheme(chartTitleColor: GColor.black, actionButtonColor: GColor(red: 53/255.0, green: 120/255.0, blue: 246/255.0, alpha: 1.0), chartBackgroundColor: GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0), chartLabelsColor: GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.5), chartHelperLinesColor: GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.1), chartStrongLinesColor: GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.35), barChartStrongLinesColor: GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.2), chartDetailsTextColor: GColor(red: 109/255.0, green: 109/255.0, blue: 114/255.0, alpha: 1.0), chartDetailsArrowColor: GColor(red: 197/255.0, green: 199/255.0, blue: 205/255.0, alpha: 1.0), chartDetailsViewColor: GColor(red: 245/255.0, green: 245/255.0, blue: 251/255.0, alpha: 1.0), rangeViewFrameColor: GColor(red: 202/255.0, green: 212/255.0, blue: 222/255.0, alpha: 1.0), rangeViewTintColor: GColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 0.5), rangeViewMarkerColor: GColor.white, rangeCropImage: GImage(named: "selection_frame_light"))
|
||||
|
||||
|
||||
public static var defaultNightTheme = ChartTheme(chartTitleColor: GColor.white, actionButtonColor: GColor(red: 84/255.0, green: 164/255.0, blue: 247/255.0, alpha: 1.0), tableBackgroundColor: GColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 1.0), chartBackgroundColor: GColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0), tableSeparatorColor: GColor(red: 18/255.0, green: 26/255.0, blue: 35/255.0, alpha: 1.0), chartLabelsColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.6), chartHelperLinesColor: GColor(red: 133/255.0, green: 150/255.0, blue: 171/255.0, alpha: 0.20), chartStrongLinesColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45), barChartStrongLinesColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45), chartDetailsTextColor: GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0), chartDetailsArrowColor: GColor(red: 76/255.0, green: 84/255.0, blue: 96/255.0, alpha: 1.0), chartDetailsViewColor: GColor(red: 25/255.0, green: 35/255.0, blue: 47/255.0, alpha: 1.0), descriptionActionColor: GColor(red: 24/255.0, green: 145/255.0, blue: 255/255.0, alpha: 1.0), rangeViewFrameColor: GColor(red: 53/255.0, green: 70/255.0, blue: 89/255.0, alpha: 1.0), rangeViewTintColor: GColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 0.5), rangeViewMarkerColor: GColor.white)
|
||||
|
||||
|
||||
// public var actionButtonColor: GColor { // Кнопка Zoom Out/ Смена режима день/ночь
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 53/255.0, green: 120/255.0, blue: 246/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 84/255.0, green: 164/255.0, blue: 247/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var tableBackgroundColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartBackgroundColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var tableSeparatorColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 200/255.0, green: 199/255.0, blue: 204/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 18/255.0, green: 26/255.0, blue: 35/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartLabelsColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.5)
|
||||
// case .night: return GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.6)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartHelperLinesColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.1)
|
||||
// case .night: return GColor(red: 133/255.0, green: 150/255.0, blue: 171/255.0, alpha: 0.20)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartStrongLinesColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 24/255.0, green: 45/255.0, blue: 59/255.0, alpha: 0.35)
|
||||
// case .night: return GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var barChartStrongLinesColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 37/255.0, green: 37/255.0, blue: 41/255.0, alpha: 0.2)
|
||||
// case .night: return GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartDetailsTextColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 109/255.0, green: 109/255.0, blue: 114/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartDetailsArrowColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 197/255.0, green: 199/255.0, blue: 205/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 76/255.0, green: 84/255.0, blue: 96/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var chartDetailsViewColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 245/255.0, green: 245/255.0, blue: 251/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 25/255.0, green: 35/255.0, blue: 47/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public var descriptionActionColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 1/255.0, green: 125/255.0, blue: 229/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 24/255.0, green: 145/255.0, blue: 255/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var rangeViewBackgroundColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var rangeViewFrameColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 202/255.0, green: 212/255.0, blue: 222/255.0, alpha: 1.0)
|
||||
// case .night: return GColor(red: 53/255.0, green: 70/255.0, blue: 89/255.0, alpha: 1.0)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var rangeViewTintColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor(red: 239/255.0, green: 239/255.0, blue: 244/255.0, alpha: 0.5)
|
||||
// case .night: return GColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 0.5)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public var rangeViewMarkerColor: GColor {
|
||||
// switch self {
|
||||
// case .day: return GColor.white
|
||||
// case .night: return GColor.white
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
|
||||
public var rangeCropImage: GImage? {
|
||||
// case .day:
|
||||
let image = GImage(named: "selection_frame_light")
|
||||
#if os(macOS)
|
||||
image?.resizingMode = .stretch
|
||||
image?.capInsets = NSEdgeInsets(top: 15, left: 15, bottom: 15, right: 15)
|
||||
#endif
|
||||
return image
|
||||
// case .night:
|
||||
// let image = GImage(named: "selection_frame_dark")
|
||||
// #if os(macOS)
|
||||
// image?.resizingMode = .stretch
|
||||
// image?.capInsets = NSEdgeInsets(top: 15, left: 15, bottom: 15, right: 15)
|
||||
// #endif
|
||||
// return image
|
||||
}
|
||||
public static var defaultNightTheme = ChartTheme(chartTitleColor: GColor.white, actionButtonColor: GColor(red: 84/255.0, green: 164/255.0, blue: 247/255.0, alpha: 1.0), chartBackgroundColor: GColor(red: 34/255.0, green: 47/255.0, blue: 63/255.0, alpha: 1.0), chartLabelsColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.6), chartHelperLinesColor: GColor(red: 133/255.0, green: 150/255.0, blue: 171/255.0, alpha: 0.20), chartStrongLinesColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45), barChartStrongLinesColor: GColor(red: 186/255.0, green: 204/255.0, blue: 225/255.0, alpha: 0.45), chartDetailsTextColor: GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0), chartDetailsArrowColor: GColor(red: 76/255.0, green: 84/255.0, blue: 96/255.0, alpha: 1.0), chartDetailsViewColor: GColor(red: 25/255.0, green: 35/255.0, blue: 47/255.0, alpha: 1.0), rangeViewFrameColor: GColor(red: 53/255.0, green: 70/255.0, blue: 89/255.0, alpha: 1.0), rangeViewTintColor: GColor(red: 24/255.0, green: 34/255.0, blue: 45/255.0, alpha: 0.5), rangeViewMarkerColor: GColor.white, rangeCropImage: GImage(named: "selection_frame_light"))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ class ChartDetailsView: UIControl {
|
|||
self.viewModel = viewModel
|
||||
|
||||
titleLabel.setText(viewModel.title, animated: false)
|
||||
titleLabel.setVisible(!viewModel.title.isEmpty, animated: animated)
|
||||
arrowView.setVisible(viewModel.showArrow, animated: animated)
|
||||
titleLabel.setVisible(!viewModel.title.isEmpty, animated: false)
|
||||
arrowView.setVisible(viewModel.showArrow, animated: false)
|
||||
arrowButton.isUserInteractionEnabled = viewModel.showArrow
|
||||
|
||||
let width: CGFloat = margin * 2 + (viewModel.showPrefixes ? (prefixLabelWidth + margin) : 0) + textLabelWidth + valueLabelWidth
|
||||
|
|
|
|||
|
|
@ -19,10 +19,47 @@ public enum ChartType {
|
|||
|
||||
public extension ChartTheme {
|
||||
convenience init(presentationTheme: PresentationTheme) {
|
||||
let tableBackgroundColor = UIColor(rgb: 0xefeff4)
|
||||
let rangeViewTintColor = UIColor(rgb: 0xefeff4)
|
||||
let rangeViewFrameColor = presentationTheme.chart.rangeViewFrameColor
|
||||
let rangeViewMarkerColor = presentationTheme.chart.rangeViewMarkerColor
|
||||
|
||||
let rangeImage = generateImage(CGSize(width: 114.0, height: 42.0), rotatedContext: { size, context in
|
||||
let bounds = CGRect(origin: CGPoint(), size: size)
|
||||
context.clear(bounds)
|
||||
|
||||
self.init(chartTitleColor: presentationTheme.list.itemPrimaryTextColor, actionButtonColor: presentationTheme.list.itemAccentColor, tableBackgroundColor: tableBackgroundColor, chartBackgroundColor: presentationTheme.list.itemBlocksBackgroundColor, tableSeparatorColor: presentationTheme.list.itemSecondaryTextColor, chartLabelsColor: presentationTheme.list.itemSecondaryTextColor, chartHelperLinesColor: presentationTheme.list.itemSecondaryTextColor, chartStrongLinesColor: presentationTheme.list.itemSecondaryTextColor, barChartStrongLinesColor: presentationTheme.list.itemSecondaryTextColor, chartDetailsTextColor: presentationTheme.list.itemSecondaryTextColor, chartDetailsArrowColor: presentationTheme.list.itemSecondaryTextColor, chartDetailsViewColor: presentationTheme.list.itemSecondaryTextColor, descriptionActionColor: presentationTheme.list.itemSecondaryTextColor, rangeViewFrameColor: presentationTheme.list.itemSecondaryTextColor, rangeViewTintColor: rangeViewTintColor, rangeViewMarkerColor: UIColor.white)
|
||||
context.setFillColor(rangeViewFrameColor.cgColor)
|
||||
var path = UIBezierPath.init(roundedRect: CGRect(x: 0.0, y: 0.0, width: 11.0, height: 42.0), byRoundingCorners: [.topLeft, .bottomLeft], cornerRadii: CGSize(width: 6.0, height: 6.0))
|
||||
context.addPath(path.cgPath)
|
||||
context.fillPath()
|
||||
|
||||
path = UIBezierPath.init(roundedRect: CGRect(x: 103.0, y: 0.0, width: 11.0, height: 42.0), byRoundingCorners: [.topRight, .bottomRight], cornerRadii: CGSize(width: 6.0, height: 6.0))
|
||||
context.addPath(path.cgPath)
|
||||
context.fillPath()
|
||||
|
||||
context.setFillColor(rangeViewFrameColor.cgColor)
|
||||
context.fill(CGRect(x: 7.0, y: 0.0, width: 4.0, height: 1.0))
|
||||
context.fill(CGRect(x: 7.0, y: 41.0, width: 4.0, height: 1.0))
|
||||
|
||||
context.fill(CGRect(x: 100.0, y: 0.0, width: 4.0, height: 1.0))
|
||||
context.fill(CGRect(x: 100.0, y: 41.0, width: 4.0, height: 1.0))
|
||||
|
||||
context.fill(CGRect(x: 11.0, y: 0.0, width: 92.0, height: 1.0))
|
||||
context.fill(CGRect(x: 11.0, y: 41.0, width: 92.0, height: 1.0))
|
||||
|
||||
context.setLineCap(.round)
|
||||
context.setLineWidth(1.5)
|
||||
context.setStrokeColor(rangeViewMarkerColor.cgColor)
|
||||
context.move(to: CGPoint(x: 7.0, y: 17.0))
|
||||
context.addLine(to: CGPoint(x: 4.0, y: 21.0))
|
||||
context.addLine(to: CGPoint(x: 7.0, y: 25.0))
|
||||
context.strokePath()
|
||||
|
||||
context.move(to: CGPoint(x: 107.0, y: 17.0))
|
||||
context.addLine(to: CGPoint(x: 110.0, y: 21.0))
|
||||
context.addLine(to: CGPoint(x: 107.0, y: 25.0))
|
||||
context.strokePath()
|
||||
})?.resizableImage(withCapInsets: UIEdgeInsets(top: 15.0, left: 15.0, bottom: 15.0, right: 15.0), resizingMode: .stretch)
|
||||
|
||||
self.init(chartTitleColor: presentationTheme.list.itemPrimaryTextColor, actionButtonColor: presentationTheme.list.itemAccentColor, chartBackgroundColor: presentationTheme.list.itemBlocksBackgroundColor, chartLabelsColor: presentationTheme.chart.labelsColor, chartHelperLinesColor: presentationTheme.chart.helperLinesColor, chartStrongLinesColor: presentationTheme.chart.strongLinesColor, barChartStrongLinesColor: presentationTheme.chart.barStrongLinesColor, chartDetailsTextColor: presentationTheme.chart.detailsTextColor, chartDetailsArrowColor: presentationTheme.chart.detailsArrowColor, chartDetailsViewColor: presentationTheme.chart.detailsViewColor, rangeViewFrameColor: rangeViewFrameColor, rangeViewTintColor: presentationTheme.list.blocksBackgroundColor.withAlphaComponent(0.5), rangeViewMarkerColor: rangeViewMarkerColor, rangeCropImage: rangeImage)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -88,7 +125,7 @@ public final class ChartNode: ASDisplayNode {
|
|||
}
|
||||
|
||||
public func setupTheme(_ theme: ChartTheme) {
|
||||
self.chartView.apply(theme: ChartTheme.defaultDayTheme, animated: false)
|
||||
self.chartView.apply(theme: theme, animated: false)
|
||||
}
|
||||
|
||||
public func setup(controller: BaseChartController) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ private class LeftAlignedIconButton: UIButton {
|
|||
let titleRect = super.titleRect(forContentRect: contentRect)
|
||||
let imageSize = currentImage?.size ?? .zero
|
||||
let availableWidth = contentRect.width - imageEdgeInsets.right - imageSize.width - titleRect.width
|
||||
return titleRect.offsetBy(dx: round(availableWidth / 2), dy: 0)
|
||||
return titleRect.offsetBy(dx: round(availableWidth / 2) - imageEdgeInsets.left, dy: 0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -27,7 +27,6 @@ class ChartStackSection: UIView, ChartThemeContainer {
|
|||
var rangeView: RangeChartView
|
||||
var visibilityView: ChartVisibilityView
|
||||
var sectionContainerView: UIView
|
||||
var separators: [UIView] = []
|
||||
|
||||
var titleLabel: UILabel!
|
||||
var backButton: UIButton!
|
||||
|
|
@ -64,7 +63,7 @@ class ChartStackSection: UIView, ChartThemeContainer {
|
|||
backButton.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .regular)
|
||||
backButton.setTitleColor(UIColor(rgb: 0x007ee5), for: .normal)
|
||||
backButton.setImage(UIImage(bundleImageName: "Chart/arrow_left"), for: .normal)
|
||||
backButton.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: 0.0, right: 3.0)
|
||||
backButton.imageEdgeInsets = UIEdgeInsets(top: 0.0, left: 6.0, bottom: 0.0, right: 3.0)
|
||||
backButton.imageView?.tintColor = UIColor(rgb: 0x007ee5)
|
||||
|
||||
backButton.setVisible(false, animated: false)
|
||||
|
|
@ -87,19 +86,14 @@ class ChartStackSection: UIView, ChartThemeContainer {
|
|||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
self.theme = theme
|
||||
|
||||
UIView.perform(animated: animated && self.isVisibleInWindow) {
|
||||
self.backgroundColor = theme.tableBackgroundColor
|
||||
|
||||
UIView.perform(animated: animated && self.isVisibleInWindow) {
|
||||
self.sectionContainerView.backgroundColor = theme.chartBackgroundColor
|
||||
self.rangeView.backgroundColor = theme.chartBackgroundColor
|
||||
self.visibilityView.backgroundColor = theme.chartBackgroundColor
|
||||
|
||||
self.backButton.tintColor = theme.actionButtonColor
|
||||
self.backButton.setTitleColor(theme.actionButtonColor, for: .normal)
|
||||
|
||||
for separator in self.separators {
|
||||
separator.backgroundColor = theme.tableSeparatorColor
|
||||
}
|
||||
self.backButton.imageView?.tintColor = theme.actionButtonColor
|
||||
}
|
||||
|
||||
if rangeView.isVisibleInWindow || chartView.isVisibleInWindow {
|
||||
|
|
@ -158,12 +152,12 @@ class ChartStackSection: UIView, ChartThemeContainer {
|
|||
let bounds = self.bounds
|
||||
self.titleLabel.frame = CGRect(origin: CGPoint(x: backButton.alpha > 0.0 ? 36.0 : 0.0, y: 5.0), size: CGSize(width: bounds.width, height: 28.0))
|
||||
self.sectionContainerView.frame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: 750.0))
|
||||
self.chartView.frame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: 250.0))
|
||||
self.chartView.frame = CGRect(origin: CGPoint(), size: CGSize(width: bounds.width, height: 310.0))
|
||||
|
||||
self.rangeView.isHidden = !self.displayRange
|
||||
|
||||
self.rangeView.frame = CGRect(origin: CGPoint(x: 0.0, y: 250.0), size: CGSize(width: bounds.width, height: 42.0))
|
||||
self.visibilityView.frame = CGRect(origin: CGPoint(x: 0.0, y: self.displayRange ? 308.0 : 266.0), size: CGSize(width: bounds.width, height: 350.0))
|
||||
self.rangeView.frame = CGRect(origin: CGPoint(x: 0.0, y: 310.0), size: CGSize(width: bounds.width, height: 42.0))
|
||||
self.visibilityView.frame = CGRect(origin: CGPoint(x: 0.0, y: self.displayRange ? 368.0 : 326.0), size: CGSize(width: bounds.width, height: 350.0))
|
||||
self.backButton.frame = CGRect(x: 0.0, y: 0.0, width: 96.0, height: 38.0)
|
||||
|
||||
self.chartView.setNeedsDisplay()
|
||||
|
|
|
|||
|
|
@ -152,7 +152,6 @@ extension ChartVisibilityView: ChartThemeContainer {
|
|||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
UIView.perform(animated: animated) {
|
||||
self.backgroundColor = theme.chartBackgroundColor
|
||||
self.tintColor = theme.descriptionActionColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -311,19 +311,17 @@ private extension RangeChartView {
|
|||
|
||||
extension RangeChartView: ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
let colusre = {
|
||||
let closure = {
|
||||
self.lowerBoundTintView.backgroundColor = theme.rangeViewTintColor
|
||||
self.upperBoundTintView.backgroundColor = theme.rangeViewTintColor
|
||||
}
|
||||
|
||||
|
||||
let image = UIImage(bundleImageName: "Chart/selection_frame_light")
|
||||
self.cropFrameView.setImage(image, animated: animated)
|
||||
self.cropFrameView.setImage(theme.rangeCropImage, animated: animated)
|
||||
|
||||
if animated {
|
||||
UIView.animate(withDuration: .defaultDuration, animations: colusre)
|
||||
UIView.animate(withDuration: .defaultDuration, animations: closure)
|
||||
} else {
|
||||
colusre()
|
||||
closure()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -113,11 +113,13 @@ public struct ManagedAnimationItem: Equatable {
|
|||
public let source: ManagedAnimationSource
|
||||
var frames: ManagedAnimationFrameRange
|
||||
var duration: Double
|
||||
var loop: Bool
|
||||
|
||||
public init(source: ManagedAnimationSource, frames: ManagedAnimationFrameRange, duration: Double) {
|
||||
public init(source: ManagedAnimationSource, frames: ManagedAnimationFrameRange, duration: Double, loop: Bool = false) {
|
||||
self.source = source
|
||||
self.frames = frames
|
||||
self.duration = duration
|
||||
self.loop = loop
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -269,7 +269,7 @@ private enum StatsEntry: ItemListNodeEntry {
|
|||
return false
|
||||
}
|
||||
case let .post(lhsIndex, lhsTheme, lhsStrings, lhsDateTimeFormat, lhsMessage, lhsInteractions):
|
||||
if case let .post(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsMessage, rhsInteractions) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsInteractions == rhsInteractions {
|
||||
if case let .post(rhsIndex, rhsTheme, rhsStrings, rhsDateTimeFormat, rhsMessage, rhsInteractions) = rhs, lhsIndex == rhsIndex, lhsTheme === rhsTheme, lhsStrings === rhsStrings, lhsDateTimeFormat == rhsDateTimeFormat, lhsMessage.id == rhsMessage.id, lhsInteractions == rhsInteractions {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
|
|
@ -420,8 +420,6 @@ private func statsControllerEntries(data: ChannelStats?, messages: [Message]?, i
|
|||
}
|
||||
|
||||
public func channelStatsController(context: AccountContext, peerId: PeerId, cachedPeerData: CachedPeerData) -> ViewController {
|
||||
var pushControllerImpl: ((ViewController) -> Void)?
|
||||
var presentControllerImpl: ((ViewController, ViewControllerPresentationArguments?) -> Void)?
|
||||
var navigateToMessageImpl: ((MessageId) -> Void)?
|
||||
|
||||
let actionsDisposable = DisposableSet()
|
||||
|
|
@ -506,16 +504,6 @@ public func channelStatsController(context: AccountContext, peerId: PeerId, cach
|
|||
controller.didDisappear = { [weak controller] _ in
|
||||
controller?.clearItemNodesHighlight(animated: true)
|
||||
}
|
||||
pushControllerImpl = { [weak controller] c in
|
||||
if let controller = controller {
|
||||
(controller.navigationController as? NavigationController)?.pushViewController(c, animated: true)
|
||||
}
|
||||
}
|
||||
presentControllerImpl = { [weak controller] c, a in
|
||||
if let controller = controller {
|
||||
controller.present(c, in: .window(.root), with: a)
|
||||
}
|
||||
}
|
||||
navigateToMessageImpl = { [weak controller] messageId in
|
||||
if let navigationController = controller?.navigationController as? NavigationController {
|
||||
context.sharedContext.navigateToChatController(NavigateToChatControllerParams(navigationController: navigationController, context: context, chatLocation: .peer(messageId.peerId), subject: .message(messageId), keepStack: .always, useExisting: false, purposefulAction: {}))
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@ final class StatsEmptyStateItemNode: ItemListControllerEmptyStateItemNode {
|
|||
|
||||
self.animationNode = AnimatedStickerNode()
|
||||
if let path = getAppBundle().path(forResource: "Charts", ofType: "tgs") {
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .once, mode: .direct)
|
||||
self.animationNode.setup(source: AnimatedStickerNodeLocalFileSource(path: path), width: 192, height: 192, playbackMode: .loop, mode: .direct)
|
||||
self.animationNode.visibility = true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ class StatsGraphItemNode: ListViewItemNode {
|
|||
super.didLoad()
|
||||
|
||||
self.view.interactiveTransitionGestureRecognizerTest = { point -> Bool in
|
||||
return point.x > 30.0 || (point.y > 250.0 && point.y < 295.0)
|
||||
return point.x > 30.0 || (point.y > 310.0 && point.y < 355.0)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,12 +150,12 @@ class StatsGraphItemNode: ListViewItemNode {
|
|||
case .plain:
|
||||
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 301.0)
|
||||
contentSize = CGSize(width: params.width, height: 361.0)
|
||||
insets = itemListNeighborsPlainInsets(neighbors)
|
||||
case .blocks:
|
||||
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 301.0)
|
||||
contentSize = CGSize(width: params.width, height: 361.0)
|
||||
insets = itemListNeighborsGroupedInsets(neighbors)
|
||||
}
|
||||
|
||||
|
|
@ -260,7 +260,7 @@ class StatsGraphItemNode: ListViewItemNode {
|
|||
}
|
||||
|
||||
if let updatedGraph = updatedGraph {
|
||||
if case let .Loaded(_, data) = updatedGraph, let updatedController = updatedController {
|
||||
if case .Loaded = updatedGraph, let updatedController = updatedController {
|
||||
strongSelf.chartNode.setup(controller: updatedController)
|
||||
strongSelf.activityIndicator.isHidden = true
|
||||
strongSelf.chartNode.isHidden = false
|
||||
|
|
|
|||
|
|
@ -224,6 +224,7 @@ public func customizeDefaultDarkPresentationTheme(theme: PresentationTheme, edit
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: theme.contextMenu,
|
||||
inAppNotification: theme.inAppNotification,
|
||||
chart: theme.chart,
|
||||
preview: theme.preview
|
||||
)
|
||||
}
|
||||
|
|
@ -543,6 +544,17 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
|
|||
)
|
||||
)
|
||||
)
|
||||
let chart = PresentationThemeChart(
|
||||
labelsColor: UIColor(rgb: 0x8e8e93),
|
||||
helperLinesColor: UIColor(rgb: 0xd8d8d8, alpha: 0.35),
|
||||
strongLinesColor: UIColor(rgb: 0xd8d8d8, alpha: 0.35),
|
||||
barStrongLinesColor: UIColor(rgb: 0xd8d8d8, alpha: 0.45),
|
||||
detailsTextColor: UIColor(rgb: 0xffffff),
|
||||
detailsArrowColor: UIColor(rgb: 0xd8d8d8),
|
||||
detailsViewColor: UIColor(rgb: 0x000000),
|
||||
rangeViewFrameColor: UIColor(rgb: 0x6d6d72),
|
||||
rangeViewMarkerColor: UIColor(rgb: 0xffffff)
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: extendingThemeReference?.name ?? .builtin(.night),
|
||||
|
|
@ -558,6 +570,7 @@ public func makeDefaultDarkPresentationTheme(extendingThemeReference: Presentati
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: contextMenu,
|
||||
inAppNotification: inAppNotification,
|
||||
chart: chart,
|
||||
preview: preview
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
|||
var actionSheet = theme.actionSheet
|
||||
var contextMenu = theme.contextMenu
|
||||
var inAppNotification = theme.inAppNotification
|
||||
|
||||
var chart = theme.chart
|
||||
|
||||
var mainBackgroundColor: UIColor?
|
||||
var mainSelectionColor: UIColor?
|
||||
|
|
@ -234,7 +234,6 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
|||
|
||||
var outgoingBubbleFillColor: UIColor?
|
||||
var outgoingBubbleFillGradientColor: UIColor?
|
||||
var outgoingBubbleHighlightedFillColor: UIColor?
|
||||
var outgoingPrimaryTextColor: UIColor?
|
||||
var outgoingSecondaryTextColor: UIColor?
|
||||
var outgoingLinkTextColor: UIColor?
|
||||
|
|
@ -423,6 +422,16 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
|||
)
|
||||
)
|
||||
|
||||
chart = chart.withUpdated(
|
||||
labelsColor: accentColor?.withMultiplied(hue: 1.033, saturation: 0.211, brightness: 0.882).withAlphaComponent(0.6),
|
||||
helperLinesColor: accentColor?.withMultiplied(hue: 1.037, saturation: 0.271, brightness: 0.671).withAlphaComponent(0.35),
|
||||
strongLinesColor: accentColor?.withMultiplied(hue: 1.037, saturation: 0.271, brightness: 0.671).withAlphaComponent(0.35),
|
||||
barStrongLinesColor: accentColor?.withMultiplied(hue: 1.033, saturation: 0.211, brightness: 0.882).withAlphaComponent(0.45),
|
||||
detailsArrowColor: accentColor?.withMultiplied(hue: 1.051, saturation: 0.254, brightness: 0.376),
|
||||
detailsViewColor: accentColor?.withMultiplied(hue: 1.035, saturation: 0.571, brightness: 0.184),
|
||||
rangeViewFrameColor: accentColor?.withMultiplied(hue: 1.030, saturation: 0.494, brightness: 0.349)
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: title.flatMap { .custom($0) } ?? theme.name,
|
||||
index: theme.index,
|
||||
|
|
@ -437,6 +446,7 @@ public func customizeDefaultDarkTintedPresentationTheme(theme: PresentationTheme
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: contextMenu,
|
||||
inAppNotification: inAppNotification,
|
||||
chart: chart,
|
||||
preview: theme.preview
|
||||
)
|
||||
}
|
||||
|
|
@ -463,7 +473,6 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
|||
|
||||
let outgoingBubbleFillGradientColor = accentColor.withMultiplied(hue: 1.019, saturation: 0.731, brightness: 0.59)
|
||||
let outgoingBubbleFillColor = outgoingBubbleFillGradientColor.withMultiplied(hue: 0.966, saturation: 0.61, brightness: 0.98)
|
||||
let outgoingBubbleHighlightedFillColor: UIColor
|
||||
let outgoingScamColor = UIColor(rgb: 0xffffff)
|
||||
let outgoingPrimaryTextColor = UIColor(rgb: 0xffffff)
|
||||
let outgoingSecondaryTextColor = UIColor(rgb: 0xffffff, alpha: 0.5)
|
||||
|
|
@ -792,6 +801,18 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
|||
)
|
||||
)
|
||||
)
|
||||
|
||||
let chart = PresentationThemeChart(
|
||||
labelsColor: UIColor(rgb: 0xbacce1, alpha: 0.6),
|
||||
helperLinesColor: UIColor(rgb: 0xbacce1, alpha: 0.35),
|
||||
strongLinesColor: UIColor(rgb: 0xbacce1, alpha: 0.35),
|
||||
barStrongLinesColor: UIColor(rgb: 0xbacce1, alpha: 0.45),
|
||||
detailsTextColor: UIColor(rgb: 0xffffff),
|
||||
detailsArrowColor: UIColor(rgb: 0x4c5460),
|
||||
detailsViewColor: UIColor(rgb: 0x19232f),
|
||||
rangeViewFrameColor: UIColor(rgb: 0x354659),
|
||||
rangeViewMarkerColor: UIColor(rgb: 0xffffff)
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: extendingThemeReference?.name ?? .builtin(.nightAccent),
|
||||
|
|
@ -807,6 +828,7 @@ public func makeDefaultDarkTintedPresentationTheme(extendingThemeReference: Pres
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: contextMenu,
|
||||
inAppNotification: inAppNotification,
|
||||
chart: chart,
|
||||
preview: preview
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -312,6 +312,7 @@ public func customizeDefaultDayTheme(theme: PresentationTheme, editing: Bool, ti
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: theme.contextMenu,
|
||||
inAppNotification: theme.inAppNotification,
|
||||
chart: theme.chart,
|
||||
preview: theme.preview
|
||||
)
|
||||
}
|
||||
|
|
@ -731,13 +732,13 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
|||
sectionSeparatorColor: UIColor(rgb: 0x8a8a8a, alpha: 0.2),
|
||||
itemBackgroundColor: UIColor(rgb: 0x000000, alpha: 0.0),
|
||||
itemHighlightedBackgroundColor: UIColor(rgb: 0x3c3c43, alpha: 0.2),
|
||||
primaryColor: UIColor(rgb: 0x000000, alpha: 1.0),
|
||||
primaryColor: UIColor(rgb: 0x000000),
|
||||
secondaryColor: UIColor(rgb: 0x000000, alpha: 0.8),
|
||||
destructiveColor: UIColor(rgb: 0xff3b30),
|
||||
badgeFillColor: UIColor(rgb: 0x007ee5),
|
||||
badgeForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0),
|
||||
badgeForegroundColor: UIColor(rgb: 0xffffff),
|
||||
badgeInactiveFillColor: UIColor(rgb: 0xb6b6bb),
|
||||
badgeInactiveForegroundColor: UIColor(rgb: 0xffffff, alpha: 1.0),
|
||||
badgeInactiveForegroundColor: UIColor(rgb: 0xffffff),
|
||||
extractedContentTintColor: .white
|
||||
)
|
||||
|
||||
|
|
@ -755,6 +756,18 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
|||
)
|
||||
)
|
||||
|
||||
let chart = PresentationThemeChart(
|
||||
labelsColor: UIColor(rgb: 0x252529, alpha: 0.5),
|
||||
helperLinesColor: UIColor(rgb: 0x182d3b, alpha: 0.3),
|
||||
strongLinesColor: UIColor(rgb: 0x182d3b, alpha: 0.3),
|
||||
barStrongLinesColor: UIColor(rgb: 0x252529, alpha: 0.2),
|
||||
detailsTextColor: UIColor(rgb: 0x6d6d72),
|
||||
detailsArrowColor: UIColor(rgb: 0xc5c7cd),
|
||||
detailsViewColor: UIColor(rgb: 0xf5f5fb),
|
||||
rangeViewFrameColor: UIColor(rgb: 0xcad4de),
|
||||
rangeViewMarkerColor: UIColor(rgb: 0xffffff)
|
||||
)
|
||||
|
||||
return PresentationTheme(
|
||||
name: extendingThemeReference?.name ?? .builtin(day ? .day : .dayClassic),
|
||||
index: extendingThemeReference?.index ?? PresentationThemeReference.builtin(day ? .day : .dayClassic).index,
|
||||
|
|
@ -769,6 +782,7 @@ public func makeDefaultDayPresentationTheme(extendingThemeReference: Presentatio
|
|||
actionSheet: actionSheet,
|
||||
contextMenu: contextMenu,
|
||||
inAppNotification: inAppNotification,
|
||||
chart: chart,
|
||||
preview: preview
|
||||
)
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -1083,6 +1083,34 @@ public final class PresentationThemeInAppNotification {
|
|||
}
|
||||
}
|
||||
|
||||
public final class PresentationThemeChart {
|
||||
public let labelsColor: UIColor
|
||||
public let helperLinesColor: UIColor
|
||||
public let strongLinesColor: UIColor
|
||||
public let barStrongLinesColor: UIColor
|
||||
public let detailsTextColor: UIColor
|
||||
public let detailsArrowColor: UIColor
|
||||
public let detailsViewColor: UIColor
|
||||
public let rangeViewFrameColor: UIColor
|
||||
public let rangeViewMarkerColor: UIColor
|
||||
|
||||
public init(labelsColor: UIColor, helperLinesColor: UIColor, strongLinesColor: UIColor, barStrongLinesColor: UIColor, detailsTextColor: UIColor, detailsArrowColor: UIColor, detailsViewColor: UIColor, rangeViewFrameColor: UIColor, rangeViewMarkerColor: UIColor) {
|
||||
self.labelsColor = labelsColor
|
||||
self.helperLinesColor = helperLinesColor
|
||||
self.strongLinesColor = strongLinesColor
|
||||
self.barStrongLinesColor = barStrongLinesColor
|
||||
self.detailsTextColor = detailsTextColor
|
||||
self.detailsArrowColor = detailsArrowColor
|
||||
self.detailsViewColor = detailsViewColor
|
||||
self.rangeViewFrameColor = rangeViewFrameColor
|
||||
self.rangeViewMarkerColor = rangeViewMarkerColor
|
||||
}
|
||||
|
||||
public func withUpdated(labelsColor: UIColor? = nil, helperLinesColor: UIColor? = nil, strongLinesColor: UIColor? = nil, barStrongLinesColor: UIColor? = nil, detailsTextColor: UIColor? = nil, detailsArrowColor: UIColor? = nil, detailsViewColor: UIColor? = nil, rangeViewFrameColor: UIColor? = nil, rangeViewMarkerColor: UIColor? = nil) -> PresentationThemeChart {
|
||||
return PresentationThemeChart(labelsColor: labelsColor ?? self.labelsColor, helperLinesColor: helperLinesColor ?? self.helperLinesColor, strongLinesColor: strongLinesColor ?? self.strongLinesColor, barStrongLinesColor: barStrongLinesColor ?? self.barStrongLinesColor, detailsTextColor: detailsTextColor ?? self.detailsTextColor, detailsArrowColor: detailsArrowColor ?? self.detailsArrowColor, detailsViewColor: detailsViewColor ?? self.detailsViewColor, rangeViewFrameColor: rangeViewFrameColor ?? self.rangeViewFrameColor, rangeViewMarkerColor: rangeViewMarkerColor ?? self.rangeViewMarkerColor)
|
||||
}
|
||||
}
|
||||
|
||||
public enum PresentationThemeBuiltinName {
|
||||
case dayClassic
|
||||
case day
|
||||
|
|
@ -1144,7 +1172,7 @@ public enum PresentationThemeName: Equatable {
|
|||
}
|
||||
|
||||
public extension PresentationThemeReference {
|
||||
public var name: PresentationThemeName {
|
||||
var name: PresentationThemeName {
|
||||
switch self {
|
||||
case let .builtin(theme):
|
||||
switch theme {
|
||||
|
|
@ -1179,11 +1207,12 @@ public final class PresentationTheme: Equatable {
|
|||
public let actionSheet: PresentationThemeActionSheet
|
||||
public let contextMenu: PresentationThemeContextMenu
|
||||
public let inAppNotification: PresentationThemeInAppNotification
|
||||
public let chart: PresentationThemeChart
|
||||
public let preview: Bool
|
||||
|
||||
public let resourceCache: PresentationsResourceCache = PresentationsResourceCache()
|
||||
|
||||
public init(name: PresentationThemeName, index: Int64, referenceTheme: PresentationBuiltinThemeReference, overallDarkAppearance: Bool, intro: PresentationThemeIntro, passcode: PresentationThemePasscode, rootController: PresentationThemeRootController, list: PresentationThemeList, chatList: PresentationThemeChatList, chat: PresentationThemeChat, actionSheet: PresentationThemeActionSheet, contextMenu: PresentationThemeContextMenu, inAppNotification: PresentationThemeInAppNotification, preview: Bool = false) {
|
||||
public init(name: PresentationThemeName, index: Int64, referenceTheme: PresentationBuiltinThemeReference, overallDarkAppearance: Bool, intro: PresentationThemeIntro, passcode: PresentationThemePasscode, rootController: PresentationThemeRootController, list: PresentationThemeList, chatList: PresentationThemeChatList, chat: PresentationThemeChat, actionSheet: PresentationThemeActionSheet, contextMenu: PresentationThemeContextMenu, inAppNotification: PresentationThemeInAppNotification, chart: PresentationThemeChart, preview: Bool = false) {
|
||||
self.name = name
|
||||
self.index = index
|
||||
self.referenceTheme = referenceTheme
|
||||
|
|
@ -1197,6 +1226,7 @@ public final class PresentationTheme: Equatable {
|
|||
self.actionSheet = actionSheet
|
||||
self.contextMenu = contextMenu
|
||||
self.inAppNotification = inAppNotification
|
||||
self.chart = chart
|
||||
self.preview = preview
|
||||
}
|
||||
|
||||
|
|
@ -1230,10 +1260,10 @@ public final class PresentationTheme: Equatable {
|
|||
break
|
||||
}
|
||||
}
|
||||
return PresentationTheme(name: name.flatMap(PresentationThemeName.custom) ?? .custom(self.name.string), index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat.withUpdated(defaultWallpaper: defaultWallpaper), actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification)
|
||||
return PresentationTheme(name: name.flatMap(PresentationThemeName.custom) ?? .custom(self.name.string), index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat.withUpdated(defaultWallpaper: defaultWallpaper), actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification, chart: self.chart, preview: self.preview)
|
||||
}
|
||||
|
||||
public func withUpdated(preview: Bool) -> PresentationTheme {
|
||||
return PresentationTheme(name: self.name, index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat, actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification, preview: preview)
|
||||
return PresentationTheme(name: self.name, index: self.index, referenceTheme: self.referenceTheme, overallDarkAppearance: self.overallDarkAppearance, intro: self.intro, passcode: self.passcode, rootController: self.rootController, list: self.list, chatList: self.chatList, chat: self.chat, actionSheet: self.actionSheet, contextMenu: self.contextMenu, inAppNotification: self.inAppNotification, chart: self.chart, preview: preview)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1700,6 +1700,39 @@ extension PresentationThemeInAppNotification: Codable {
|
|||
}
|
||||
}
|
||||
|
||||
extension PresentationThemeChart: Codable {
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case labels
|
||||
case helperLines
|
||||
case strongLines
|
||||
case barStrongLines
|
||||
case detailsText
|
||||
case detailsArrow
|
||||
case detailsView
|
||||
case rangeViewFrame
|
||||
case rangeViewMarker
|
||||
}
|
||||
|
||||
public convenience init(from decoder: Decoder) throws {
|
||||
let values = try decoder.container(keyedBy: CodingKeys.self)
|
||||
self.init(labelsColor: try decodeColor(values, .labels), helperLinesColor: try decodeColor(values, .helperLines), strongLinesColor: try decodeColor(values, .strongLines), barStrongLinesColor: try decodeColor(values, .barStrongLines), detailsTextColor: try decodeColor(values, .detailsText), detailsArrowColor: try decodeColor(values, .detailsArrow), detailsViewColor: try decodeColor(values, .detailsView), rangeViewFrameColor: try decodeColor(values, .rangeViewFrame), rangeViewMarkerColor: try decodeColor(values, .rangeViewMarker))
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var values = encoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
try encodeColor(&values, self.labelsColor, .labels)
|
||||
try encodeColor(&values, self.helperLinesColor, .helperLines)
|
||||
try encodeColor(&values, self.strongLinesColor, .strongLines)
|
||||
try encodeColor(&values, self.barStrongLinesColor, .barStrongLines)
|
||||
try encodeColor(&values, self.detailsTextColor, .detailsText)
|
||||
try encodeColor(&values, self.detailsArrowColor, .detailsArrow)
|
||||
try encodeColor(&values, self.detailsViewColor, .detailsView)
|
||||
try encodeColor(&values, self.rangeViewFrameColor, .rangeViewFrame)
|
||||
try encodeColor(&values, self.rangeViewMarkerColor, .rangeViewMarker)
|
||||
}
|
||||
}
|
||||
|
||||
extension PresentationThemeName: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let value = try decoder.singleValueContainer()
|
||||
|
|
@ -1776,6 +1809,7 @@ extension PresentationTheme: Codable {
|
|||
case actionSheet
|
||||
case contextMenu
|
||||
case notification
|
||||
case chart
|
||||
}
|
||||
|
||||
public convenience init(from decoder: Decoder) throws {
|
||||
|
|
@ -1808,7 +1842,8 @@ extension PresentationTheme: Codable {
|
|||
chat: try values.decode(PresentationThemeChat.self, forKey: .chat),
|
||||
actionSheet: try values.decode(PresentationThemeActionSheet.self, forKey: .actionSheet),
|
||||
contextMenu: try values.decode(PresentationThemeContextMenu.self, forKey: .contextMenu),
|
||||
inAppNotification: try values.decode(PresentationThemeInAppNotification.self, forKey: .notification)
|
||||
inAppNotification: try values.decode(PresentationThemeInAppNotification.self, forKey: .notification),
|
||||
chart: try values.decode(PresentationThemeChart.self, forKey: .chart)
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -1826,5 +1861,6 @@ extension PresentationTheme: Codable {
|
|||
try container.encode(self.actionSheet, forKey: .actionSheet)
|
||||
try container.encode(self.contextMenu, forKey: .contextMenu)
|
||||
try container.encode(self.inAppNotification, forKey: .notification)
|
||||
try container.encode(self.chart, forKey: .chart)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "selection_frame_dark.pdf",
|
||||
"resizing" : {
|
||||
"mode" : "3-part-horizontal",
|
||||
"center" : {
|
||||
"mode" : "stretch",
|
||||
"width" : 1
|
||||
},
|
||||
"cap-insets" : {
|
||||
"right" : 11,
|
||||
"left" : 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
%PDF-1.4
|
||||
%Óëéá
|
||||
1 0 obj
|
||||
<</Producer (Adobe XD)
|
||||
/ProductionLibrary (Skia/PDF m69)>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<</Filter /FlateDecode
|
||||
/Length 323>> stream
|
||||
xœ<EFBFBD>’MN1…÷9…×HìØùñ º.,8ÀÊbŠD{ 'ÓvBZ$&Ò(zvü9Î#@[ÙOÌG÷íª@$£ÉmàôîÞžàËyæž‹€—<E282AC>áeƒr:¸çÂáì³×ú…kÊptiÚ©‹>)å Ô©SÝ JŒ¢) °zÆKº<4B>´¢Hf7Æ.<£Œ±Ulü5…(eÌz;ní<0E>¹¿à[µfsc×éwøNÜú5Â&oW\~É·™tÄm„ß`vŸÖ{Õ*CK°þŠ=N'Õ|¡T<C2A1>ªžˆþ’[ŠRšü öbÐ35ÏL¡d‚Õvu™—ÖM³U±²ÏD-=°1‰X—¬Ù×<C399>²ÉT¼a«ß'Û€²°™zq¯nßc¹¨M=ÄÿÀ<C3BF>"Xîà+&
ð-y€ïÝKSª²
|
||||
endstream
|
||||
endobj
|
||||
3 0 obj
|
||||
<</Type /Catalog
|
||||
/Pages 4 0 R>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<</Type /Pages
|
||||
/Count 1
|
||||
/Kids [5 0 R]>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<</Type /Page
|
||||
/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
|
||||
/ExtGState <</G0 6 0 R
|
||||
/G1 7 0 R>>>>
|
||||
/MediaBox [0 0 114 42]
|
||||
/Contents 2 0 R
|
||||
/Parent 4 0 R>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<</ca 1
|
||||
/BM /Normal>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<</CA 1
|
||||
/ca 1
|
||||
/LC 1
|
||||
/LJ 1
|
||||
/LW 1.5
|
||||
/ML 4
|
||||
/SA true
|
||||
/BM /Normal>>
|
||||
endobj
|
||||
xref
|
||||
0 8
|
||||
0000000000 65535 f
|
||||
0000000015 00000 n
|
||||
0000000089 00000 n
|
||||
0000000482 00000 n
|
||||
0000000529 00000 n
|
||||
0000000584 00000 n
|
||||
0000000765 00000 n
|
||||
0000000802 00000 n
|
||||
trailer
|
||||
<</Size 8
|
||||
/Root 3 0 R
|
||||
/Info 1 0 R>>
|
||||
startxref
|
||||
880
|
||||
%%EOF
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "selection_frame_light.pdf",
|
||||
"resizing" : {
|
||||
"mode" : "3-part-horizontal",
|
||||
"center" : {
|
||||
"mode" : "stretch",
|
||||
"width" : 1
|
||||
},
|
||||
"cap-insets" : {
|
||||
"right" : 11,
|
||||
"left" : 11
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
|
|
@ -1,62 +0,0 @@
|
|||
%PDF-1.4
|
||||
%Óëéá
|
||||
1 0 obj
|
||||
<</Producer (Adobe XD)
|
||||
/ProductionLibrary (Skia/PDF m69)>>
|
||||
endobj
|
||||
2 0 obj
|
||||
<</Filter /FlateDecode
|
||||
/Length 323>> stream
|
||||
xœ<EFBFBD>’ÏNÃ0Æï~
|
||||
Ÿ‘ìÄùã'Øypà*‡‰ñþNºY6$5оÏõÏuÌH¶&¶M<ÎGø†*0‹#¢@Ñävòxz‡·'ü—c@W¼½¶½ìðV8àyGxø¦ì´>þ’„3!™U;uï’röÂ<C3B6>:Õ‘Ä(š’`P¨Ä’î<E28099>–”8â£wæ±eôÎT-¸ñ׿”)ëõs+w0æþofnÅæ2z—Þrèð<C3A8>¸Õk„MÞ~q¹‘¯=éˆ[ÞÁŸV{Õ©]]õ¾b—ÓÉÂ5^8U ùª'æ¿ä–„£”&?ȽôÃÆ‹ÛÄ1N¾dôBuèë²QZm„¸ŽPÐà2{Q÷Áù˜D¬Ê ÙÕ†“¹8-,l
Êl¤x…}<7D>
Eë>þn¡r_1i€oÁ|¿BªV
|
||||
endstream
|
||||
endobj
|
||||
3 0 obj
|
||||
<</Type /Catalog
|
||||
/Pages 4 0 R>>
|
||||
endobj
|
||||
4 0 obj
|
||||
<</Type /Pages
|
||||
/Count 1
|
||||
/Kids [5 0 R]>>
|
||||
endobj
|
||||
5 0 obj
|
||||
<</Type /Page
|
||||
/Resources <</ProcSets [/PDF /Text /ImageB /ImageC /ImageI]
|
||||
/ExtGState <</G0 6 0 R
|
||||
/G1 7 0 R>>>>
|
||||
/MediaBox [0 0 114 42]
|
||||
/Contents 2 0 R
|
||||
/Parent 4 0 R>>
|
||||
endobj
|
||||
6 0 obj
|
||||
<</ca 1
|
||||
/BM /Normal>>
|
||||
endobj
|
||||
7 0 obj
|
||||
<</CA 1
|
||||
/ca 1
|
||||
/LC 1
|
||||
/LJ 1
|
||||
/LW 1.5
|
||||
/ML 4
|
||||
/SA true
|
||||
/BM /Normal>>
|
||||
endobj
|
||||
xref
|
||||
0 8
|
||||
0000000000 65535 f
|
||||
0000000015 00000 n
|
||||
0000000089 00000 n
|
||||
0000000482 00000 n
|
||||
0000000529 00000 n
|
||||
0000000584 00000 n
|
||||
0000000765 00000 n
|
||||
0000000802 00000 n
|
||||
trailer
|
||||
<</Size 8
|
||||
/Root 3 0 R
|
||||
/Info 1 0 R>>
|
||||
startxref
|
||||
880
|
||||
%%EOF
|
||||
Binary file not shown.
|
|
@ -256,6 +256,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||
var loadStickerSaveStatus: MediaId?
|
||||
var loadCopyMediaResource: MediaResource?
|
||||
var isAction = false
|
||||
var isDice = false
|
||||
if messages.count == 1 {
|
||||
for media in messages[0].media {
|
||||
if let file = media as? TelegramMediaFile {
|
||||
|
|
@ -270,6 +271,8 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||
if !messages[0].containsSecretMedia {
|
||||
loadCopyMediaResource = largestImageRepresentation(image.representations)?.resource
|
||||
}
|
||||
} else if let _ = media as? TelegramMediaDice {
|
||||
isDice = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -283,8 +286,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||
if Namespaces.Message.allScheduled.contains(message.id.namespace) {
|
||||
canReply = false
|
||||
canPin = false
|
||||
}
|
||||
else if messages[0].flags.intersection([.Failed, .Unsent]).isEmpty {
|
||||
} else if messages[0].flags.intersection([.Failed, .Unsent]).isEmpty {
|
||||
switch chatPresentationInterfaceState.chatLocation {
|
||||
case .peer:
|
||||
if let channel = messages[0].peers[messages[0].id.peerId] as? TelegramChannel {
|
||||
|
|
@ -411,7 +413,7 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||
resourceAvailable = false
|
||||
}
|
||||
|
||||
if !messages[0].text.isEmpty || resourceAvailable {
|
||||
if !messages[0].text.isEmpty || resourceAvailable || isDice {
|
||||
let message = messages[0]
|
||||
var isExpired = false
|
||||
for media in message.media {
|
||||
|
|
@ -423,40 +425,44 @@ func contextMenuForChatPresentationIntefaceState(chatPresentationInterfaceState:
|
|||
actions.append(.action(ContextMenuActionItem(text: chatPresentationInterfaceState.strings.Conversation_ContextMenuCopy, icon: { theme in
|
||||
return generateTintedImage(image: UIImage(bundleImageName: "Chat/Context Menu/Copy"), color: theme.actionSheet.primaryTextColor)
|
||||
}, action: { _, f in
|
||||
let copyTextWithEntities = {
|
||||
var messageEntities: [MessageTextEntity]?
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? TextEntitiesMessageAttribute {
|
||||
messageEntities = attribute.entities
|
||||
break
|
||||
if isDice {
|
||||
UIPasteboard.general.string = "🎲"
|
||||
} else {
|
||||
let copyTextWithEntities = {
|
||||
var messageEntities: [MessageTextEntity]?
|
||||
for attribute in message.attributes {
|
||||
if let attribute = attribute as? TextEntitiesMessageAttribute {
|
||||
messageEntities = attribute.entities
|
||||
break
|
||||
}
|
||||
}
|
||||
storeMessageTextInPasteboard(message.text, entities: messageEntities)
|
||||
}
|
||||
storeMessageTextInPasteboard(message.text, entities: messageEntities)
|
||||
}
|
||||
if resourceAvailable {
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) {
|
||||
let _ = (context.account.postbox.mediaBox.resourceData(largest.resource, option: .incremental(waitUntilFetchStatus: false))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
if data.complete, let imageData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) {
|
||||
if let image = UIImage(data: imageData) {
|
||||
if !message.text.isEmpty {
|
||||
copyTextWithEntities()
|
||||
if resourceAvailable {
|
||||
for media in message.media {
|
||||
if let image = media as? TelegramMediaImage, let largest = largestImageRepresentation(image.representations) {
|
||||
let _ = (context.account.postbox.mediaBox.resourceData(largest.resource, option: .incremental(waitUntilFetchStatus: false))
|
||||
|> take(1)
|
||||
|> deliverOnMainQueue).start(next: { data in
|
||||
if data.complete, let imageData = try? Data(contentsOf: URL(fileURLWithPath: data.path)) {
|
||||
if let image = UIImage(data: imageData) {
|
||||
if !message.text.isEmpty {
|
||||
copyTextWithEntities()
|
||||
} else {
|
||||
UIPasteboard.general.image = image
|
||||
}
|
||||
} else {
|
||||
UIPasteboard.general.image = image
|
||||
copyTextWithEntities()
|
||||
}
|
||||
} else {
|
||||
copyTextWithEntities()
|
||||
}
|
||||
} else {
|
||||
copyTextWithEntities()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
} else {
|
||||
copyTextWithEntities()
|
||||
}
|
||||
} else {
|
||||
copyTextWithEntities()
|
||||
}
|
||||
f(.default)
|
||||
})))
|
||||
|
|
|
|||
|
|
@ -148,8 +148,6 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||
}
|
||||
|
||||
private func setupNode(item: ChatMessageItem) {
|
||||
var isDice = false
|
||||
|
||||
if let telegramDice = self.telegramDice, let diceEmojis = item.associatedData.animatedEmojiStickers["🎲"] {
|
||||
let animationNode = ManagedDiceAnimationNode(context: item.context, emojis: diceEmojis.map { $0.file })
|
||||
self.animationNode = animationNode
|
||||
|
|
@ -836,13 +834,12 @@ class ChatMessageAnimatedStickerItemNode: ChatMessageItemView {
|
|||
}
|
||||
|
||||
if let item = self.item, self.imageNode.frame.contains(location) {
|
||||
if self.telegramFile != nil {
|
||||
if let _ = self.telegramFile {
|
||||
let _ = item.controllerInteraction.openMessage(item.message, .default)
|
||||
} else if let _ = self.telegramDice {
|
||||
item.controllerInteraction.displayMessageTooltip(item.content.firstMessage.id, item.presentationData.strings.Conversation_Dice, self, self.imageNode.frame)
|
||||
} else if let _ = self.emojiFile {
|
||||
let (emoji, fitz) = item.message.text.basicEmoji
|
||||
if emoji == "🎲" {
|
||||
|
||||
} else if let animationNode = self.animationNode as? AnimatedStickerNode {
|
||||
if let animationNode = self.animationNode as? AnimatedStickerNode {
|
||||
var startTime: Signal<Double, NoError>
|
||||
if animationNode.playIfNeeded() {
|
||||
startTime = .single(0.0)
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
|||
|
||||
self.disposable.set(sticker.start(next: { [weak self] data in
|
||||
if let strongSelf = self {
|
||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3))
|
||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0))
|
||||
}
|
||||
}))
|
||||
case .rolling:
|
||||
|
|
@ -73,7 +73,7 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
|||
case let .value(currentValue):
|
||||
switch diceState {
|
||||
case .rolling:
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local("DiceRolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3))
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local("DiceRolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0, loop: true))
|
||||
case let .value(value):
|
||||
break
|
||||
}
|
||||
|
|
@ -103,11 +103,11 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode, GenericAnimatedStick
|
|||
|
||||
self.disposable.set(sticker.start(next: { [weak self] data in
|
||||
if let strongSelf = self {
|
||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3))
|
||||
strongSelf.trackTo(item: ManagedAnimationItem(source: .resource(strongSelf.context.account.postbox.mediaBox, file.resource), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 180), duration: 3.0))
|
||||
}
|
||||
}))
|
||||
case .rolling:
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local("DiceRolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3))
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local("DiceRolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3, loop: true))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue