Skip to content

SwiftUI: explain enabled-but-unreachable environments in the new-thread picker - #8621

Open
saphid wants to merge 4 commits into
pingdotgg:t3code/rebuild-mobile-app-swiftfrom
saphid:swiftui/pr-131-unreachable-environments
Open

SwiftUI: explain enabled-but-unreachable environments in the new-thread picker#8621
saphid wants to merge 4 commits into
pingdotgg:t3code/rebuild-mobile-app-swiftfrom
saphid:swiftui/pr-131-unreachable-environments

Conversation

@saphid

@saphid saphid commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

What users observed

In the SwiftUI iOS client, the environment picker on the new-thread screen enabled environments it could not actually reach. Picking one looked successful but the new thread then failed (or silently never started) — the picker gave no signal that the environment was enabled-but-unreachable.

Cause

The picker derived its enabled state only from the environment catalog; reachability (whether the environment's connection can actually serve a new thread) was not part of that decision, and no feedback existed for the unreachable case.

What changed

  • Unreachable-but-enabled environments stay visible and explainable: the picker explains why a task can't start there instead of failing later.
  • Recovery is hardened: when an environment becomes reachable again (or the catalog refreshes), the picker re-evaluates and the user can proceed without restarting the screen.
  • Task start paths evaluate the picker's mutations before asserting, so stale selections fail loudly at the picker rather than as a later thread error.

Affected: SwiftUI iOS client only — server, contracts, web/desktop, and React Native are unchanged.

Base: t3code/rebuild-mobile-app-swift at b67837984e5650888b1eed0e1cd7fff83625f696.

UI changes

Before / after (mixed catalog, dark)

After — mixed catalog

Before / after (no project, dark)

After — no project

Interaction video

Play the mixed-catalog interaction video

Light-mode captures and the full set are embedded in the tracking issue.

Intentionally unchanged

  • Reachability semantics themselves (still owned by the environment/connection state the app already renders).
  • Web/desktop picker behavior.

Verification

  • Focused native suite T3CodeTests/DailyUXNewTaskTests (picker behavior, unreachable recovery, mutation evaluation) — run on this re-materialized head, iPhone 16 Pro / iOS 26.5 simulator; 80 test cases passed, 0 failed (xcodebuild exit 0).
  • Full app + test-target build for the simulator succeeded (xcodebuild test, exit 0).
  • git diff --check clean.

Known gaps / honest disclosures

  • This branch is a re-materialization of work originally developed and device-verified against an earlier state of the mobile rebuild stack; the captures above are from that accepted head, not from this exact commit. CI on this PR provides the current-head build/test signal.

Affected: SwiftUI iOS client only.


Note

Low Risk
SwiftUI-only UX and routing changes around environment connection display; no server or auth changes, with behavior locked by focused unit tests.

Overview
The SwiftUI iOS new task flow now explains when enabled environments cannot be reached, instead of silently failing or sending users straight to Add project.

Routing and semantics: DailyUXCreationContext adds helpers that treat only enabled + .disconnected environments as unreachable (.reconnecting stays usable via HTTP fallback). newTaskDestination(in:) opens the new-task screen when there are reachable projects or at least one such unreachable environment; otherwise it still routes to project creation. The workspace compose button uses the same logic and updates its accessibility hint for the three cases (has projects, unreachable-only, neither).

UI: The empty No projects state in NewThreadView is scrollable and can list unreachable environments with warning styling, plus a single-flight Try again that calls model.reload() via NewTaskRetryState. The project picker gains an Unavailable environments section (up to three visible names, full list in accessibility) that still appears when search returns no matches, driven by NewTaskProjectPickerPresentation.

Tests: DailyUXNewTaskTests covers unreachable filtering, routing, retry state, and picker presentation.

Reviewed by Cursor Bugbot for commit 77c3bf8. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Show enabled-but-unreachable environments in the new-thread picker

  • Adds DailyUXCreationDestination enum and DailyUXCreationContext.newTaskDestination to route users to the new-task composer when there are unreachable environments, even with zero projects.
  • Adds NewTaskProjectPickerPresentation and NewTaskRetryState to display up to 3 unreachable environments (with a "+N more" summary) and provide a single-flight retry button in NewThreadView.swift.
  • unreachableEnvironments is defined as enabled environments whose connectionState == .disconnected; other transient states like .reconnecting are excluded.
  • WorkspaceView accessibility hint and routing logic now adapt based on whether projects exist or environments are unreachable.
  • Risk: openNewTaskOrProjectCreation now opens the new-task composer instead of add-project when there are no projects but there are .disconnected enabled environments; verify callers of DailyUXCreationContext.newTaskDestination handle the .addProject fallback.

Macroscope summarized 77c3bf8.

@coderabbitai

coderabbitai Bot commented Aug 29, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2140c4f7-e778-4e84-a3b3-4e31afd55b3d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 29, 2026

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9e6ff8e. Configure here.

Comment thread apps/swift-ios/Features/Workspace/DailyUXModels.swift
@macroscopeapp

macroscopeapp Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This SwiftUI PR changes the default compose routing for no-project workspaces and adds a new unreachable-environment retry workflow across the workspace and project picker. Because it changes existing production behavior and introduces user-facing capability rather than an off-by-default option, human review is warranted.

You can add or adjust custom eligibility rules. Learn more.

Reconnecting is a transient state whose HTTP fallback still serves work,
so announcing those environments as unreachable in the picker, empty
state, and compose hint contradicted the sidebar and connection hub,
which present reconnecting separately from offline. Only disconnected
environments are unreachable now.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant