diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index ff585a7..917654f 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -489,7 +489,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -511,7 +511,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -530,7 +530,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -547,7 +547,7 @@ buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; GENERATE_INFOPLIST_FILE = YES; MARKETING_VERSION = 1.0; @@ -679,7 +679,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; @@ -702,7 +702,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 131; + CURRENT_PROJECT_VERSION = 132; DEVELOPMENT_TEAM = JND55328G8; ENABLE_BITCODE = NO; INFOPLIST_FILE = Runner/Info.plist; diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index 244faf0..cdf5bbb 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -43,7 +43,7 @@ CFBundleSignature ???? CFBundleVersion - 131 + 132 LSRequiresIPhoneOS ITSAppUsesNonExemptEncryption diff --git a/ios/fastlane/report.xml b/ios/fastlane/report.xml index 58f0bb5..bc3e239 100644 --- a/ios/fastlane/report.xml +++ b/ios/fastlane/report.xml @@ -5,22 +5,22 @@ - + - + - + - + diff --git a/pubspec.yaml b/pubspec.yaml index d21af7c..740a7c7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 2026.0403.1+45 +version: 2026.0404.1+46 environment: sdk: ^3.9.2 diff --git a/worker/src/components/dashboard/dashboard-shell.tsx b/worker/src/components/dashboard/dashboard-shell.tsx index 02b0c15..89c85a0 100644 --- a/worker/src/components/dashboard/dashboard-shell.tsx +++ b/worker/src/components/dashboard/dashboard-shell.tsx @@ -450,15 +450,40 @@ export function DashboardShell() { // --- Composition stacked area chart --- +const MIN_CHART_W = 320; +const COMPOSITION_CHART_H = 236; + +function useResponsiveChartWidth(minWidth = MIN_CHART_W) { + const [element, setElement] = useState(null); + const [width, setWidth] = useState(minWidth); + + useEffect(() => { + if (!element) return; + + const sync = () => setWidth(Math.max(element.clientWidth, minWidth)); + sync(); + + if (typeof ResizeObserver === "undefined") return; + + const observer = new ResizeObserver(sync); + observer.observe(element); + + return () => { observer.disconnect(); }; + }, [element, minWidth]); + + return { setElement, width }; +} + function CompositionChart({ points }: { points: CompositionPoint[] }) { const [hover, setHover] = useState(null); + const { setElement, width } = useResponsiveChartWidth(); const count = points.length; if (count === 0) return null; const maxVal = Math.max(...points.map((p) => p.human + p.overhead), 1); - const innerW = 100; - const innerH = 188; const pad = { top: 16, right: 16, bottom: 32, left: 48 }; + const innerW = Math.max(width - pad.left - pad.right, 240); + const innerH = COMPOSITION_CHART_H - pad.top - pad.bottom; const xs = points.map((_, i) => i / Math.max(count - 1, 1)); @@ -473,11 +498,10 @@ function CompositionChart({ points }: { points: CompositionPoint[] }) { const gridLines = niceGridLines(maxVal, 3); return ( -
+
setHover(null)} > @@ -569,6 +593,7 @@ const CHART_PAD = { top: 20, right: 16, bottom: 32, left: 48 }; function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; maxValue: number }) { const [hover, setHover] = useState(null); + const { setElement, width } = useResponsiveChartWidth(); const count = points.length; if (count === 0) return null; @@ -579,7 +604,7 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max })); const maxValue = Math.max(...normalized.map((p) => p.perNode), 1); - const innerW = 100; + const innerW = Math.max(width - CHART_PAD.left - CHART_PAD.right, 240); const innerH = CHART_H - CHART_PAD.top - CHART_PAD.bottom; const peakIdx = normalized.reduce((best, p, i) => (p.perNode > normalized[best].perNode ? i : best), 0); @@ -599,11 +624,10 @@ function TrafficChart({ points, maxValue: _rawMax }: { points: ChartPoint[]; max .filter((_, i) => i % labelStep === 0 || i === count - 1); return ( -
+
setHover(null)} > diff --git a/worker/src/layouts/BaseLayout.astro b/worker/src/layouts/BaseLayout.astro index 1da0464..6fc0c54 100644 --- a/worker/src/layouts/BaseLayout.astro +++ b/worker/src/layouts/BaseLayout.astro @@ -20,7 +20,7 @@ import "../index.css";