Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
7f283ed
Add an experimental redesign of the wordpress-rs posts list
nbradbury Sep 10, 2026
992360d
Fix CI: repair the ViewModel test, satisfy detekt, and cover the new …
nbradbury Sep 10, 2026
c7a91f7
Address review of the posts list redesign metrics fetching
nbradbury Sep 10, 2026
03860f6
Remove duplicated logic from the posts list redesign
nbradbury Sep 10, 2026
199d65d
Add a condensed density to the posts list
nbradbury Sep 10, 2026
ab11fb1
Use the app's usual font for the posts list title bar
nbradbury Sep 10, 2026
35fa79c
Animate the posts list between its two densities
nbradbury Sep 10, 2026
8131bfe
Put the posts list overflow button at the row's edge
nbradbury Sep 10, 2026
80894e1
Align the hero row's overflow button with the other rows
nbradbury Sep 10, 2026
5d35545
Construct the failed request result instead of mocking it
nbradbury Sep 10, 2026
a8a4c5d
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 10, 2026
c170fa5
Make modifier the first optional parameter of RowThumbnail
nbradbury Sep 10, 2026
4eebce3
Use the density icons for the posts list density toggle
nbradbury Sep 10, 2026
41d070d
Fade the posts list empty and error states in
nbradbury Sep 10, 2026
8529d48
Drop animateContentSize from the posts list cards
nbradbury Sep 11, 2026
f661a62
Remove more duplication from the posts list redesign
nbradbury Sep 11, 2026
adc4849
Give every post with a featured image the hero treatment
nbradbury Sep 11, 2026
5d1eba5
Tighten the spacing around the posts list cards
nbradbury Sep 11, 2026
7f434d0
Keep the author filter where it was in the posts list top bar
nbradbury Sep 11, 2026
db2bcc9
Stop rows shimmering when a featured image cannot be resolved
nbradbury Sep 11, 2026
53cac6c
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 13, 2026
6a0e073
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 14, 2026
e99a12b
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 14, 2026
a7d2c7c
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 14, 2026
416674a
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 14, 2026
207e43b
Address review: metric job cancellation, condensed visibility, image …
nbradbury Sep 16, 2026
758f3e3
Merge remote-tracking branch 'origin/trunk' into feature/post-pages-r…
nbradbury Sep 16, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,20 @@ import org.wordpress.android.ui.blaze.BlazeFlowSource
import org.wordpress.android.ui.compose.theme.AppThemeM3
import org.wordpress.android.ui.main.BaseAppCompatActivity
import org.wordpress.android.ui.postsrs.screens.PostRsListScreen
import org.wordpress.android.ui.prefs.experimentalfeatures.ExperimentalFeatures
import org.wordpress.android.ui.reader.ReaderActivityLauncher
import org.wordpress.android.ui.reader.ReaderPostPagerActivity.DirectOperation
import org.wordpress.android.ui.stats.StatsConstants
import org.wordpress.android.ui.stats.refresh.lists.detail.StatsDetailActivity
import org.wordpress.android.util.ToastUtils
import org.wordpress.android.util.extensions.setContent
import javax.inject.Inject

@AndroidEntryPoint
class PostRsListActivity : BaseAppCompatActivity() {
@Inject
lateinit var experimentalFeatures: ExperimentalFeatures

private val viewModel: PostRsListViewModel by viewModels()

private val settingsLauncher = registerForActivityResult(
Expand All @@ -43,13 +48,18 @@ class PostRsListActivity : BaseAppCompatActivity() {

observeEvents()

val isRedesignEnabled = experimentalFeatures.isEnabled(
ExperimentalFeatures.Feature.CONTENT_LIST_REDESIGN
)

setContent {
val tabStates by viewModel.tabStates.collectAsState()
val isSearchActive by viewModel.isSearchActive.collectAsState()
val isOpeningPost by viewModel.isOpeningPost.collectAsState()
val searchQuery by viewModel.searchQuery.collectAsState()
val authorFilter by viewModel.authorFilter.collectAsState()
val confirmation by viewModel.pendingConfirmation.collectAsState()
val density by viewModel.density.collectAsState()
AppThemeM3 {
PostRsListScreen(
tabStates = tabStates,
Expand Down Expand Up @@ -77,7 +87,11 @@ class PostRsListActivity : BaseAppCompatActivity() {
onNavigateBack = { onBackPressedDispatcher.onBackPressed() },
onPostClick = viewModel::openPost,
onPostMenuAction = viewModel::onPostMenuAction,
onCreatePost = viewModel::createNewPost
onCreatePost = viewModel::createNewPost,
onRowsVisible = viewModel::onRowsVisible,
onDensityToggled = viewModel::onDensityToggled,
density = density,
isRedesignEnabled = isRedesignEnabled
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import org.wordpress.android.R
import org.wordpress.android.ui.rs.RsDateFormatter
import org.wordpress.android.ui.rs.contentlist.ContentListRowUiState
import org.wordpress.android.util.DateTimeUtils
import org.wordpress.android.util.HtmlUtils
import uniffi.wp_api.AnyPostWithEditContext
Expand Down Expand Up @@ -59,6 +60,14 @@ data class PostRsUiModel(
val title: String,
val excerpt: String,
val date: String,
/** Raw publish date, used to bucket rows into the redesigned list's date groups. */
val dateGmtMillis: Long = 0L,
/** All-time views, or null when stats are unavailable or not fetched yet. */
val viewCount: Long? = null,
/** All-time comment count, or null when stats are unavailable or not fetched yet. */
val commentCount: Long? = null,
/** True while this row's metrics are expected but have not arrived, so it shows a skeleton. */
val areMetricsPending: Boolean = false,
val lastModified: String = "",
val link: String = "",
val hasPassword: Boolean = false,
Expand All @@ -69,6 +78,8 @@ data class PostRsUiModel(
val authorDisplayName: String? = null,
val featuredImageId: Long = 0L,
val featuredImageUrl: String? = null,
/** True when the media lookup answered without a URL, so the row should stop waiting for one. */
val isFeaturedImageUnresolvable: Boolean = false,
val actions: List<PostRsMenuAction> = emptyList(),
val badges: List<Int> = emptyList(),
val displayState: PostDisplayState =
Expand Down Expand Up @@ -169,6 +180,7 @@ private fun FullEntityAnyPostWithEditContext.toUiModel(
?: ""
).let { HtmlUtils.fastStripHtml(it).trim() },
date = RsDateFormatter.format(post.dateGmt, nowLabel, isScheduled = post.status is PostStatus.Future),
dateGmtMillis = post.dateGmt.time,
lastModified = DateTimeUtils.iso8601UTCFromDate(
post.modifiedGmt
),
Expand Down Expand Up @@ -199,6 +211,28 @@ private fun FullEntityAnyPostWithEditContext.toUiModel(
)
}

/**
* Projects a post onto the shared row model the redesigned list renders. Keeping the projection
* here means the row component itself stays free of anything post-specific, so the pages screen
* can supply its own equivalent.
*/
fun PostRsUiModel.toContentListRowUiState() = ContentListRowUiState(
id = remotePostId,
title = title,
excerpt = excerpt,
dateLabel = date,
imageUrl = featuredImageUrl,
isImagePending = featuredImageId != 0L &&
featuredImageUrl == null &&
!isFeaturedImageUnresolvable,
viewCount = viewCount,
commentCount = commentCount,
areMetricsPending = areMetricsPending,
badges = badges,
isSyncing = displayState == PostDisplayState.FETCHING_WITH_DATA,
hasSyncFailed = displayState == PostDisplayState.FAILED_WITH_DATA
)

@StringRes
internal fun PostStatus?.toLabel(): Int = when (this) {
is PostStatus.Publish ->
Expand Down
Loading
Loading