mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-06-16 05:55:20 +00:00
Charts improvements
This commit is contained in:
parent
598f270635
commit
bcae054398
@ -5382,7 +5382,7 @@ Any member of this group will be able to see messages in the channel.";
|
||||
"Stats.MessageForwards_0" = "%@ forwards";
|
||||
"Stats.MessageForwards_1" = "%@ forward";
|
||||
"Stats.MessageForwards_2" = "%@ forwards";
|
||||
"Stats.MessageForwards_3_10" = "%@ forwardss";
|
||||
"Stats.MessageForwards_3_10" = "%@ forwards";
|
||||
"Stats.MessageForwards_many" = "%@ forwards";
|
||||
"Stats.MessageForwards_any" = "%@ forwards";
|
||||
|
||||
@ -5392,4 +5392,4 @@ Any member of this group will be able to see messages in the channel.";
|
||||
"InstantPage.Views_3_10" = "%@ views";
|
||||
"InstantPage.Views_many" = "%@ views";
|
||||
"InstantPage.Views_any" = "%@ views";
|
||||
"InstantPage.FeedbackButtonShort" = "Leave feedback";
|
||||
"InstantPage.FeedbackButtonShort" = "Wrong layout?";
|
||||
|
@ -74,20 +74,23 @@ public struct ChartDetailsViewModel {
|
||||
public internal(set) var values: [Value]
|
||||
public internal(set) var totalValue: Value?
|
||||
public internal(set) var tapAction: (() -> Void)?
|
||||
public internal(set) var hideAction: (() -> Void)?
|
||||
|
||||
static let blank = ChartDetailsViewModel(title: "", showArrow: false, showPrefixes: false, values: [], totalValue: nil, tapAction: nil)
|
||||
static let blank = ChartDetailsViewModel(title: "", showArrow: false, showPrefixes: false, values: [], totalValue: nil, tapAction: nil, hideAction: nil)
|
||||
public init(title: String,
|
||||
showArrow: Bool,
|
||||
showPrefixes: Bool,
|
||||
values: [Value],
|
||||
totalValue: Value?,
|
||||
tapAction: (() -> Void)?) {
|
||||
tapAction: (() -> Void)?,
|
||||
hideAction: (() -> Void)?) {
|
||||
self.title = title
|
||||
self.showArrow = showArrow
|
||||
self.showPrefixes = showPrefixes
|
||||
self.values = values
|
||||
self.totalValue = totalValue
|
||||
self.tapAction = tapAction
|
||||
self.hideAction = hideAction
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,10 +70,11 @@ enum BaseConstants {
|
||||
}()
|
||||
}
|
||||
|
||||
public class BaseChartController: GColorModeContainer {
|
||||
public class BaseChartController: ChartThemeContainer {
|
||||
//let performanceRenderer = PerformanceRenderer()
|
||||
var initialChartsCollection: ChartsCollection
|
||||
var isZoomed: Bool = false
|
||||
public var isZoomable: Bool = true
|
||||
|
||||
var chartTitle: String = ""
|
||||
|
||||
@ -148,7 +149,7 @@ public class BaseChartController: GColorModeContainer {
|
||||
fatalError("Abstract")
|
||||
}
|
||||
|
||||
public func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
fatalError("Abstract")
|
||||
}
|
||||
|
||||
@ -180,7 +181,7 @@ public class BaseChartController: GColorModeContainer {
|
||||
fatalError("Abstract")
|
||||
}
|
||||
|
||||
public func apply(colorMode: GColorMode, animated: Bool) {
|
||||
public func apply(theme: ChartTheme, animated: Bool) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -18,15 +18,16 @@ enum GeneralChartComponentConstants {
|
||||
static let defaultZoomedRangeLength = CGFloat(TimeInterval.day)
|
||||
}
|
||||
|
||||
class GeneralChartComponentController: GColorModeContainer {
|
||||
class GeneralChartComponentController: ChartThemeContainer {
|
||||
var chartsCollection: ChartsCollection = ChartsCollection.blank
|
||||
var chartVisibility: [Bool] = []
|
||||
var lastChartInteractionPoint: CGPoint = .zero
|
||||
var isChartInteractionBegun: Bool = false
|
||||
var isChartInteracting: Bool = false
|
||||
let isZoomed: Bool
|
||||
var isZoomable = true
|
||||
|
||||
var colorMode: GColorMode = .day
|
||||
var theme: ChartTheme = ChartTheme.defaultDayTheme
|
||||
var totalHorizontalRange: ClosedRange<CGFloat> = BaseConstants.defaultRange
|
||||
var totalVerticalRange: ClosedRange<CGFloat> = BaseConstants.defaultRange
|
||||
var initialHorizontalRange: ClosedRange<CGFloat> = BaseConstants.defaultRange
|
||||
@ -214,8 +215,8 @@ class GeneralChartComponentController: GColorModeContainer {
|
||||
var setDetailsViewModel: ((ChartDetailsViewModel, Bool) -> Void)?
|
||||
var chartRangePagingClosure: ((Bool, CGFloat) -> Void)? // isEnabled, PageSize
|
||||
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
self.colorMode = colorMode
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
self.theme = theme
|
||||
}
|
||||
|
||||
// MARK: - Helpers
|
||||
@ -310,12 +311,15 @@ class GeneralChartComponentController: GColorModeContainer {
|
||||
dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
|
||||
}
|
||||
let viewModel = ChartDetailsViewModel(title: dateString,
|
||||
showArrow: !self.isZoomed,
|
||||
showArrow: self.isZoomable && !self.isZoomed,
|
||||
showPrefixes: false,
|
||||
values: values,
|
||||
totalValue: nil,
|
||||
tapAction: { [weak self] in
|
||||
self?.zoomInOnDateClosure?(closestDate) })
|
||||
self?.zoomInOnDateClosure?(closestDate) },
|
||||
hideAction: { [weak self] in
|
||||
|
||||
})
|
||||
return viewModel
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,7 @@ public class BaseLinesChartController: BaseChartController {
|
||||
isChartInteractionBegun = false
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
|
||||
}
|
||||
|
||||
@ -114,11 +114,14 @@ public class BaseLinesChartController: BaseChartController {
|
||||
dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
|
||||
}
|
||||
let viewModel = ChartDetailsViewModel(title: dateString,
|
||||
showArrow: !self.isZoomed,
|
||||
showArrow: self.isZoomable && !self.isZoomed,
|
||||
showPrefixes: false,
|
||||
values: values,
|
||||
totalValue: nil,
|
||||
tapAction: { [weak self] in self?.didTapZoomIn(date: closestDate) })
|
||||
tapAction: { [weak self] in self?.didTapZoomIn(date: closestDate) },
|
||||
hideAction: { [weak self] in
|
||||
self?.setDetailsChartVisibleClosure?(false, true)
|
||||
})
|
||||
return viewModel
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ public class GeneralLinesChartController: BaseLinesChartController {
|
||||
return visibleCharts
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
cancelChartInteraction()
|
||||
|
||||
let horizontalRange = ClosedRange(uncheckedBounds:
|
||||
@ -184,11 +184,11 @@ public class GeneralLinesChartController: BaseLinesChartController {
|
||||
upper: totalHorizontalRange.lowerBound + rangeFraction.upperBound * totalHorizontalRange.distance))
|
||||
|
||||
zoomedChartRange = horizontalRange
|
||||
updateChartRangeTitle(animated: true)
|
||||
updateChartRangeTitle(animated: animated)
|
||||
|
||||
updateMainChartHorizontalRange(range: horizontalRange, animated: false)
|
||||
updateHorizontalLimits(horizontalRange: horizontalRange, animated: true)
|
||||
updateVerticalLimitsAndRange(horizontalRange: horizontalRange, animated: true)
|
||||
updateHorizontalLimits(horizontalRange: horizontalRange, animated: animated)
|
||||
updateVerticalLimitsAndRange(horizontalRange: horizontalRange, animated: animated)
|
||||
}
|
||||
|
||||
func updateMainChartHorizontalRange(range: ClosedRange<CGFloat>, animated: Bool) {
|
||||
@ -239,12 +239,12 @@ public class GeneralLinesChartController: BaseLinesChartController {
|
||||
}
|
||||
}
|
||||
|
||||
override public func apply(colorMode: GColorMode, animated: Bool) {
|
||||
horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
|
||||
lineBulletsRenderer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
|
||||
verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
|
||||
override public func apply(theme: ChartTheme, animated: Bool) {
|
||||
horizontalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = theme.chartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = theme.chartHelperLinesColor
|
||||
lineBulletsRenderer.setInnerColor(theme.chartBackgroundColor, animated: animated)
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
}
|
||||
}
|
||||
|
@ -199,7 +199,7 @@ public class TwoAxisLinesChartController: BaseLinesChartController {
|
||||
self.setupChartCollection(chartsCollection: initialChartCollection, animated: true, isZoomed: false)
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
cancelChartInteraction()
|
||||
|
||||
let horizontalRange = ClosedRange(uncheckedBounds:
|
||||
@ -297,14 +297,14 @@ public class TwoAxisLinesChartController: BaseLinesChartController {
|
||||
}
|
||||
}
|
||||
|
||||
public override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
|
||||
public override func apply(theme: ChartTheme, animated: Bool) {
|
||||
horizontalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
|
||||
for controller in graphControllers {
|
||||
controller.verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
|
||||
controller.lineBulletsRenderer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
|
||||
controller.verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
|
||||
controller.verticalScalesRenderer.horizontalLinesColor = theme.chartHelperLinesColor
|
||||
controller.lineBulletsRenderer.setInnerColor(theme.chartBackgroundColor, animated: animated)
|
||||
controller.verticalScalesRenderer.axisXColor = theme.chartStrongLinesColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -151,13 +151,16 @@ class PercentChartComponentController: GeneralChartComponentController {
|
||||
dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
|
||||
}
|
||||
let viewModel = ChartDetailsViewModel(title: dateString,
|
||||
showArrow: !self.isZoomed,
|
||||
showArrow: self.isZoomable && !self.isZoomed,
|
||||
showPrefixes: true,
|
||||
values: values,
|
||||
totalValue: nil,
|
||||
tapAction: { [weak self] in
|
||||
self?.hideDetailsView(animated: true)
|
||||
self?.zoomInOnDateClosure?(closestDate) })
|
||||
self?.zoomInOnDateClosure?(closestDate) },
|
||||
hideAction: { [weak self] in
|
||||
self?.hideDetailsView(animated: true)
|
||||
})
|
||||
return viewModel
|
||||
}
|
||||
|
||||
@ -188,13 +191,13 @@ class PercentChartComponentController: GeneralChartComponentController {
|
||||
verticalLineRenderer.isEnabled = false
|
||||
}
|
||||
|
||||
override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = colorMode.barChartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = colorMode.barChartStrongLinesColor
|
||||
verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
|
||||
horizontalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = theme.barChartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = theme.barChartStrongLinesColor
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
}
|
||||
}
|
||||
|
@ -281,7 +281,7 @@ public class PercentPieChartController: BaseChartController {
|
||||
})
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
if isZoomed {
|
||||
return pieController.chartRangeFractionDidUpdated(rangeFraction)
|
||||
} else {
|
||||
@ -289,11 +289,11 @@ public class PercentPieChartController: BaseChartController {
|
||||
}
|
||||
}
|
||||
|
||||
public override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
public override func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
pieController.apply(colorMode: colorMode, animated: animated)
|
||||
percentController.apply(colorMode: colorMode, animated: animated)
|
||||
transitionRenderer.backgroundColor = colorMode.chartBackgroundColor
|
||||
pieController.apply(theme: theme, animated: animated)
|
||||
percentController.apply(theme: theme, animated: animated)
|
||||
transitionRenderer.backgroundColor = theme.chartBackgroundColor
|
||||
}
|
||||
}
|
||||
|
@ -156,7 +156,8 @@ class PieChartComponentController: GeneralChartComponentController {
|
||||
color: pieItem.color,
|
||||
visible: true)],
|
||||
totalValue: nil,
|
||||
tapAction: nil)
|
||||
tapAction: nil,
|
||||
hideAction: nil)
|
||||
return viewModel
|
||||
}
|
||||
|
||||
|
@ -226,19 +226,19 @@ class BarsComponentController: GeneralChartComponentController {
|
||||
|
||||
mainBarsRenderer.setSelectedIndex(nil, animated: animated)
|
||||
}
|
||||
override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = colorMode.barChartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = colorMode.barChartStrongLinesColor
|
||||
mainBarsRenderer.update(backgroundColor: colorMode.chartBackgroundColor, animated: false)
|
||||
previewBarsChartRenderer.update(backgroundColor: colorMode.chartBackgroundColor, animated: false)
|
||||
horizontalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = theme.barChartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = theme.barChartStrongLinesColor
|
||||
mainBarsRenderer.update(backgroundColor: theme.chartBackgroundColor, animated: false)
|
||||
previewBarsChartRenderer.update(backgroundColor: theme.chartBackgroundColor, animated: false)
|
||||
|
||||
secondVerticalScalesRenderer?.labelsColor = colorMode.chartLabelsColor
|
||||
secondVerticalScalesRenderer?.axisXColor = colorMode.barChartStrongLinesColor
|
||||
secondVerticalScalesRenderer?.horizontalLinesColor = colorMode.barChartStrongLinesColor
|
||||
secondVerticalScalesRenderer?.labelsColor = theme.chartLabelsColor
|
||||
secondVerticalScalesRenderer?.axisXColor = theme.barChartStrongLinesColor
|
||||
secondVerticalScalesRenderer?.horizontalLinesColor = theme.barChartStrongLinesColor
|
||||
}
|
||||
|
||||
override func updateChartRangeTitle(animated: Bool) {
|
||||
|
@ -235,7 +235,7 @@ public class DailyBarsChartController: BaseChartController {
|
||||
switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: true)
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
if isZoomed {
|
||||
return linesController.chartRangeFractionDidUpdated(rangeFraction)
|
||||
} else {
|
||||
@ -243,11 +243,11 @@ public class DailyBarsChartController: BaseChartController {
|
||||
}
|
||||
}
|
||||
|
||||
override public func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override public func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
linesController.apply(colorMode: colorMode, animated: animated)
|
||||
barsController.apply(colorMode: colorMode, animated: animated)
|
||||
linesController.apply(theme: theme, animated: animated)
|
||||
barsController.apply(theme: theme, animated: animated)
|
||||
}
|
||||
|
||||
public override var drawChartVisibity: Bool {
|
||||
|
@ -202,14 +202,14 @@ class LinesComponentController: GeneralChartComponentController {
|
||||
lineBulletsRenderer.isEnabled = false
|
||||
}
|
||||
|
||||
override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
horizontalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = colorMode.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
|
||||
lineBulletsRenderer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
|
||||
verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
|
||||
horizontalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.labelsColor = theme.chartLabelsColor
|
||||
verticalScalesRenderer.axisXColor = theme.chartStrongLinesColor
|
||||
verticalScalesRenderer.horizontalLinesColor = theme.chartHelperLinesColor
|
||||
lineBulletsRenderer.setInnerColor(theme.chartBackgroundColor, animated: animated)
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,12 @@ public class StackedBarsChartController: BaseChartController {
|
||||
let barsController: BarsComponentController
|
||||
let zoomedBarsController: BarsComponentController
|
||||
|
||||
override public var isZoomable: Bool {
|
||||
didSet {
|
||||
barsController.isZoomable = self.isZoomable
|
||||
}
|
||||
}
|
||||
|
||||
override public init(chartsCollection: ChartsCollection) {
|
||||
let horizontalScalesRenderer = HorizontalScalesRenderer()
|
||||
let verticalScalesRenderer = VerticalScalesRenderer()
|
||||
@ -235,7 +241,7 @@ public class StackedBarsChartController: BaseChartController {
|
||||
switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: true)
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
if isZoomed {
|
||||
return zoomedBarsController.chartRangeFractionDidUpdated(rangeFraction)
|
||||
} else {
|
||||
@ -243,10 +249,10 @@ public class StackedBarsChartController: BaseChartController {
|
||||
}
|
||||
}
|
||||
|
||||
public override func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
public override func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
zoomedBarsController.apply(colorMode: colorMode, animated: animated)
|
||||
barsController.apply(colorMode: colorMode, animated: animated)
|
||||
zoomedBarsController.apply(theme: theme, animated: animated)
|
||||
barsController.apply(theme: theme, animated: animated)
|
||||
}
|
||||
}
|
||||
|
@ -235,7 +235,7 @@ public class StepBarsChartController: BaseChartController {
|
||||
switchToChart(chartsCollection: barsController.chartsCollection, isZoomed: false, animated: true)
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool = true) {
|
||||
if isZoomed {
|
||||
return zoomedBarsController.chartRangeFractionDidUpdated(rangeFraction)
|
||||
} else {
|
||||
@ -243,11 +243,11 @@ public class StepBarsChartController: BaseChartController {
|
||||
}
|
||||
}
|
||||
|
||||
override public func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override public func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
zoomedBarsController.apply(colorMode: colorMode, animated: animated)
|
||||
barsController.apply(colorMode: colorMode, animated: animated)
|
||||
zoomedBarsController.apply(theme: theme, animated: animated)
|
||||
barsController.apply(theme: theme, animated: animated)
|
||||
}
|
||||
|
||||
public override var drawChartVisibity: Bool {
|
||||
|
@ -200,11 +200,14 @@ public class StepBarsChartController2: BaseChartController {
|
||||
dateString = BaseConstants.headerMediumRangeFormatter.string(from: closestDate)
|
||||
}
|
||||
let viewModel = ChartDetailsViewModel(title: dateString,
|
||||
showArrow: !self.isZoomed,
|
||||
showArrow: self.isZoomable && !self.isZoomed,
|
||||
showPrefixes: false,
|
||||
values: values,
|
||||
totalValue: nil,
|
||||
tapAction: { [weak self] in })
|
||||
tapAction: { [weak self] in },
|
||||
hideAction: { [weak self] in
|
||||
self?.setDetailsChartVisibleClosure?(false, true)
|
||||
})
|
||||
return viewModel
|
||||
}
|
||||
|
||||
@ -317,7 +320,7 @@ public class StepBarsChartController2: BaseChartController {
|
||||
self.setupChartCollection(chartsCollection: self.initialChartCollection, animated: true, isZoomed: false)
|
||||
}
|
||||
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>) {
|
||||
public override func updateChartRange(_ rangeFraction: ClosedRange<CGFloat>, animated: Bool) {
|
||||
cancelChartInteraction()
|
||||
|
||||
let horizontalRange = ClosedRange(uncheckedBounds:
|
||||
@ -360,15 +363,15 @@ public class StepBarsChartController2: BaseChartController {
|
||||
}
|
||||
}
|
||||
|
||||
override public func apply(colorMode: GColorMode, animated: Bool) {
|
||||
super.apply(colorMode: colorMode, animated: animated)
|
||||
override public func apply(theme: ChartTheme, animated: Bool) {
|
||||
super.apply(theme: theme, animated: animated)
|
||||
|
||||
self.graphControllers.forEach { controller in
|
||||
controller.verticalScalesRenderer.horizontalLinesColor = colorMode.chartHelperLinesColor
|
||||
controller.lineBulletsRenderer.setInnerColor(colorMode.chartBackgroundColor, animated: animated)
|
||||
controller.verticalScalesRenderer.axisXColor = colorMode.chartStrongLinesColor
|
||||
controller.verticalScalesRenderer.horizontalLinesColor = theme.chartHelperLinesColor
|
||||
controller.lineBulletsRenderer.setInnerColor(theme.chartBackgroundColor, animated: animated)
|
||||
controller.verticalScalesRenderer.axisXColor = theme.chartStrongLinesColor
|
||||
}
|
||||
verticalLineRenderer.linesColor = colorMode.chartStrongLinesColor
|
||||
verticalLineRenderer.linesColor = theme.chartStrongLinesColor
|
||||
}
|
||||
|
||||
public override var drawChartVisibity: Bool {
|
||||
|
@ -13,21 +13,14 @@ import Cocoa
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
class ChartDetailsRenderer: BaseChartRenderer, GColorModeContainer {
|
||||
class ChartDetailsRenderer: BaseChartRenderer, ChartThemeContainer {
|
||||
private lazy var colorAnimator = AnimationController<CGFloat>(current: 1, refreshClosure: refreshClosure)
|
||||
private var fromColorMode: GColorMode = .day
|
||||
private var currentColorMode: GColorMode = .day
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
if currentColorMode != colorMode {
|
||||
fromColorMode = currentColorMode
|
||||
currentColorMode = colorMode
|
||||
if animated {
|
||||
colorAnimator.set(current: 0)
|
||||
colorAnimator.animate(to: 1, duration: .defaultDuration)
|
||||
} else {
|
||||
colorAnimator.set(current: 1)
|
||||
}
|
||||
}
|
||||
private var fromColorMode: ChartTheme = ChartTheme.defaultDayTheme
|
||||
private var currentColorMode: ChartTheme = ChartTheme.defaultDayTheme
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
fromColorMode = currentColorMode
|
||||
currentColorMode = theme
|
||||
colorAnimator.set(current: 1)
|
||||
}
|
||||
|
||||
private var valuesAnimators: [AnimationController<CGFloat>] = []
|
||||
|
@ -23,173 +23,179 @@ public typealias GColor = NSColor
|
||||
typealias NSEdgeInsets = UIEdgeInsets
|
||||
#endif
|
||||
|
||||
public protocol GColorModeContainer {
|
||||
func apply(colorMode: GColorMode, animated: Bool)
|
||||
public protocol ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool)
|
||||
}
|
||||
|
||||
public enum GColorMode {
|
||||
case day
|
||||
case night
|
||||
}
|
||||
|
||||
extension GColorMode {
|
||||
public var chartTitleColor: GColor { // Текст с датой на чарте
|
||||
switch self {
|
||||
case .day: return .black
|
||||
case .night: return .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 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
|
||||
public let barChartStrongLinesColor: GColor
|
||||
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 rangeViewMarkerColor: GColor
|
||||
|
||||
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) {
|
||||
self.chartTitleColor = chartTitleColor
|
||||
self.actionButtonColor = actionButtonColor
|
||||
self.tableBackgroundColor = tableBackgroundColor
|
||||
self.chartBackgroundColor = chartBackgroundColor
|
||||
self.tableSeparatorColor = tableSeparatorColor
|
||||
self.chartLabelsColor = chartLabelsColor
|
||||
self.chartHelperLinesColor = chartHelperLinesColor
|
||||
self.chartStrongLinesColor = chartStrongLinesColor
|
||||
self.barChartStrongLinesColor = barChartStrongLinesColor
|
||||
self.chartDetailsTextColor = chartDetailsTextColor
|
||||
self.chartDetailsArrowColor = chartDetailsArrowColor
|
||||
self.chartDetailsViewColor = chartDetailsViewColor
|
||||
self.descriptionActionColor = descriptionActionColor
|
||||
self.rangeViewFrameColor = rangeViewFrameColor
|
||||
self.rangeViewTintColor = rangeViewTintColor
|
||||
self.rangeViewMarkerColor = rangeViewMarkerColor
|
||||
}
|
||||
|
||||
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 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 var sectionTitleColor: 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: 133/255.0, green: 150/255.0, blue: 171/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 descriptionChatNameColor: GColor {
|
||||
switch self {
|
||||
case .day: return .black
|
||||
case .night: return GColor(red: 254/255.0, green: 254/255.0, blue: 254/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 viewTintColor: GColor {
|
||||
switch self {
|
||||
case .day: return .black
|
||||
case .night: return GColor(red: 254/255.0, green: 254/255.0, blue: 254/255.0, alpha: 1.0)
|
||||
}
|
||||
}
|
||||
// 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? {
|
||||
switch self {
|
||||
case .day:
|
||||
// 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
|
||||
}
|
||||
// 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
|
||||
}
|
||||
}
|
||||
|
@ -15,20 +15,21 @@ private let verticalMargins: CGFloat = 8
|
||||
private var labelHeight: CGFloat = 18
|
||||
private var margin: CGFloat = 10
|
||||
private var prefixLabelWidth: CGFloat = 27
|
||||
private var textLabelWidth: CGFloat = 80
|
||||
private var textLabelWidth: CGFloat = 96
|
||||
private var valueLabelWidth: CGFloat = 65
|
||||
|
||||
class ChartDetailsView: UIControl {
|
||||
let titleLabel = UILabel()
|
||||
let arrowView = UIImageView()
|
||||
let activityIndicator = UIActivityIndicatorView()
|
||||
let arrowButton = UIButton()
|
||||
|
||||
var prefixViews: [UILabel] = []
|
||||
var labelsViews: [UILabel] = []
|
||||
var valuesViews: [UILabel] = []
|
||||
|
||||
private var viewModel: ChartDetailsViewModel?
|
||||
private var colorMode: GColorMode = .day
|
||||
private var theme: ChartTheme = ChartTheme.defaultDayTheme
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
@ -36,13 +37,16 @@ class ChartDetailsView: UIControl {
|
||||
layer.cornerRadius = cornerRadius
|
||||
clipsToBounds = true
|
||||
|
||||
addTarget(self, action: #selector(didTap), for: .touchUpInside)
|
||||
addTarget(self, action: #selector(didTapWhole), for: .touchUpInside)
|
||||
titleLabel.font = UIFont.systemFont(ofSize: 12, weight: .bold)
|
||||
arrowView.image = UIImage(bundleImageName: "Chart/arrow_right")
|
||||
arrowView.contentMode = .scaleAspectFill
|
||||
|
||||
arrowButton.addTarget(self, action: #selector(didTap), for: .touchUpInside)
|
||||
|
||||
addSubview(titleLabel)
|
||||
addSubview(arrowView)
|
||||
addSubview(arrowButton)
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
@ -66,6 +70,8 @@ class ChartDetailsView: UIControl {
|
||||
}
|
||||
let labelsCount: Int = viewModel.values.count + ((viewModel.totalValue == nil) ? 0 : 1)
|
||||
|
||||
arrowButton.frame = CGRect(x: 0.0, y: 0.0, width: width, height: 30.0)
|
||||
|
||||
setLabelsCount(array: &prefixViews,
|
||||
count: viewModel.showPrefixes ? labelsCount : 0,
|
||||
font: UIFont.systemFont(ofSize: 12, weight: .bold))
|
||||
@ -82,14 +88,14 @@ class ChartDetailsView: UIControl {
|
||||
var x: CGFloat = margin
|
||||
if viewModel.showPrefixes {
|
||||
let prefixLabel = self.prefixViews[index]
|
||||
prefixLabel.textColor = self.colorMode.chartDetailsTextColor
|
||||
prefixLabel.textColor = self.theme.chartDetailsTextColor
|
||||
prefixLabel.setText(value.prefix, animated: false)
|
||||
prefixLabel.frame = CGRect(x: x, y: y, width: prefixLabelWidth, height: labelHeight)
|
||||
x += prefixLabelWidth + margin
|
||||
prefixLabel.alpha = value.visible ? 1 : 0
|
||||
}
|
||||
let titleLabel = self.labelsViews[index]
|
||||
titleLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
|
||||
titleLabel.setTextColor(self.theme.chartDetailsTextColor, animated: false)
|
||||
titleLabel.setText(value.title, animated: false)
|
||||
titleLabel.frame = CGRect(x: x, y: y, width: textLabelWidth, height: labelHeight)
|
||||
titleLabel.alpha = value.visible ? 1 : 0
|
||||
@ -109,21 +115,21 @@ class ChartDetailsView: UIControl {
|
||||
var x: CGFloat = margin
|
||||
if viewModel.showPrefixes {
|
||||
let prefixLabel = self.prefixViews[viewModel.values.count]
|
||||
prefixLabel.textColor = self.colorMode.chartDetailsTextColor
|
||||
prefixLabel.textColor = self.theme.chartDetailsTextColor
|
||||
prefixLabel.setText(value.prefix, animated: false)
|
||||
prefixLabel.frame = CGRect(x: x, y: y, width: prefixLabelWidth, height: labelHeight)
|
||||
prefixLabel.alpha = value.visible ? 1 : 0
|
||||
x += prefixLabelWidth + margin
|
||||
}
|
||||
let titleLabel = self.labelsViews[viewModel.values.count]
|
||||
titleLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
|
||||
titleLabel.setTextColor(self.theme.chartDetailsTextColor, animated: false)
|
||||
titleLabel.setText(value.title, animated: false)
|
||||
titleLabel.frame = CGRect(x: x, y: y, width: textLabelWidth, height: labelHeight)
|
||||
titleLabel.alpha = value.visible ? 1 : 0
|
||||
x += textLabelWidth
|
||||
|
||||
let valueLabel = self.valuesViews[viewModel.values.count]
|
||||
valueLabel.setTextColor(self.colorMode.chartDetailsTextColor, animated: false)
|
||||
valueLabel.setTextColor(self.theme.chartDetailsTextColor, animated: false)
|
||||
valueLabel.setText(value.value, animated: false)
|
||||
valueLabel.frame = CGRect(x: x, y: y, width: valueLabelWidth, height: labelHeight)
|
||||
valueLabel.alpha = value.visible ? 1 : 0
|
||||
@ -154,6 +160,10 @@ class ChartDetailsView: UIControl {
|
||||
viewModel?.tapAction?()
|
||||
}
|
||||
|
||||
@objc private func didTapWhole() {
|
||||
viewModel?.hideAction?()
|
||||
}
|
||||
|
||||
func setLabelsCount(array: inout [UILabel],
|
||||
count: Int,
|
||||
font: UIFont,
|
||||
@ -172,16 +182,16 @@ class ChartDetailsView: UIControl {
|
||||
}
|
||||
}
|
||||
|
||||
extension ChartDetailsView: GColorModeContainer {
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
self.colorMode = colorMode
|
||||
self.titleLabel.setTextColor(colorMode.chartDetailsTextColor, animated: animated)
|
||||
extension ChartDetailsView: ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
self.theme = theme
|
||||
self.titleLabel.setTextColor(theme.chartDetailsTextColor, animated: animated)
|
||||
if let viewModel = self.viewModel {
|
||||
self.setup(viewModel: viewModel, animated: animated)
|
||||
}
|
||||
UIView.perform(animated: animated) {
|
||||
self.arrowView.tintColor = colorMode.chartDetailsArrowColor
|
||||
self.backgroundColor = colorMode.chartDetailsViewColor
|
||||
self.arrowView.tintColor = theme.chartDetailsArrowColor
|
||||
self.backgroundColor = theme.chartDetailsViewColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import Display
|
||||
import AsyncDisplayKit
|
||||
import AppBundle
|
||||
import GraphCore
|
||||
import TelegramPresentationData
|
||||
|
||||
public enum ChartType {
|
||||
case lines
|
||||
@ -14,6 +15,15 @@ public enum ChartType {
|
||||
case step
|
||||
}
|
||||
|
||||
public extension ChartTheme {
|
||||
convenience init(presentationTheme: PresentationTheme) {
|
||||
let tableBackgroundColor = UIColor(rgb: 0xefeff4)
|
||||
let rangeViewTintColor = UIColor(rgb: 0xefeff4)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
public final class ChartNode: ASDisplayNode {
|
||||
private var chartView: ChartStackSection {
|
||||
return self.view as! ChartStackSection
|
||||
@ -33,6 +43,16 @@ public final class ChartNode: ASDisplayNode {
|
||||
self.view.disablesInteractiveTransitionGestureRecognizer = true
|
||||
}
|
||||
|
||||
public func setupTheme(_ theme: ChartTheme) {
|
||||
self.chartView.apply(theme: ChartTheme.defaultDayTheme, animated: false)
|
||||
}
|
||||
|
||||
public override func layout() {
|
||||
super.layout()
|
||||
|
||||
self.chartView.setNeedsDisplay()
|
||||
}
|
||||
|
||||
public func setup(_ data: String, type: ChartType, getDetailsData: @escaping (Date, @escaping (String?) -> Void) -> Void) {
|
||||
if let data = data.data(using: .utf8) {
|
||||
ChartsDataManager.readChart(data: data, extraCopiesCount: 0, sync: true, success: { [weak self] collection in
|
||||
@ -40,19 +60,22 @@ public final class ChartNode: ASDisplayNode {
|
||||
switch type {
|
||||
case .lines:
|
||||
controller = GeneralLinesChartController(chartsCollection: collection)
|
||||
controller.isZoomable = false
|
||||
case .twoAxis:
|
||||
controller = TwoAxisLinesChartController(chartsCollection: collection)
|
||||
controller.isZoomable = false
|
||||
case .pie:
|
||||
controller = PercentPieChartController(chartsCollection: collection)
|
||||
case .bars:
|
||||
controller = StackedBarsChartController(chartsCollection: collection)
|
||||
controller.isZoomable = false
|
||||
case .step:
|
||||
controller = StepBarsChartController(chartsCollection: collection)
|
||||
}
|
||||
controller.getDetailsData = { date, completion in
|
||||
getDetailsData(date, { detailsData in
|
||||
if let detailsData = detailsData, let data = detailsData.data(using: .utf8) {
|
||||
ChartsDataManager.readChart(data: data, extraCopiesCount: 0, sync: true, success: { [weak self] collection in
|
||||
ChartsDataManager.readChart(data: data, extraCopiesCount: 0, sync: true, success: { collection in
|
||||
Queue.mainQueue().async {
|
||||
completion(collection)
|
||||
}
|
||||
@ -66,7 +89,6 @@ public final class ChartNode: ASDisplayNode {
|
||||
}
|
||||
if let strongSelf = self {
|
||||
strongSelf.chartView.setup(controller: controller, title: "")
|
||||
strongSelf.chartView.apply(colorMode: .day, animated: false)
|
||||
}
|
||||
}) { error in
|
||||
|
||||
|
@ -22,7 +22,7 @@ private class LeftAlignedIconButton: UIButton {
|
||||
}
|
||||
}
|
||||
|
||||
class ChartStackSection: UIView, GColorModeContainer {
|
||||
class ChartStackSection: UIView, ChartThemeContainer {
|
||||
var chartView: ChartView
|
||||
var rangeView: RangeChartView
|
||||
var visibilityView: ChartVisibilityView
|
||||
@ -81,37 +81,37 @@ class ChartStackSection: UIView, GColorModeContainer {
|
||||
backButton.setVisible(false, animated: false)
|
||||
}
|
||||
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
UIView.perform(animated: animated && self.isVisibleInWindow) {
|
||||
self.backgroundColor = colorMode.tableBackgroundColor
|
||||
self.backgroundColor = theme.tableBackgroundColor
|
||||
|
||||
self.sectionContainerView.backgroundColor = colorMode.chartBackgroundColor
|
||||
self.rangeView.backgroundColor = colorMode.chartBackgroundColor
|
||||
self.visibilityView.backgroundColor = colorMode.chartBackgroundColor
|
||||
self.sectionContainerView.backgroundColor = theme.chartBackgroundColor
|
||||
self.rangeView.backgroundColor = theme.chartBackgroundColor
|
||||
self.visibilityView.backgroundColor = theme.chartBackgroundColor
|
||||
|
||||
self.backButton.tintColor = colorMode.actionButtonColor
|
||||
self.backButton.setTitleColor(colorMode.actionButtonColor, for: .normal)
|
||||
self.backButton.tintColor = theme.actionButtonColor
|
||||
self.backButton.setTitleColor(theme.actionButtonColor, for: .normal)
|
||||
|
||||
for separator in self.separators {
|
||||
separator.backgroundColor = colorMode.tableSeparatorColor
|
||||
separator.backgroundColor = theme.tableSeparatorColor
|
||||
}
|
||||
}
|
||||
|
||||
if rangeView.isVisibleInWindow || chartView.isVisibleInWindow {
|
||||
chartView.loadDetailsViewIfNeeded()
|
||||
chartView.apply(colorMode: colorMode, animated: animated && chartView.isVisibleInWindow)
|
||||
controller.apply(colorMode: colorMode, animated: animated)
|
||||
rangeView.apply(colorMode: colorMode, animated: animated && rangeView.isVisibleInWindow)
|
||||
chartView.apply(theme: theme, animated: animated && chartView.isVisibleInWindow)
|
||||
controller.apply(theme: theme, animated: animated)
|
||||
rangeView.apply(theme: theme, animated: animated && rangeView.isVisibleInWindow)
|
||||
} else {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + TimeInterval.random(in: 0...0.1)) {
|
||||
self.chartView.loadDetailsViewIfNeeded()
|
||||
self.controller.apply(colorMode: colorMode, animated: false)
|
||||
self.chartView.apply(colorMode: colorMode, animated: false)
|
||||
self.rangeView.apply(colorMode: colorMode, animated: false)
|
||||
self.controller.apply(theme: theme, animated: false)
|
||||
self.chartView.apply(theme: theme, animated: false)
|
||||
self.rangeView.apply(theme: theme, animated: false)
|
||||
}
|
||||
}
|
||||
|
||||
self.titleLabel.setTextColor(colorMode.chartTitleColor, animated: animated && titleLabel.isVisibleInWindow)
|
||||
self.titleLabel.setTextColor(theme.chartTitleColor, animated: animated && titleLabel.isVisibleInWindow)
|
||||
}
|
||||
|
||||
@objc private func didTapBackButton() {
|
||||
@ -147,10 +147,10 @@ class ChartStackSection: UIView, GColorModeContainer {
|
||||
|
||||
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: 400.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.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: 308.0), size: CGSize(width: bounds.width, height: 222.0))
|
||||
self.visibilityView.frame = CGRect(origin: CGPoint(x: 0.0, y: 308.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)
|
||||
}
|
||||
|
||||
@ -214,9 +214,9 @@ class ChartStackSection: UIView, GColorModeContainer {
|
||||
controller.initializeChart()
|
||||
updateToolViews(animated: false)
|
||||
|
||||
// rangeView.setRange(0.8...1.0, animated: false)
|
||||
rangeView.setRange(0.8...1.0, animated: false)
|
||||
// TimeInterval.animationDurationMultipler = 0.00001
|
||||
// controller.updateChartRange(0.8...1.0)
|
||||
controller.updateChartRange(0.8...1.0, animated: false)
|
||||
// TimeInterval.animationDurationMultipler = 1.0
|
||||
}
|
||||
}
|
||||
|
@ -162,8 +162,8 @@ class ChartView: UIControl {
|
||||
}
|
||||
|
||||
|
||||
extension ChartView: GColorModeContainer {
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
detailsView?.apply(colorMode: colorMode, animated: animated && (detailsView?.isVisibleInWindow ?? false))
|
||||
extension ChartView: ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
detailsView?.apply(theme: theme, animated: animated && (detailsView?.isVisibleInWindow ?? false))
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
import UIKit
|
||||
import GraphCore
|
||||
import Display
|
||||
|
||||
private enum Constants {
|
||||
static let itemHeight: CGFloat = 30
|
||||
@ -38,10 +39,18 @@ class ChartVisibilityView: UIView {
|
||||
for (index, item) in items.enumerated() {
|
||||
let view = selectionViews[index]
|
||||
view.item = item
|
||||
view.tapClosure = { [weak self] in
|
||||
view.tapClosure = { [weak self, weak view] in
|
||||
guard let self = self else { return }
|
||||
self.setItemSelected(!self.selectedItems[index], at: index, animated: true)
|
||||
self.notifyItemSelection()
|
||||
|
||||
let selected = !self.selectedItems[index]
|
||||
|
||||
let selectedItemsCount = self.selectedItems.filter { $0 }.count
|
||||
if selectedItemsCount == 1 && !selected {
|
||||
view?.layer.addShakeAnimation()
|
||||
} else {
|
||||
self.setItemSelected(selected, at: index, animated: true)
|
||||
self.notifyItemSelection()
|
||||
}
|
||||
}
|
||||
|
||||
view.longTapClosure = { [weak self] in
|
||||
@ -138,11 +147,11 @@ class ChartVisibilityView: UIView {
|
||||
}
|
||||
}
|
||||
|
||||
extension ChartVisibilityView: GColorModeContainer {
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
extension ChartVisibilityView: ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
UIView.perform(animated: animated) {
|
||||
self.backgroundColor = colorMode.chartBackgroundColor
|
||||
self.tintColor = colorMode.descriptionActionColor
|
||||
self.backgroundColor = theme.chartBackgroundColor
|
||||
self.tintColor = theme.descriptionActionColor
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ class RangeChartView: UIControl {
|
||||
private var selectedMarkerInitialLocation: CGPoint?
|
||||
private var isBoundCropHighlighted: Bool = false
|
||||
private var isRangePagingEnabled: Bool = false
|
||||
|
||||
private var targetTapLocation: CGPoint?
|
||||
|
||||
public let chartView = ChartView()
|
||||
|
||||
@ -154,6 +156,8 @@ class RangeChartView: UIControl {
|
||||
selectedMarkerInitialLocation = point
|
||||
isBoundCropHighlighted = true
|
||||
} else {
|
||||
targetTapLocation = point
|
||||
selectedMarkerHorizontalOffset = cropFrameView.frame.width / 2.0
|
||||
selectedMarker = nil
|
||||
selectedMarkerInitialLocation = nil
|
||||
return
|
||||
@ -175,11 +179,23 @@ class RangeChartView: UIControl {
|
||||
self._isTracking = true
|
||||
}
|
||||
|
||||
targetTapLocation = nil
|
||||
|
||||
sendActions(for: .valueChanged)
|
||||
}
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
guard isEnabled else { return }
|
||||
if let point = targetTapLocation {
|
||||
let horizontalPosition = point.x - selectedMarkerHorizontalOffset
|
||||
let fraction = fractionFor(offsetX: horizontalPosition)
|
||||
updateMarkerOffset(.center, fraction: fraction)
|
||||
|
||||
sendActions(for: .touchUpInside)
|
||||
|
||||
self.targetTapLocation = nil
|
||||
return
|
||||
}
|
||||
guard let selectedMarker = selectedMarker else {
|
||||
touchedOutsideClosure?()
|
||||
return
|
||||
@ -204,6 +220,7 @@ class RangeChartView: UIControl {
|
||||
}
|
||||
|
||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
self.targetTapLocation = nil
|
||||
self.selectedMarker = nil
|
||||
self.selectedMarkerInitialLocation = nil
|
||||
self.isBoundCropHighlighted = false
|
||||
@ -292,11 +309,11 @@ private extension RangeChartView {
|
||||
}
|
||||
}
|
||||
|
||||
extension RangeChartView: GColorModeContainer {
|
||||
func apply(colorMode: GColorMode, animated: Bool) {
|
||||
extension RangeChartView: ChartThemeContainer {
|
||||
func apply(theme: ChartTheme, animated: Bool) {
|
||||
let colusre = {
|
||||
self.lowerBoundTintView.backgroundColor = colorMode.rangeViewTintColor
|
||||
self.upperBoundTintView.backgroundColor = colorMode.rangeViewTintColor
|
||||
self.lowerBoundTintView.backgroundColor = theme.rangeViewTintColor
|
||||
self.upperBoundTintView.backgroundColor = theme.rangeViewTintColor
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,6 +22,7 @@ static_library(
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/MergeLists:MergeLists",
|
||||
"//submodules/PhotoResources:PhotoResources",
|
||||
"//submodules/GraphCore:GraphCore",
|
||||
"//submodules/GraphUI:GraphUI",
|
||||
],
|
||||
frameworks = [
|
||||
|
@ -23,6 +23,7 @@ swift_library(
|
||||
"//submodules/PresentationDataUtils:PresentationDataUtils",
|
||||
"//submodules/MergeLists:MergeLists",
|
||||
"//submodules/PhotoResources:PhotoResources",
|
||||
"//submodules/GraphCore:GraphCore",
|
||||
"//submodules/GraphUI:GraphUI",
|
||||
],
|
||||
visibility = [
|
||||
|
@ -8,7 +8,9 @@ import SyncCore
|
||||
import TelegramPresentationData
|
||||
import ItemListUI
|
||||
import PresentationDataUtils
|
||||
import GraphCore
|
||||
import GraphUI
|
||||
import ActivityIndicator
|
||||
|
||||
class StatsGraphItem: ListViewItem, ItemListItem {
|
||||
let presentationData: ItemListPresentationData
|
||||
@ -72,6 +74,7 @@ class StatsGraphItemNode: ListViewItemNode {
|
||||
private let maskNode: ASImageNode
|
||||
|
||||
let chartNode: ChartNode
|
||||
private let activityIndicator: ActivityIndicator
|
||||
|
||||
private var item: StatsGraphItem?
|
||||
|
||||
@ -89,12 +92,15 @@ class StatsGraphItemNode: ListViewItemNode {
|
||||
self.bottomStripeNode.isLayerBacked = true
|
||||
|
||||
self.chartNode = ChartNode()
|
||||
self.activityIndicator = ActivityIndicator(type: ActivityIndicatorType.custom(.black, 16.0, 2.0, false))
|
||||
self.activityIndicator.isHidden = true
|
||||
|
||||
super.init(layerBacked: false, dynamicBounce: false)
|
||||
|
||||
self.clipsToBounds = true
|
||||
|
||||
self.addSubnode(self.chartNode)
|
||||
self.addSubnode(self.activityIndicator)
|
||||
}
|
||||
|
||||
override func didLoad() {
|
||||
@ -201,21 +207,36 @@ class StatsGraphItemNode: ListViewItemNode {
|
||||
strongSelf.bottomStripeNode.isHidden = hasCorners
|
||||
}
|
||||
|
||||
strongSelf.chartNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: layout.size.width - leftInset - rightInset, height: 500.0))
|
||||
strongSelf.chartNode.frame = CGRect(origin: CGPoint(x: leftInset, y: 0.0), size: CGSize(width: layout.size.width - leftInset - rightInset, height: 750.0))
|
||||
strongSelf.maskNode.image = hasCorners ? PresentationResourcesItemList.cornersImage(item.presentationData.theme, top: hasTopCorners, bottom: hasBottomCorners) : nil
|
||||
|
||||
strongSelf.backgroundNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: contentSize.height + min(insets.top, separatorHeight) + min(insets.bottom, separatorHeight)))
|
||||
strongSelf.maskNode.frame = strongSelf.backgroundNode.frame.insetBy(dx: params.leftInset, dy: 0.0)
|
||||
strongSelf.topStripeNode.frame = CGRect(origin: CGPoint(x: 0.0, y: -min(insets.top, separatorHeight)), size: CGSize(width: params.width, height: separatorHeight))
|
||||
strongSelf.bottomStripeNode.frame = CGRect(origin: CGPoint(x: bottomStripeInset, y: contentSize.height - separatorHeight), size: CGSize(width: params.width - bottomStripeInset, height: separatorHeight))
|
||||
|
||||
strongSelf.activityIndicator.frame = CGRect(origin: CGPoint(x: floor((layout.size.width - 16.0) / 2.0), y: floor((layout.size.height - 16.0) / 2.0)), size: CGSize(width: 16.0, height: 16.0))
|
||||
}
|
||||
|
||||
if let updatedGraph = updatedGraph, case let .Loaded(_, data) = updatedGraph {
|
||||
strongSelf.chartNode.setup(data, type: item.type, getDetailsData: { [weak self] date, completion in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
item.getDetailsData?(date, completion)
|
||||
}
|
||||
})
|
||||
strongSelf.activityIndicator.type = .custom(item.presentationData.theme.list.itemSecondaryTextColor, 16.0, 2.0, false)
|
||||
|
||||
if let updatedGraph = updatedGraph {
|
||||
if case let .Loaded(_, data) = updatedGraph {
|
||||
strongSelf.chartNode.setup(data, type: item.type, getDetailsData: { [weak self] date, completion in
|
||||
if let strongSelf = self, let item = strongSelf.item {
|
||||
item.getDetailsData?(date, completion)
|
||||
}
|
||||
})
|
||||
strongSelf.activityIndicator.isHidden = true
|
||||
strongSelf.chartNode.isHidden = false
|
||||
} else if case .OnDemand = updatedGraph {
|
||||
strongSelf.activityIndicator.isHidden = false
|
||||
strongSelf.chartNode.isHidden = true
|
||||
}
|
||||
}
|
||||
|
||||
if let updatedTheme = updatedTheme {
|
||||
strongSelf.chartNode.setupTheme(ChartTheme(presentationTheme: updatedTheme))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -147,7 +147,6 @@ class StatsOverviewItemNode: ListViewItemNode {
|
||||
let leftInset = params.leftInset
|
||||
let rightInset: CGFloat = params.rightInset
|
||||
var updatedTheme: PresentationTheme?
|
||||
var updatedGraph: ChannelStatsGraph?
|
||||
|
||||
if currentItem?.presentationData.theme !== item.presentationData.theme {
|
||||
updatedTheme = item.presentationData.theme
|
||||
@ -214,16 +213,23 @@ class StatsOverviewItemNode: ListViewItemNode {
|
||||
let itemBackgroundColor: UIColor
|
||||
let itemSeparatorColor: UIColor
|
||||
|
||||
let height: CGFloat
|
||||
if item.stats.viewsPerPost.current.isZero && item.stats.sharesPerPost.current.isZero {
|
||||
height = 64.0
|
||||
} else {
|
||||
height = 120.0
|
||||
}
|
||||
|
||||
switch item.style {
|
||||
case .plain:
|
||||
itemBackgroundColor = item.presentationData.theme.list.plainBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemPlainSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 120.0)
|
||||
contentSize = CGSize(width: params.width, height: height)
|
||||
insets = itemListNeighborsPlainInsets(neighbors)
|
||||
case .blocks:
|
||||
itemBackgroundColor = item.presentationData.theme.list.itemBlocksBackgroundColor
|
||||
itemSeparatorColor = item.presentationData.theme.list.itemBlocksSeparatorColor
|
||||
contentSize = CGSize(width: params.width, height: 120.0)
|
||||
contentSize = CGSize(width: params.width, height: height)
|
||||
insets = itemListNeighborsGroupedInsets(neighbors)
|
||||
}
|
||||
|
||||
|
@ -41,7 +41,7 @@ public enum ChannelStatsGraph: Equatable {
|
||||
switch self {
|
||||
case let .OnDemand(token):
|
||||
return token
|
||||
case let .Loaded(token, data):
|
||||
case let .Loaded(token, _):
|
||||
return token
|
||||
default:
|
||||
return nil
|
||||
|
@ -53,7 +53,7 @@ private class ChatHistoryListSelectionRecognizer: UIPanGestureRecognizer {
|
||||
let translation = location.offsetBy(dx: -self.initialLocation.x, dy: -self.initialLocation.y)
|
||||
|
||||
if self.recognized == nil {
|
||||
if (fabs(translation.y) >= selectionGestureActivationThreshold) {
|
||||
if (abs(translation.y) >= selectionGestureActivationThreshold) {
|
||||
self.recognized = true
|
||||
}
|
||||
}
|
||||
@ -1709,7 +1709,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
var resultMessages: [Message]?
|
||||
self.forEachVisibleItemNode { itemNode in
|
||||
if resultMessages == nil, let itemNode = itemNode as? ListViewItemNode, itemNode.frame.contains(point) {
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item as? ChatMessageItem {
|
||||
if let itemNode = itemNode as? ChatMessageItemView, let item = itemNode.item {
|
||||
switch item.content {
|
||||
case let .message(message, _, _ , _):
|
||||
resultMessages = [message]
|
||||
@ -1750,6 +1750,8 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
self.selectionScrollSkipUpdate = false
|
||||
case .possible:
|
||||
break
|
||||
@unknown default:
|
||||
fatalError()
|
||||
}
|
||||
}
|
||||
|
||||
@ -1825,7 +1827,7 @@ public final class ChatHistoryListNode: ListView, ChatHistoryNode {
|
||||
if let strongSelf = self, let delta = strongSelf.selectionScrollDelta {
|
||||
let distance: CGFloat = 15.0 * min(1.0, 0.15 + abs(delta * delta))
|
||||
let direction: ListViewScrollDirection = delta > 0.0 ? .up : .down
|
||||
strongSelf.scrollWithDirection(direction, distance: distance)
|
||||
let _ = strongSelf.scrollWithDirection(direction, distance: distance)
|
||||
|
||||
if let location = strongSelf.selectionLastLocation {
|
||||
if !strongSelf.selectionScrollSkipUpdate {
|
||||
|
@ -245,11 +245,14 @@ enum ManagedDiceAnimationState: Equatable {
|
||||
|
||||
final class ManagedDiceAnimationNode: ManagedAnimationNode {
|
||||
private let context: AccountContext
|
||||
private let emojis: [TelegramMediaFile]
|
||||
|
||||
private var diceState: ManagedDiceAnimationState = .rolling
|
||||
private let disposable = MetaDisposable()
|
||||
|
||||
init(context: AccountContext) {
|
||||
init(context: AccountContext, emojis: [TelegramMediaFile]) {
|
||||
self.context = context
|
||||
self.emojis = emojis
|
||||
|
||||
super.init(size: CGSize(width: 136.0, height: 136.0))
|
||||
|
||||
@ -268,6 +271,16 @@ final class ManagedDiceAnimationNode: ManagedAnimationNode {
|
||||
case .rolling:
|
||||
switch diceState {
|
||||
case let .value(value):
|
||||
// self.disposable.set(freeMediaFileInteractiveFetched(account: item.context.account, fileReference: .standalone(media: emojiFile)).start())
|
||||
//
|
||||
// return chatMessageAnimationData(postbox: self.account.postbox, resource: self.resource, fitzModifier: self.fitzModifier, width: width, height: height, synchronousLoad: false)
|
||||
// |> filter { data in
|
||||
// return data.size != 0
|
||||
// }
|
||||
// |> map { data -> (String, Bool) in
|
||||
// return (data.path, data.complete)
|
||||
// }
|
||||
|
||||
self.trackTo(item: ManagedAnimationItem(source: .local("DiceRolling"), frames: ManagedAnimationFrameRange(startFrame: 0, endFrame: 0), duration: 0.3))
|
||||
case .rolling:
|
||||
break
|
||||
|
@ -8,18 +8,18 @@ private enum ID3Tag: CaseIterable {
|
||||
var header: Data {
|
||||
switch self {
|
||||
case .v2:
|
||||
return Data(bytes: [ 0x49, 0x44, 0x33, 0x02, 0x00 ])
|
||||
return Data([ 0x49, 0x44, 0x33, 0x02, 0x00 ])
|
||||
case .v3:
|
||||
return Data(bytes: [ 0x49, 0x44, 0x33, 0x03, 0x00 ])
|
||||
return Data([ 0x49, 0x44, 0x33, 0x03, 0x00 ])
|
||||
}
|
||||
}
|
||||
|
||||
var artworkHeader: Data {
|
||||
switch self {
|
||||
case .v2:
|
||||
return Data(bytes: [ 0x50, 0x49, 0x43 ])
|
||||
return Data([ 0x50, 0x49, 0x43 ])
|
||||
case .v3:
|
||||
return Data(bytes: [ 0x41, 0x50, 0x49, 0x43 ])
|
||||
return Data([ 0x41, 0x50, 0x49, 0x43 ])
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ private let artOffset = 10
|
||||
private let v2FrameOffset: UInt32 = 6
|
||||
private let v3FrameOffset: UInt32 = 10
|
||||
|
||||
private let tagEnding = Data(bytes: [ 0x00, 0x00, 0x00 ])
|
||||
private let tagEnding = Data([ 0x00, 0x00, 0x00 ])
|
||||
|
||||
private enum ID3ArtworkFormat: CaseIterable {
|
||||
case jpg
|
||||
@ -67,9 +67,9 @@ private enum ID3ArtworkFormat: CaseIterable {
|
||||
var magic: Data {
|
||||
switch self {
|
||||
case .jpg:
|
||||
return Data(bytes: [ 0xff, 0xd8, 0xff ])
|
||||
return Data([ 0xff, 0xd8, 0xff ])
|
||||
case .png:
|
||||
return Data(bytes: [ 0x89, 0x50, 0x4e, 0x47 ])
|
||||
return Data([ 0x89, 0x50, 0x4e, 0x47 ])
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,7 +118,7 @@ private class DataStream {
|
||||
}
|
||||
|
||||
func upTo(_ marker: UInt8) -> Data? {
|
||||
if let end = (self.position ..< self.data.count).index( where: { self.data[$0] == marker } ) {
|
||||
if let end = (self.position ..< self.data.count).firstIndex( where: { self.data[$0] == marker } ) {
|
||||
let upTo = self.next(end - self.position)
|
||||
self.skip()
|
||||
return upTo
|
||||
@ -132,7 +132,7 @@ private class DataStream {
|
||||
}
|
||||
|
||||
func skipThrough(_ marker: UInt8) {
|
||||
if let end = (self.position ..< self.data.count).index( where: { self.data[$0] == marker } ) {
|
||||
if let end = (self.position ..< self.data.count).firstIndex( where: { self.data[$0] == marker } ) {
|
||||
self.position = end + 1
|
||||
} else {
|
||||
self.position = self.data.count
|
||||
|
@ -105,11 +105,8 @@ final class WallpaperUploadManagerImpl: WallpaperUploadManager {
|
||||
return result
|
||||
}
|
||||
|
||||
let autoNightModeTriggered = presentationData.autoNightModeTriggered ?? false
|
||||
let autoNightModeTriggered = presentationData.autoNightModeTriggered
|
||||
disposable.set(uploadSignal.start(next: { [weak self] status in
|
||||
guard let strongSelf = self else {
|
||||
return
|
||||
}
|
||||
if case let .complete(wallpaper) = status {
|
||||
let updateWallpaper: (TelegramWallpaper) -> Void = { wallpaper in
|
||||
if let resource = wallpaper.mainResource {
|
||||
|
Loading…
x
Reference in New Issue
Block a user