Skip to content

Commit a7ae3b0

Browse files
authored
chore(release): bump mobile version to 1.1.11 (#4)
1 parent 211e75f commit a7ae3b0

6 files changed

Lines changed: 115 additions & 4 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.1.11] — 2026-02-22
9+
10+
### Fixed
11+
- Updated preview mode moon motion so left/right travel direction follows local contact bearing progression when bearing data is available.
12+
- Wired contact bearing values into preview payload construction so direction-aware geometry has access to C1/C2/C3/C4 bearing inputs.
13+
- Added regression tests for bearing-based travel direction selection and fallback behavior when bearing pairs are incomplete.
14+
815
## [1.1.10] — 2026-02-22
916

1017
### Fixed

apps/mobile/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@eclipse-timer/mobile",
3-
"version": "1.1.10",
3+
"version": "1.1.11",
44
"private": true,
55
"main": "index.js",
66
"scripts": {

apps/mobile/src/navigation/RootNavigator.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,10 @@ function TimerRoute({ navigation, catalog, onOpenMenu }: TimerRouteProps) {
353353
maxUtc: result.maxUtc,
354354
c3Utc: result.c3Utc,
355355
c4Utc: result.c4Utc,
356+
c1BearingDeg: result.c1BearingDeg,
357+
c2BearingDeg: result.c2BearingDeg,
358+
c3BearingDeg: result.c3BearingDeg,
359+
c4BearingDeg: result.c4BearingDeg,
356360
};
357361

358362
navigation.navigate("Preview", { payload });

apps/mobile/src/screens/EclipsePreviewScreen.tsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import { colorForContactKey } from "../utils/contactTheme";
1616
import { fmtLocalHuman, fmtUtcHuman } from "../utils/date";
1717
import {
1818
calculatePreviewMoonGeometry,
19+
determinePreviewTravelDirection,
1920
PREVIEW_STAGE_SIZE,
2021
PREVIEW_SUN_RADIUS,
2122
} from "../utils/previewGeometry";
@@ -46,6 +47,10 @@ export type PreviewPayload = {
4647
maxUtc?: string;
4748
c3Utc?: string;
4849
c4Utc?: string;
50+
c1BearingDeg?: number;
51+
c2BearingDeg?: number;
52+
c3BearingDeg?: number;
53+
c4BearingDeg?: number;
4954
};
5055

5156
type EclipsePreviewScreenProps = {
@@ -310,8 +315,23 @@ export default function EclipsePreviewScreen({
310315
contacts: contactProgress,
311316
stageSize: SIM_STAGE_SIZE,
312317
sunRadius: SUN_RADIUS,
318+
travelDirection: determinePreviewTravelDirection({
319+
c1BearingDeg: payload.c1BearingDeg,
320+
c2BearingDeg: payload.c2BearingDeg,
321+
c3BearingDeg: payload.c3BearingDeg,
322+
c4BearingDeg: payload.c4BearingDeg,
323+
}),
313324
}),
314-
[contactProgress, payload.kindAtLocation, payload.magnitude, progress],
325+
[
326+
contactProgress,
327+
payload.c1BearingDeg,
328+
payload.c2BearingDeg,
329+
payload.c3BearingDeg,
330+
payload.c4BearingDeg,
331+
payload.kindAtLocation,
332+
payload.magnitude,
333+
progress,
334+
],
315335
);
316336

317337
const phaseLabel = useMemo(

apps/mobile/src/utils/previewGeometry.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,49 @@ export type PreviewMoonGeometry = {
2020
moonTravelHalfSpan: number;
2121
};
2222

23+
export type PreviewDirectionBearings = {
24+
c1BearingDeg?: number;
25+
c2BearingDeg?: number;
26+
c3BearingDeg?: number;
27+
c4BearingDeg?: number;
28+
};
29+
2330
function clamp01(v: number) {
2431
return Math.max(0, Math.min(1, v));
2532
}
2633

34+
function normalizeSignedDeltaDeg(fromDeg: number, toDeg: number) {
35+
const delta = ((toDeg - fromDeg + 540) % 360) - 180;
36+
return delta === -180 ? 180 : delta;
37+
}
38+
39+
function resolveDirectionalBearingPair(bearings: PreviewDirectionBearings) {
40+
const pairs: Array<[number | undefined, number | undefined]> = [
41+
[bearings.c1BearingDeg, bearings.c4BearingDeg],
42+
[bearings.c2BearingDeg, bearings.c3BearingDeg],
43+
[bearings.c1BearingDeg, bearings.c3BearingDeg],
44+
[bearings.c2BearingDeg, bearings.c4BearingDeg],
45+
];
46+
47+
for (const [start, end] of pairs) {
48+
if (typeof start !== "number" || !Number.isFinite(start)) continue;
49+
if (typeof end !== "number" || !Number.isFinite(end)) continue;
50+
return { start, end };
51+
}
52+
53+
return null;
54+
}
55+
56+
export function determinePreviewTravelDirection(
57+
bearings: PreviewDirectionBearings | undefined,
58+
): 1 | -1 {
59+
if (!bearings) return 1;
60+
const pair = resolveDirectionalBearingPair(bearings);
61+
if (!pair) return 1;
62+
const delta = normalizeSignedDeltaDeg(pair.start, pair.end);
63+
return delta >= 0 ? 1 : -1;
64+
}
65+
2766
export function determineMoonRadius(kindAtLocation: EclipseKindAtLocation) {
2867
if (kindAtLocation === "annular") return 58;
2968
if (kindAtLocation === "total") return 76;
@@ -109,6 +148,7 @@ export function calculatePreviewMoonGeometry(params: {
109148
contacts?: PreviewMotionContacts;
110149
stageSize?: number;
111150
sunRadius?: number;
151+
travelDirection?: 1 | -1;
112152
}): PreviewMoonGeometry {
113153
const stageSize = params.stageSize ?? PREVIEW_STAGE_SIZE;
114154
const sunRadius = params.sunRadius ?? PREVIEW_SUN_RADIUS;
@@ -121,7 +161,8 @@ export function calculatePreviewMoonGeometry(params: {
121161
);
122162

123163
const anchors = buildMotionAnchors(params.contacts ?? {}, sunRadius, moonRadius);
124-
const moonOffsetX = interpolateOffsetX(params.progress, anchors);
164+
const travelDirection = params.travelDirection ?? 1;
165+
const moonOffsetX = interpolateOffsetX(params.progress, anchors) * travelDirection;
125166
const moonCenterX = stageSize / 2 + moonOffsetX;
126167
const moonCenterY = stageSize / 2 + moonClosestOffset;
127168

apps/mobile/tests/preview-geometry.test.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
import { describe, expect, it } from "vitest";
22

3-
import { calculatePreviewMoonGeometry, PREVIEW_SUN_RADIUS } from "../src/utils/previewGeometry";
3+
import {
4+
calculatePreviewMoonGeometry,
5+
determinePreviewTravelDirection,
6+
PREVIEW_SUN_RADIUS,
7+
} from "../src/utils/previewGeometry";
48

59
describe("preview moon geometry", () => {
610
it("places C1 at exact outer tangency", () => {
@@ -49,4 +53,39 @@ describe("preview moon geometry", () => {
4953
expect(c3Distance).toBeCloseTo(Math.abs(PREVIEW_SUN_RADIUS - c3Geometry.moonRadius), 6);
5054
expect(postC3Distance).toBeGreaterThan(c3Distance);
5155
});
56+
57+
it("uses contact bearings to keep moon travel direction accurate", () => {
58+
const leftToRightDirection = determinePreviewTravelDirection({
59+
c1BearingDeg: 100,
60+
c4BearingDeg: 140,
61+
});
62+
const rightToLeftDirection = determinePreviewTravelDirection({
63+
c1BearingDeg: 140,
64+
c4BearingDeg: 100,
65+
});
66+
67+
const baseParams = {
68+
progress: 0.25,
69+
kindAtLocation: "total" as const,
70+
contacts: { c1: 0, c2: 0.25, max: 0.5, c3: 0.75, c4: 1 },
71+
};
72+
73+
const leftToRight = calculatePreviewMoonGeometry({
74+
...baseParams,
75+
travelDirection: leftToRightDirection,
76+
});
77+
const rightToLeft = calculatePreviewMoonGeometry({
78+
...baseParams,
79+
travelDirection: rightToLeftDirection,
80+
});
81+
82+
expect(leftToRight.moonOffsetX).toBeLessThan(0);
83+
expect(rightToLeft.moonOffsetX).toBeGreaterThan(0);
84+
expect(Math.abs(leftToRight.moonOffsetX)).toBeCloseTo(Math.abs(rightToLeft.moonOffsetX), 6);
85+
});
86+
87+
it("falls back to default travel direction when bearings are missing", () => {
88+
expect(determinePreviewTravelDirection(undefined)).toBe(1);
89+
expect(determinePreviewTravelDirection({ c2BearingDeg: 120 })).toBe(1);
90+
});
5291
});

0 commit comments

Comments
 (0)