@@ -35,6 +35,8 @@ import {
3535 formatWindSpeed ,
3636 convertPrecipitation ,
3737 formatPrecipitation ,
38+ getWindCardinal ,
39+ getWindArrowRotation ,
3840} from "@/lib/units" ;
3941import type { Report } from "@/types/api" ;
4042import { FRICTION_RATINGS , RATING_COLORS , CATEGORY_COLORS } from "@/constants/config" ;
@@ -795,7 +797,8 @@ export default function CragDetailScreen() {
795797 < ConditionItem
796798 icon = "flag-outline"
797799 label = { t ( "dialog.wind" , "Wind" ) }
798- value = { formatWindSpeed ( convertWindSpeed ( conditions . current . windSpeed_kph , "kmh" , units . windSpeed ) , units . windSpeed ) }
800+ value = { `${ formatWindSpeed ( convertWindSpeed ( conditions . current . windSpeed_kph , "kmh" , units . windSpeed ) , units . windSpeed ) } ${ conditions . current . windDirection != null ? ` ${ getWindCardinal ( conditions . current . windDirection ) } ` : "" } ` }
801+ windDirection = { conditions . current . windDirection }
799802 colors = { colors }
800803 />
801804 < ConditionItem
@@ -926,6 +929,7 @@ export default function CragDetailScreen() {
926929 const rc = getRatingColors ( rl ) ;
927930 const temp = h . temp_c ?? h . temperature_c ;
928931 const wind = h . wind_kph ?? h . windSpeed_kph ;
932+ const windDir = h . wind_direction ;
929933 return (
930934 < View key = { `good-${ i } ` } style = { [ styles . hourlyRow , {
931935 backgroundColor : rl === "Great" ? "rgba(34,197,94,0.08)" : "rgba(59,130,246,0.06)" ,
@@ -939,9 +943,14 @@ export default function CragDetailScreen() {
939943 { formatTemperature ( convertTemperature ( temp , "celsius" , units . temperature ) , units . temperature , 0 ) }
940944 </ Text >
941945 < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } > { h . humidity } %</ Text >
942- < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } >
943- { formatWindSpeed ( convertWindSpeed ( wind , "kmh" , units . windSpeed ) , units . windSpeed , 0 ) }
944- </ Text >
946+ < View style = { { flexDirection : "row" , alignItems : "center" } } >
947+ < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } >
948+ { formatWindSpeed ( convertWindSpeed ( wind , "kmh" , units . windSpeed ) , units . windSpeed , 0 ) }
949+ </ Text >
950+ { windDir != null && (
951+ < Text style = { [ styles . hourlyValue , { color : colors . muted , transform : [ { rotate : `${ getWindArrowRotation ( windDir ) } deg` } ] , marginLeft : 2 } ] } > ↑</ Text >
952+ ) }
953+ </ View >
945954 { rc && rl && (
946955 < View style = { [ styles . smallBadge , { backgroundColor : rc . bg , marginLeft : "auto" } ] } >
947956 < Text style = { [ styles . smallBadgeText , { color : rc . text } ] } > { t ( `ratings.${ rl ! . toLowerCase ( ) } ` , rl ) } </ Text >
@@ -980,6 +989,9 @@ export default function CragDetailScreen() {
980989 </ Text >
981990 < Ionicons name = "flag-outline" size = { 12 } color = { colors . muted } />
982991 < Text style = { [ styles . forecastWind , { color : colors . muted } ] } > { Math . round ( wind ) } </ Text >
992+ { day . windDirectionDominant != null && (
993+ < Text style = { [ styles . forecastWind , { color : colors . muted , transform : [ { rotate : `${ getWindArrowRotation ( day . windDirectionDominant ) } deg` } ] } ] } > ↑</ Text >
994+ ) }
983995 </ View >
984996 </ View >
985997 ) ;
@@ -1136,6 +1148,7 @@ function HourlyTimeline({ hours, colors, units, t }: { hours: any[]; colors: (ty
11361148 const rowBg = rl === "Great" ? "rgba(34,197,94,0.06)" : rl === "Good" ? "rgba(59,130,246,0.04)" : "transparent" ;
11371149 const temp = h . temp_c ?? h . temperature_c ;
11381150 const wind = h . wind_kph ?? h . windSpeed_kph ;
1151+ const windDir = h . wind_direction ;
11391152 return (
11401153 < View key = { i } style = { [ styles . hourlyRow , { backgroundColor : rowBg } , i > 0 && { borderTopWidth : 1 , borderTopColor : colors . border } ] } >
11411154 < Text style = { [ styles . hourlyTime , { color : colors . text } ] } > { fmtHour ( h . time , units ?. timeFormat || "24h" ) } </ Text >
@@ -1144,9 +1157,14 @@ function HourlyTimeline({ hours, colors, units, t }: { hours: any[]; colors: (ty
11441157 { formatTemperature ( convertTemperature ( temp , "celsius" , units . temperature ) , units . temperature , 0 ) }
11451158 </ Text >
11461159 < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } > { h . humidity } %</ Text >
1147- < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } >
1148- { formatWindSpeed ( convertWindSpeed ( wind , "kmh" , units . windSpeed ) , units . windSpeed , 0 ) }
1149- </ Text >
1160+ < View style = { { flexDirection : "row" , alignItems : "center" } } >
1161+ < Text style = { [ styles . hourlyValue , { color : colors . muted } ] } >
1162+ { formatWindSpeed ( convertWindSpeed ( wind , "kmh" , units . windSpeed ) , units . windSpeed , 0 ) }
1163+ </ Text >
1164+ { windDir != null && (
1165+ < Text style = { [ styles . hourlyValue , { color : colors . muted , transform : [ { rotate : `${ getWindArrowRotation ( windDir ) } deg` } ] , marginLeft : 2 } ] } > ↑</ Text >
1166+ ) }
1167+ </ View >
11501168 { rc && rl && (
11511169 < View style = { [ styles . smallBadge , { backgroundColor : rc . bg , marginLeft : "auto" } ] } >
11521170 < Text style = { [ styles . smallBadgeText , { color : rc . text } ] } > { t ( `ratings.${ rl ! . toLowerCase ( ) } ` , rl ) } </ Text >
@@ -1159,12 +1177,17 @@ function HourlyTimeline({ hours, colors, units, t }: { hours: any[]; colors: (ty
11591177 ) ;
11601178}
11611179
1162- function ConditionItem ( { icon, label, value, colors } : { icon : keyof typeof Ionicons . glyphMap ; label : string ; value : string ; colors : ( typeof Colors ) [ "light" ] } ) {
1180+ function ConditionItem ( { icon, label, value, windDirection , colors } : { icon : keyof typeof Ionicons . glyphMap ; label : string ; value : string ; windDirection ?: number ; colors : ( typeof Colors ) [ "light" ] } ) {
11631181 return (
11641182 < View style = { styles . conditionItem } >
11651183 < Ionicons name = { icon } size = { 20 } color = { colors . primary } />
11661184 < Text style = { [ styles . conditionLabel , { color : colors . textSecondary } ] } > { label } </ Text >
1167- < Text style = { [ styles . conditionValue , { color : colors . text } ] } > { value } </ Text >
1185+ < View style = { { flexDirection : "row" , alignItems : "center" , gap : 4 } } >
1186+ < Text style = { [ styles . conditionValue , { color : colors . text } ] } > { value } </ Text >
1187+ { windDirection != null && (
1188+ < Text style = { [ styles . conditionValue , { color : colors . muted , transform : [ { rotate : `${ getWindArrowRotation ( windDirection ) } deg` } ] } ] } > ↑</ Text >
1189+ ) }
1190+ </ View >
11681191 </ View >
11691192 ) ;
11701193}
0 commit comments