mirror of https://github.com/readrops/Readrops.git
Add item readtime on item list activity and item activity
This commit is contained in:
parent
cc88fc8334
commit
a1d4112322
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="WizardSettings">
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="vectorWizard">
|
||||
<value>
|
||||
<PersistentState>
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="vectorAssetStep">
|
||||
<value>
|
||||
<PersistentState>
|
||||
<option name="children">
|
||||
<map>
|
||||
<entry key="clipartAsset">
|
||||
<value>
|
||||
<PersistentState>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="url" value="jar:file:/Applications/Android%20Studio.app/Contents/plugins/android/lib/android.jar!/images/material_design_icons/device/ic_access_time_black_24dp.xml" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
<option name="values">
|
||||
<map>
|
||||
<entry key="outputName" value="ic_read_time" />
|
||||
<entry key="sourceFile" value="$USER_HOME$" />
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</PersistentState>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</option>
|
||||
</component>
|
||||
</project>
|
|
@ -14,6 +14,7 @@ import android.view.View;
|
|||
import android.webkit.WebSettings;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.readrops.app.database.ItemWithFeed;
|
||||
|
@ -37,6 +38,8 @@ public class ItemActivity extends AppCompatActivity {
|
|||
private TextView author;
|
||||
private TextView readTime;
|
||||
|
||||
private RelativeLayout readTimeLayout;
|
||||
|
||||
private CollapsingToolbarLayout toolbarLayout;
|
||||
private ReadropsWebView webView;
|
||||
|
||||
|
@ -71,6 +74,7 @@ public class ItemActivity extends AppCompatActivity {
|
|||
title = findViewById(R.id.activity_item_title);
|
||||
author = findViewById(R.id.activity_item_author);
|
||||
readTime = findViewById(R.id.activity_item_readtime);
|
||||
readTimeLayout = findViewById(R.id.activity_item_readtime_layout);
|
||||
|
||||
viewModel = ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication()).create(ItemViewModel.class);
|
||||
viewModel.getItemById(itemId).observe(this, this::bindUI);
|
||||
|
@ -87,6 +91,18 @@ public class ItemActivity extends AppCompatActivity {
|
|||
author.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
if (item.getReadTime() > 0) {
|
||||
int minutes = (int)Math.round(item.getReadTime());
|
||||
if (minutes < 1)
|
||||
readTime.setText(getResources().getString(R.string.read_time_lower_than_1));
|
||||
else if (minutes > 1)
|
||||
readTime.setText(getResources().getString(R.string.read_time, String.valueOf(minutes)));
|
||||
else
|
||||
readTime.setText(getResources().getString(R.string.read_time_one_minute));
|
||||
|
||||
readTimeLayout.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
webView.setItem(itemWithFeed);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -203,18 +203,22 @@ public class LocalFeedRepository extends ARepository implements QueryCallback {
|
|||
for (Item dbItem : items) {
|
||||
if (!Boolean.valueOf(database.itemDao().guidExist(dbItem.getGuid()))) {
|
||||
if (dbItem.getDescription() != null) {
|
||||
dbItem.setCleanDescription(Jsoup.parse(dbItem.getDescription()).text());
|
||||
|
||||
if (dbItem.getImageLink() == null) {
|
||||
String imageUrl = HtmlParser.getDescImageLink(dbItem.getDescription(), feed.getSiteUrl());
|
||||
if (imageUrl != null) {
|
||||
dbItem.setImageLink(imageUrl);
|
||||
|
||||
if (dbItem.getContent() != null) // removing cover image in content if found in description
|
||||
if (dbItem.getContent() != null) {
|
||||
// removing cover image in content if found in description
|
||||
dbItem.setContent(HtmlParser.deleteCoverImage(dbItem.getContent()));
|
||||
}
|
||||
}
|
||||
|
||||
dbItem.setCleanDescription(Jsoup.parse(dbItem.getDescription()).text());
|
||||
dbItem.setReadTime(Utils.readTimeFromString(dbItem.getContent()));
|
||||
} else
|
||||
dbItem.setReadTime(Utils.readTimeFromString(dbItem.getCleanDescription()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
database.itemDao().insert(dbItem);
|
||||
|
|
|
@ -90,6 +90,7 @@ public class MainActivity extends AppCompatActivity implements SimpleCallback, S
|
|||
|
||||
viewModel.getItemsWithFeed().observe(this, (itemWithFeeds -> {
|
||||
newItems = itemWithFeeds;
|
||||
|
||||
if (!refreshLayout.isRefreshing())
|
||||
adapter.submitList(newItems);
|
||||
}));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package com.readrops.app;
|
||||
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
@ -104,6 +105,15 @@ public class MainItemListAdapter extends ListAdapter<ItemWithFeed, MainItemListA
|
|||
|
||||
if (itemWithFeed.getColor() != 0)
|
||||
viewHolder.feedName.setTextColor(itemWithFeed.getColor());
|
||||
|
||||
Resources resources = viewHolder.itemView.getResources();
|
||||
int minutes = (int)Math.round(itemWithFeed.getItem().getReadTime());
|
||||
if (minutes < 1)
|
||||
viewHolder.itemReadTime.setText(resources.getString(R.string.read_time_lower_than_1));
|
||||
else if (minutes > 1)
|
||||
viewHolder.itemReadTime.setText(resources.getString(R.string.read_time, String.valueOf(minutes)));
|
||||
else
|
||||
viewHolder.itemReadTime.setText(resources.getString(R.string.read_time_one_minute));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -149,6 +159,7 @@ public class MainItemListAdapter extends ListAdapter<ItemWithFeed, MainItemListA
|
|||
private TextView itemDescription;
|
||||
private ImageView feedIcon;
|
||||
private ImageView itemImage;
|
||||
private TextView itemReadTime;
|
||||
|
||||
ItemViewHolder(@NonNull View itemView) {
|
||||
super(itemView);
|
||||
|
@ -166,6 +177,7 @@ public class MainItemListAdapter extends ListAdapter<ItemWithFeed, MainItemListA
|
|||
itemDescription = itemView.findViewById(R.id.item_description);
|
||||
feedIcon = itemView.findViewById(R.id.item_feed_icon);
|
||||
itemImage = itemView.findViewById(R.id.item_image);
|
||||
itemReadTime = itemView.findViewById(R.id.item_readtime);
|
||||
}
|
||||
|
||||
private void bind(ItemWithFeed itemWithFeed) {
|
||||
|
@ -180,6 +192,8 @@ public class MainItemListAdapter extends ListAdapter<ItemWithFeed, MainItemListA
|
|||
itemDescription.setText(item.getCleanDescription());
|
||||
} else
|
||||
itemDescription.setVisibility(View.GONE);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public ImageView getItemImage() {
|
||||
|
|
|
@ -20,7 +20,7 @@ public interface ItemDao {
|
|||
@Query("Select * from Item Order By pub_date DESC")
|
||||
LiveData<List<Item>> getAll();
|
||||
|
||||
@Query("Select Item.id, title, clean_description, image_link, pub_date, name, color, icon_url from Item Inner Join Feed on Item.feed_id = Feed.id Order By Item.id DESC")
|
||||
@Query("Select Item.id, title, clean_description, image_link, pub_date, name, color, icon_url, read_time from Item Inner Join Feed on Item.feed_id = Feed.id Order By Item.id DESC")
|
||||
LiveData<List<ItemWithFeed>> getAllItemWithFeeds();
|
||||
|
||||
@Query("Select case When :guid In (Select guid from Item) Then 'true' else 'false' end")
|
||||
|
@ -32,6 +32,6 @@ public interface ItemDao {
|
|||
@Insert
|
||||
void insertAll(List<Item> items);
|
||||
|
||||
@Query("Select title, Item.description, content, pub_date, author, 0 as color, name from Item Inner Join Feed on Item.feed_id = Feed.id And Item.id = :id")
|
||||
@Query("Select title, Item.description, content, pub_date, author, 0 as color, read_time, name from Item Inner Join Feed on Item.feed_id = Feed.id And Item.id = :id")
|
||||
LiveData<ItemWithFeed> getItemById(int id);
|
||||
}
|
||||
|
|
|
@ -47,6 +47,9 @@ public class Item {
|
|||
@ColumnInfo(index = true)
|
||||
private String guid;
|
||||
|
||||
@ColumnInfo(name = "read_time")
|
||||
private double readTime;
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
@ -139,6 +142,14 @@ public class Item {
|
|||
return getImageLink() != null;
|
||||
}
|
||||
|
||||
public double getReadTime() {
|
||||
return readTime;
|
||||
}
|
||||
|
||||
public void setReadTime(double readTime) {
|
||||
this.readTime = readTime;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
if (content != null)
|
||||
return content;
|
||||
|
|
|
@ -23,6 +23,8 @@ public final class Utils {
|
|||
|
||||
public static final String HTTPS_PREFIX = "https://";
|
||||
|
||||
public static final int AVERAGE_WORDS_PER_MINUTE = 250;
|
||||
|
||||
public static void displayErrorInMainThread(Context context, String message) {
|
||||
Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
|
||||
|
||||
|
@ -55,4 +57,11 @@ public final class Utils {
|
|||
return displayMetrics.widthPixels;
|
||||
}
|
||||
|
||||
public static double readTimeFromString(String value) {
|
||||
int nbWords = value.split("\\s+").length;
|
||||
double minutes = (double)nbWords / AVERAGE_WORDS_PER_MINUTE;
|
||||
|
||||
return minutes;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
|
||||
</vector>
|
|
@ -58,6 +58,7 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="@style/Base.TextAppearance.AppCompat.Headline"
|
||||
android:layout_marginBottom="8dp"
|
||||
tools:text="This is a title" />
|
||||
|
||||
<TextView
|
||||
|
@ -66,20 +67,42 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/activity_item_title"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone"
|
||||
tools:text="By Santa Klaus" />
|
||||
tools:text="By Santa Klaus"
|
||||
tools:visibility="visible"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/activity_item_readtime_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
android:layout_below="@id/activity_item_title"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/activity_item_readtime_icon"
|
||||
android:layout_width="16dp"
|
||||
android:layout_height="16dp"
|
||||
android:layout_toStartOf="@id/activity_item_readtime"
|
||||
android:layout_alignBottom="@id/activity_item_readtime_icon"
|
||||
android:layout_centerVertical="true"
|
||||
android:src="@drawable/ic_read_time" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/activity_item_readtime"
|
||||
style="@style/Base.TextAppearance.AppCompat.Body1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/activity_item_title"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone"
|
||||
tools:text="3 minutes reading" />
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:textAlignment="viewStart"
|
||||
tools:text="3 minutes read" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<com.readrops.app.utils.ReadropsWebView
|
||||
|
|
|
@ -64,6 +64,13 @@
|
|||
android:layout_below="@id/layout_start"
|
||||
android:layout_marginTop="6dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/item_feed_title_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_toStartOf="@id/item_readtime">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/item_feed_icon"
|
||||
android:layout_width="20dp"
|
||||
|
@ -76,17 +83,43 @@
|
|||
android:id="@+id/item_feed_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_toRightOf="@id/item_feed_icon"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
tools:text="Numerama" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_readtime"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="6dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_toStartOf="@id/item_interpoint"
|
||||
tools:text="3 mins read" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_interpoint"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
android:layout_toStartOf="@id/item_date"
|
||||
android:text="@string/interpoint"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/item_date"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginLeft="4dp"
|
||||
tools:text="January 10 2019" />
|
||||
</RelativeLayout>
|
||||
|
||||
|
|
|
@ -17,5 +17,8 @@
|
|||
<string name="add_feed_connexion_error">Erreur de connexion au site</string>
|
||||
<string name="add_feed_unknownhost_error">Site inconnu</string>
|
||||
<string name="by_author">par %1$s</string>
|
||||
<string name="read_time">%1$s minutes</string>
|
||||
<string name="read_time_lower_than_1">Moins d\'une minute</string>
|
||||
<string name="read_time_one_minute">1 minute</string>
|
||||
|
||||
</resources>
|
|
@ -18,4 +18,8 @@
|
|||
<string name="add_feed_connexion_error">Connection error</string>
|
||||
<string name="add_feed_unknownhost_error">Unknown host</string>
|
||||
<string name="by_author">by %1$s</string>
|
||||
<string name="read_time">%1$s mins read</string>
|
||||
<string name="read_time_lower_than_1">Less than a minute</string>
|
||||
<string name="read_time_one_minute">1 min read</string>
|
||||
<string name="interpoint" translatable="false">·</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in New Issue