Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard Cards: Display 3 latest pages card #18337

Merged
merged 32 commits into from
May 1, 2023
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
79d8891
Adds: style for pages item title in pages card
AjeshRPai Apr 11, 2023
bf0bfae
+ Adds:the logic to get the status text for pages item
AjeshRPai Apr 28, 2023
2150760
+ Adds:the logic to get the status icon for pages item
AjeshRPai Apr 28, 2023
a5ee320
Fixes: the string value of PagesCardContentType
AjeshRPai Apr 28, 2023
f067c12
* Updates: the status mapping card builder
AjeshRPai Apr 28, 2023
da3a02a
Adds: test for published status check
AjeshRPai Apr 28, 2023
6138662
+ Adds: test for page status - draft and scheduled
AjeshRPai Apr 28, 2023
d25f87d
* Updates: the logic of building the create Page card
AjeshRPai Apr 28, 2023
225bed9
Updates: the logic of mapping the pages items
AjeshRPai Apr 28, 2023
7a53f65
[WIP] Adds: logic for setting the status icon and text
AjeshRPai Apr 28, 2023
a176707
Updates: function statement for readability
AjeshRPai Apr 28, 2023
fae312a
Updates: text style for status and updates color of published icon
AjeshRPai Apr 29, 2023
1a6621c
Adds: text view for last edited time or scheduled time
AjeshRPai Apr 29, 2023
9d469bf
Adds: long title in preview to check how long title behave
AjeshRPai Apr 29, 2023
e7bc21e
[WIP] + Adds: the logic for showing the last edited or scheduled time
AjeshRPai Apr 29, 2023
8702d9f
+ Adds: Missing dependency for builder in test class
AjeshRPai Apr 29, 2023
b4a3d6c
* Updates: getLastEditedOrScheduledTime fun to make it readable
AjeshRPai Apr 29, 2023
574b12e
+ Adds: UI string import statically for readability
AjeshRPai May 1, 2023
b3aaeea
+ Adds: the logic to show scheduled date in relative time span
AjeshRPai May 1, 2023
6c04275
- Removes: Unneeded UiString from the statement and import
AjeshRPai May 1, 2023
daf67c8
+ Adds: UI string import statically for readability
AjeshRPai May 1, 2023
45449c1
+ Adds: test for relative time shown on card
AjeshRPai May 1, 2023
6e648d5
* Updates: statements and models used in test class
AjeshRPai May 1, 2023
ff7e61f
+ Adds: PagesCardBuilderParams import statically for readability
AjeshRPai May 1, 2023
8009e5a
+ Adds: Helper for PagesCardBuilderParams function to test class
AjeshRPai May 1, 2023
b4269b0
*[WIP] Updates: the xml for Pages item in pages card
AjeshRPai May 1, 2023
61b94fd
* Updates: the naming of icon resources used to show status of page
AjeshRPai May 1, 2023
da70b14
* Implements: the background for page status text view in light/dark
AjeshRPai May 1, 2023
51dd6dd
* Implements: the colors for pages card components in light/dark
AjeshRPai May 1, 2023
1113efc
^ Replaces: hardcoded dimensions in pages_item with values from dimens
AjeshRPai May 1, 2023
2d7358c
* Fixes: Relative time not shown in minutes
AjeshRPai May 1, 2023
ffbe3fe
Refactor: reduce the length of the data path
zwarm May 1, 2023
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 @@ -217,8 +217,8 @@ sealed class MySiteCardAndItem(open val type: Type, open val activeQuickStartIte
) : PagesCard(dashboardCardType = DashboardCardType.PAGES_CARD) {
data class PageContentItem(
val title: UiString,
@DrawableRes val statusIcon: Int,
val status: UiString,
@DrawableRes val statusIcon: Int?,
val status: UiString?,
val lastEditedOrScheduledTime: UiString,
val onCardClick: () -> Unit
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,17 @@ import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.Das
import org.wordpress.android.ui.mysite.MySiteCardAndItemBuilderParams.PagesCardBuilderParams
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.util.config.DashboardCardPagesConfig
import java.util.Date
import javax.inject.Inject
import org.wordpress.android.ui.mysite.cards.dashboard.pages.PagesCardContentType.DRAFT
import org.wordpress.android.ui.mysite.cards.dashboard.pages.PagesCardContentType.PUBLISH
import org.wordpress.android.ui.mysite.cards.dashboard.pages.PagesCardContentType.SCHEDULED
import org.wordpress.android.util.DateTimeUtilsWrapper

private const val REQUIRED_PAGES_IN_CARD: Int = 3

class PagesCardBuilder @Inject constructor(
private val dashboardCardPagesConfig: DashboardCardPagesConfig
private val dashboardCardPagesConfig: DashboardCardPagesConfig,
private val dateTimeUtilsWrapper: DateTimeUtilsWrapper
) {
fun build(params: PagesCardBuilderParams): PagesCard? {
if (!dashboardCardPagesConfig.isEnabled()) {
Expand All @@ -25,22 +29,25 @@ class PagesCardBuilder @Inject constructor(

private fun convertToPagesItems(params: PagesCardBuilderParams): PagesCard.PagesCardWithData {
val pages = params.pageCard?.pages
val content = pages?.let { getPagesContentItems(pages) } ?: emptyList()
val createPageCard = getCreatePageCard(params)
val content = pages?.filterByPagesCardSupportedStatus()?.let { getPagesContentItems(pages) } ?: emptyList()
val createPageCard = getCreatePageCard(content, params.onFooterLinkClick)
return PagesCard.PagesCardWithData(
title = UiString.UiStringRes(R.string.dashboard_pages_card_title),
pages = content,
footerLink = createPageCard
)
}

private fun List<PagesCardModel.PageCardModel>.filterByPagesCardSupportedStatus() =
this.filter { it.status in PagesCardContentType.getList() }

private fun getPagesContentItems(pages: List<PagesCardModel.PageCardModel>): List<PageContentItem> {
return pages.map{ page ->
return pages.map { page ->
PageContentItem(
title = getPageTitle(page.title),
statusIcon = getStatusIcon(page.status),
status = getStatusText(page.status),
lastEditedOrScheduledTime = getLastEditedOrScheduledTime(page.lastModifiedOrScheduledOn),
lastEditedOrScheduledTime = getLastEditedOrScheduledTime(page),
onCardClick = { }
)
}
Expand All @@ -49,59 +56,68 @@ class PagesCardBuilder @Inject constructor(
private fun getPageTitle(title: String) =
if (title.isEmpty()) UiString.UiStringRes(R.string.my_site_untitled_post) else UiString.UiStringText(title)

@Suppress("UNUSED_PARAMETER")
private fun getStatusIcon(status: String): Int {
// implement the logic to get the correct icon
return R.drawable.ic_pages_white_24dp
private fun getStatusIcon(status: String): Int? {
return when (status) {
DRAFT.status -> R.drawable.ic_draft_page_draft_dashboard_card
PUBLISH.status -> R.drawable.ic_published_page_dashboard_card
SCHEDULED.status -> R.drawable.ic_scheduled_page_dashboard_card
else -> null
}
}

@Suppress("UNUSED_PARAMETER")
private fun getStatusText(status: String): UiString {
// implement the logic to get the correct text
return UiString.UiStringText("")
private fun getStatusText(status: String): UiString.UiStringRes? {
return when (status) {
DRAFT.status -> UiString.UiStringRes(R.string.dashboard_card_page_item_status_draft)
PUBLISH.status -> UiString.UiStringRes(R.string.dashboard_card_page_item_status_published)
SCHEDULED.status -> UiString.UiStringRes(R.string.dashboard_card_page_item_status_scheduled)
else -> null
}
}

@Suppress("UNUSED_PARAMETER")
private fun getLastEditedOrScheduledTime(lastModifiedOrScheduledOn: Date): UiString {
// implement the logic to get the text
return UiString.UiStringText("")
private fun getLastEditedOrScheduledTime(page: PagesCardModel.PageCardModel): UiString {
return UiString.UiStringText(
when (page.status) {
DRAFT.status, PUBLISH.status -> dateTimeUtilsWrapper.javaDateToTimeSpan(page.lastModifiedOrScheduledOn)
SCHEDULED.status -> dateTimeUtilsWrapper.javaDateToTimeSpan(page.date)
else -> ""
}
)
}

private fun getCreatePageCard(params: PagesCardBuilderParams): CreatNewPageItem {
private fun getCreatePageCard(pages: List<PageContentItem>, onFooterLinkClick: () -> Unit): CreatNewPageItem {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice refactor ❤️

// Create new page button is shown with image if there is
// less than three pages for a user
val pages = params.pageCard?.pages ?: emptyList()
return if (pages.isEmpty()) {
createNewPageCardWithAddPageMessage(params)
createNewPageCardWithAddPageMessage(onFooterLinkClick)
} else if (pages.size < REQUIRED_PAGES_IN_CARD) {
createNewPageCardWithAddAnotherPageMessage(params)
createNewPageCardWithAddAnotherPageMessage(onFooterLinkClick)
} else {
createNewPageCardWithOnlyButton(params)
createNewPageCardWithOnlyButton(onFooterLinkClick)
}
}

private fun createNewPageCardWithAddPageMessage(params: PagesCardBuilderParams): CreatNewPageItem {
private fun createNewPageCardWithAddPageMessage(onFooterLinkClick: () -> Unit): CreatNewPageItem {
return CreatNewPageItem(
label = UiString.UiStringRes(R.string.dashboard_pages_card_no_pages_create_page_button),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(early np - since this is a draft) but you could statically import the namespace and drop the UiString prefix.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice, Thanks. Done in 574b12e

description = UiString.UiStringRes(R.string.dashboard_pages_card_create_another_page_description),
imageRes = R.drawable.illustration_page_card_create_page,
onClick = params.onFooterLinkClick
onClick = onFooterLinkClick
)
}

private fun createNewPageCardWithAddAnotherPageMessage(params: PagesCardBuilderParams): CreatNewPageItem {
private fun createNewPageCardWithAddAnotherPageMessage(onFooterLinkClick: () -> Unit): CreatNewPageItem {
return CreatNewPageItem(
label = UiString.UiStringRes(R.string.dashboard_pages_card_create_another_page_button),
description = UiString.UiStringRes(R.string.dashboard_pages_card_create_another_page_description),
imageRes = R.drawable.illustration_page_card_create_page,
onClick = params.onFooterLinkClick
onClick = onFooterLinkClick
)
}

private fun createNewPageCardWithOnlyButton(params: PagesCardBuilderParams): CreatNewPageItem {
private fun createNewPageCardWithOnlyButton(onFooterLinkClick: () -> Unit): CreatNewPageItem {
return CreatNewPageItem(
label = UiString.UiStringRes(R.string.dashboard_pages_card_create_another_page_button),
onClick = params.onFooterLinkClick
onClick = onFooterLinkClick
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,14 @@ package org.wordpress.android.ui.mysite.cards.dashboard.pages
// this class represents the type of pages card that will be displayed
enum class PagesCardContentType(val status: String) {
DRAFT("draft"),
PUBLISHED("published"),
SCHEDULED("scheduled")
PUBLISH("publish"),
SCHEDULED("future");

companion object {
fun getList(): List<String> {
return values().map {
it.toString()
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.wordpress.android.databinding.PagesItemBinding
import org.wordpress.android.ui.mysite.MySiteCardAndItem.Card.DashboardCards.DashboardCard.PagesCard.PagesCardWithData.PageContentItem
import org.wordpress.android.ui.mysite.MySiteCardAndItemViewHolder
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.ui.utils.UiString
import org.wordpress.android.util.extensions.viewBinding

class PagesItemViewHolder(
Expand All @@ -15,5 +16,14 @@ class PagesItemViewHolder(
) {
fun bind(item: PageContentItem) = with(binding) {
uiHelpers.setTextOrHide(title, item.title)
setStatusIcon(item.status, item.statusIcon)
uiHelpers.setTextOrHide(lastEditedOrScheduledTime, item.lastEditedOrScheduledTime)
}

private fun setStatusIcon(statusText: UiString?, statusIcon: Int?) = with(binding) {
statusText?.let {
uiHelpers.setTextOrHide(status, it)
statusIcon?.let { status.setCompoundDrawablesWithIntrinsicBounds(statusIcon, 0, 0, 0) }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="8dp"
android:height="13dp"
android:viewportWidth="8"
android:viewportHeight="13">
<path
android:pathData="M7.867,0.333L7.267,0.533C7.2,0.533 4.867,1.2 3.8,1.933C2.667,2.667 2.2,3.333 1.933,3.733C1.533,4.333 0.8,6.867 0.8,7.933L0.2,9.467C0.067,9.733 0.2,10 0.467,10.133C0.533,10.133 0.6,10.2 0.667,10.2C0.867,10.2 1.067,10.067 1.133,9.867L1.533,8.867C1.733,8.867 2,8.8 2.333,8.733C2.8,8.667 3.267,8.533 3.8,8.4C4.333,8.267 4.867,8.067 5.4,7.867C5.867,7.667 6.333,7.4 6.667,7.067C7,6.733 7.2,6.267 7.333,5.8C7.467,5.333 7.533,4.733 7.6,4.2C7.667,3.667 7.667,3.067 7.733,2.533C7.733,2 7.8,1.533 7.867,1.133V0.333ZM6.6,4.067C6.533,4.6 6.467,5.067 6.4,5.467C6.267,5.867 6.133,6.133 6,6.333C5.8,6.533 5.467,6.733 5.067,6.933C4.6,7.133 4.133,7.267 3.6,7.467C3.2,7.6 2.733,7.667 2.4,7.733L6,4C6.2,3.8 6.4,3.533 6.667,3.267C6.667,3.533 6.667,3.8 6.6,4.067ZM0,12.333H5.333V11.333H0V12.333Z"
android:fillColor="#666666"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:pathData="M6,0.2C2.8,0.2 0.133,2.8 0.133,6.067C0.133,9.267 2.733,11.933 6,11.933C9.2,11.933 11.867,9.333 11.867,6.067C11.867,2.8 9.2,0.2 6,0.2ZM10.333,3.867H8.6C8.267,2.867 7.867,2 7.333,1.333C8.667,1.733 9.733,2.667 10.333,3.867ZM10.8,6C10.8,6.4 10.733,6.8 10.667,7.2H8.733C8.8,6.8 8.8,6.4 8.8,6C8.8,5.6 8.733,5.2 8.733,4.8H10.667C10.8,5.2 10.8,5.6 10.8,6ZM6,10.467C5.333,10 4.8,9.2 4.467,8.133H7.533C7.2,9.2 6.667,10.067 6,10.467ZM4.267,7.2C4.2,6.8 4.2,6.467 4.2,6C4.2,5.6 4.267,5.2 4.267,4.8H7.733C7.8,5.2 7.8,5.533 7.8,6C7.8,6.467 7.733,6.8 7.733,7.2H4.267ZM1.2,6C1.2,5.6 1.267,5.2 1.333,4.8H3.267C3.2,5.2 3.2,5.6 3.2,6C3.2,6.4 3.267,6.8 3.267,7.2H1.333C1.2,6.8 1.2,6.4 1.2,6ZM6,1.533C6.667,2 7.2,2.8 7.533,3.867H4.467C4.8,2.8 5.333,1.933 6,1.533ZM4.667,1.333C4.133,2 3.733,2.867 3.467,3.867H1.667C2.267,2.667 3.333,1.733 4.667,1.333ZM1.667,8.2H3.4C3.667,9.2 4.067,10.067 4.6,10.667C3.4,10.267 2.267,9.333 1.667,8.2ZM7.333,10.667C7.867,10 8.267,9.2 8.533,8.2H10.267C9.733,9.333 8.667,10.267 7.333,10.667Z"
android:fillColor="#666666"/>
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:pathData="M10.667,0H1.333C0.6,0 0,0.6 0,1.333V10.667C0,11.4 0.6,12 1.333,12H10.667C11.4,12 12,11.4 12,10.667V1.333C12,0.6 11.4,0 10.667,0ZM11,10.667C11,10.867 10.867,11 10.667,11H1.333C1.133,11 1,10.867 1,10.667V2.667H11V10.667ZM4,4.667H2.667V6H4V4.667ZM4,7.333H2.667V8.667H4V7.333ZM6.667,4.667H5.333V6H6.667V4.667ZM9.333,4.667H8V6H9.333V4.667ZM6.667,7.333H5.333V8.667H6.667V7.333ZM9.333,7.333H8V8.667H9.333V7.333Z"
android:fillColor="#666666"/>
</vector>
31 changes: 30 additions & 1 deletion WordPress/src/main/res/layout/pages_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,37 @@
style="@style/MySitePostItemTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/title" />
tools:text="This is a long title to check how the text behaves when its too long" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/status"
style="@style/MySiteCardPagesCardPagesItemStatus"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:background="#F2F2F7"
tools:drawableStart="@drawable/ic_published_page_dashboard_card"
tools:text="@string/dashboard_card_page_item_status_published"
android:drawablePadding="@dimen/margin_medium"
app:layout_constraintStart_toStartOf="parent"
android:paddingStart="10dp"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

np (again, a bit early) - just a reminder to use android:paddingHorizontal and android:paddingVertical. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, Thanks for point it out. Done in b4269b0

android:paddingEnd="10dp"
android:paddingTop="4dp"
android:paddingBottom="4dp"
app:layout_constraintTop_toBottomOf="@+id/title" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/lastEditedOrScheduledTime"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="in 2 hours"
android:textColor="#666666"
android:paddingStart="8dp"
android:paddingEnd="8dp"
app:layout_constraintBottom_toBottomOf="@+id/status"
app:layout_constraintStart_toEndOf="@+id/status"
app:layout_constraintTop_toTopOf="@+id/status" />
</androidx.constraintlayout.widget.ConstraintLayout>
3 changes: 3 additions & 0 deletions WordPress/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4522,6 +4522,9 @@ translators: %s: Select control option value e.g: "Auto, 25%". -->
<string name="dashboard_pages_card_no_pages_create_page_button">Add Pages to your site</string>
<string name="dashboard_pages_card_create_another_page_button">Create Another Page</string>
<string name="dashboard_pages_card_create_another_page_description">Start with bespoke, mobile friendly layouts</string>
<string name="dashboard_card_page_item_status_draft" translatable="false" >@string/pages_drafts</string>
<string name="dashboard_card_page_item_status_published" translatable="false" >@string/pages_published</string>
<string name="dashboard_card_page_item_status_scheduled" translatable="false" >@string/pages_scheduled</string>

<!-- Jetpack - Dashboard cards - Activity Card -->
<string name="dashboard_activity_card_title">Recent activity</string>
Expand Down
8 changes: 8 additions & 0 deletions WordPress/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,14 @@
<item name="cornerSize">@dimen/my_site_dashboard_card_page_create_page_illustration_image_view_corner_radius</item>
</style>

<style name="MySiteCardPagesCardPagesItemStatus">
<item name="android:textAlignment">viewStart</item>
<item name="android:textAppearance">?attr/textAppearanceBody2</item>
<item name="android:textColor">#666666</item>
<item name="android:maxLines">1</item>
<item name="android:ellipsize">end</item>
</style>

<!--People Management Styles-->
<style name="PersonAvatar">
<item name="android:layout_width">@dimen/people_avatar_sz</item>
Expand Down
Loading