Skip to content

[WIP] Create a Generic "Transit Status" application inside of Tube Status project#4

Draft
CometDog wants to merge 5 commits intoC-D-Lewis:masterfrom
CometDog:cometdog/tube-status/full-poc-generic-tube-status-implementation
Draft

[WIP] Create a Generic "Transit Status" application inside of Tube Status project#4
CometDog wants to merge 5 commits intoC-D-Lewis:masterfrom
CometDog:cometdog/tube-status/full-poc-generic-tube-status-implementation

Conversation

@CometDog
Copy link

[WIP]

Overview

This is going to be the complete POC for this project which includes:

  • Making Tube Status generic in the watch code so it does not have to understand that it is loading data for any specific transit system (TfL in this case)
  • Adding a generic interface to the phone code so that any backend system can conform to a structure that the phone and watch can load with the expected results
    • As a concept, TfL, JR Kanto East, and NYC MTA Subway are included as first examples of how three different systems can conform to the required interface
  • Creating a way to select a transit system to display
    • The first time a user opens the app, it should prompt them to select a transit system
    • The select transit system should be stored on the watch persistently so it does not need to prompt again on future startups
    • There should be a mechanism on the watch itself to change the transit system
  • Creating a mechanism in which Tube Status can continue to be built and function identically to how it does today
  • Creating a mechanism in which "Transit Status" (the working name) can be built, allowing all the functionality of switching transit systems without affecting Tube Status

Data Flow

A primary goal of mine is to impact Tube Status in ways that only benefit the code for it without letting Transit Status muddy the implementation. Generifying the watch code and restructuring the routes in which the data flows should be beneficial to Tube Status on its own, even if Transit Status never came to fruition. Below are two diagrams to show how Tube Status and Transit Status can benefit from the same data flow.

image ---------- image

You can see between these two sequences, the only different is that Transit Status has a process to allow the user to select a Transit System, whereas Tube Status will always just request TfL. The data flow is identical from that point onwards.

TODO:

  • Store the selected transit system persistently on the watch
  • Decide on and implement a mechanism for showing the the transit selection screen again
  • Clean up the initial loading screen that appears before the transit selection is shown. It is so fast it feels like a jitter
  • Split the new build process out to its own script

Build

Build Tube Status with:
pebble build (this is the default behavior of build

Build Transit Status with:
pebble build -- --variant=transit_status (will reset the local state back to Tube Status after build is complete)

The build process works entirely inside of the wscript, though it should probably be split out into its own script (in the TODOs). The package-tube_status.json file only overrides values from package.json during build time. Overrides are also at the top level, so you can't append things like MessageKeys, you'd have to duplicate the entire list from package.json if you want to do that.

Internally in the build process, the transit status JSON is merged with the default, npm install is run, and the build proceeds. After the process finishes, it puts the original package.json back and runs npm install again to put it back into the Tube Status configuration.

@CometDog CometDog changed the title Cometdog/tube status/full poc generic tube status implementation [WIP] Create a Generic "Transit Status" application inside of Tube Status project Jan 17, 2026
Comment on lines +23 to +32
DictionaryIterator *out_iter;
AppMessageResult result = app_message_outbox_begin(&out_iter);
if (result == APP_MSG_OK) {
dict_write_int8(out_iter, MESSAGE_KEY_RequestAvailableTransitSystems, 1);
app_message_outbox_send();
APP_LOG(APP_LOG_LEVEL_DEBUG, "Requested available transit systems");
} else {
APP_LOG(APP_LOG_LEVEL_ERROR, "Failed to begin outbox: %d", result);
}
return;
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could probably move this simple app messaging to its own function instead of re-writing it in a few different spots. I just didn't think to do that until right now

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can also use pebble-packet for a simpler AppMessage experience

Comment on lines +129 to +140
console.log(`Sending configs for ${neededConfigs.length} lines with issues (out of ${allConfigs.length} total)`);
await sendLineConfigs(neededConfigs);
} else {
console.log('No issues detected, skipping line configurations');
}

try {
const lines = await fetchLinesWithIssues();
await sendNextLine(lines, 0);
} catch (e) {
console.log('Failed to send data');
console.log(e);
// Send status updates
await sendLineStatuses(lines);
} catch (e) {
console.log('Failed to send data');
console.log(e);
}
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mentioned that we probably don't need to split the config and status pushes to the watch, so I'll look at re-combining the config and status logic into one batch of data

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This piece is still under the WIP commit. I just extracted your Line Status window and removed what wasn't needed to get it going. It's a bit visually uninteresting but is probably rarely seen in regular usage anyway. Once some sort of UI is decided on I should probably see how the line status window and this one overlap and try to DRY it up, if it's even worth doing so.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will Transit Status have a significant departure from the current line list window UI? Curious

Copy link
Author

@CometDog CometDog Jan 19, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will not. I intend for everything to look identical to Tube Status today. The only change would be the addition of a transit system selection window, which should mirror the style of the line status window. (This is why I'm considering making the line status draw functions more abstract so they can be reused across both screens)

Right now in the top text it says the region (London, UK; Kanto, Japan) and the bottom text says the system (TfL; JR East). It only lacks the left aligned icon, which is probably not necessary to include.

I'll update the PR with screenshots when I get the line selection persistence complete. That's all that is functionally left here.

@CometDog
Copy link
Author

@C-D-Lewis do you think you have an opinion on the action a user should take to be able to select a new transit system in the app?

That's the last piece I'm struggling with because additional click actions on the MenuLayer cause the single click actions to perform poorly and I don't know if I like using tap actions for this.

Maybe if the user presses up from the line status window's top menu cell, it pushes the window from the top, sort of like timeline on the watch face screen (or from the bottom)

@C-D-Lewis
Copy link
Owner

@C-D-Lewis do you think you have an opinion on the action a user should take to be able to select a new transit system in the app?

That's the last piece I'm struggling with because additional click actions on the MenuLayer cause the single click actions to perform poorly and I don't know if I like using tap actions for this.

Maybe if the user presses up from the line status window's top menu cell, it pushes the window from the top, sort of like timeline on the watch face screen (or from the bottom)

I used to have a menu for settings in the app way back when timeline was still supported - if you download my app News Headlines and press UP from the headline list, I think bringing back this interaction style in a similar manner will work nicely.

@CometDog
Copy link
Author

This is a good idea but to note as I work on it, this implementation means that I have to override the press handlers on the MenuLayer because you can't register click handlers AND utilize the internal MenuLayerCallbacks for up/down press. Re-implementing that behavior is extremely trivial though.

@CometDog
Copy link
Author

I've failed you because I've mentally been unable to return to this change when it's in the final stretch. I don't mind closing this out and re-opening later when I have that last piece complete.

I also don't mind my GitHub inbox nagging me to finish this PR. Either way you'd want to go.

@C-D-Lewis
Copy link
Owner

Don't fret! It's a large project. I think there's great potential so if you want to work on it at your own pace, then please do!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants