diff --git a/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift index 39b814610a..a5881397ab 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/GeneralChartComponentController.swift @@ -169,6 +169,8 @@ class GeneralChartComponentController: ChartThemeContainer { return (closestDate, minIndex) } + var currentChartValue: CGFloat? + func chartInteractionDidBegin(point: CGPoint, manual: Bool = true) { if manual && !isChartInteracting && detailsVisible { self.hideDetailsView(animated: true) @@ -187,13 +189,18 @@ class GeneralChartComponentController: ChartThemeContainer { isChartInteracting = true let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970) + var chartValueUpdated = true + if chartValue == currentChartValue { + chartValueUpdated = false + } + currentChartValue = chartValue let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX - showDetailsView(at: chartValue, detailsViewPosition: detailsViewPosition, dataIndex: minIndex, date: closestDate, animted: chartWasInteracting) + showDetailsView(at: chartValue, detailsViewPosition: detailsViewPosition, dataIndex: minIndex, date: closestDate, animated: chartWasInteracting, feedback: chartWasInteracting && chartValueUpdated) } var detailsVisible = false - func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) { - setDetailsViewModel?(chartDetailsViewModel(closestDate: date, pointIndex: dataIndex), animted, false) + func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animated: Bool, feedback: Bool) { + setDetailsViewModel?(chartDetailsViewModel(closestDate: date, pointIndex: dataIndex), animated, feedback) setDetailsChartVisibleClosure?(true, true) setDetailsViewPositionClosure?(detailsViewPosition) detailsVisible = true @@ -202,12 +209,14 @@ class GeneralChartComponentController: ChartThemeContainer { func chartInteractionDidEnd() { isChartInteracting = false ignoreInteraction = false + currentChartValue = nil } func hideDetailsView(animated: Bool) { isChartInteractionBegun = false setDetailsChartVisibleClosure?(false, animated) detailsVisible = false + currentChartValue = nil } var visibleDetailsChartValues: [ChartsCollection.Chart] { diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift index 6c8d9f0f21..18aaf99d2f 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Lines/GeneralLinesChartController.swift @@ -143,8 +143,12 @@ public class GeneralLinesChartController: BaseLinesChartController { self.lineBulletsRenderer.isEnabled = true let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970) + var chartValueUpdated = true + if self.verticalLineRenderer.values == [chartValue] { + chartValueUpdated = false + } let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX - self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin) + self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin && chartValueUpdated) self.setDetailsChartVisibleClosure?(true, true) self.setDetailsViewPositionClosure?(detailsViewPosition) self.verticalLineRenderer.values = [chartValue] diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift index f2a04ff12d..bad9b54000 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Lines/TwoAxisLinesChartController.swift @@ -172,8 +172,12 @@ public class TwoAxisLinesChartController: BaseLinesChartController { } let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970) + var chartValueUpdated = true + if self.verticalLineRenderer.values == [chartValue] { + chartValueUpdated = false + } let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX - self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin) + self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin && chartValueUpdated) self.setDetailsChartVisibleClosure?(true, true) self.setDetailsViewPositionClosure?(detailsViewPosition) self.verticalLineRenderer.values = [chartValue] diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift index 2b723dc748..e2615a4dcf 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Percent And Pie/PercentChartComponentController.swift @@ -179,8 +179,8 @@ class PercentChartComponentController: GeneralChartComponentController { return previewPercentChartRenderer } - override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) { - super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animted: animted) + override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animated: Bool, feedback: Bool) { + super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animated: animated, feedback: feedback) verticalLineRenderer.values = [chartPosition] verticalLineRenderer.isEnabled = true } diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift index 464fa77bd6..2840fcc7e7 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/BarsComponentController.swift @@ -206,9 +206,9 @@ class BarsComponentController: GeneralChartComponentController { return previewBarsChartRenderer } - override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) { + override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animated: Bool, feedback: Bool) { let rangeWithOffset = detailsViewPosition - barsWidth / currentHorizontalMainChartRange.distance * chartFrame().width / 2 - super.showDetailsView(at: chartPosition, detailsViewPosition: rangeWithOffset, dataIndex: dataIndex, date: date, animted: animted) + super.showDetailsView(at: chartPosition, detailsViewPosition: rangeWithOffset, dataIndex: dataIndex, date: date, animated: animated, feedback: feedback) mainBarsRenderer.setSelectedIndex(dataIndex, animated: true) } diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift index 4c0c6e7e3e..c64dce830f 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/LinesComponentController.swift @@ -182,13 +182,13 @@ class LinesComponentController: GeneralChartComponentController { return previewLinesChartRenderer } - override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animted: Bool) { - super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animted: animted) + override func showDetailsView(at chartPosition: CGFloat, detailsViewPosition: CGFloat, dataIndex: Int, date: Date, animated: Bool, feedback: Bool) { + super.showDetailsView(at: chartPosition, detailsViewPosition: detailsViewPosition, dataIndex: dataIndex, date: date, animated: animated, feedback: feedback) verticalLineRenderer.values = [chartPosition] verticalLineRenderer.isEnabled = true lineBulletsRenderer.isEnabled = true - lineBulletsRenderer.setVisible(true, animated: animted) + lineBulletsRenderer.setVisible(true, animated: animated) lineBulletsRenderer.bullets = chartLines.compactMap { chart in return LineBulletsRenderer.Bullet(coordinate: chart.points[dataIndex], offset: .zero, color: chart.color) } diff --git a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift index 581fa962ed..131f1a001e 100644 --- a/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift +++ b/submodules/GraphCore/Sources/Charts/Controllers/Stacked Bars/TwoAxisStepBarsChartController.swift @@ -189,8 +189,12 @@ public class TwoAxisStepBarsChartController: BaseLinesChartController { } let chartValue: CGFloat = CGFloat(closestDate.timeIntervalSince1970) + var chartValueUpdated = true + if self.verticalLineRenderer.values == [chartValue] { + chartValueUpdated = false + } let detailsViewPosition = (chartValue - horizontalRange.lowerBound) / horizontalRange.distance * chartFrame.width + chartFrame.minX + barOffset - self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin) + self.setDetailsViewModel?(chartDetailsViewModel(closestDate: closestDate, pointIndex: minIndex, loading: false), chartInteractionWasBegin, chartInteractionWasBegin && chartValueUpdated) self.setDetailsChartVisibleClosure?(true, true) self.setDetailsViewPositionClosure?(detailsViewPosition) self.verticalLineRenderer.values = [chartValue] diff --git a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift index b11be4000c..e516e2765d 100644 --- a/submodules/StatisticsUI/Sources/StatsOverviewItem.swift +++ b/submodules/StatisticsUI/Sources/StatsOverviewItem.swift @@ -156,11 +156,13 @@ class StatsOverviewItemNode: ListViewItemNode { let titleFont = Font.regular(item.presentationData.fontSize.itemListBaseHeaderFontSize) let deltaFont = Font.regular(item.presentationData.fontSize.itemListBaseHeaderFontSize) + let displayInteractions = item.stats.sharesPerPost.current > 0 || item.stats.viewsPerPost.current > 0 + let (followersValueLabelLayout, followersValueLabelApply) = makeFollowersValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: compactNumericCountString(Int(item.stats.followers.current)), font: valueFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (viewsPerPostValueLabelLayout, viewsPerPostValueLabelApply) = makeViewsPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.stats.viewsPerPost.current > 0 || item.stats.sharesPerPost.current > 0 ? compactNumericCountString(Int(item.stats.viewsPerPost.current)) : "", font: valueFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (viewsPerPostValueLabelLayout, viewsPerPostValueLabelApply) = makeViewsPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: displayInteractions ? compactNumericCountString(Int(item.stats.viewsPerPost.current)) : "", font: valueFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (sharesPerPostValueLabelLayout, sharesPerPostValueLabelApply) = makeSharesPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.stats.sharesPerPost.current > 0 || item.stats.viewsPerPost.current > 0 ? compactNumericCountString(Int(item.stats.sharesPerPost.current)) : "", font: valueFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (sharesPerPostValueLabelLayout, sharesPerPostValueLabelApply) = makeSharesPerPostValueLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: displayInteractions ? compactNumericCountString(Int(item.stats.sharesPerPost.current)) : "", font: valueFont, textColor: item.presentationData.theme.list.itemPrimaryTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) var enabledNotifications: Double = 0.0 if item.stats.enabledNotifications.total > 0 { @@ -171,9 +173,9 @@ class StatsOverviewItemNode: ListViewItemNode { let (followersTitleLabelLayout, followersTitleLabelApply) = makeFollowersTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Stats_Followers, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (viewsPerPostTitleLabelLayout, viewsPerPostTitleLabelApply) = makeViewsPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.stats.viewsPerPost.current > 0 || item.stats.sharesPerPost.current > 0 ? item.presentationData.strings.Stats_ViewsPerPost : "", font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (viewsPerPostTitleLabelLayout, viewsPerPostTitleLabelApply) = makeViewsPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: displayInteractions ? item.presentationData.strings.Stats_ViewsPerPost : "", font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) - let (sharesPerPostTitleLabelLayout, sharesPerPostTitleLabelApply) = makeSharesPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.stats.sharesPerPost.current > 0 || item.stats.viewsPerPost.current > 0 ? item.presentationData.strings.Stats_SharesPerPost : "", font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) + let (sharesPerPostTitleLabelLayout, sharesPerPostTitleLabelApply) = makeSharesPerPostTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: displayInteractions ? item.presentationData.strings.Stats_SharesPerPost : "", font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) let (enabledNotificationsTitleLabelLayout, enabledNotificationsTitleLabelApply) = makeEnabledNotificationsTitleLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: item.presentationData.strings.Stats_EnabledNotifications, font: titleFont, textColor: item.presentationData.theme.list.sectionHeaderTextColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -197,7 +199,7 @@ class StatsOverviewItemNode: ListViewItemNode { viewsPerPostDeltaPercentage = abs(viewsPerPostDeltaValue / item.stats.viewsPerPost.previous) } - let viewsPerPostDeltaText = abs(viewsPerPostDeltaPercentage) > 0.0 ? String(format: "%@ (%.02f%%)", viewsPerPostDelta, viewsPerPostDeltaPercentage * 100.0) : "" + let viewsPerPostDeltaText = abs(viewsPerPostDeltaPercentage) > 0.0 && displayInteractions ? String(format: "%@ (%.02f%%)", viewsPerPostDelta, viewsPerPostDeltaPercentage * 100.0) : "" let (viewsPerPostDeltaLabelLayout, viewsPerPostDeltaLabelApply) = makeViewsPerPostDeltaLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: viewsPerPostDeltaText, font: deltaFont, textColor: viewsPerPostDeltaValue > 0.0 ? item.presentationData.theme.list.freeTextSuccessColor : item.presentationData.theme.list.freeTextErrorColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets())) @@ -209,7 +211,7 @@ class StatsOverviewItemNode: ListViewItemNode { sharesPerPostDeltaPercentage = abs(sharesPerPostDeltaValue / item.stats.sharesPerPost.previous) } - let sharesPerPostDeltaText = abs(sharesPerPostDeltaPercentage) > 0.0 ? String(format: "%@ (%.02f%%)", sharesPerPostDelta, sharesPerPostDeltaPercentage * 100.0) : "" + let sharesPerPostDeltaText = abs(sharesPerPostDeltaPercentage) > 0.0 && displayInteractions ? String(format: "%@ (%.02f%%)", sharesPerPostDelta, sharesPerPostDeltaPercentage * 100.0) : "" let (sharesPerPostDeltaLabelLayout, sharesPerPostDeltaLabelApply) = makeSharesPerPostDeltaLabelLayout(TextNodeLayoutArguments(attributedString: NSAttributedString(string: sharesPerPostDeltaText, font: deltaFont, textColor: sharesPerPostDeltaValue > 0.0 ? item.presentationData.theme.list.freeTextSuccessColor : item.presentationData.theme.list.freeTextErrorColor), backgroundColor: nil, maximumNumberOfLines: 1, truncationType: .end, constrainedSize: CGSize(width: params.width, height: CGFloat.greatestFiniteMagnitude), alignment: .natural, cutout: nil, insets: UIEdgeInsets()))