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

Adding unread posts count to Reader bottom sheet #13625

Merged
merged 12 commits into from
Jan 7, 2021
Merged
2 changes: 2 additions & 0 deletions WordPress/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ android {
buildConfigField "boolean", "MY_SITE_IMPROVEMENTS", "false"
buildConfigField "boolean", "BACKUP_AVAILABLE", "false"
buildConfigField "boolean", "FOLLOW_UNFOLLOW_COMMENTS", "false"
buildConfigField "boolean", "UNREAD_POSTS_COUNT", "false"
}

// Gutenberg's dependency - react-native-video is using
Expand Down Expand Up @@ -122,6 +123,7 @@ android {
dimension "buildType"
// Enable this for testing consolidated media picker
// buildConfigField "boolean", "CONSOLIDATED_MEDIA_PICKER", "true"
buildConfigField "boolean", "UNREAD_POSTS_COUNT", "true"
}

jalapeno { // Pre-Alpha version, used for PR builds, can be installed along release, alpha, beta, dev versions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ protected static void createTables(SQLiteDatabase db) {
+ " is_notifications_enabled INTEGER DEFAULT 0,"
+ " date_updated TEXT,"
+ " organization_id INTEGER DEFAULT 0,"
+ " unseen_count INTEGER DEFAULT 0,"
+ " PRIMARY KEY (blog_id)"
+ ")");
}
Expand Down Expand Up @@ -116,6 +117,7 @@ private static ReaderBlog getBlogInfoFromCursor(Cursor c) {
blogInfo.isNotificationsEnabled = SqlUtils.sqlToBool(c.getInt(c.getColumnIndex("is_notifications_enabled")));
blogInfo.numSubscribers = c.getInt(c.getColumnIndex("num_followers"));
blogInfo.organizationId = c.getInt(c.getColumnIndex("organization_id"));
blogInfo.numUnseenPosts = c.getInt(c.getColumnIndex("unseen_count"));

return blogInfo;
}
Expand All @@ -126,8 +128,9 @@ public static void addOrUpdateBlog(ReaderBlog blogInfo) {
}
String sql = "INSERT OR REPLACE INTO tbl_blog_info"
+ " (blog_id, feed_id, blog_url, image_url, feed_url, name, description, is_private, is_jetpack, "
+ " is_following, is_notifications_enabled, num_followers, date_updated, organization_id)"
+ " VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)";
+ " is_following, is_notifications_enabled, num_followers, date_updated, "
+ " organization_id, unseen_count)"
+ " VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14, ?15)";
SQLiteStatement stmt = ReaderDatabase.getWritableDb().compileStatement(sql);
try {
stmt.bindLong(1, blogInfo.blogId);
Expand All @@ -144,6 +147,7 @@ public static void addOrUpdateBlog(ReaderBlog blogInfo) {
stmt.bindLong(12, blogInfo.numSubscribers);
stmt.bindString(13, DateTimeUtils.iso8601FromDate(new Date()));
stmt.bindLong(14, blogInfo.organizationId);
stmt.bindLong(15, blogInfo.numUnseenPosts);
stmt.execute();
} finally {
SqlUtils.closeStatement(stmt);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
*/
public class ReaderDatabase extends SQLiteOpenHelper {
protected static final String DB_NAME = "wpreader.db";
private static final int DB_VERSION = 146;
private static final int DB_VERSION = 147;
private static final int DB_LAST_VERSION_WITHOUT_MIGRATION_SCRIPT = 136; // do not change this value

/*
Expand Down Expand Up @@ -105,6 +105,7 @@ public class ReaderDatabase extends SQLiteOpenHelper {
* 144 - added tbl_posts.is_wpforteams_site
* 145 - added tbl_blog_info.is_wp_for_teams
* 146 - replaced tbl_blog_info.is_wp_for_teams and tbl_posts.is_wpforteams_site with organization_id
* 147 - added tbl_blog_info.unseen_count
*/

/*
Expand Down Expand Up @@ -223,6 +224,9 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("ALTER TABLE tbl_blog_info ADD organization_id INTEGER;");
db.execSQL("ALTER TABLE tbl_posts ADD organization_id INTEGER;");
currentVersion++;
case 146:
db.execSQL("ALTER TABLE tbl_blog_info ADD unseen_count INTEGER;");
currentVersion++;
}
if (currentVersion != newVersion) {
throw new RuntimeException(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class ReaderBlog {
public boolean isNotificationsEnabled;
public int numSubscribers;
public int organizationId;
public int numUnseenPosts;

private String mName;
private String mDescription;
Expand Down Expand Up @@ -81,6 +82,10 @@ public static ReaderBlog fromJson(JSONObject json) {
blog.numSubscribers = json.optInt("subscribers_count");
}

if (json.has("unseen_count")) {
blog.numUnseenPosts = json.optInt("unseen_count");
Copy link
Member

Choose a reason for hiding this comment

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

Checking that the parameter exists with has() doesn't seem to be necessary here, as we're using optInt() which fallbacks to 0 by default.

}

// blogId will be empty for feeds, so set it to the feedId (consistent with /read/ endpoints)
if (blog.blogId == 0 && blog.feedId != 0) {
blog.blogId = blog.feedId;
Expand Down Expand Up @@ -192,6 +197,7 @@ public boolean isSameAs(ReaderBlog blogInfo) {
&& this.isFollowing == blogInfo.isFollowing
&& this.isPrivate == blogInfo.isPrivate
&& this.numSubscribers == blogInfo.numSubscribers
&& this.numUnseenPosts == blogInfo.numUnseenPosts
&& this.getName().equals(blogInfo.getName())
&& this.getDescription().equals(blogInfo.getDescription())
&& this.getUrl().equals(blogInfo.getUrl())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ public void onErrorResponse(VolleyError volleyError) {

AppLog.d(AppLog.T.READER, "reader service > updating followed blogs");
// request using ?meta=site,feed to get extra info
WordPress.getRestClientUtilsV1_1().get("read/following/mine?meta=site%2Cfeed", listener, errorListener);
WordPress.getRestClientUtilsV1_2().get("read/following/mine?meta=site%2Cfeed", listener, errorListener);
}

private void handleFollowedBlogsResponse(final JSONObject jsonObject) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ sealed class SubfilterListItem(val type: ItemType, val isTrackedItem: Boolean =
} else {
UiStringRes(R.string.reader_untitled_post)
}
val showUnseenCount: Boolean = blog.numUnseenPosts > 0
val unseenCount: Int = blog.numUnseenPosts
}

data class Tag(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@ import org.wordpress.android.ui.reader.subfilter.SubfilterListItem.Site
import org.wordpress.android.ui.reader.subfilter.SubfilterListItem.Tag
import org.wordpress.android.ui.reader.subfilter.adapters.SubfilterListAdapter
import org.wordpress.android.ui.reader.viewmodels.SubfilterPageViewModel
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.config.UnreadPostsCountFeatureConfig
import org.wordpress.android.widgets.WPTextView
import java.lang.ref.WeakReference
import javax.inject.Inject

class SubfilterPageFragment : DaggerFragment() {
@Inject lateinit var viewModelFactory: ViewModelProvider.Factory
@Inject lateinit var uiHelpers: UiHelpers
@Inject lateinit var unreadPostsCountFeatureConfig: UnreadPostsCountFeatureConfig
@Inject lateinit var statsUtils: StatsUtils

private lateinit var subFilterViewModel: SubFilterViewModel
private lateinit var viewModel: SubfilterPageViewModel
Expand Down Expand Up @@ -70,7 +74,7 @@ class SubfilterPageFragment : DaggerFragment() {

recyclerView = view.findViewById(R.id.content_recycler_view)
recyclerView.layoutManager = LinearLayoutManager(requireActivity())
recyclerView.adapter = SubfilterListAdapter(uiHelpers)
recyclerView.adapter = SubfilterListAdapter(uiHelpers, statsUtils, unreadPostsCountFeatureConfig)

emptyStateContainer = view.findViewById(R.id.empty_state_container)
title = emptyStateContainer.findViewById(R.id.title)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,17 @@ import org.wordpress.android.ui.reader.subfilter.viewholders.SiteViewHolder
import org.wordpress.android.ui.reader.subfilter.viewholders.SubFilterDiffCallback
import org.wordpress.android.ui.reader.subfilter.viewholders.SubfilterListItemViewHolder
import org.wordpress.android.ui.reader.subfilter.viewholders.TagViewHolder
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.config.UnreadPostsCountFeatureConfig

class SubfilterListAdapter(val uiHelpers: UiHelpers) : Adapter<SubfilterListItemViewHolder>() {
class SubfilterListAdapter(
val uiHelpers: UiHelpers,
val statsUtils: StatsUtils,
val unreadPostsCountFeatureConfig: UnreadPostsCountFeatureConfig
) : Adapter<SubfilterListItemViewHolder>() {
private var items: List<SubfilterListItem> = listOf()

fun update(newItems: List<SubfilterListItem>) {
val diffResult = DiffUtil.calculateDiff(
SubFilterDiffCallback(
Expand All @@ -42,7 +49,12 @@ class SubfilterListAdapter(val uiHelpers: UiHelpers) : Adapter<SubfilterListItem
val item = items[position]
when (holder) {
is SectionTitleViewHolder -> holder.bind(item as SectionTitle, uiHelpers)
is SiteViewHolder -> holder.bind(item as Site, uiHelpers)
is SiteViewHolder -> holder.bind(
item as Site,
uiHelpers,
statsUtils,
unreadPostsCountFeatureConfig.isEnabled()
)
is SiteAllViewHolder -> holder.bind(item as SiteAll, uiHelpers)
is TagViewHolder -> holder.bind(item as Tag, uiHelpers)
is DividerViewHolder -> {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import android.view.ViewGroup
import android.widget.TextView
import org.wordpress.android.R
import org.wordpress.android.ui.reader.subfilter.SubfilterListItem.Site
import org.wordpress.android.ui.stats.refresh.utils.ONE_THOUSAND
import org.wordpress.android.ui.stats.refresh.utils.StatsUtils
import org.wordpress.android.ui.utils.UiHelpers
import org.wordpress.android.util.UrlUtils

Expand All @@ -13,8 +15,9 @@ class SiteViewHolder(
) : SubfilterListItemViewHolder(parent, R.layout.subfilter_list_item) {
private val itemTitle = itemView.findViewById<TextView>(R.id.item_title)
private val itemUrl = itemView.findViewById<TextView>(R.id.item_url)
private val itemUnseenCount = itemView.findViewById<TextView>(R.id.unseen_count)

fun bind(site: Site, uiHelpers: UiHelpers) {
fun bind(site: Site, uiHelpers: UiHelpers, statsUtils: StatsUtils, showUnreadpostsCount: Boolean) {
super.bind(site, uiHelpers)
this.itemTitle.text = uiHelpers.getTextOfUiString(parent.context, site.label)
this.itemUrl.visibility = View.VISIBLE
Expand All @@ -26,5 +29,12 @@ class SiteViewHolder(
blog.hasFeedUrl() -> UrlUtils.getHost(blog.feedUrl)
else -> ""
}

if (showUnreadpostsCount && site.showUnseenCount) {
this.itemUnseenCount.text = statsUtils.toFormattedString(site.unseenCount, ONE_THOUSAND)
this.itemUnseenCount.visibility = View.VISIBLE
} else {
this.itemUnseenCount.visibility = View.GONE
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,19 @@ class SubFilterDiffCallback(
override fun areContentsTheSame(
oldItemPosition: Int,
newItemPosition: Int
): Boolean = oldList[oldItemPosition].isSelected == newList[newItemPosition].isSelected
): Boolean {
val areBothSites = oldList[oldItemPosition].type == SITE && newList[newItemPosition].type == SITE
val isSelectedStateSame = oldList[oldItemPosition].isSelected == newList[newItemPosition].isSelected

return if (areBothSites) {
val oldSiteContent = oldList[oldItemPosition] as Site
val newSiteContent = newList[newItemPosition] as Site

isSelectedStateSame &&
oldSiteContent.showUnseenCount == newSiteContent.showUnseenCount &&
oldSiteContent.unseenCount == newSiteContent.unseenCount
} else {
isSelectedStateSame
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.wordpress.android.util.config

import org.wordpress.android.BuildConfig
import org.wordpress.android.annotation.FeatureInDevelopment
import javax.inject.Inject

/**
* Configuration of the Unread Posts Count
*/
@FeatureInDevelopment
class UnreadPostsCountFeatureConfig
@Inject constructor(appConfig: AppConfig) : FeatureConfig(
appConfig,
BuildConfig.UNREAD_POSTS_COUNT
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@color/on_surface_emphasis_lowest"/>

<!-- arbitrary high number -->
<corners android:radius="15dp" />
</shape>
27 changes: 25 additions & 2 deletions WordPress/src/main/res/layout/subfilter_list_item.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@
style="@style/SiteTagFilteredTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/unseen_count"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toTopOf="@+id/item_url"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginBottom="@dimen/margin_large"
app:layout_goneMarginEnd="0dp"
tools:text="Unknown" />

<TextView
Expand All @@ -23,10 +24,32 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintEnd_toStartOf="@+id/unseen_count"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/item_title"
android:visibility="visible"
app:layout_goneMarginEnd="0dp"
tools:text="www.unknown.com" />

<com.google.android.material.textview.MaterialTextView
android:id="@+id/unseen_count"
android:layout_width="wrap_content"
android:layout_height="@dimen/reader_subfilter_unseen_count_height"
android:background="@drawable/bg_oval_surface_overlay_emphasis_lowest"
android:ellipsize="end"
android:gravity="center"
android:importantForAccessibility="no"
android:includeFontPadding="false"
android:maxLines="1"
android:paddingEnd="@dimen/margin_large"
android:paddingStart="@dimen/margin_large"
android:textAppearance="?attr/textAppearanceCaption"
android:textColor="@color/material_on_surface_emphasis_high_type"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="10"
tools:visibility="visible"/>

</androidx.constraintlayout.widget.ConstraintLayout>
2 changes: 2 additions & 0 deletions WordPress/src/main/res/values/dimens.xml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@

<dimen name="reader_subfilter_component_height">48dp</dimen>

<dimen name="reader_subfilter_unseen_count_height">30dp</dimen>

<item name="reader_photo_title_shadow_offset" format="float" type="dimen">3.0</item>
<item name="reader_photo_title_shadow_radius" format="float" type="dimen">1.5</item>

Expand Down