Skip to content

fix(navigation): restore meeting edit and unify home actions [WPB-27923] - #5233

Merged
MohamadJaara merged 2 commits into
developfrom
kubaz/fix/nav3-home-actions
Aug 28, 2026
Merged

fix(navigation): restore meeting edit and unify home actions [WPB-27923]#5233
MohamadJaara merged 2 commits into
developfrom
kubaz/fix/nav3-home-actions

Conversation

@Garzas

@Garzas Garzas commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

https://wearezeta.atlassian.net/browse/WPB-27923


PR Submission Checklist for internal contributors

  • The PR Title

    • conforms to the style of semantic commits messages¹ supported in Wire's Github Workflow²
    • contains a reference JIRA issue number like SQPIT-764
    • answers the question: If merged, this PR will: ... ³
  • The PR Description

    • is free of optional paragraphs and you have filled the relevant parts to the best of your ability

What's new in this PR?

Issues

  • Editing an existing meeting no longer opened the edit flow after the Navigation 3 migration.
  • Home top-level navigation actions had inconsistent ownership:
    • meeting creation was exposed as a flat Home function,
    • Cells and Settings had dedicated contracts,
    • Conversations used a separate contract outside HomeTopLevelNavigation3Actions.
  • The Navigation3 suffix did not communicate whether a contract was reusable UI API or directly coupled to the Navigation 3 runtime.

Causes

The Navigation 3 migration removed the previous editMeeting callback mapping from the Meetings Home screen.

At the same time, top-level navigation contracts were migrated incrementally. This left Home with multiple ways of exposing child navigation and no documented naming rule.

Solutions

This PR restores meeting editing by mapping the selected meeting to:

NewMeetingType.Edit(meetingId)

The same meetingId is then passed to the typed NewMeetingDetailsRoute.

It also makes HomeTopLevelNavigation3Actions the single composition point for every interactive Home root:

flowchart TD
    HomeNavigation3Actions --> HomeTopLevelNavigation3Actions
    HomeTopLevelNavigation3Actions --> ConversationListNavigationActions
    HomeTopLevelNavigation3Actions --> SettingsNavigation3Actions
    HomeTopLevelNavigation3Actions --> AllFilesNavigationActions
    HomeTopLevelNavigation3Actions --> WhatsNewNavigationActions
    HomeTopLevelNavigation3Actions --> MeetingsHomeNavigationActions
Loading

Feature-specific functions are no longer flattened into the Home contract.

Main Conversations and Archive reuse the same decorated conversation-list action bundle, including Navigation 3 result handling.

Naming rule

The Navigation3 suffix describes technical coupling, not migration status.

Contract Responsibility
ConversationListNavigationActions Reusable, navigation-neutral conversation-list actions
ConversationEntryNavigation3Actions Actions coupled to the Navigation 3 conversation entry and result lifecycle
MeetingsHomeNavigationActions Starts a meeting flow from the Home root
MeetingsNavigation3Actions Actions performed inside Navigation 3 meeting-flow entries
AllFilesNavigationActions Reusable Cells UI actions
SettingsNavigation3Actions Actions coupled to typed Settings Navigation 3 destinations

This naming rule is documented in ADR 0014 so future migrations follow the same structure.

The new Home-root action bundles are data classes to preserve Compose parameter stability.

@Garzas
Garzas requested review from saleniuk and sbakhtiarov August 28, 2026 11:06
@Garzas Garzas self-assigned this Aug 28, 2026
@AndroidBob

Copy link
Copy Markdown
Collaborator

New ADR(s) in this PR 📚:

14. Migrate to Navigation 3 with KMP-ready navigation contracts

Date: 2026-08-10

Status

Proposed

Context

Wire currently uses Compose Destinations on top of Navigation Compose 2. Generated destinations,
route strings and NavBackStackEntry lookups are used not only for navigation, but also to select
Metro graphs, recover arguments and decide ViewModel ownership. This makes authentication,
multi-account switching, logout, process restoration and tablet presentation difficult to reason
about and has moved navigation recovery logic into WireActivity.

Navigation state, a Metro graph instance and a ViewModel owner have related, but different,
lifecycles. Treating them as one mechanism can recreate a ViewModel against the wrong account or
make an existing screen depend on a temporarily unavailable currentSession.

Compose Destinations is not the desired long-term navigation layer. Navigation 3 gives Wire an
application-owned, typed and saveable back stack, explicit entry decorators and a KMP-compatible
route model.

Decision

