| ... | @@ -2,12 +2,12 @@ import { HStack, ProgressView, Spacer, Text, VStack } from "@expo/ui/swift-ui"; | ... | @@ -2,12 +2,12 @@ import { HStack, ProgressView, Spacer, Text, VStack } from "@expo/ui/swift-ui"; |
| 2 | import { | 2 | import { |
| 3 | accessibilityElement, | 3 | accessibilityElement, |
| 4 | accessibilityLabel, | 4 | accessibilityLabel, |
| | 5 | fixedSize, |
| 5 | font, | 6 | font, |
| 6 | foregroundStyle, | 7 | foregroundStyle, |
| 7 | frame, | 8 | frame, |
| 8 | layoutPriority, | 9 | layoutPriority, |
| 9 | lineLimit, | 10 | lineLimit, |
| 10 | minimumScaleFactor, | | |
| 11 | progressViewStyle, | 11 | progressViewStyle, |
| 12 | tint, | 12 | tint, |
| 13 | widgetURL, | 13 | widgetURL, |
| ... | @@ -33,6 +33,8 @@ function SubscriptionUsage( | ... | @@ -33,6 +33,8 @@ function SubscriptionUsage( |
| 33 | const accessory = family === "accessoryRectangular"; | 33 | const accessory = family === "accessoryRectangular"; |
| 34 | const compact = | 34 | const compact = |
| 35 | family === "systemSmall" || accessory || environment.levelOfDetail === "simplified"; | 35 | family === "systemSmall" || accessory || environment.levelOfDetail === "simplified"; |
| | 36 | // Budget short cards for two quotas per provider, including their secondary text. |
| | 37 | const dense = family === "systemSmall" || family === "systemMedium"; |
| 36 | const limit = family === "systemExtraLarge" ? 6 : family === "systemLarge" ? 4 : 2; | 38 | const limit = family === "systemExtraLarge" ? 6 : family === "systemLarge" ? 4 : 2; |
| 37 | const monochrome = | 39 | const monochrome = |
| 38 | environment.widgetRenderingMode !== "fullColor" || environment.isLuminanceReduced; | 40 | environment.widgetRenderingMode !== "fullColor" || environment.isLuminanceReduced; |
| ... | @@ -77,6 +79,7 @@ function SubscriptionUsage( | ... | @@ -77,6 +79,7 @@ function SubscriptionUsage( |
| 77 | : provider.detail; | 79 | : provider.detail; |
| 78 | const barModifiers = [ | 80 | const barModifiers = [ |
| 79 | progressViewStyle("linear"), | 81 | progressViewStyle("linear"), |
| | 82 | frame({ height: 4 }), |
| 80 | ...(monochrome ? [] : [tint(provider.name === "Claude" ? "#d97757" : "#8e8e93")]), | 83 | ...(monochrome ? [] : [tint(provider.name === "Claude" ? "#d97757" : "#8e8e93")]), |
| 81 | ]; | 84 | ]; |
| 82 | if (accessory) { | 85 | if (accessory) { |
| ... | @@ -99,7 +102,6 @@ function SubscriptionUsage( | ... | @@ -99,7 +102,6 @@ function SubscriptionUsage( |
| 99 | modifiers={[ | 102 | modifiers={[ |
| 100 | font({ textStyle: "caption", weight: "semibold" }), | 103 | font({ textStyle: "caption", weight: "semibold" }), |
| 101 | lineLimit(1), | 104 | lineLimit(1), |
| 102 | minimumScaleFactor(0.75), | | |
| 103 | foregroundStyle("primary"), | 105 | foregroundStyle("primary"), |
| 104 | ]} | 106 | ]} |
| 105 | > | 107 | > |
| ... | @@ -132,35 +134,37 @@ function SubscriptionUsage( | ... | @@ -132,35 +134,37 @@ function SubscriptionUsage( |
| 132 | <VStack | 134 | <VStack |
| 133 | key={provider.name} | 135 | key={provider.name} |
| 134 | alignment="leading" | 136 | alignment="leading" |
| 135 | spacing={compact ? 2 : 4} | 137 | spacing={dense ? 1 : compact ? 2 : 4} |
| 136 | modifiers={[frame({ maxWidth: Infinity, alignment: "leading" })]} | 138 | modifiers={[ |
| | 139 | frame({ maxWidth: Infinity, alignment: "leading" }), |
| | 140 | fixedSize({ horizontal: false, vertical: true }), |
| | 141 | ]} |
| 137 | > | 142 | > |
| 138 | <Text | 143 | <Text |
| 139 | modifiers={[ | 144 | modifiers={[ |
| 140 | font({ textStyle: compact ? "caption" : "headline", weight: "bold" }), | 145 | font({ textStyle: compact ? "caption" : "headline", weight: "bold" }), |
| 141 | lineLimit(1), | 146 | lineLimit(1), |
| 142 | minimumScaleFactor(0.75), | | |
| 143 | foregroundStyle("primary"), | 147 | foregroundStyle("primary"), |
| 144 | ]} | 148 | ]} |
| 145 | > | 149 | > |
| 146 | {provider.name} | 150 | {provider.name} |
| 147 | </Text> | 151 | </Text> |
| 148 | {(!compact || shown.length === 0) && detail !== "Subscription remaining" ? ( | 152 | {!compact || shown.length === 0 ? ( |
| 149 | <Text | 153 | <Text |
| 150 | modifiers={[ | 154 | modifiers={[ |
| 151 | font({ textStyle: "caption2" }), | 155 | font({ textStyle: "caption2" }), |
| 152 | foregroundStyle("secondary"), | 156 | foregroundStyle("secondary"), |
| 153 | lineLimit(compact ? 1 : 2), | 157 | lineLimit(1), |
| 154 | ]} | 158 | ]} |
| 155 | > | 159 | > |
| 156 | {detail} | 160 | {detail === "Subscription remaining" ? " " : detail} |
| 157 | </Text> | 161 | </Text> |
| 158 | ) : null} | 162 | ) : null} |
| 159 | {shown.map((window) => ( | 163 | {shown.map((window) => ( |
| 160 | <VStack | 164 | <VStack |
| 161 | key={window.label} | 165 | key={window.label} |
| 162 | alignment="leading" | 166 | alignment="leading" |
| 163 | spacing={2} | 167 | spacing={dense ? 1 : 2} |
| 164 | modifiers={[ | 168 | modifiers={[ |
| 165 | accessibilityElement("ignore"), | 169 | accessibilityElement("ignore"), |
| 166 | accessibilityLabel( | 170 | accessibilityLabel( |
| ... | @@ -171,10 +175,9 @@ function SubscriptionUsage( | ... | @@ -171,10 +175,9 @@ function SubscriptionUsage( |
| 171 | <HStack spacing={4}> | 175 | <HStack spacing={4}> |
| 172 | <Text | 176 | <Text |
| 173 | modifiers={[ | 177 | modifiers={[ |
| 174 | font({ textStyle: compact ? "caption2" : "caption" }), | 178 | font({ textStyle: compact || dense ? "caption2" : "caption" }), |
| 175 | foregroundStyle("secondary"), | 179 | foregroundStyle("secondary"), |
| 176 | lineLimit(1), | 180 | lineLimit(1), |
| 177 | minimumScaleFactor(0.75), | | |
| 178 | ]} | 181 | ]} |
| 179 | > | 182 | > |
| 180 | {window.label} | 183 | {window.label} |
| ... | @@ -182,9 +185,11 @@ function SubscriptionUsage( | ... | @@ -182,9 +185,11 @@ function SubscriptionUsage( |
| 182 | <Spacer /> | 185 | <Spacer /> |
| 183 | <Text | 186 | <Text |
| 184 | modifiers={[ | 187 | modifiers={[ |
| 185 | font({ textStyle: compact ? "caption2" : "caption", weight: "semibold" }), | 188 | font({ |
| | 189 | textStyle: compact || dense ? "caption2" : "caption", |
| | 190 | weight: "semibold", |
| | 191 | }), |
| 186 | lineLimit(1), | 192 | lineLimit(1), |
| 187 | minimumScaleFactor(0.75), | | |
| 188 | layoutPriority(1), | 193 | layoutPriority(1), |
| 189 | foregroundStyle( | 194 | foregroundStyle( |
| 190 | window.remaining <= 10 && !monochrome | 195 | window.remaining <= 10 && !monochrome |
| ... | @@ -200,14 +205,7 @@ function SubscriptionUsage( | ... | @@ -200,14 +205,7 @@ function SubscriptionUsage( |
| 200 | </HStack> | 205 | </HStack> |
| 201 | <ProgressView value={window.remaining / 100} modifiers={barModifiers} /> | 206 | <ProgressView value={window.remaining / 100} modifiers={barModifiers} /> |
| 202 | {!compact ? ( | 207 | {!compact ? ( |
| 203 | <Text | 208 | <Text modifiers={[font({ size: 10 }), foregroundStyle("secondary"), lineLimit(1)]}> |
| 204 | modifiers={[ | | |
| 205 | font({ textStyle: "caption2" }), | | |
| 206 | foregroundStyle("secondary"), | | |
| 207 | lineLimit(1), | | |
| 208 | minimumScaleFactor(0.75), | | |
| 209 | ]} | | |
| 210 | > | | |
| 211 | {window.reset} | 209 | {window.reset} |
| 212 | </Text> | 210 | </Text> |
| 213 | ) : null} | 211 | ) : null} |
| ... | @@ -216,7 +214,13 @@ function SubscriptionUsage( | ... | @@ -216,7 +214,13 @@ function SubscriptionUsage( |
| 216 | {!compact && | 214 | {!compact && |
| 217 | !stale && | 215 | !stale && |
| 218 | (period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) > limit ? ( | 216 | (period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) > limit ? ( |
| 219 | <Text modifiers={[font({ textStyle: "caption2" }), foregroundStyle("secondary")]}> | 217 | <Text |
| | 218 | modifiers={[ |
| | 219 | font({ textStyle: "caption2" }), |
| | 220 | foregroundStyle("secondary"), |
| | 221 | lineLimit(1), |
| | 222 | ]} |
| | 223 | > |
| 220 | {(period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) - | 224 | {(period === "auto" ? (provider.totalWindows ?? windows.length) : windows.length) - |
| 221 | limit}{" "} | 225 | limit}{" "} |
| 222 | more in T3 | 226 | more in T3 |
| ... | @@ -228,11 +232,11 @@ function SubscriptionUsage( | ... | @@ -228,11 +232,11 @@ function SubscriptionUsage( |
| 228 | return ( | 232 | return ( |
| 229 | <VStack | 233 | <VStack |
| 230 | alignment="leading" | 234 | alignment="leading" |
| 231 | spacing={accessory ? 2 : 6} | 235 | spacing={accessory || dense ? 2 : 6} |
| 232 | modifiers={props.url ? [widgetURL(props.url)] : []} | 236 | modifiers={props.url ? [widgetURL(props.url)] : []} |
| 233 | > | 237 | > |
| 234 | {compact ? ( | 238 | {compact ? ( |
| 235 | <VStack alignment="leading" spacing={accessory ? 4 : 8}> | 239 | <VStack alignment="leading" spacing={accessory || dense ? 4 : 8}> |
| 236 | {columns} | 240 | {columns} |
| 237 | </VStack> | 241 | </VStack> |
| 238 | ) : ( | 242 | ) : ( |
| ... | @@ -243,12 +247,7 @@ function SubscriptionUsage( | ... | @@ -243,12 +247,7 @@ function SubscriptionUsage( |
| 243 | {!accessory ? <Spacer /> : null} | 247 | {!accessory ? <Spacer /> : null} |
| 244 | {!accessory ? ( | 248 | {!accessory ? ( |
| 245 | <Text | 249 | <Text |
| 246 | modifiers={[ | 250 | modifiers={[font({ textStyle: "caption2" }), foregroundStyle("secondary"), lineLimit(1)]} |
| 247 | font({ textStyle: "caption2" }), | | |
| 248 | foregroundStyle("secondary"), | | |
| 249 | lineLimit(1), | | |
| 250 | minimumScaleFactor(0.75), | | |
| 251 | ]} | | |
| 252 | > | 251 | > |
| 253 | {props.checkedAt | 252 | {props.checkedAt |
| 254 | ? `As of ${new Date(props.checkedAt).toLocaleString(undefined, { hour: "numeric", minute: "2-digit", month: "short", day: "numeric" })}` | 253 | ? `As of ${new Date(props.checkedAt).toLocaleString(undefined, { hour: "numeric", minute: "2-digit", month: "short", day: "numeric" })}` |