Skip to content

Add home screen widget (#1075)#1538

Open
robertgodfrey wants to merge 1 commit into
OneBusAway:mainfrom
robertgodfrey:stop-widget
Open

Add home screen widget (#1075)#1538
robertgodfrey wants to merge 1 commit into
OneBusAway:mainfrom
robertgodfrey:stop-widget

Conversation

@robertgodfrey

@robertgodfrey robertgodfrey commented Mar 20, 2026

Copy link
Copy Markdown
Contributor

Resolves #698 and #1075: Adds a home screen widget that shows arrival information. I've been wanting a widget with this functionality forever! 😁

Design decisions open for discussion

  • Widgets are per-stop, rather than like in the iOS version where there is one widget that displays the "today view"
  • Widgets can display a maximum of three routes
  • All selected routes will always be displayed on a widget - if there are no upcoming ETAs, the route will display N/A instead of a time
  • ETAs older than -2 minutes are hidden so the widget won't be filled with buses that have already deparated
  • ETAs refresh every five minutes via API call, or immediately when the user taps the refresh icon
  • Relative time labels ("5 min" → "4 min") update every minute without additional API calls

Notes

  • Widgets have an adaptive layout that shows/hides ETA columns and rows as the widget is resized
  • Tapping the widget opens the arrivals list for the configured stop
  • I tested on two physical devices, one running Android 16 and one running Android 8

Android 8 relaunches the config screen after the widget is placed via requestPinAppWidget. I initially wanted to close this silently, but I couldn't find a reliable way to distinguish between the initial relaunch and a user-initiated edit (available Android 12+). The current behavior on Android 8 shows the config screen pre-filled and the user taps Save or Back to dismiss it.

Main Files

StopTimesWidget: AppWidgetProvider managing widget lifecycle, alarm scheduling, and RemoteViews rendering
WidgetArrivalWorker: WorkManager worker that fetches arrivals from the OBA API
StopTimesWidgetConfigActivity: dialog configuration screen
StopPickerActivity: stop selection screen showing starred and recent stops from the local database
WidgetPrefs, WidgetConfig, WidgetArrivalSnapshot: persistence layer using SharedPreferences + Gson

Screenshots

Screenshot 2026-03-19 at 10 25 25 PM

Videos (too big to attach here and I don't feel like editing them, so they're in a CloudFlare bucket):

  • Apply the AndroidStyle.xml style template to your code in Android Studio.

  • Run the unit tests with gradlew connectedObaGoogleDebugAndroidTest to make sure you didn't break anything

  • If you have multiple commits please combine them into one commit by squashing them for the initial submission of the pull request. When addressing comments on a pull request, please push a new commit per comment when possible (reviewers will squash and merge using GitHub merge tool)

Summary by CodeRabbit

  • New Features
    • New "Stop Times" home-screen widget with live ETA badges, relative-time ticks, automatic refresh, loading/empty states, resize support and preview
    • In-app configuration flow: pick a stop, choose 1–3 routes, name the widget, pin or edit instances
    • Adds "Add widget" action to stop screens to start the configuration flow
    • New widget visuals, styles and icons for themed badges and previews

Review Change Stack

@aaronbrethorst

Copy link
Copy Markdown
Member

Neat, thanks @robertgodfrey!

@aaronbrethorst

Copy link
Copy Markdown
Member

@robertgodfrey it looks like CI is failing because you need to add the new resources to our example white label apps (Agency X and Agency Y) as well. Let me know if you have questions: https://opentransitsoftwarefoundation.org/join-our-slack

@robertgodfrey

robertgodfrey commented Mar 20, 2026

Copy link
Copy Markdown
Contributor Author

Ah! Okay got it, I'll get the tests working tomorrow

Edit - looks like that last change I pushed did it

@coderabbitai

coderabbitai Bot commented May 9, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 4a6fa636-1502-4e82-b812-ff8e54ee2c43

📥 Commits

Reviewing files that changed from the base of the PR and between d5dae28 and 08d98f5.

📒 Files selected for processing (31)
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
✅ Files skipped from review due to trivial changes (14)
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/values/strings.xml
🚧 Files skipped from review as they are similar to previous changes (17)
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java

📝 Walkthrough

Walkthrough

Adds a Stop Times home-screen widget with configuration and stop picker UIs, background worker + caching, an AppWidgetProvider that schedules refreshes and renders cached arrivals, and required layouts, drawables, strings, styles, and manifest entries.

Changes

Stop Times Widget Implementation

Layer / File(s) Summary
Widget Configuration Data Models
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java, .../WidgetArrivalSnapshot.java, .../WidgetPrefs.java
WidgetConfig stores immutable stop/widget identity and optional route filters. WidgetArrivalSnapshot caches API arrival data with fetched timestamp and per-route arrivals. WidgetPrefs serializes both to SharedPreferences with Gson and supports pending pin config storage.
Background Arrival Worker
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
WorkManager Worker fetches OBA arrivals with an expanding look-ahead window (start 65 min, +60 min attempts), groups by configured routes, caps arrivals per route, builds WidgetArrivalSnapshot, saves it, and triggers widget refresh.
App Widget Provider and Lifecycle
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
AppWidgetProvider manages per-widget config, alarm scheduling (per-minute relative labels, per-5-minute data refresh), handles refresh/relative-time/pin-apply actions, enqueues worker refreshes, and binds RemoteViews from cached snapshots with size-aware visibility.
Widget Configuration Activity
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
Configuration screen starts StopPickerActivity, receives selected stop, loads routes async (generation counter to ignore stale results), renders route chips, validates 1–3 routes, persists config or requests pinning with pending config and optional RemoteViews preview.
Stop Picker Activity
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
Loads starred and recent stops via two CursorLoaders, presents a sectioned ListView adapter with headers/empty rows and favorite indicators; tapping a stop returns EXTRA_STOP_ID / EXTRA_STOP_NAME.
Integration with Arrivals UI
onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
Adds add_stop_widget menu action that launches StopTimesWidgetConfigActivity pre-filled with current stop id/name.
Manifest Declarations
onebusaway-android/src/main/AndroidManifest.xml
Adds uses-permission android:name="android.permission.USE_EXACT_ALARM" (minSdkVersion=33), registers StopTimesWidgetConfigActivity (exported, themed), StopPickerActivity (non-exported), and StopTimesWidget receiver (non-exported) with widget metadata.
Widget Layout and Preview
onebusaway-android/src/main/res/layout/stop_times_widget.xml, stop_times_widget_preview.xml, stop_times_widget_config.xml
Widget layout: header (stop name + refresh), three route rows with up to three ETA pills each, loading spinner, footer updated-at label. Config layout: stop selector, widget name input, route chip group, save button. Preview layout for pinning.
Stop Picker Layout
onebusaway-android/src/main/res/layout/activity_stop_picker.xml, list_item_empty_section.xml
Stop picker layout with full-screen ListView and empty-section item used by the adapter.
Widget Styling Resources
onebusaway-android/src/main/res/drawable*/widget_*.xml, .../values/colors.xml, values/styles.xml, values/themes.xml
Drawables for widget background/header and ETA pill states (scheduled/early/on-time/late), vector icons, colors for widget UI, Widget.Onebusawayandroid.AppWidget.Container and WidgetConfigDialogTheme, and theme attrs for widget container radii/padding.
Attribute, String, and Menu Resources
onebusaway-android/src/main/res/values/attrs.xml, values/strings.xml, menu*/arrivals_list.xml
Adds AppWidgetAttrs (dimensions), widget strings (labels, prompts, status, preview), and add_stop_widget menu item in arrivals list.
Widget Provider Configuration
onebusaway-android/src/main/res/xml/stop_times_widget_info.xml, .../xml-v31/stop_times_widget_info.xml
AppWidgetProvider metadata: minWidth/minHeight, updatePeriodMillis=0, initial/preview layouts, resizeMode horizontal

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.66% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Add home screen widget (#1075)' directly and clearly summarizes the main change—implementing a home screen widget feature for the OneBusAway app.
Linked Issues check ✅ Passed All changes comprehensively implement the objectives from #698: widget displays arrival information for configured stops/routes, supports route selection (up to 3), shows relative times updating without API calls, refreshes data every 5 minutes via API, and provides home screen widget functionality as requested.
Out of Scope Changes check ✅ Passed All modifications are within scope: new widget classes (StopTimesWidget, StopTimesWidgetConfigActivity, StopPickerActivity), supporting services (WidgetArrivalWorker, WidgetPrefs, WidgetConfig, WidgetArrivalSnapshot), layout/drawable resources for widget UI, string resources, menu integration to launch widget config, and manifest declarations—all directly supporting the widget feature.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Tip

💬 Introducing Slack Agent: The best way for teams to turn conversations into code.

Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.

  • Generate code and open pull requests
  • Plan features and break down work
  • Investigate incidents and troubleshoot customer tickets together
  • Automate recurring tasks and respond to alerts with triggers
  • Summarize progress and report instantly

Built for teams:

  • Shared memory across your entire org—no repeating context
  • Per-thread sandboxes to safely plan and execute work
  • Governance built-in—scoped access, auditability, and budget controls

One agent for your entire SDLC. Right inside Slack.

👉 Get started


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 9

🧹 Nitpick comments (1)
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java (1)

33-38: ⚡ Quick win

Consider adding validation and defensive copying.

For defensive coding and true immutability:

  1. Validate that required fields (stopId, stopName, widgetName) are non-null
  2. Make a defensive copy of routeShortNames to prevent external mutation
🛡️ Suggested improvements
 public WidgetConfig(String stopId, String stopName, String widgetName, Map<String, String> routeShortNames) {
+    if (stopId == null || stopName == null || widgetName == null) {
+        throw new IllegalArgumentException("stopId, stopName, and widgetName must not be null");
+    }
     this.stopId = stopId;
     this.stopName = stopName;
     this.widgetName = widgetName;
-    this.routeShortNames = routeShortNames;
+    this.routeShortNames = routeShortNames != null ? new HashMap<>(routeShortNames) : null;
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java`
around lines 33 - 38, The WidgetConfig constructor currently assigns parameters
directly; add null checks for stopId, stopName, and widgetName (throw
IllegalArgumentException or Objects.requireNonNull) and defensively copy
routeShortNames (e.g., new HashMap<>(routeShortNames) or Collections.emptyMap()
when null) before assigning to this.routeShortNames to prevent external mutation
and ensure required fields are present; update the WidgetConfig(String stopId,
String stopName, String widgetName, Map<String,String> routeShortNames)
constructor accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java`:
- Around line 247-260: The PendingIntent request codes for widget button clicks
(bindRefreshIntent) and scheduled alarms (scheduleExactAlarm) collide because
both use appWidgetId-derived integers; modify both bindRefreshIntent and the
alarm-scheduling methods (e.g., scheduleExactAlarm and any callers that create
ACTION_REFRESH_WIDGET or ACTION_UPDATE_RELATIVE_TIMES PIs) to use a single,
shared request-code generator function (or consistent offset scheme) that
encodes both the widget id and the PI-purpose (click vs alarm) into the
requestCode (for example combine appWidgetId with a small constant tag or
bitmask) so each PendingIntent.getBroadcast call (for ACTION_REFRESH_WIDGET and
ACTION_UPDATE_RELATIVE_TIMES) produces a unique requestCode per purpose per
widget, and update all four places that create these broadcast PIs to use that
generator.
- Around line 317-337: scheduleExactAlarm currently always uses
ELAPSED_REALTIME_WAKEUP which unnecessarily wakes the device for the per-minute
relative-times UI update; modify the call sites (the
ACTION_UPDATE_RELATIVE_TIMES per-minute chain vs the 5-minute API refresh) or
change scheduleExactAlarm signature to accept a boolean/useWakeup flag so that
when scheduling ACTION_UPDATE_RELATIVE_TIMES you use
AlarmManager.ELAPSED_REALTIME (non-wakeup) instead of ELAPSED_REALTIME_WAKEUP,
keeping the wakeup behavior for the 5-minute refresh; update the logic in
scheduleExactAlarm to choose the alarm type based on that flag and retain the
existing PendingIntent creation and trigger time calculation.
- Around line 105-126: When handling ACTION_APPLY_PENDING_CONFIG, check that
widgetId is not AppWidgetManager.INVALID_APPWIDGET_ID before persisting or
scheduling: if widgetId equals INVALID_APPWIDGET_ID, return early and do not
call WidgetPrefs.saveConfig(context, widgetId, config),
scheduleRepeatingRefreshBroadcasts(context, widgetId) or refreshWidget; perform
this guard at the start of the ACTION_APPLY_PENDING_CONFIG branch in
StopTimesWidget so bogus IDs never corrupt prefs or register alarms.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`:
- Around line 173-187: The click listener on selectStopButton always launches
StopPickerActivity even when a stop is selected; change it so if selectedStopId
is null it launches mStopPickerLauncher as before, but if selectedStopId is
non-null it clears the selection (set selectedStopId and selectedStopName to
null or empty), reset the UI by calling updateStopButton() and
updateSaveButton(), and clear any loaded routes (e.g., call
loadRoutesForStop(null) or remove displayed routes) so the chip X behaves as a
remove affordance rather than re-opening the picker. Ensure this logic lives
where selectStopButton.setOnClickListener(...) is set so updateStopButton() and
onSave() continue to work correctly.
- Around line 199-219: The generation check currently runs on the background
thread before enqueuing the UI update, allowing a race where a newer generation
can be set after the check but before mainHandler.post executes; move or repeat
the check inside the Runnable posted to mainHandler so you only call
populateRouteChips(routes) when mLoadGeneration.get() == generation (i.e., keep
the existing generation local variable and perform the comparison inside the
lambda passed to mainHandler.post) and remove or keep the bg-thread check as a
fast-fail but ensure the atomic check-and-update happens in the Runnable that
calls populateRouteChips.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java`:
- Around line 93-126: fetchArrivals currently treats zero-length arrival arrays
as a fetch failure and keeps expanding the look‑ahead, which causes doWork to
always retry and never persist an empty snapshot; change fetchArrivals (and its
usage in doWork) so that ObaArrivalInfoResponse is returned as soon as response
!= null and response.getArrivalInfo() != null (even if length == 0), only
retry/expand when response == null or response.getArrivalInfo() == null, and let
doWork proceed to buildSnapshot, WidgetPrefs.saveSnapshot and return
Result.success() for honest empty results so the widget can persist an empty
snapshot instead of looping retries.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java`:
- Around line 43-44: The single global PENDING_CONFIG_KEY in WidgetPrefs can be
clobbered by concurrent pin flows; change the persistence to use a per-request
identifier (e.g., a generated requestId) propagated through the pin flow
(callback Intent extras) and use that id to compose the prefs key instead of the
constant "pending_pin_config"; update all read/write sites referenced in
WidgetPrefs (including the logic around the methods/blocks covering lines
~79-96) to accept/require the requestId, persist/load using the request-specific
key, and read the same requestId from the incoming callback extras so multiple
in-flight flows do not collide.

In `@onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml`:
- Around line 34-36: The layout uses android:paddingHorizontal and
android:paddingVertical (in stop_times_widget_preview.xml) which require API 26;
replace each paddingHorizontal with android:paddingLeft and
android:paddingRight, and each paddingVertical with android:paddingTop and
android:paddingBottom for API-21 compatibility, updating all occurrences
referenced (originally at lines 34, 36, 65, 80, 81, 99) so the layout no longer
uses API-26-only attributes.

In `@onebusaway-android/src/main/res/xml/stop_times_widget_info.xml`:
- Around line 19-20: The previewImage attribute is pointing to a layout
(android:previewImage="@layout/stop_times_widget") which is invalid; update the
widget info by changing android:previewImage to reference a drawable (e.g.,
android:previewImage="@drawable/your_preview_drawable") or, if you need a layout
preview on Android 12+, replace/add
android:previewLayout="@layout/stop_times_widget" instead—adjust the resource
name (stop_times_widget) accordingly and ensure the drawable resource exists.

---

Nitpick comments:
In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java`:
- Around line 33-38: The WidgetConfig constructor currently assigns parameters
directly; add null checks for stopId, stopName, and widgetName (throw
IllegalArgumentException or Objects.requireNonNull) and defensively copy
routeShortNames (e.g., new HashMap<>(routeShortNames) or Collections.emptyMap()
when null) before assigning to this.routeShortNames to prevent external mutation
and ensure required fields are present; update the WidgetConfig(String stopId,
String stopName, String widgetName, Map<String,String> routeShortNames)
constructor accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e2354634-cf09-46b2-ac88-e5c563b86711

📥 Commits

Reviewing files that changed from the base of the PR and between e65872a and acb5bc2.

📒 Files selected for processing (30)
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml

Comment on lines +173 to +187
selectStopButton.setOnClickListener(v ->
mStopPickerLauncher.launch(new Intent(this, StopPickerActivity.class)));

if (selectedStopId != null) {
loadRoutesForStop(selectedStopId);
}

updateSaveButton();
saveButton.setOnClickListener(v -> onSave());
}

private void updateStopButton() {
selectStopButton.setText(selectedStopName);
selectStopButton.setIconResource(R.drawable.ic_close);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

"X" icon on the stop button is a remove affordance, but clicking it re-launches the picker.

After a stop is selected, updateStopButton sets ic_close on the chip-style button (the PR description and screenshot describe this as the remove option). However the click listener installed at line 173 always launches StopPickerActivity, regardless of whether a stop is already selected. Users who tap the visible X to clear their selection will instead be sent back into the picker — and there is no way to deselect the stop from this screen. Either change the click behavior when a stop is already selected to clear selectedStopId/selectedStopName, the chips, and the save button, or replace ic_close with a "change/edit" affordance.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`
around lines 173 - 187, The click listener on selectStopButton always launches
StopPickerActivity even when a stop is selected; change it so if selectedStopId
is null it launches mStopPickerLauncher as before, but if selectedStopId is
non-null it clears the selection (set selectedStopId and selectedStopName to
null or empty), reset the UI by calling updateStopButton() and
updateSaveButton(), and clear any loaded routes (e.g., call
loadRoutesForStop(null) or remove displayed routes) so the chip X behaves as a
remove affordance rather than re-opening the picker. Ensure this logic lives
where selectStopButton.setOnClickListener(...) is set so updateStopButton() and
onSave() continue to work correctly.

Comment on lines +43 to +44
private static final String PENDING_CONFIG_KEY = "pending_pin_config";

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Single pending-pin slot can misapply config across concurrent widget adds.

Using one global pending_pin_config key means a second pin flow overwrites the first before it is consumed, so the wrong config can be attached to a widget.

Suggested direction
- private static final String PENDING_CONFIG_KEY = "pending_pin_config";
+ // Use a per-request key (or queue) instead of a single global slot.
+ private static final String PENDING_CONFIG_PREFIX = "pending_pin_config_";

Use a request identifier propagated through the pin flow (e.g., in callback extras) and persist/load by that key so multiple in-flight flows do not collide.

Also applies to: 79-96

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java`
around lines 43 - 44, The single global PENDING_CONFIG_KEY in WidgetPrefs can be
clobbered by concurrent pin flows; change the persistence to use a per-request
identifier (e.g., a generated requestId) propagated through the pin flow
(callback Intent extras) and use that id to compose the prefs key instead of the
constant "pending_pin_config"; update all read/write sites referenced in
WidgetPrefs (including the logic around the methods/blocks covering lines
~79-96) to accept/require the requestId, persist/load using the request-specific
key, and read the same requestId from the incoming callback extras so multiple
in-flight flows do not collide.

Comment thread onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml Outdated
Comment thread onebusaway-android/src/main/res/xml/stop_times_widget_info.xml Outdated
@robertgodfrey

robertgodfrey commented May 9, 2026

Copy link
Copy Markdown
Contributor Author

Oh nice, we have coderabbit now. I'll address these comments

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java`:
- Around line 101-102: The call to buildSnapshot(...) passes
config.getRouteShortNameMap() without null/empty checks which can throw if
preferences are malformed; before calling buildSnapshot (where
WidgetArrivalSnapshot is created), retrieve the map into a local variable, test
for null or empty and substitute Collections.emptyMap() or new HashMap<>() when
missing, then pass that safe map into buildSnapshot; apply the same guard to
every other call site that passes config.getRouteShortNameMap() to ensure
graceful recovery.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f48c8db5-2b8f-4bb6-9064-de09f32470e6

📥 Commits

Reviewing files that changed from the base of the PR and between acb5bc2 and 5adb57f.

📒 Files selected for processing (31)
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
✅ Files skipped from review due to trivial changes (15)
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/res/values/colors.xml
🚧 Files skipped from review as they are similar to previous changes (15)
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java (1)

249-268: ⚡ Quick win

Enforce the 3-route cap while chips are being toggled.

Right now the UI allows an invalid 4+ route selection and only rejects it later in onSave(). Disabling additional unchecked chips once 3 are selected would keep the screen consistent with the “Select 1–3 routes” contract and avoid a failed save round-trip.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`
around lines 249 - 268, The chip UI currently lets users select 4+ routes;
enforce the 1–3 limit by adding a CompoundButton.OnCheckedChangeListener to each
Chip (in StopTimesWidgetConfigActivity where chips are created/added to
chipGroup) that recalculates the number of checked chips (using chip.isChecked()
over chipGroup children or a selectedCount) and when the count reaches 3
disables all unchecked chips (chip.setEnabled(false) / setClickable(false)) and
when the count falls below 3 re-enables them; ensure you also apply this logic
once after creating chips (so existingRouteFilter initial state disables extras)
and leave onSave() validation intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`:
- Around line 202-214: The code currently builds the selectable routes from
response.getArrivalInfo() (ObaArrivalInfoRequest) which excludes routes that
serve the stop but have no upcoming arrivals; instead, fetch the full list of
routes that serve the stop (e.g., via response.getStop().getRoutes() if
available or by issuing an ObaStop/StopWithRoutes request for stopId), iterate
that list to construct Route objects (using the route id and any available
shortName), and merge/override shortName values from response.getArrivalInfo()
when present to preserve nicer labels; keep the seen dedupe set and sort by
compareRouteNames as before (update the code around the Route construction in
StopTimesWidgetConfigActivity to use the stop’s route list rather than only
response.getArrivalInfo()).
- Around line 254-264: The code currently disables the Chip minimum touch target
via chip.ensureAccessibleTouchTarget(0) in StopTimesWidgetConfigActivity, which
reduces accessibility; remove that call or replace it with a proper minimum
touch-target call such as chip.setEnsureMinTouchTargetSize(true) or call
ensureAccessibleTouchTarget(...) with a converted 48dp-to-px value so the Chip
meets the 48dp accessibility guideline; update the code around the chip
configuration (the block that sets chip.setChipIcon...,
chip.setChipEndPadding(...), chip.ensureAccessibleTouchTarget(0)) to use one of
those fixes.

---

Nitpick comments:
In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`:
- Around line 249-268: The chip UI currently lets users select 4+ routes;
enforce the 1–3 limit by adding a CompoundButton.OnCheckedChangeListener to each
Chip (in StopTimesWidgetConfigActivity where chips are created/added to
chipGroup) that recalculates the number of checked chips (using chip.isChecked()
over chipGroup children or a selectedCount) and when the count reaches 3
disables all unchecked chips (chip.setEnabled(false) / setClickable(false)) and
when the count falls below 3 re-enables them; ensure you also apply this logic
once after creating chips (so existingRouteFilter initial state disables extras)
and leave onSave() validation intact.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e36fed72-2e48-4b6a-bf6f-3674e37536d8

📥 Commits

Reviewing files that changed from the base of the PR and between 5adb57f and d5dae28.

📒 Files selected for processing (31)
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
✅ Files skipped from review due to trivial changes (16)
  • onebusaway-android/src/main/res/drawable-v21/widget_background.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_scheduled.xml
  • onebusaway-android/src/main/res/layout/list_item_empty_section.xml
  • onebusaway-android/src/main/res/drawable/widget_header_bg.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_early.xml
  • onebusaway-android/src/main/res/xml-v31/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/values/attrs.xml
  • onebusaway-android/src/main/res/drawable/ic_chip_check.xml
  • onebusaway-android/src/main/res/layout/activity_stop_picker.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_on_time.xml
  • onebusaway-android/src/main/res/drawable/widget_eta_bg_late.xml
  • onebusaway-android/src/main/res/drawable/ic_edit.xml
  • onebusaway-android/src/main/res/values/colors.xml
  • onebusaway-android/src/main/res/xml/stop_times_widget_info.xml
  • onebusaway-android/src/main/res/menu-v14/arrivals_list.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_config.xml
🚧 Files skipped from review as they are similar to previous changes (14)
  • onebusaway-android/src/main/res/values/styles.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget_preview.xml
  • onebusaway-android/src/main/res/menu/arrivals_list.xml
  • onebusaway-android/src/main/AndroidManifest.xml
  • onebusaway-android/src/main/res/layout/stop_times_widget.xml
  • onebusaway-android/src/main/res/values/themes.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalSnapshot.java
  • onebusaway-android/src/main/res/values/strings.xml
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/ArrivalsListFragment.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetArrivalWorker.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetConfig.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopPickerActivity.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/WidgetPrefs.java
  • onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidget.java

Comment on lines +202 to +214
final ObaArrivalInfoResponse response =
ObaArrivalInfoRequest.newRequest(this, stopId, MAX_MINUTES_AFTER).call();

final List<Route> routes = new ArrayList<>();
final Set<String> seen = new HashSet<>();
if (response != null && response.getArrivalInfo() != null) {
for (ObaArrivalInfo info : response.getArrivalInfo()) {
if (seen.add(info.getRouteId())) {
routes.add(new Route(info.getRouteId(), info.getShortName()));
}
}
}
Collections.sort(routes, (a, b) -> compareRouteNames(a.shortName, b.shortName));

@coderabbitai coderabbitai Bot May 10, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Route selection is currently limited to routes that already have arrival rows.

This list is built only from response.getArrivalInfo(), so any route that serves the stop but has no trips in the next 24 hours never becomes selectable here. That conflicts with the widget behavior of showing configured routes as N/A, and it blocks valid configurations for late-night / infrequent service.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@onebusaway-android/src/main/java/org/onebusaway/android/ui/widget/StopTimesWidgetConfigActivity.java`
around lines 202 - 214, The code currently builds the selectable routes from
response.getArrivalInfo() (ObaArrivalInfoRequest) which excludes routes that
serve the stop but have no upcoming arrivals; instead, fetch the full list of
routes that serve the stop (e.g., via response.getStop().getRoutes() if
available or by issuing an ObaStop/StopWithRoutes request for stopId), iterate
that list to construct Route objects (using the route id and any available
shortName), and merge/override shortName values from response.getArrivalInfo()
when present to preserve nicer labels; keep the seen dedupe set and sort by
compareRouteNames as before (update the code around the Route construction in
StopTimesWidgetConfigActivity to use the stop’s route list rather than only
response.getArrivalInfo()).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I don't think this is a real issue

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@robertgodfrey Fair point. With MAX_MINUTES_AFTER = 1440 (24 hours), virtually every route that serves a stop will have at least one trip in that window, so the limitation I described is an extremely marginal edge case in practice. I'll accept your judgment here.

@aaronbrethorst

Copy link
Copy Markdown
Member

@robertgodfrey I haven't forgotten about you! I'm just a one person show on Android and several other projects right now 🙃

@robertgodfrey

Copy link
Copy Markdown
Contributor Author

No worries! I know it's a pretty big PR 😄

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.

Add home screen widget that shows arrival information

2 participants