Always show map + feed info #42
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
gtfs.zone/coloring-book#42
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Approach
Always initialize an empty feed on app startup (if no existing data), so the invariant "there is always a feed" holds throughout the app lifecycle. This eliminates all conditional "no feed loaded" branches and simplifies state management significantly.
Phase 1: Always initialize empty feed on startup
src/index.ts(~line 217): remove thehasExistingRowsbranch entirelyinitializeEmpty()if no existing rows, then unconditionally callupdateFileList(),updateMap(),browseNavigation.refresh(), and enable the export button — same as thehasExistingRows === truepath'Welcome to edit.gtfs.zone! Create a new GTFS feed...')createNewFeed()insrc/modules/ui.ts(~line 1144) no longer needshideMapOverlay()— remove that callPhase 2: Remove the welcome overlay
#map-overlay<div>fromsrc/index.html(~lines 336–351)showMapOverlay(),hideMapOverlay(), andshowLoading()methods fromsrc/modules/map-controller.ts(~lines 630–660)hideMapOverlay()inui.ts(~lines 265, 350, 1150) and any remaining references inindex.ts// Keep welcome overlay visible initiallycomment block inmap-controller.ts(~lines 117–120)There were more
hideMapOverlay()/showLoading()call sites than the plan listed (also at the error path inloadGTFSFileand inloadGTFSFromURL), all removed.Phase 3: File list — show all files unconditionally
updateFileList()(src/modules/ui.ts~line 409): remove theif (required.length > 0)/if (optional.length > 0)guards — always render required and optional sections (theothersection retains its guard since empty feeds have no "other" files)src/index.html(~lines 454–459) —updateFileList()is now called at startup so it will always be populatedhasFilesdisabled check fromupdateFileList()and theexport-btn.disabled = falsecalls inloadGTFSFile()andloadGTFSFromURL(); it is set enabled once at startup inindex.tsPhase 4: Always show Feed Information block
src/modules/page-content-renderer.ts: changegetFeedInfo()to return{}(empty object) instead ofnullwhen no rows exist — change return type fromRecord<string, unknown> | nulltoRecord<string, unknown>renderHomePage()(~line 287): change${feedInfo ? this.renderFeedInfoProperties(feedInfo) : ''}to${this.renderFeedInfoProperties(feedInfo)}(unconditional)Phase 5: Remove dead "load data first" guards
toggleAddStopMode()(src/modules/ui.ts~line 1285): remove the!this.gtfsParser.getFileDataSync('stops.txt')check and the "Load GTFS data first" warning —stops.txtalways exists after empty inittoggleEditStopsMode()(~line 1337): same removalBug fix: feed_info edits lost on refresh (discovered during testing)
After completing all phases, testing revealed that editing a
feed_infofield (e.g.feed_publisher_name) would show the correct notification and appear in the Changes tab, but the text box would immediately clear, and everything — including the patch — was gone after a page refresh.Root cause: two bugs in
initializeEmpty()insrc/modules/gtfs-parser.ts:Array mismatch:
gtfsData[filename].data = []and the[]passed tosetupVirtualwere two separate array instances.persistDirtyBlobsreadsgtfsData.data, while the virtual table mutates its ownflatarray — so blob saves always saw an empty array and were silently skipped.No initial
feed_inforow: The virtual tableupdatehandler returns early whenbyIdhas no entry for the key. With an emptyfeed_infotable, every field edit was a no-op in memory. On reload, patch replay also silently failed for the same reason — leavinghasExistingRows = falseand causinginitializeEmpty()to callclearDatabase(), destroying the patches.Fix (committed
d313755): share the same array reference betweengtfsData.dataandsetupVirtual; seedfeed_infowith a schema-keyed all-empty-string row; flush the seed blob to IDB immediately (not deferred) so patch replay always has a row to land on even after a quick refresh.Relevant files
src/index.ts— startup initialization (~lines 217–241)src/index.html— welcome overlay (~336–351), file list placeholder (~454–459)src/modules/map-controller.ts— overlay methods (~630–660), init comment (~117–120)src/modules/ui.ts—updateFileList()(~409),loadGTFSFile()(~265),loadGTFSFromURL()(~350),createNewFeed()(~1144),toggleAddStopMode()(~1285),toggleEditStopsMode()(~1337)src/modules/page-content-renderer.ts—getFeedInfo()(~361),renderHomePage()(~287)src/modules/gtfs-parser.ts—initializeEmpty()(~517),persistDirtyBlobs()(~399)Original Issue
Hiding things causes problems, lets keep it simple