Repository navigation
refactor: rebuild NetworkMock sheet, response detail and sequence workflows - #165
MaxMichel2 wants to merge 2 commits into
Conversation
Save search, filter selections and sort per API group through navigation-owned state. Put sort in the shared filter panel, retain missing selections after reload and provide a clear recovery for empty results. Quiet Network labels and deeper dark status containers keep mocked operations prominent. Validation: 63 NetworkMock host tests, 96 device tests and 15 Konsist tests passed. Detekt, sample debug build and API generation/compatibility passed; public signatures are unchanged. Checked settled light/dark list captures. Refreshed the code graph without dropping unchanged document nodes; clustered reports/wiki remain stale. Native iOS, TalkBack and enlarged fonts were not executed.
…uence Replace the tabbed sheet with quick radio choices and dedicated response and sequence screens. Retain drafts through host recreation, serialize UI writes, and atomically consume sequences across repository instances without real-network fallback for unavailable selected mocks. Validation: Android host tests, 99 NetworkMock and 25 core device tests, Konsist, Detekt Full, sample debug build and Metalava compatibility pass. Dokka and Zensical builds pass separately. Manual response, compare, sequence, failure, Network and Cancel flows checked; 200% font layout exercised. Full spoken TalkBack verification, Apple runtime and final visual sign-off remain pending.
| internal val mutations = sharedMutations ?: NetworkMockMutationCoordinator( | ||
| stateRepository = stateRepository, | ||
| scope = viewModelScope | ||
| ) |
There was a problem hiding this comment.
Public writes stop after failure
A failed write permanently stalls callers of the public NetworkMockViewModel constructor. The new consumer leaves the failed command at the front and blocks later writes, but mutations, retryFailed() and cancelFailed() are internal. Even after storage recovers, another public setter only queues behind the failure. Expose failure state and recovery through the public API, or let these callers recover without internal controls.
| } catch (e: Exception) { | ||
| logger.w( | ||
| throwable = e | ||
| ) { "$method $path -> ERROR (could not load selected mock response)" } | ||
| throw e | ||
| } | ||
| checkNotNull(value = call) { | ||
| "Selected mock response ${mockMatch.key.compositeKey} " + | ||
| "${step.statusCode}/${step.mediaType}/${step.exampleName} is unavailable" | ||
| } |
There was a problem hiding this comment.
Replaced mocks still fail requests
A response-load error escapes before the plugin checks whether that selection is still current. If loading response A suspends, another writer selects a valid response B, and A's load then throws or returns null, the request fails on A instead of retrying with B. Recheck the revision on both load-failure paths. Retry when it changed, and fail without network fallback only when the unavailable selection is still current.
| Column(modifier = Modifier.padding(all = 16.dp)) { | ||
| ErrorState(message = message) | ||
| TextButton( | ||
| enabled = viewModel.mutations.interactionsEnabled, | ||
| onClick = viewModel::reload | ||
| ) { Text(text = "Reload specification") } |
There was a problem hiding this comment.
OperationDetailError puts its reload button after ErrorState, whose root uses fillMaxSize(). On a bounded screen, the error view takes all remaining height and leaves the button below the visible area. The sheet's new Retry loading and Close row has the same problem. Give the error view a bounded or weighted area so the recovery controls remain visible.
| ResponseDetailContent( | ||
| preview = if (second == null) { | ||
| PreviewSheetState.Single( | ||
| response = primary | ||
| ) | ||
| } else { | ||
| PreviewSheetState.Compare(first = primary, second = second) | ||
| }, |
There was a problem hiding this comment.
Comparisons repeat during updates
PreviewSheetState.Compare is rebuilt whenever ResponseDetailScreen recomposes. A save changes enabled, and live sequence progress changes currentState, so ResponseDetailContent runs again with a fresh object and repeats its JSON formatting and line comparison. The old sheet retained the object and reused its lazy result. Keep it in remember(primary, second) to avoid repeating up to one million comparison cells on the UI thread.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Summary
Validation
Dependency
Layer baseline and merge target:
fix/timecapsule-restore-target, after #164. Includes the two NetworkMock checkpoint commits only, not inherited layers. Append to existing native GitHub stack #162 after #164. Merge order: #157 → #159 → #160 → #161 → #163 → #164 → this PR. No history rewriting.Fix failed-write recovery for public ViewModel callers and retry errors from replaced mock selections before merging.
Findings
Summary
Rebuilds NetworkMock around a quick-choice sheet, full-screen response details, saved filters, and a sequence editor. Adds retained save recovery and atomic sequence consumption.
Diagram
%%{init: {'theme': 'neutral'}}%% flowchart TD List[Operation list] --> Sheet[Quick-choice sheet] Sheet --> Detail[Response detail] Sheet --> Builder[Sequence builder] Sheet --> Queue[Retained save queue] Detail --> Queue Builder --> Queue Queue --> Store[DataStore state and revision] Queue --> Recovery[Retry or Cancel on failure] Request[Ktor request] --> Snapshot[Read state and prepare response] Snapshot --> Check{Revision still current?} Store --> Check Check -->|No| Snapshot Check -->|Yes| Response[Return mock and advance sequence]Reviews (1) · Last reviewed commit: ":lipstick: Rebuild NetworkMock operation..." · Reviewed by Greptile