import { Helper } from "../../helper" ; import { ActivityInfoModel , UserSettingsModel } from "@elevate/shared/models" ; import { AppResourcesModel } from "../../models/app-resources.model" ; import { ActivityProcessor } from "../../processors/activity-processor" ; import { AbstractExtendedDataModifier } from "./abstract-extended-data.modifier" ; import { ElevationDataView } from "./views/elevation-data.view" ; import { PaceDataView } from "./views/pace-data.view" ; import { RunningCadenceDataView } from "./views/running-cadence.data.view" ; import { RunningGradeDataView } from "./views/running-grade-data.view" ; import { RunningPowerDataView } from "./views/running-power-data.view" ; import { GradeAdjustedPaceDataView } from "./views/grade-adjusted-pace-data.view" ; import * as $ from "jquery" ; import * as _ from "lodash" ; export class RunningExtendedDataModifier extends AbstractExtendedDataModifier { constructor ( activityProcessor , activityInfo , appResources , userSettings , type ) { super ( activityProcessor , activityInfo , appResources , userSettings , type ) ; } protected insertContentSummaryGridContent ( ) { super . insertContentSummaryGridContent ( ) ; let q3Move = "-" ; let units = "" ; if ( this . analysisData . paceData && this . userSettings . displayAdvancedSpeedData ) { q3Move = Helper . secondsToHHMMSS ( this . analysisData . paceData . upperQuartilePace / this . speedUnitsData . speedUnitFactor , true ) ; units = "/" + this . speedUnitsData . units ; } this . insertContentAtGridPosition ( 1 , 0 , q3Move , "75% Quartile Pace" , units , "displayAdvancedSpeedData" ) ; let climbPaceDisplayed = "-" ; if ( this . analysisData . gradeData && this . userSettings . displayAdvancedGradeData ) { const avgClimbPace = Helper . convertSpeedToPace ( this . analysisData . gradeData . upFlatDownMoveData . up ) ; if ( avgClimbPace !== - 1 ) { const seconds = avgClimbPace / this . speedUnitsData . speedUnitFactor ; if ( seconds ) { climbPaceDisplayed = Helper . secondsToHHMMSS ( seconds , true ) ; } } this . insertContentAtGridPosition ( 1 , 3 , climbPaceDisplayed , "Avg climbing pace" , "/" + this . speedUnitsData . units , "displayAdvancedGradeData" ) ; } if ( this . userSettings . displayAdvancedPowerData ) { let averageWatts = "-" ; let averageWattsTitle = "Average Power" ; let userSettingKey = "displayAdvancedPowerData" ; if ( this . analysisData . powerData && this . analysisData . powerData . avgWatts ) { if ( this . analysisData . powerData . hasPowerMeter ) { averageWatts = this . printNumber ( this . analysisData . powerData . avgWatts ) ; userSettingKey = "displayAdvancedPowerData" ; } else { if ( this . userSettings . displayRunningPowerEstimation ) { averageWattsTitle = "Estimated " + averageWattsTitle ; userSettingKey = "displayRunningPowerEstimation" ; averageWatts = "<span style='font-size: 14px;'>~</span>" + this . printNumber ( this . analysisData . powerData . avgWatts ) ; } } } this . insertContentAtGridPosition ( 0 , 4 , averageWatts , averageWattsTitle , "w" , userSettingKey ) ; } if ( this . userSettings . displayAdvancedPowerData ) { if ( this . analysisData . powerData && this . analysisData . powerData . weightedPower && this . analysisData . powerData . hasPowerMeter ) { const weightedPower = this . printNumber ( this . analysisData . powerData . weightedPower ) ; this . insertContentAtGridPosition ( 1 , 4 , weightedPower , "Weighted Power" , "w" , "displayAdvancedPowerData" ) ; } } if ( this . userSettings . displayAdvancedSpeedData && this . activityInfo . isOwner && this . activityInfo . supportsGap ) { let runningStressScore = "-" ; let labelRSS = "Running Stress Score" ; if ( this . analysisData . paceData && this . analysisData . paceData . runningStressScore ) { runningStressScore = this . printNumber ( this . analysisData . paceData . runningStressScore ) + " <span class=\"summarySubGridTitle\">(" + this . printNumber ( this . analysisData . paceData . runningStressScorePerHour , 1 ) + " / hour)</span>" ; } else if ( this . analysisData . paceData && ! _ . isNumber ( this . athleteSnapshot . athleteSettings . runningFtp ) ) { labelRSS = "<span style='cursor: not-allowed'><i>No running FTP in dated athlete </br>settings for this activity date</i></span>" ; } else { labelRSS = "Unable to display </br>\"Running Stress Score\"" ; } this . insertContentAtGridPosition ( 0 , 5 , runningStressScore , labelRSS , "" , null ) ; } if ( this . userSettings . displayRunningPerformanceIndex && this . activityInfo . isOwner && _ . isNumber ( this . analysisData . runningPerformanceIndex ) ) { const runIndex = this . printNumber ( this . analysisData . runningPerformanceIndex , 1 ) ; this . insertContentAtGridPosition ( 1 , 4 , runIndex , "Running Index" , "" , "displayRunningPerformanceIndex" ) ; } } protected placeSummaryPanel ( panelAdded ) { this . makeSummaryGrid ( 2 , 6 ) ; super . placeSummaryPanel ( panelAdded ) ; } protected placeExtendedStatsButtonSegment ( buttonAdded ) { setTimeout ( ( ) => { let htmlButton = "<section>" ; htmlButton += "<a class=\"btn-block btn-xs button raceshape-btn btn-primary\" data-xtd-seg-effort-stats id=\"" + this . segmentEffortButtonId + "\">" ; htmlButton += "Show extended statistics of effort" ; htmlButton += "</a>" ; htmlButton += "</section>" ; if ( $ ( "[data-xtd-seg-effort-stats]" ) . length === 0 ) { $ ( ".leaderboard-summary" ) . after ( htmlButton ) . each ( ( ) => { super . placeExtendedStatsButtonSegment ( buttonAdded ) ; } ) ; } } ) ; } protected setDataViewsNeeded ( ) { super . setDataViewsNeeded ( ) ; if ( this . analysisData . paceData && this . userSettings . displayAdvancedSpeedData ) { const measurementPreference = window . currentAthlete . get ( "measurement_preference" ) ; const units = ( measurementPreference == "meters" ) ? "/km" : "/mi" ; const paceDataView = new PaceDataView ( this . analysisData . paceData , units ) ; paceDataView . setSupportsGap ( this . activityInfo . supportsGap ) ; paceDataView . setAppResources ( this . appResources ) ; paceDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; paceDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( paceDataView ) ; } if ( this . analysisData . paceData && this . analysisData . paceData . gradeAdjustedPaceZones && this . userSettings . displayAdvancedSpeedData ) { const measurementPreference = window . currentAthlete . get ( "measurement_preference" ) ; const units = ( measurementPreference == "meters" ) ? "/km" : "/mi" ; const gradeAdjustedPaceDataView = new GradeAdjustedPaceDataView ( this . analysisData . paceData , units ) ; gradeAdjustedPaceDataView . setAppResources ( this . appResources ) ; gradeAdjustedPaceDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; gradeAdjustedPaceDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( gradeAdjustedPaceDataView ) ; } if ( this . analysisData . powerData && this . userSettings . displayAdvancedPowerData ) { const isEstimatedRunningPowerFeatureEnabled = this . userSettings . displayRunningPowerEstimation ; if ( this . analysisData . powerData . hasPowerMeter || isEstimatedRunningPowerFeatureEnabled ) { const powerDataView = new RunningPowerDataView ( this . analysisData . powerData , "w" ) ; powerDataView . setAppResources ( this . appResources ) ; powerDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; powerDataView . setActivityType ( this . activityType ) ; powerDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( powerDataView ) ; } } if ( this . analysisData . cadenceData && this . userSettings . displayCadenceData ) { const runningCadenceDataView = new RunningCadenceDataView ( this . analysisData . cadenceData , "spm" , this . userSettings ) ; runningCadenceDataView . setAppResources ( this . appResources ) ; runningCadenceDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; runningCadenceDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( runningCadenceDataView ) ; } if ( this . analysisData . gradeData && this . userSettings . displayAdvancedGradeData ) { const runningGradeDataView = new RunningGradeDataView ( this . analysisData . gradeData , "%" ) ; runningGradeDataView . setAppResources ( this . appResources ) ; runningGradeDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; runningGradeDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( runningGradeDataView ) ; } if ( this . analysisData . elevationData && this . userSettings . displayAdvancedElevationData ) { const elevationDataView = new ElevationDataView ( this . analysisData . elevationData , "m" ) ; elevationDataView . setAppResources ( this . appResources ) ; elevationDataView . setIsAuthorOfViewedActivity ( this . activityInfo . isOwner ) ; elevationDataView . setIsSegmentEffortView ( this . type === AbstractExtendedDataModifier . TYPE_SEGMENT ) ; this . dataViews . push ( elevationDataView ) ; } } }