Skip to content

Commit e38e0ea

Browse files
authored
Merge pull request #118 from MrAlders0n/dev
Release v1.5.0 (merge dev into main)
2 parents aedd170 + 82379ef commit e38e0ea

14 files changed

Lines changed: 3338 additions & 721 deletions

.github/workflows/deploy.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,13 @@ jobs:
5656
cp -r dev-content/* _site/dev/ 2>/dev/null || true
5757
cp -r dev-content/content _site/dev/ 2>/dev/null || true
5858
59-
# Inject dev badge with date (visual display and JS constant with DEV-EPOCH format)
60-
DEV_DATE=$(date -u +"%Y-%m-%d %H:%M UTC")
59+
# Inject DEV version (visual display) and JS constant with DEV-EPOCH format
6160
DEV_EPOCH=$(date -u +%s)
62-
sed -i 's|MeshCore Wardrive</h1>|MeshCore Wardrive <span class="ml-2 px-2 py-0.5 text-xs font-semibold rounded bg-amber-600/20 text-amber-400 border border-amber-600/40">DEV</span> <span class="text-xs text-slate-500">'"${DEV_DATE}"'</span></h1>|' _site/dev/index.html
61+
# Replace the visible version in the dedicated span (this is what the UI shows)
62+
sed -i 's|<span id="appVersion"[^>]*>[^<]*</span>|<span id="appVersion" class="text-sm text-slate-400">DEV-'"${DEV_EPOCH}"'</span>|' _site/dev/index.html
63+
# Inject into JS constant
6364
sed -i 's|const APP_VERSION = "UNKNOWN";|const APP_VERSION = "DEV-'"${DEV_EPOCH}"'";|' _site/dev/content/wardrive.js
64-
65+
6566
find _site -name ". git" -exec rm -rf {} + 2>/dev/null || true
6667
find _site -name ".github" -exec rm -rf {} + 2>/dev/null || true
6768

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ Thumbs.db
2121

2222
# Temporary files
2323
tmp/
24+
test-log-ui.html

IMPLEMENTATION_SUMMARY.md

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
# Two-Bar Status System - Implementation Summary
2+
3+
## Overview
4+
This implementation separates connection status from operational status into two independent status bars.
5+
6+
## Visual Structure
7+
8+
```
9+
┌────────────────────────────────────────────────────────┐
10+
│ Connection Status Bar (#connectionStatus) │
11+
│ ● Connected │
12+
└────────────────────────────────────────────────────────┘
13+
┌────────────────────────────────────────────────────────┐
14+
│ Dynamic App Status Bar (#status) │
15+
│ Ping sent │
16+
└────────────────────────────────────────────────────────┘
17+
```
18+
19+
## Connection Status Bar
20+
**Purpose**: Shows ONLY connection state
21+
**Location**: Top bar with status indicator dot
22+
**Messages**: Exactly 4 fixed states
23+
24+
### The Four States
25+
1. **Connected** (green) - Ready for wardriving after GPS init completes
26+
2. **Connecting** (blue) - During entire connection process (steps 1-9)
27+
3. **Disconnected** (red) - No device connected
28+
4. **Disconnecting** (blue) - During entire disconnection process
29+
30+
### Key Behavior
31+
- Updates immediately (no delay)
32+
- Never shows operational messages
33+
- Controlled by `setConnStatus(text, color)`
34+
35+
## Dynamic App Status Bar
36+
**Purpose**: Shows ALL operational messages
37+
**Location**: Status message box below connection bar
38+
**Messages**: ~30 different operational messages
39+
40+
### Message Types
41+
- GPS status ("Priming GPS", "Waiting for GPS fix")
42+
- Channel setup ("Looking for #wardriving channel", "Created #wardriving")
43+
- Capacity check ("Acquiring wardriving slot", "Acquired wardriving slot")
44+
- Ping operations ("Sending manual ping", "Ping sent")
45+
- Countdown timers ("Waiting for next auto ping (15s)")
46+
- API operations ("Posting to API")
47+
- Error messages ("WarDriving app has reached capacity")
48+
- Empty placeholder (em dash: ``)
49+
50+
### Key Behavior
51+
- 500ms minimum visibility for first display
52+
- Immediate updates for countdown timers
53+
- Shows `` when no message present
54+
- Blocks connection words (Connected/Connecting/Disconnecting/Disconnected)
55+
- Controlled by `setDynamicStatus(text, color, immediate)`
56+
57+
## Connection Flow Example
58+
59+
### During Connection
60+
```
61+
Time | Connection Bar | Dynamic Bar
62+
------|------------------|---------------------------
63+
0s | Connecting | —
64+
1s | Connecting | Acquiring wardriving slot
65+
3s | Connecting | Acquired wardriving slot
66+
4s | Connecting | Looking for #wardriving channel
67+
5s | Connecting | Channel #wardriving found
68+
6s | Connecting | Priming GPS
69+
8s | Connected | —
70+
```
71+
72+
### During Disconnection (Normal)
73+
```
74+
Time | Connection Bar | Dynamic Bar
75+
------|------------------|---------------------------
76+
0s | Disconnecting | —
77+
1s | Disconnected | —
78+
```
79+
80+
### During Disconnection (Error - Capacity Full)
81+
```
82+
Time | Connection Bar | Dynamic Bar
83+
------|------------------|---------------------------
84+
0s | Disconnecting | —
85+
1s | Disconnected | WarDriving app has reached capacity
86+
```
87+
88+
## Key Implementation Details
89+
90+
### Function Signatures
91+
```javascript
92+
// Connection Status Bar
93+
setConnStatus(text, color)
94+
// Example: setConnStatus("Connected", STATUS_COLORS.success)
95+
96+
// Dynamic App Status Bar
97+
setDynamicStatus(text, color, immediate = false)
98+
// Example: setDynamicStatus("Ping sent", STATUS_COLORS.success)
99+
// Example: setDynamicStatus("—") // Empty state
100+
```
101+
102+
### Protection Mechanisms
103+
1. **Em Dash Normalization**: Empty/null/whitespace values become ``
104+
2. **Connection Word Blocking**: Prevents connection words in dynamic bar
105+
3. **Minimum Visibility**: First dynamic message respects 500ms minimum
106+
4. **Countdown Updates**: Immediate updates every second after first display
107+
108+
### Error Message Changes
109+
All error messages in dynamic bar NO LONGER have "Disconnected:" prefix:
110+
111+
**Before**:
112+
- `"Disconnected: WarDriving app has reached capacity"`
113+
- `"Disconnected: WarDriving slot has been revoked"`
114+
115+
**After**:
116+
- Connection Bar: `"Disconnected"`
117+
- Dynamic Bar: `"WarDriving app has reached capacity"`
118+
- Dynamic Bar: `"WarDriving slot has been revoked"`
119+
120+
## Files Modified
121+
122+
### Code
123+
- `content/wardrive.js`
124+
- Added `setConnStatus()` function
125+
- Added `setDynamicStatus()` function
126+
- Updated ~30+ status calls throughout
127+
- Updated countdown timer integration
128+
- Updated error handling
129+
130+
### Documentation
131+
- `docs/STATUS_MESSAGES.md`
132+
- Complete rewrite with two-bar system
133+
- Connection Status Bar section (4 messages)
134+
- Dynamic App Status Bar section (~30 messages)
135+
- Implementation details and examples
136+
137+
- `docs/CONNECTION_WORKFLOW.md`
138+
- Updated all workflow steps with separate bars
139+
- Connection sequence clearly shows both bars
140+
- Disconnection sequence clearly shows both bars
141+
- Error flows updated without prefix
142+
143+
## Testing Checklist
144+
145+
### Connection Workflow
146+
- [ ] Connection bar shows "Connecting" from start to GPS init
147+
- [ ] Connection bar shows "Connected" only after GPS init completes
148+
- [ ] Dynamic bar shows intermediate messages (capacity check, channel setup, GPS)
149+
- [ ] Dynamic bar clears to `` when connection completes
150+
151+
### Disconnection Workflow
152+
- [ ] Connection bar shows "Disconnecting" during disconnect process
153+
- [ ] Connection bar shows "Disconnected" after cleanup completes
154+
- [ ] Dynamic bar shows `` for normal disconnect
155+
- [ ] Dynamic bar shows error message (without prefix) for error disconnect
156+
157+
### Error Scenarios
158+
- [ ] Capacity full: Connection bar "Disconnected", Dynamic bar "WarDriving app has reached capacity"
159+
- [ ] App down: Connection bar "Disconnected", Dynamic bar "WarDriving app is down"
160+
- [ ] Slot revoked: Connection bar "Disconnected", Dynamic bar "WarDriving slot has been revoked"
161+
- [ ] Public key error: Connection bar "Disconnected", Dynamic bar "Unable to read device public key; try again"
162+
163+
### Dynamic Messages
164+
- [ ] Ping operations show in dynamic bar only
165+
- [ ] GPS status shows in dynamic bar only
166+
- [ ] Countdown timers show in dynamic bar with smooth updates
167+
- [ ] API posting shows in dynamic bar only
168+
- [ ] Connection words NEVER appear in dynamic bar
169+
- [ ] Em dash (``) appears when no message to display
170+
171+
### Visual Appearance
172+
- [ ] Connection status indicator dot changes color with connection state
173+
- [ ] Both bars visible and clearly separated
174+
- [ ] Messages properly colored (green success, blue info, red error, etc.)
175+
- [ ] No visual glitches during transitions
176+
177+
## Summary
178+
179+
This implementation successfully separates connection state management from operational status display, providing:
180+
181+
1. **Clear Connection State**: Always visible in top bar
182+
2. **Rich Operational Feedback**: All app operations in dynamic bar
183+
3. **Better UX**: Users can see connection state AND what the app is doing
184+
4. **Consistent Behavior**: Connection bar for state, dynamic bar for everything else
185+
5. **Proper Error Handling**: Error reasons clearly shown without confusion
186+
187+
The code is complete, documented, and ready for testing and deployment.

README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,27 @@ A lightweight debugging system designed for development without impacting produc
150150

151151
---
152152

153+
## 🛠️ Development
154+
155+
### Building Tailwind CSS
156+
157+
This project uses Tailwind CSS v4 to generate the styles. If you make changes to the HTML or need to rebuild the CSS:
158+
159+
```bash
160+
# Install dependencies
161+
npm install
162+
163+
# Build CSS once
164+
npm run build:css
165+
166+
# Watch for changes and rebuild automatically
167+
npm run watch:css
168+
```
169+
170+
The CSS is generated from `content/tailwind-in.css` and outputs to `content/tailwind.css`.
171+
172+
---
173+
153174
## 🙏 Credits
154175

155176
This project is a fork and adaptation:

content/style.css

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,125 @@ body,
177177
.mesh-control .top-rpt-row div:last-child {
178178
flex: 0 0 auto;
179179
white-space: nowrap;
180+
}
181+
182+
/* Session Log - Static Expandable Section */
183+
#logBottomSheet.open {
184+
display: block !important;
185+
}
186+
187+
#logExpandArrow.expanded {
188+
transform: rotate(180deg);
189+
}
190+
191+
/* Log Entry Styling */
192+
.logEntry {
193+
display: flex;
194+
flex-direction: column;
195+
gap: 0.5rem;
196+
padding: 0.75rem;
197+
background: rgba(15, 23, 42, 0.5);
198+
border: 1px solid rgba(51, 65, 85, 0.7);
199+
border-radius: 0.5rem;
200+
}
201+
202+
.logRowTop {
203+
display: flex;
204+
justify-content: space-between;
205+
align-items: center;
206+
font-size: 0.75rem;
207+
color: #cbd5e1;
208+
}
209+
210+
.logTime {
211+
font-weight: 500;
212+
}
213+
214+
.logCoords {
215+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
216+
color: #94a3b8;
217+
white-space: nowrap;
218+
overflow: hidden;
219+
text-overflow: ellipsis;
220+
max-width: 12rem;
221+
}
222+
223+
/* Heard Repeats Chips Container */
224+
.heardChips {
225+
display: flex;
226+
flex-wrap: wrap;
227+
gap: 0.375rem;
228+
align-items: center;
229+
}
230+
231+
/* Chip Base Styling */
232+
.chip {
233+
display: inline-flex;
234+
align-items: center;
235+
gap: 0.25rem;
236+
padding: 0.375rem 0.625rem;
237+
border-radius: 999px;
238+
font-size: 0.75rem;
239+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
240+
font-weight: 500;
241+
background: rgba(51, 65, 85, 0.6);
242+
border: 1px solid rgba(71, 85, 105, 0.8);
243+
color: #e2e8f0;
244+
white-space: nowrap;
245+
}
246+
247+
.chipId {
248+
font-weight: 600;
249+
}
250+
251+
.chipSnr {
252+
font-weight: 400;
253+
}
254+
255+
/* SNR Color Coding */
256+
.snr-red .chipSnr {
257+
color: #f87171;
258+
font-weight: 600;
259+
}
260+
261+
.snr-orange .chipSnr {
262+
color: #fb923c;
263+
font-weight: 600;
264+
}
265+
266+
.snr-green .chipSnr {
267+
color: #4ade80;
268+
font-weight: 600;
269+
}
270+
271+
/* Mobile-responsive chip styling */
272+
@media (max-width: 640px) {
273+
/* Reduce chip size for mobile */
274+
.chip {
275+
padding: 0.25rem 0.5rem;
276+
font-size: 0.625rem;
277+
gap: 0.2rem;
278+
}
279+
280+
/* 3-column grid layout for chips on mobile */
281+
.heardChips {
282+
display: grid;
283+
grid-template-columns: repeat(3, 1fr);
284+
gap: 0.25rem;
285+
}
286+
287+
/* Ensure chips don't overflow their grid cells */
288+
.chip {
289+
min-width: 0;
290+
justify-content: center;
291+
}
292+
293+
/* Adjust chip text to be more compact */
294+
.chipId {
295+
font-size: 0.625rem;
296+
}
297+
298+
.chipSnr {
299+
font-size: 0.625rem;
300+
}
180301
}

0 commit comments

Comments
 (0)