Commit 18046b0
Improve error handling in RS post list (#22633)
* Add context menu UI to RS post list (no networking)
Add three-dot overflow menu to each post card with status-aware actions:
Published/Private posts get View, Read, Move to Draft, Duplicate, Share,
Blaze, Stats, Comments, and Trash. Draft/Pending/Scheduled posts get
Duplicate and Trash. Trashed posts get Move to Draft and Delete Permanently.
Navigation actions (View, Read, Share, Stats, Comments, Blaze) are fully
wired to launch the appropriate activities. Mutation actions (Move to Draft,
Duplicate, Trash, Delete) are UI-only no-ops that will be connected to
wordpress-rs networking in a follow-up PR.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Show "Not implemented yet" toast for menu actions that require networking
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address code review feedback
- Group confirmation dialog callbacks into ConfirmationDialogState data
class, reducing PostRsListScreen from 19 to 15 parameters
- Extract TrashConfirmationDialog and DeleteConfirmationDialog composables
- Add TODO for findPost() linear scan optimization
- Fix import ordering for uniffi.wp_api.PostStatus
- Remove unused featuredImageId field from PostRsUiModel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix menu actions using tab instead of unreliable PostStatus pattern matching
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add Publish action and update draft post menu items
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Minor formatting change
* Address review feedback: deduplicate search check, fix class equality
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Simplify confirmation dialogs and state management
* Only show Stats menu item when site stats are enabled
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace redundant booleans with PendingConfirmation in dialog state
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Only show Comments menu item when comments are open on the post
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add wordpress-rs networking for post context menu actions
Replace "Not implemented yet" placeholders with actual API calls for
Trash, Delete Permanently, Publish, Move to Draft, and Duplicate
actions using wordpress-rs (no FluxC). After each successful mutation
all initialized tab collections are refreshed so the list updates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert Duplicate action to "Not implemented yet" toast
The duplicate networking (fetching + creating on server) is deferred
to a later branch so the approach can be revisited.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Animate post disappearance on trash, delete, publish, and move to draft
Optimistically remove the post from local tab state on success so
Compose's animateItem() can fade it out and smoothly slide remaining
items up, instead of the list jumping instantly.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clean up review feedback: remove unused strings, consolidate events
- Remove unused post_rs_duplicated and post_rs_error_duplicate strings
- Consolidate ShowError into ShowToast (both showed a toast)
- Make ConfirmationDialogState a data class
- Remove trailing blank line in PostRsRestClient
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add warning logs for silent returns and O(1) post lookup index
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Simplify findPost to use early-return loop instead of cached index
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Suppress detekt LargeClass warning on PostRsListViewModel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Show no-network message before attempting post mutations
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Resolve selected site once at ViewModel init and finish Activity if null
Instead of checking getSelectedSite() in 6 different places with
inconsistent null-handling patterns, store the site at construction
time and send Finish event (with toast) if no site is selected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use site!! and extract getFluxCPost helper in PostRsListViewModel
Replace defensive val site = site ?: return with site!! since the
Activity finishes on init when site is null. Consolidate two
postStore.getPostByRemotePostId calls into a getFluxCPost helper
that shows a toast when the post isn't found.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace site!! with requireNotNull-backed non-null property
Use a private _site backing field with a non-null site getter that
calls requireNotNull with a descriptive message. This eliminates 14
uses of site!! and provides a clear error if site is accessed after
the Activity should have finished.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Unwrap lines that were broken well before the 120 char limit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix line wrapping in PostRsRestClient to match 120-char limit
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update wordpress-rs to latest trunk build
Adapt to API change: WpSelfHostedService replaced by WpService
with factory method, ApiUrlResolver parameter removed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Support WordPress.com sites in the RS post list
Rename WpSelfHostedServiceProvider to WpServiceProvider and add WP.com
support using WpService.wordpressCom() with bearer token auth. Update
PostRsRestClient to route WP.com post mutations through the WP.com REST
API proxy. Update ActivityLauncher gateway to allow WP.com sites when
the RS post list experimental feature is enabled.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Update RS post list experimental feature description
Remove "self-hosted" qualifier since the feature now supports all sites
with application passwords.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Updated feature description
* Require application passwords for all sites and cache WP.com API client
Simplify the RS post list gateway to require hasApplicationPassword()
for all sites, matching the feature description. Cache WP.com WpApiClient
instances by siteId to avoid recreating them on every mutation call.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add thread safety and sign-out cleanup for WP.com API clients
Add @synchronized to PostRsRestClient.getApiClient() to prevent
concurrent access to the wpComClients cache. Add clearWpComClients()
and call it from AppInitializer on sign-out to prevent stale bearer
token usage.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Allow WP.com sites in RS post list without application passwords
WP.com sites use OAuth bearer tokens and don't require application
passwords. Update the gateway to allow WP.com sites through and update
the feature description to reflect both supported site types.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add appNotifier to WP.com API clients in PostRsRestClient
WP.com clients were missing the WpAppNotifier callback, so invalid
authentication on post mutations would not trigger the notification
handler. Wire it up to match the self-hosted client behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use dynamic auth provider for WP.com bearer tokens
Replace staticWithAuth with WpDynamicAuthenticationProvider so the
OAuth token is read from AccountStore on each request instead of
being baked in at client creation time. This avoids stale tokens
if the token is refreshed without a sign-out.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Extract shared createWpComAuthProvider helper
Consolidate the identical WpDynamicAuthenticationProvider creation
from PostRsRestClient and WpServiceProvider into a single
package-level function in WpServiceProvider.kt.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix 404 on WP.com post mutations by using WpComDotOrgApiUrlResolver
The WP.com API client was using WpOrgSiteApiUrlResolver with a URL
that included wp/v2/sites/{id}/, causing wordpress-rs to double
the wp/v2 path segment when constructing request URLs. Use the
library's WpComDotOrgApiUrlResolver instead, which correctly
handles WP.com URL construction from a site ID.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add KDoc to getApiClient in PostRsRestClient
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use import alias to fix checkstyle dotorg violation in PostRsRestClient
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Move WP.com API client creation from PostRsRestClient to WpApiClientProvider
Centralizes WP.com WpApiClient caching and creation in WpApiClientProvider
(fluxc module), eliminating duplicate dependencies and sign-out cleanup
from PostRsRestClient. The shared createWpComAuthProvider helper also
moves to fluxc so both WpApiClientProvider and WpServiceProvider can use it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix import ordering in AppInitializer for WpApiClientProvider
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Updated logic for when new post list should be shown
* Implement duplicate post in RS post list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Shortened error toast
* Remove unused post_rs_not_implemented_yet string
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Consolidate post action boilerplate into shared helper
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add KDocs
* Add KDocs to removePostFromState and createCollection
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Revert post_not_found string to original text
The shortened version affected non-RS callers (EditPostActivity,
GutenbergKitActivity, EditorLinkHandler, ActivityLauncher).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add author filter (Me/Everyone) to RS post list
Adds the same author filtering capability as the legacy post list,
allowing users on WP.com multi-author sites to filter posts by author.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fix shimmer stuck on empty tab by clearing isLoading in list info observer
When an API response returns no items and the collection was already
empty, the data observer doesn't fire so isLoading was never cleared.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Show user avatar in author filter toolbar icon and dropdown
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Address review feedback: fix NPE risk, style, and import order
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Wrap AuthorFilterButton in Box for idiomatic DropdownMenu anchoring
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Fetch and display author names in RS post list
Author names are resolved via a batched Users API call
(mirroring the featured image pattern) and shown next to
the date when filtering by "Everyone" on multi-author sites.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Clear media URL and author name caches on pull-to-refresh
Adds clearCaches() to PostRsRestClient and calls it from
refreshTab() when the user explicitly pulls to refresh, so
stale author names and featured image URLs are evicted.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Extract AuthorFilterIcon composable to deduplicate icon logic
The toolbar button and dropdown menu leading icon in AuthorFilterButton
had identical rendering logic copy-pasted. Extract into a shared private
AuthorFilterIcon composable.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Simplify isSingleUserSite null check to idiomatic Kotlin
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add fallback icon for avatar load failure in AuthorFilterIcon
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Combine early returns in resolveAuthorNames to fix detekt ReturnCount
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add auth headers to Coil image loader for private site featured images
Adds an OkHttp interceptor to the global Coil ImageLoader that uses
AuthenticationUtils to attach auth headers (Bearer, Basic, Cookie) to
image requests. This enables featured images to load in the Compose
post list on private WPCom, private Atomic, and HTTP-auth sites.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Replace toasts with snackbars and add retry to error states in RS post list
Snackbars provide better visibility and support action buttons (e.g. "Retry")
compared to toasts. When a refresh or pagination error occurs with stale posts
already displayed, the posts now remain visible with a snackbar instead of being
replaced by a full-screen error. The full-screen error state also gains a retry
button so users no longer need to discover pull-to-refresh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Show friendly error messages instead of raw wordpress-rs exceptions
Network errors from wordpress-rs surface verbose internal messages like
"UniffiWpApiException$RequestExecutionFailed..." to the user. Replace all
raw e.message / listInfo.errorMessage usage with a helper that checks
network state and returns the appropriate user-facing string.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Use more descriptive error subtitles and center-align error text
The error screen title and subtitle were both "An error occurred". Now the
subtitle gives actionable context: a network-specific message when offline,
or a generic request failure message otherwise. The subtitle text is also
center-aligned to match the title.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add error simulation toggles for manual testing
Flip any SIMULATE_*_ERROR constant to true to trigger that error path.
Remove before merging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Updated comment
* Detect authentication errors and show a specific message
Inspect WpApiException subtypes to distinguish offline, auth, and generic
errors. Invalid or revoked application passwords now show "Your
authentication has expired. Please sign in again." instead of the generic
request failure message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Add SIMULATE_AUTH_ERROR toggle for testing auth error path
Throws a WpApiException with HttpAuthenticationRejectedError to verify
the "Your authentication has expired" message appears. Remove before
merging.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Unwrap FetchException.Api before matching error types
The friendly error messages weren't matching specific error types
because exceptions are now wrapped in FetchException.Api. Unwrap
the inner WpApiException before checking for auth errors, offline
status, and other specific error codes.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Hide retry button for authentication errors
Auth failures won't resolve by retrying, so suppress the retry action
in both the full-screen error state and snackbar messages.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Remove error simulation code from PostRsListViewModel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* Extract unwrapException helper in PostRsListViewModel
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 09ba92d commit 18046b0
6 files changed
Lines changed: 165 additions & 24 deletions
File tree
- WordPress/src/main
- java/org/wordpress/android/ui/postsrs
- screens
- res/values
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
53 | 53 | | |
54 | 54 | | |
55 | 55 | | |
| 56 | + | |
56 | 57 | | |
57 | 58 | | |
58 | 59 | | |
| |||
Lines changed: 8 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
13 | 19 | | |
14 | 20 | | |
15 | 21 | | |
| |||
27 | 33 | | |
28 | 34 | | |
29 | 35 | | |
30 | | - | |
| 36 | + | |
| 37 | + | |
31 | 38 | | |
32 | 39 | | |
33 | 40 | | |
| |||
Lines changed: 119 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
41 | 43 | | |
| 44 | + | |
| 45 | + | |
42 | 46 | | |
43 | 47 | | |
44 | 48 | | |
| |||
75 | 79 | | |
76 | 80 | | |
77 | 81 | | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
78 | 85 | | |
79 | 86 | | |
80 | 87 | | |
| |||
302 | 309 | | |
303 | 310 | | |
304 | 311 | | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
305 | 351 | | |
306 | 352 | | |
307 | | - | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
308 | 356 | | |
309 | 357 | | |
310 | 358 | | |
| |||
324 | 372 | | |
325 | 373 | | |
326 | 374 | | |
327 | | - | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
328 | 378 | | |
329 | 379 | | |
330 | 380 | | |
331 | 381 | | |
332 | | - | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
333 | 385 | | |
334 | 386 | | |
335 | 387 | | |
| |||
363 | 415 | | |
364 | 416 | | |
365 | 417 | | |
366 | | - | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
367 | 421 | | |
368 | 422 | | |
369 | 423 | | |
| |||
456 | 510 | | |
457 | 511 | | |
458 | 512 | | |
459 | | - | |
| 513 | + | |
| 514 | + | |
460 | 515 | | |
461 | 516 | | |
462 | 517 | | |
| |||
525 | 580 | | |
526 | 581 | | |
527 | 582 | | |
528 | | - | |
529 | | - | |
530 | | - | |
531 | | - | |
| 583 | + | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
| 590 | + | |
| 591 | + | |
| 592 | + | |
| 593 | + | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
532 | 597 | | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
533 | 606 | | |
534 | 607 | | |
535 | 608 | | |
| |||
551 | 624 | | |
552 | 625 | | |
553 | 626 | | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
554 | 630 | | |
555 | 631 | | |
556 | 632 | | |
| |||
674 | 750 | | |
675 | 751 | | |
676 | 752 | | |
677 | | - | |
678 | | - | |
679 | | - | |
680 | | - | |
681 | | - | |
682 | | - | |
683 | | - | |
684 | | - | |
685 | | - | |
686 | | - | |
687 | | - | |
| 753 | + | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
| 757 | + | |
| 758 | + | |
| 759 | + | |
| 760 | + | |
| 761 | + | |
| 762 | + | |
| 763 | + | |
| 764 | + | |
| 765 | + | |
| 766 | + | |
| 767 | + | |
| 768 | + | |
| 769 | + | |
| 770 | + | |
| 771 | + | |
| 772 | + | |
| 773 | + | |
| 774 | + | |
| 775 | + | |
688 | 776 | | |
| 777 | + | |
| 778 | + | |
| 779 | + | |
| 780 | + | |
| 781 | + | |
| 782 | + | |
| 783 | + | |
| 784 | + | |
| 785 | + | |
| 786 | + | |
| 787 | + | |
689 | 788 | | |
690 | 789 | | |
691 | 790 | | |
| |||
Lines changed: 21 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
32 | 35 | | |
33 | 36 | | |
34 | 37 | | |
| |||
55 | 58 | | |
56 | 59 | | |
57 | 60 | | |
| 61 | + | |
| 62 | + | |
58 | 63 | | |
59 | 64 | | |
60 | 65 | | |
61 | 66 | | |
62 | 67 | | |
63 | 68 | | |
| 69 | + | |
64 | 70 | | |
65 | 71 | | |
66 | 72 | | |
| |||
75 | 81 | | |
76 | 82 | | |
77 | 83 | | |
| 84 | + | |
78 | 85 | | |
79 | 86 | | |
80 | 87 | | |
| |||
93 | 100 | | |
94 | 101 | | |
95 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
96 | 116 | | |
97 | 117 | | |
| 118 | + | |
98 | 119 | | |
99 | 120 | | |
100 | 121 | | |
| |||
Lines changed: 14 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
| 31 | + | |
31 | 32 | | |
32 | 33 | | |
33 | 34 | | |
| |||
68 | 69 | | |
69 | 70 | | |
70 | 71 | | |
71 | | - | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
72 | 76 | | |
73 | 77 | | |
74 | 78 | | |
| |||
170 | 174 | | |
171 | 175 | | |
172 | 176 | | |
173 | | - | |
| 177 | + | |
174 | 178 | | |
175 | 179 | | |
176 | 180 | | |
| |||
187 | 191 | | |
188 | 192 | | |
189 | 193 | | |
190 | | - | |
| 194 | + | |
| 195 | + | |
191 | 196 | | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
192 | 203 | | |
193 | 204 | | |
194 | 205 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1010 | 1010 | | |
1011 | 1011 | | |
1012 | 1012 | | |
| 1013 | + | |
| 1014 | + | |
1013 | 1015 | | |
1014 | 1016 | | |
1015 | 1017 | | |
| |||
0 commit comments