Skip to content

Commit a7bc660

Browse files
author
Lalit Sharma
committed
feat: implement shared map-link intake to timer and update changelog to version 1.1.40
1 parent 7bcce54 commit a7bc660

7 files changed

Lines changed: 350 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ 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.40] — 2026-02-27
9+
10+
### Fixed
11+
- Tightened `Photography Guide` landscape composite corona rendering so the ring appears only when `MAX` is during true totality (`C2 < MAX < C3`) and never for non-total scenarios.
12+
13+
### Changed
14+
- Bumped `apps/mobile` version to `1.1.40`.
15+
816
## [1.1.39] — 2026-02-27
917

1018
### 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.39",
3+
"version": "1.1.40",
44
"private": true,
55
"main": "index.js",
66
"scripts": {

apps/mobile/src/screens/PhotographyGuideScreen.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { fmtLocalHuman, fmtUtcHuman } from "../utils/date";
1717
import {
1818
buildLandscapeCompositeLayout,
1919
buildPhotographyGuideSchedule,
20+
isMaxDuringTotality,
2021
type PhotographyGuidePictureCount,
2122
type PhotographyGuideRow,
2223
} from "../utils/photographyGuide";
@@ -124,6 +125,16 @@ export default function PhotographyGuideScreen({
124125
? TOTALITY_SKY_COLOR
125126
: DEFAULT_COMPOSITE_SKY_COLOR;
126127
const isWithinEclipseArea = payload.visible && payload.kindAtLocation !== "none";
128+
const isMaxDuringTotalityWindow = useMemo(
129+
() =>
130+
isMaxDuringTotality({
131+
kindAtLocation: payload.kindAtLocation,
132+
c2Utc: payload.c2Utc,
133+
maxUtc: payload.maxUtc,
134+
c3Utc: payload.c3Utc,
135+
}),
136+
[payload.c2Utc, payload.c3Utc, payload.kindAtLocation, payload.maxUtc],
137+
);
127138
const scheduleResult = useMemo(
128139
() =>
129140
buildPhotographyGuideSchedule({
@@ -485,7 +496,7 @@ export default function PhotographyGuideScreen({
485496
/>
486497
{compositeLayout.placements.map((placement) => {
487498
const showTotalityCorona =
488-
payload.kindAtLocation === "total" &&
499+
isMaxDuringTotalityWindow &&
489500
placement.phaseBucket === "MAX" &&
490501
placement.showMoon &&
491502
Boolean(placement.moon);

apps/mobile/src/utils/photographyGuide.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,24 @@ function parseUtcMs(iso?: string): number | undefined {
107107
return parsed;
108108
}
109109

110+
export function isMaxDuringTotality(params: {
111+
kindAtLocation: EclipseKindAtLocation;
112+
c2Utc?: string;
113+
maxUtc?: string;
114+
c3Utc?: string;
115+
}) {
116+
if (params.kindAtLocation !== "total") return false;
117+
118+
const c2Ms = parseUtcMs(params.c2Utc);
119+
const maxMs = parseUtcMs(params.maxUtc);
120+
const c3Ms = parseUtcMs(params.c3Utc);
121+
if (typeof c2Ms !== "number" || typeof maxMs !== "number" || typeof c3Ms !== "number") {
122+
return false;
123+
}
124+
125+
return c2Ms < maxMs && maxMs < c3Ms;
126+
}
127+
110128
function clamp01(value: number) {
111129
return Math.max(0, Math.min(1, value));
112130
}

apps/mobile/tests/photography-guide.test.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { describe, expect, it } from "vitest";
33
import {
44
buildLandscapeCompositeLayout,
55
buildPhotographyGuideSchedule,
6+
isMaxDuringTotality,
67
} from "../src/utils/photographyGuide";
78

89
function isoUtc(hour: number, minute: number) {
@@ -86,6 +87,46 @@ describe("photography guide schedule", () => {
8687
expect(result.schedule.rows[2]?.phaseBucket).toBe("MAX");
8788
});
8889

90+
it("detects when MAX occurs during totality", () => {
91+
expect(
92+
isMaxDuringTotality({
93+
kindAtLocation: "total",
94+
c2Utc: isoUtc(10, 30),
95+
maxUtc: isoUtc(11, 0),
96+
c3Utc: isoUtc(11, 30),
97+
}),
98+
).toBe(true);
99+
});
100+
101+
it("does not mark MAX as totality outside total eclipses or without valid C2/C3 bounds", () => {
102+
expect(
103+
isMaxDuringTotality({
104+
kindAtLocation: "partial",
105+
c2Utc: isoUtc(10, 30),
106+
maxUtc: isoUtc(11, 0),
107+
c3Utc: isoUtc(11, 30),
108+
}),
109+
).toBe(false);
110+
111+
expect(
112+
isMaxDuringTotality({
113+
kindAtLocation: "annular",
114+
c2Utc: isoUtc(10, 30),
115+
maxUtc: isoUtc(11, 0),
116+
c3Utc: isoUtc(11, 30),
117+
}),
118+
).toBe(false);
119+
120+
expect(
121+
isMaxDuringTotality({
122+
kindAtLocation: "total",
123+
c2Utc: isoUtc(11, 30),
124+
maxUtc: isoUtc(11, 0),
125+
c3Utc: isoUtc(10, 30),
126+
}),
127+
).toBe(false);
128+
});
129+
89130
it("builds a stable 3-shot schedule around MAX", () => {
90131
const result = buildPhotographyGuideSchedule({
91132
visible: true,

0 commit comments

Comments
 (0)