DRDifferent Requests
The screens

The screens

Every screen in the SDK, and the code that shows it.

DifferentRequestsView is a tab bar, and each tab brings its own NavigationStack. Present it in a sheet and don't wrap it in a stack. Every other screen takes the same hub, inside a NavigationStack your app owns.

ScreenWhat a user does with it
DifferentRequestsView(hub:)Every screen as tabs: Requests and Inbox, plus Roadmap and What's New on Pro, with search.
RequestDetailView(hub:requestID:)One request, its thread, its vote and its follow. Open it straight from a push notification.
RoadmapView(hub:)Planned, in progress and shipped, one section each. Pass isShowingRequests: and, when empty, it offers See requests.
ChangelogView(hub:)What shipped, newest first. Pass isShowingRequests: and, when empty, it offers See requests.
InboxView(hub:)Status changes, replies and merges on what they follow.
SubmitRequestView(hub:)The new request form, pushed onto your stack. Call hub.beginSubmission() before you push it.
VoteControl(voteCount:voted:isWriting:toggle:)The vote button for your own rows. isWriting turns the button off while a vote is saving.
StatusBadge(state:)A request's status as a symbol and a word, for your own rows.

What every screen already handles

Each screen already shows its own loading, error, empty and full states. If the server returns an error for a vote, a follow, a comment or a notification marked read, the screen shows it next to the control that was tapped. Nothing fails quietly, and you do not write any of it.

Hide what this app does not include

The Roadmap and What's New screens are Pro. DifferentRequestsView already leaves their tabs out on a Free app. If you build your own tabs, build them from what the app config says.

let config = try await requests.client.config().config

if config.roadmapEnabled {
  Tab("Roadmap", systemImage: "map") {
    NavigationStack {
      RoadmapView(hub: requests)
    }
  }
}
Sign in to see which of these your app has.