We will replace Compose Destinations with Navigation 3 and Wire-owned navigation contracts.

  • Serializable routes and navigation commands live in core:navigation-kmp; concrete routes stay
    with the feature that owns them.
  • Features contribute typed wireEntry providers and expose semantic actions instead of receiving
    generated navigators or NavHostController.
  • The Home shell aggregates one feature-owned semantic action contract for every interactive
    top-level child. Feature-specific actions are not flattened into the Home contract; roots sharing
    an action surface reuse its contract, and roots without navigation actions expose none.
  • A reusable UI action contract is named after its role and omits the framework version, for example
    ConversationListNavigationActions or MeetingsHomeNavigationActions. The Navigation3 suffix
    is reserved for contracts coupled to a Navigation 3 entry, runtime or result lifecycle, for example
    ConversationEntryNavigation3Actions or MeetingsNavigation3Actions. Starting a flow belongs to
    the framework-neutral Home-root contract; actions performed inside its entries belong to the
    Navigation3 contract.
  • Navigation 3 owns back-stack entries and their ViewModelStoreOwner lifecycle.
  • Wire resolves the Metro graph independently from the typed route. A session route always carries
    the session identity from which its dependencies must be resolved.
  • Metro creates graphs and factories, while an application-owned registry controls the identity,
    retention and disposal of graph instances.
  • ViewModels receive route arguments explicitly through assisted factories. SavedStateHandle
    remains for restorable UI state, not as the source of navigation identity.
  • Results, deep links, transitions and phone/tablet presentation use typed Wire policies.
  • WireActivity remains responsible for Android lifecycle and platform entry points; navigation,
    session and intent decisions move to testable coordinators.

For example, route identity, graph selection and ViewModel ownership are separate:

@Serializable
data class ConversationRoute(
    override val sessionId: WireSessionId,
    val conversationId: ConversationId,
    override val entryId: WireNavEntryId = WireNavEntryId.random(),
) : SessionRoute

wireEntry<ConversationRoute> { route ->
    ConversationScreen(
        viewModel = conversationViewModel(route.toViewModelArgs()),
        onBack = actions::back,
    )
}

sessionId selects the retained Metro session graph. Navigation 3 retains the owner identified by
the entry while that entry exists. A temporary currentSession == null therefore does not
reinterpret an existing route, replace its graph or recreate its ViewModel.

The migration will be delivered incrementally: KMP contracts and runtime foundation, ownership
and Metro integration, vertical destination migrations, stabilization, and removal of Compose
Destinations compatibility code.

Consequences

Navigation becomes typed, application-owned and testable. Existing entries keep deterministic
ViewModel owners and Metro graphs during account transitions, and KMP clients can reuse route,
command and reducer contracts.

The migration temporarily increases the amount of adapter and test code. Wire must explicitly
implement and verify session transitions, results, deep links, responsive presentation and process
restoration; Navigation 3 does not provide Wire-specific policy by itself.

The migration is complete only when one production navigation runtime remains, generated
navigation references and dependencies are removed, and unit, screenshot, acceptance,
critical-flow and multi-account tests plus internal playtests are green.

@github-actions

github-actions Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Test Results

2 629 tests  +5   2 629 ✅ +5   1m 21s ⏱️ -1s
  334 suites +1       0 💤 ±0 
  334 files   +1       0 ❌ ±0 

Results for commit c52acd5. ± Comparison against base commit 9371126.

This pull request removes 1 and adds 6 tests. Note that renamed tests count towards both.
com.wire.android.ui.home.HomeTopLevelNavigation3Test ‑ givenWhatsNewItems_whenMapped_thenOnlySemanticNavigation3TargetsCrossTheHomeBoundary()
com.wire.android.feature.meetings.ui.create.MeetingsNavigation3SourceTest ‑ meetings Home root owns a framework neutral action bundle()
com.wire.android.navigation.runtime.WireNavigation3ProductionActionsTest ‑ given conversation list start action, when invoked, then typed new-conversation route is navigated()
com.wire.android.ui.home.HomeTopLevelNavigation3Test ‑ givenHomeShellActions_whenDefiningNavigation_thenChildNavigationIsOnlyExposedThroughTopLevel()
com.wire.android.ui.home.HomeTopLevelNavigation3Test ‑ givenHomeTopLevelActions_whenDefiningChildNavigation_thenEveryChildUsesAnOwnedContract()
com.wire.android.ui.home.HomeTopLevelNavigation3Test ‑ givenWhatsNewItems_whenMapped_thenOnlySemanticTargetsCrossTheHomeBoundary()
com.wire.android.ui.home.meetings.MeetingsScreenSourceTest ‑ editing a meeting opens the typed Navigation 3 edit flow()

♻️ This comment has been updated with latest results.

@github-actions

Copy link
Copy Markdown
Contributor

APKs built during tests are available here. Scroll down to Artifacts!

…e-actions

# Conflicts:
#	app/src/main/kotlin/com/wire/android/ui/home/meetings/MeetingsScreen.kt
@saleniuk saleniuk changed the title fix(navigation): restore meeting edit and unify home actions fix(navigation): restore meeting edit and unify home actions [WPB-27923] Aug 28, 2026
@MohamadJaara
MohamadJaara enabled auto-merge August 28, 2026 12:49
@MohamadJaara
MohamadJaara added this pull request to the merge queue Aug 28, 2026
@github-actions

Copy link
Copy Markdown
Contributor

APKs built during tests are available here. Scroll down to Artifacts!

Merged via the queue into develop with commit acec50e Aug 28, 2026
21 of 23 checks passed
@MohamadJaara
MohamadJaara deleted the kubaz/fix/nav3-home-actions branch August 28, 2026 13:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants