Skip to content

Commit adf8393

Browse files
authored
Merge pull request #20877 from wordpress-mobile/issue/20621-announcement-card-in-tags-feed
[Reader] Also add announcement card into the new Tags Feed
2 parents fef5649 + a862f9b commit adf8393

File tree

7 files changed

+201
-98
lines changed

7 files changed

+201
-98
lines changed

WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/tagsfeed/ReaderTagsFeedUiStateMapper.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class ReaderTagsFeedUiStateMapper @Inject constructor(
8686
@Suppress("LongParameterList")
8787
fun mapInitialPostsUiState(
8888
tags: List<ReaderTag>,
89+
announcementItem: ReaderTagsFeedViewModel.ReaderAnnouncementItem?,
8990
isRefreshing: Boolean,
9091
onTagChipClick: (ReaderTag) -> Unit,
9192
onMoreFromTagClick: (ReaderTag) -> Unit,
@@ -101,6 +102,7 @@ class ReaderTagsFeedUiStateMapper @Inject constructor(
101102
onItemEnteredView = onItemEnteredView,
102103
)
103104
},
105+
announcementItem = announcementItem,
104106
isRefreshing = isRefreshing,
105107
onRefresh = onRefresh,
106108
)

WordPress/src/main/java/org/wordpress/android/ui/reader/viewmodels/tagsfeed/ReaderTagsFeedViewModel.kt

Lines changed: 54 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ import org.wordpress.android.ui.reader.exceptions.ReaderPostFetchException
3131
import org.wordpress.android.ui.reader.repository.ReaderPostRepository
3232
import org.wordpress.android.ui.reader.repository.usecases.PostLikeUseCase
3333
import org.wordpress.android.ui.reader.tracker.ReaderTracker
34+
import org.wordpress.android.ui.reader.utils.ReaderAnnouncementHelper
35+
import org.wordpress.android.ui.reader.views.compose.ReaderAnnouncementCardItemData
3436
import org.wordpress.android.ui.reader.views.compose.tagsfeed.TagsFeedPostItem
3537
import org.wordpress.android.util.DisplayUtilsWrapper
3638
import org.wordpress.android.util.NetworkUtilsWrapper
@@ -53,6 +55,7 @@ class ReaderTagsFeedViewModel @Inject constructor(
5355
private val displayUtilsWrapper: DisplayUtilsWrapper,
5456
private val readerTracker: ReaderTracker,
5557
private val networkUtilsWrapper: NetworkUtilsWrapper,
58+
private val readerAnnouncementHelper: ReaderAnnouncementHelper,
5659
) : ScopedViewModel(bgDispatcher) {
5760
private val _uiStateFlow: MutableStateFlow<UiState> = MutableStateFlow(UiState.Initial)
5861
val uiStateFlow: StateFlow<UiState> = _uiStateFlow
@@ -88,41 +91,45 @@ class ReaderTagsFeedViewModel @Inject constructor(
8891
}
8992
}
9093

