@@ -89,7 +89,8 @@ const state = {
8989 autoCountdownTimer : null , // Timer for auto-ping countdown display
9090 nextAutoPingTime : null , // Timestamp when next auto-ping will occur
9191 apiCountdownTimer : null , // Timer for API post countdown display
92- apiPostTime : null // Timestamp when API post will occur
92+ apiPostTime : null , // Timestamp when API post will occur
93+ skipReason : null // Reason for skipping a ping - internal value only (e.g., "gps too old")
9394} ;
9495
9596// ---- UI helpers ----
@@ -107,6 +108,20 @@ function setStatus(text, color = STATUS_COLORS.idle) {
107108 statusEl . className = `font-semibold ${ color } ` ;
108109}
109110
111+ /**
112+ * Apply status message from countdown timer result
113+ * @param {string|{message: string, color: string}|null } result - Status message (string) or object with message and optional color
114+ * @param {string } defaultColor - Default color to use if result is a string or object without color
115+ */
116+ function applyCountdownStatus ( result , defaultColor ) {
117+ if ( ! result ) return ;
118+ if ( typeof result === 'string' ) {
119+ setStatus ( result , defaultColor ) ;
120+ } else {
121+ setStatus ( result . message , result . color || defaultColor ) ;
122+ }
123+ }
124+
110125// Countdown timer management - generalized for reuse
111126function createCountdownTimer ( getEndTime , getStatusMessage ) {
112127 return {
@@ -125,14 +140,12 @@ function createCountdownTimer(getEndTime, getStatusMessage) {
125140
126141 const remainingMs = this . endTime - Date . now ( ) ;
127142 if ( remainingMs <= 0 ) {
128- const message = getStatusMessage ( 0 ) ;
129- if ( message ) setStatus ( message , STATUS_COLORS . info ) ;
143+ applyCountdownStatus ( getStatusMessage ( 0 ) , STATUS_COLORS . info ) ;
130144 return ;
131145 }
132146
133147 const remainingSec = Math . ceil ( remainingMs / 1000 ) ;
134- const message = getStatusMessage ( remainingSec ) ;
135- if ( message ) setStatus ( message , STATUS_COLORS . idle ) ;
148+ applyCountdownStatus ( getStatusMessage ( remainingSec ) , STATUS_COLORS . idle ) ;
136149 } ,
137150
138151 stop ( ) {
@@ -150,19 +163,34 @@ const autoCountdownTimer = createCountdownTimer(
150163 ( ) => state . nextAutoPingTime ,
151164 ( remainingSec ) => {
152165 if ( ! state . running ) return null ;
153- return remainingSec === 0
154- ? "Sending auto ping..."
155- : `Waiting for next auto ping (${ remainingSec } s)` ;
166+ if ( remainingSec === 0 ) {
167+ return { message : "Sending auto ping..." , color : STATUS_COLORS . info } ;
168+ }
169+ // If there's a skip reason, show it with the countdown in warning color
170+ if ( state . skipReason ) {
171+ return {
172+ message : `Skipped (${ state . skipReason } ), next ping (${ remainingSec } s)` ,
173+ color : STATUS_COLORS . warning
174+ } ;
175+ }
176+ return {
177+ message : `Waiting for next auto ping (${ remainingSec } s)` ,
178+ color : STATUS_COLORS . idle
179+ } ;
156180 }
157181) ;
158182
159183// API post countdown timer
160184const apiCountdownTimer = createCountdownTimer (
161185 ( ) => state . apiPostTime ,
162186 ( remainingSec ) => {
163- return remainingSec === 0
164- ? "Posting to API..."
165- : `Wait to post API (${ remainingSec } s)` ;
187+ if ( remainingSec === 0 ) {
188+ return { message : "Posting to API..." , color : STATUS_COLORS . info } ;
189+ }
190+ return {
191+ message : `Wait to post API (${ remainingSec } s)` ,
192+ color : STATUS_COLORS . idle
193+ } ;
166194 }
167195) ;
168196
@@ -705,8 +733,8 @@ async function getGpsCoordinatesForPing(isAutoMode) {
705733 return await acquireFreshGpsPosition ( ) ;
706734 } catch ( e ) {
707735 debugError ( `Could not refresh GPS position for auto ping: ${ e . message } ` , e ) ;
708- const intervalSec = Math . ceil ( intervalMs / 1000 ) ;
709- setStatus ( `GPS could not refresh position, skipping ping. Next attempt ( ${ intervalSec } s)` , STATUS_COLORS . error ) ;
736+ // Set skip reason so the countdown will show the appropriate message
737+ state . skipReason = "gps too old" ;
710738 return null ;
711739 }
712740 }
@@ -873,6 +901,9 @@ function stopAutoPing(stopGps = false) {
873901 }
874902 stopAutoCountdown ( ) ;
875903
904+ // Clear skip reason
905+ state . skipReason = null ;
906+
876907 // Only stop GPS watch when disconnecting or page hidden, not during normal stop
877908 if ( stopGps ) {
878909 stopGeoWatch ( ) ;
@@ -892,12 +923,14 @@ function scheduleNextAutoPing() {
892923 const intervalMs = getSelectedIntervalMs ( ) ;
893924 debugLog ( `Scheduling next auto ping in ${ intervalMs } ms` ) ;
894925
895- // Start countdown immediately
926+ // Start countdown immediately (skipReason may be set if ping was skipped)
896927 startAutoCountdown ( intervalMs ) ;
897928
898929 // Schedule the next ping
899930 state . autoTimerId = setTimeout ( ( ) => {
900931 if ( state . running ) {
932+ // Clear skip reason before next attempt
933+ state . skipReason = null ;
901934 debugLog ( "Auto ping timer fired, sending ping" ) ;
902935 sendPing ( false ) . catch ( console . error ) ;
903936 }
@@ -928,6 +961,9 @@ function startAutoPing() {
928961 }
929962 stopAutoCountdown ( ) ;
930963
964+ // Clear any previous skip reason
965+ state . skipReason = null ;
966+
931967 // Start GPS watch for continuous updates
932968 debugLog ( "Starting GPS watch for auto mode" ) ;
933969 startGeoWatch ( ) ;
0 commit comments