91-
fun onTagsChanged(tags: List<ReaderTag>) = _uiStateFlow.update { currentState ->
92-
when {
93-
tags.isEmpty() -> {
94-
UiState.Empty(::onOpenTagsListClick)
95-
}
94+
fun onTagsChanged(tags: List<ReaderTag>) {
95+
return _uiStateFlow.update { currentState ->
96+
when {
97+
tags.isEmpty() -> {
98+
UiState.Empty(::onOpenTagsListClick)
99+
}
100+
101+
currentState is UiState.Loaded -> {
102+
val currentTags = currentState.data.map { it.tagChip.tag }
103+
if (currentState.isRefreshing) {
104+
readerTagsFeedUiStateMapper.mapInitialPostsUiState(
105+
tags,
106+
getAnnouncementItem(),
107+
false,
108+
::onTagChipClick,
109+
::onMoreFromTagClick,
110+
::onItemEnteredView,
111+
::onRefresh
112+
)
113+
} else if (currentTags != tags) {
114+
updateLoadedStateWithTags(currentState, tags)
115+
} else {
116+
currentState
117+
}
118+
}
96119

97-
currentState is UiState.Loaded -> {
98-
val currentTags = currentState.data.map { it.tagChip.tag }
99-
if (currentState.isRefreshing) {
120+
else -> {
121+
// Add tags to the list with the posts initial/loading UI
100122
readerTagsFeedUiStateMapper.mapInitialPostsUiState(
101123
tags,
124+
getAnnouncementItem(),
102125
false,
103126
::onTagChipClick,
104127
::onMoreFromTagClick,
105128
::onItemEnteredView,
106129
::onRefresh
107130
)
108-
} else if (currentTags != tags) {
109-
updateLoadedStateWithTags(currentState, tags)
110-
} else {
111-
currentState
112131
}
113132
}
114-
115-
else -> {
116-
// Add tags to the list with the posts initial/loading UI
117-
readerTagsFeedUiStateMapper.mapInitialPostsUiState(
118-
tags,
119-
false,
120-
::onTagChipClick,
121-
::onMoreFromTagClick,
122-
::onItemEnteredView,
123-
::onRefresh
124-
)
125-
}
126133
}
127134
}
128135

@@ -146,6 +153,23 @@ class ReaderTagsFeedViewModel @Inject constructor(
146153
}
147154
}
148155

156+
private fun getAnnouncementItem(): ReaderAnnouncementItem? =
157+
if (readerAnnouncementHelper.hasReaderAnnouncement()) {
158+
ReaderAnnouncementItem(
159+
items = readerAnnouncementHelper.getReaderAnnouncementItems(),
160+
onDoneClicked = ::dismissAnnouncementItem,
161+
)
162+
} else {
163+
null
164+
}
165+
166+
private fun dismissAnnouncementItem() {
167+
readerAnnouncementHelper.dismissReaderAnnouncement()
168+
_uiStateFlow.update {
169+
(it as? UiState.Loaded)?.copy(announcementItem = null) ?: it
170+
}
171+
}
172+
149173
private fun updateLoadedStateWithTags(state: UiState.Loaded, tags: List<ReaderTag>): UiState.Loaded {
150174
val currentTagsMap = state.data.associateBy { it.tagChip.tag.tagSlug }
151175
val updatedData = tags.map { tag ->
@@ -548,6 +572,7 @@ class ReaderTagsFeedViewModel @Inject constructor(
548572

549573
data class Loaded(
550574
val data: List<TagFeedItem>,
575+
val announcementItem: ReaderAnnouncementItem? = null,
551576
val isRefreshing: Boolean = false,
552577
val onRefresh: () -> Unit = {},
553578
) : UiState()
@@ -559,6 +584,11 @@ class ReaderTagsFeedViewModel @Inject constructor(
559584
data class NoConnection(val onRetryClick: () -> Unit) : UiState()
560585
}
561586

587+
data class ReaderAnnouncementItem(
588+
val items: List<ReaderAnnouncementCardItemData>,
589+
val onDoneClicked: () -> Unit,
590+
)
591+
562592
data class TagFeedItem(
563593
val tagChip: TagChip,
564594
val postList: PostList,

WordPress/src/main/java/org/wordpress/android/ui/reader/views/ReaderAnnouncementCardView.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ class ReaderAnnouncementCardView @JvmOverloads constructor(
2323
override fun Content() {
2424
AppTheme {
2525
ReaderAnnouncementCard(
26-
shouldShow = true,
2726
items = items.value,
2827
onAnnouncementCardDoneClick = { onDoneClickListener.value?.onDoneClick() }
2928
)

WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/ReaderAnnouncementCard.kt

Lines changed: 30 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,6 @@ package org.wordpress.android.ui.reader.views.compose
33
import android.content.res.Configuration
44
import androidx.annotation.DrawableRes
55
import androidx.annotation.StringRes
6-
import androidx.compose.animation.AnimatedVisibility
7-
import androidx.compose.animation.expandIn
8-
import androidx.compose.animation.shrinkOut
96
import androidx.compose.foundation.isSystemInDarkTheme
107
import androidx.compose.foundation.layout.Arrangement
118
import androidx.compose.foundation.layout.Box
@@ -35,57 +32,48 @@ import org.wordpress.android.ui.compose.unit.Margin
3532

3633
@Composable
3734
fun ReaderAnnouncementCard(
38-
shouldShow: Boolean,
3935
items: List<ReaderAnnouncementCardItemData>,
4036
onAnnouncementCardDoneClick: () -> Unit,
4137
) {
4238
val primaryColor = if (isSystemInDarkTheme()) AppColor.White else AppColor.Black
4339
val secondaryColor = if (isSystemInDarkTheme()) AppColor.Black else AppColor.White
44-
AnimatedVisibility(
45-
visible = shouldShow,
46-
enter = expandIn(),
47-
exit = shrinkOut(
48-
shrinkTowards = Alignment.TopCenter,
49-
),
40+
Column(
41+
modifier = Modifier
42+
.fillMaxWidth()
43+
.padding(Margin.ExtraLarge.value),
44+
verticalArrangement = Arrangement.spacedBy(Margin.ExtraLarge.value),
5045
) {
46+
// Title
47+
Text(
48+
text = stringResource(R.string.reader_announcement_card_title),
49+
style = MaterialTheme.typography.labelLarge,
50+
color = primaryColor,
51+
)
52+
// Items
5153
Column(
5254
modifier = Modifier
53-
.fillMaxWidth()
54-
.padding(Margin.ExtraLarge.value),
55-
verticalArrangement = Arrangement.spacedBy(Margin.ExtraLarge.value),
55+
.fillMaxWidth(),
56+
verticalArrangement = Arrangement.spacedBy(Margin.ExtraLarge.value)
57+
) {
58+
items.forEach {
59+
ReaderAnnouncementCardItem(it)
60+
}
61+
}
62+
// Done button
63+
Button(
64+
modifier = Modifier
65+
.fillMaxWidth(),
66+
onClick = { onAnnouncementCardDoneClick() },
67+
elevation = ButtonDefaults.elevation(0.dp),
68+
colors = ButtonDefaults.buttonColors(
69+
backgroundColor = primaryColor,
70+
),
5671
) {
57-
// Title
5872
Text(
59-
text = stringResource(R.string.reader_announcement_card_title),
73+
text = stringResource(id = R.string.reader_btn_done),
74+
color = secondaryColor,
6075
style = MaterialTheme.typography.labelLarge,
61-
color = primaryColor,
6276
)
63-
// Items
64-
Column(
65-
modifier = Modifier
66-
.fillMaxWidth(),
67-
verticalArrangement = Arrangement.spacedBy(Margin.ExtraLarge.value)
68-
) {
69-
items.forEach {
70-
ReaderAnnouncementCardItem(it)
71-
}
72-
}
73-
// Done button
74-
Button(
75-
modifier = Modifier
76-
.fillMaxWidth(),
77-
onClick = { onAnnouncementCardDoneClick() },
78-
elevation = ButtonDefaults.elevation(0.dp),
79-
colors = ButtonDefaults.buttonColors(
80-
backgroundColor = primaryColor,
81-
),
82-
) {
83-
Text(
84-
text = stringResource(id = R.string.reader_btn_done),
85-
color = secondaryColor,
86-
style = MaterialTheme.typography.labelLarge,
87-
)
88-
}
8977
}
9078
}
9179
}
@@ -158,7 +146,6 @@ fun ReaderTagsFeedPostListItemPreview() {
158146
.fillMaxWidth()
159147
) {
160148
ReaderAnnouncementCard(
161-
shouldShow = false,
162149
items = listOf(
163150
ReaderAnnouncementCardItemData(
164151
iconRes = R.drawable.ic_wifi_off_24px,

WordPress/src/main/java/org/wordpress/android/ui/reader/views/compose/tagsfeed/ReaderTagsFeed.kt

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewMod
6565
import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewModel.TagChip
6666
import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewModel.TagFeedItem
6767
import org.wordpress.android.ui.reader.viewmodels.tagsfeed.ReaderTagsFeedViewModel.UiState
68+
import org.wordpress.android.ui.reader.views.compose.ReaderAnnouncementCard
6869
import org.wordpress.android.ui.reader.views.compose.filter.ReaderFilterChip
6970
import org.wordpress.android.ui.utils.UiString
7071

@@ -107,6 +108,15 @@ private fun Loaded(uiState: UiState.Loaded) {
107108
modifier = Modifier
108109
.fillMaxSize(),
109110
) {
111+
uiState.announcementItem?.let { announcementItem ->
112+
item(key = "reader-announcement-card") {
113+
ReaderAnnouncementCard(
114+
items = announcementItem.items,
115+
onAnnouncementCardDoneClick = announcementItem.onDoneClicked,
116+
)
117+
}
118+
}
119+
110120
items(
111121
items = uiState.data,
112122
key = { it.tagChip.tag.tagSlug }
@@ -611,33 +621,25 @@ fun ReaderTagsFeedLoaded() {
611621
),
612622
)
613623
)
614-
val readerTag = ReaderTag(
615-
"Tag 1",
616-
"Tag 1",
617-
"Tag 1",
618-
"Tag 1",
619-
ReaderTagType.TAGS,
620-
)
621624
ReaderTagsFeed(
622625
uiState = UiState.Loaded(
623-
data = listOf(
626+
data = List(4) {
627+
val tagName = "Tag ${it + 1}"
624628
TagFeedItem(
625-
tagChip = TagChip(readerTag, {}, {}),
629+
tagChip = TagChip(
630+
tag = ReaderTag(
631+
tagName,
632+
tagName,
633+
tagName,
634+
tagName,
635+
ReaderTagType.TAGS,
636+
),
637+
onTagChipClick = {},
638+
onMoreFromTagClick = {},
639+
),
626640
postList = postListLoaded
627-
),
628-
TagFeedItem(
629-
tagChip = TagChip(readerTag, {}, {}),
630-
postList = PostList.Initial,
631-
),
632-
TagFeedItem(
633-
tagChip = TagChip(readerTag, {}, {}),
634-
postList = PostList.Error(ErrorType.Default, {}),
635-
),
636-
TagFeedItem(
637-
tagChip = TagChip(readerTag, {}, {}),
638-
postList = PostList.Error(ErrorType.NoContent, {}),
639-
),
640-
)
641+
)
642+
}
641643
)
642644
)
643645
}

0 commit comments

Comments
 (0)