Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/news-android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Luhmer <david-dev@live.de>2021-01-02 15:07:10 +0300
committerDavid Luhmer <david-dev@live.de>2021-01-02 15:07:10 +0300
commit64fc2ba71b0cc047060a6343c0757e6bec617446 (patch)
treee4f6f9fab52da4ccc6bd5e2be7348d32f654aa9e /News-Android-App/src/main/java
parenteb7c0787f3875879448d5f6928dc426e615671c8 (diff)
use ViewBinding everywhere and get rid of Butterknife
Signed-off-by: David Luhmer <david-dev@live.de>
Diffstat (limited to 'News-Android-App/src/main/java')
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java16
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java384
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java96
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.java3
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.java5
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemCardViewHolder.java78
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemFullTextViewHolder.java13
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineViewHolder.java78
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemTextViewHolder.java78
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemThumbnailViewHolder.java128
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemViewHolder.java (renamed from News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ViewHolder.java)450
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemWebViewHolder.java82
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java27
13 files changed, 894 insertions, 544 deletions
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
index 26c1f033..baad3656 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
@@ -62,7 +62,7 @@ import java.util.List;
import javax.inject.Inject;
import de.luhmer.owncloudnewsreader.adapter.NewsListRecyclerAdapter;
-import de.luhmer.owncloudnewsreader.adapter.ViewHolder;
+import de.luhmer.owncloudnewsreader.adapter.RssItemViewHolder;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm.SORT_DIRECTION;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
@@ -403,7 +403,7 @@ public class NewsReaderDetailFragment extends Fragment {
for (int i = firstVisibleItem; i < firstVisibleItem + numberItemsAhead; i++) {
//Log.v(TAG, "Mark item as read: " + i);
- ViewHolder vh = (ViewHolder) binding.list.findViewHolderForLayoutPosition(i);
+ RssItemViewHolder vh = (RssItemViewHolder) binding.list.findViewHolderForLayoutPosition(i);
if (vh != null && !vh.shouldStayUnread()) {
adapter.changeReadStateOfItem(vh, true);
}
@@ -416,8 +416,8 @@ public class NewsReaderDetailFragment extends Fragment {
for (int i = firstVisibleItem; i <= lastVisibleItem; i++) {
RecyclerView.ViewHolder vhTemp = binding.list.findViewHolderForLayoutPosition(i);
- if (vhTemp instanceof ViewHolder) { //Check for ViewHolder instance because of ProgressViewHolder
- ViewHolder vh = (ViewHolder) vhTemp;
+ if (vhTemp instanceof RssItemViewHolder) { //Check for ViewHolder instance because of ProgressViewHolder
+ RssItemViewHolder vh = (RssItemViewHolder) vhTemp;
if (!vh.shouldStayUnread()) {
adapter.changeReadStateOfItem(vh, true);
@@ -616,16 +616,16 @@ public class NewsReaderDetailFragment extends Fragment {
swipeAction = mPrefs.getString(SP_SWIPE_RIGHT_ACTION, SP_SWIPE_RIGHT_ACTION_DEFAULT);
switch (swipeAction) {
case "0": // Open link in browser and mark as read
- String currentUrl = ((ViewHolder) viewHolder).getRssItem().getLink();
+ String currentUrl = ((RssItemViewHolder) viewHolder).getRssItem().getLink();
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(currentUrl));
startActivity(browserIntent);
- adapter.changeReadStateOfItem((ViewHolder) viewHolder, true);
+ adapter.changeReadStateOfItem((RssItemViewHolder) viewHolder, true);
break;
case "1": // Star
- adapter.toggleStarredStateOfItem((ViewHolder) viewHolder);
+ adapter.toggleStarredStateOfItem((RssItemViewHolder) viewHolder);
break;
case "2": // Read
- adapter.toggleReadStateOfItem((ViewHolder) viewHolder);
+ adapter.toggleReadStateOfItem((RssItemViewHolder) viewHolder);
break;
default:
Log.e(TAG, "Swipe preferences has an invalid value");
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
index 7d6feae7..69a5ae06 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
@@ -81,6 +81,7 @@ import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
@@ -89,7 +90,7 @@ import javax.inject.Named;
import de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter;
import de.luhmer.owncloudnewsreader.adapter.NewsListRecyclerAdapter;
import de.luhmer.owncloudnewsreader.adapter.RecyclerItemClickListener;
-import de.luhmer.owncloudnewsreader.adapter.ViewHolder;
+import de.luhmer.owncloudnewsreader.adapter.RssItemViewHolder;
import de.luhmer.owncloudnewsreader.authentication.AccountGeneral;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.Feed;
@@ -150,42 +151,84 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
private ActionBarDrawerToggle drawerToggle;
private SearchView mSearchView;
- private String mSearchString;
- private static final String SEARCH_KEY = "SEARCH_KEY";
+ private String mSearchString;
+ private static final String SEARCH_KEY = "SEARCH_KEY";
- private PublishSubject<String> searchPublishSubject;
- private static final int REQUEST_CODE_PERMISSION_DOWNLOAD_WEB_ARCHIVE = 1;
+ private PublishSubject<String> searchPublishSubject;
+ private static final int REQUEST_CODE_PERMISSION_DOWNLOAD_WEB_ARCHIVE = 1;
private static final int REQUEST_CODE_PERMISSION_LOCATION = 139;
- private static final String ID_FEED_STRING = "ID_FEED_STRING";
- private static final String IS_FOLDER_BOOLEAN = "IS_FOLDER_BOOLEAN";
- private static final String OPTIONAL_FOLDER_ID = "OPTIONAL_FOLDER_ID";
- private static final String LIST_ADAPTER_TOTAL_COUNT = "LIST_ADAPTER_TOTAL_COUNT";
- private static final String LIST_ADAPTER_PAGE_COUNT = "LIST_ADAPTER_PAGE_COUNT";
+ private static final String ID_FEED_STRING = "ID_FEED_STRING";
+ private static final String IS_FOLDER_BOOLEAN = "IS_FOLDER_BOOLEAN";
+ private static final String OPTIONAL_FOLDER_ID = "OPTIONAL_FOLDER_ID";
+ private static final String LIST_ADAPTER_TOTAL_COUNT = "LIST_ADAPTER_TOTAL_COUNT";
+ private static final String LIST_ADAPTER_PAGE_COUNT = "LIST_ADAPTER_PAGE_COUNT";
- @Inject @Named("sharedPreferencesFileName") String sharedPreferencesFileName;
+ @Inject
+ @Named("sharedPreferencesFileName")
+ String sharedPreferencesFileName;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- ((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
-
- SharedPreferences defaultValueSp = getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE);
- if(!defaultValueSp.getBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)) {
- PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_data_sync, true);
- PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_display, true);
- PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_general, true);
- PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_notification, true);
- }
+ private View.OnClickListener mSnackbarListener = view -> {
+ //Toast.makeText(getActivity(), "button 1 pressed", 3000).show();
+ updateCurrentRssView();
+ };
+
+ @Override
+ public void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+
+ if (drawerToggle != null) {
+ drawerToggle.syncState();
+ }
+
+ // Fragments are not ready when calling the method below in onCreate()
+ updateButtonLayout();
+
+ //Start auto sync if enabled
+ if (mPrefs.getBoolean(SettingsActivity.CB_SYNCONSTARTUP_STRING, false)) {
+ startSync();
+ }
+
+ boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
+ if (tabletSize) {
+ showTapLogoToSyncShowcaseView();
+ }
+
+
+ // In case automatic theme selection based on time is selected, check if location permission
+ // for twilight manager is given.. otherwise request it
+ if (isUserLoggedIn() && ThemeChooser.isAutoThemeSelectionEnabled() && ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
+ ActivityCompat.requestPermissions(
+ this,
+ new String[]{ACCESS_FINE_LOCATION},
+ REQUEST_CODE_PERMISSION_LOCATION
+ );
+ }
+ }
+
+ private boolean isUserLoggedIn() {
+ return (mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) != null);
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ ((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
+
+ SharedPreferences defaultValueSp = getSharedPreferences(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, Context.MODE_PRIVATE);
+ if (!defaultValueSp.getBoolean(PreferenceManager.KEY_HAS_SET_DEFAULT_VALUES, false)) {
+ PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_data_sync, true);
+ PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_display, true);
+ PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_general, true);
+ PreferenceManager.setDefaultValues(this, sharedPreferencesFileName, Context.MODE_PRIVATE, R.xml.pref_notification, true);
+ }
super.onCreate(savedInstanceState);
binding = ActivityNewsreaderBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
- if (binding.toolbarLayout.toolbar != null) {
- setSupportActionBar(binding.toolbarLayout.toolbar);
- }
+ setSupportActionBar(binding.toolbarLayout.toolbar);
initAccountManager();
@@ -230,10 +273,10 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
binding.drawerLayout.addDrawerListener(drawerToggle);
- adjustEdgeSizeOfDrawer();
+ adjustEdgeSizeOfDrawer();
}
setSupportActionBar(binding.toolbarLayout.toolbar);
- getSupportActionBar().setDisplayShowHomeEnabled(true);
+ Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
if (drawerToggle != null) {
drawerToggle.syncState();
}
@@ -241,84 +284,39 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
//AppRater.app_launched(this);
//AppRater.rateNow(this);
- if (savedInstanceState == null) { //When the app starts (no orientation change)
- updateDetailFragment(SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_UNREAD_ITEMS.getValue(), true, null, true);
- }
- }
-
- @Override
- public void onPostCreate(Bundle savedInstanceState) {
- super.onPostCreate(savedInstanceState);
-
- if (drawerToggle != null) {
- drawerToggle.syncState();
- }
-
- // Fragments are not ready when calling the method below in onCreate()
- updateButtonLayout();
-
- //Start auto sync if enabled
- if (mPrefs.getBoolean(SettingsActivity.CB_SYNCONSTARTUP_STRING, false)) {
- startSync();
- }
-
- boolean tabletSize = getResources().getBoolean(R.bool.isTablet);
- if (tabletSize) {
- showTapLogoToSyncShowcaseView();
- }
-
-
- // In case automatic theme selection based on time is selected, check if location permission
- // for twilight manager is given.. otherwise request it
- if(isUserLoggedIn() && ThemeChooser.isAutoThemeSelectionEnabled() && ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
- ActivityCompat.requestPermissions(
- this,
- new String[]{ ACCESS_FINE_LOCATION },
- REQUEST_CODE_PERMISSION_LOCATION
- );
- }
- }
+ if (savedInstanceState == null) { //When the app starts (no orientation change)
+ updateDetailFragment(SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_UNREAD_ITEMS.getValue(), true, null, true);
+ }
+ }
- private boolean isUserLoggedIn() {
- return (mPrefs.getString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, null) != null);
+ @Override
+ protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
+ restoreInstanceState(savedInstanceState);
+ super.onRestoreInstanceState(savedInstanceState);
}
@Override
- protected void onSaveInstanceState(Bundle outState) {
+ protected void onSaveInstanceState(@NonNull Bundle outState) {
saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
- @Override
- protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
- restoreInstanceState(savedInstanceState);
- super.onRestoreInstanceState(savedInstanceState);
- }
-
- @Override
- public void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- if (drawerToggle != null) {
- drawerToggle.onConfigurationChanged(newConfig);
- }
- }
-
- private void saveInstanceState(Bundle outState) {
- NewsReaderDetailFragment ndf = getNewsReaderDetailFragment();
- if (ndf != null) {
- outState.putLong(OPTIONAL_FOLDER_ID, ndf.getIdFolder());
- outState.putBoolean(IS_FOLDER_BOOLEAN, ndf.getIdFeed() == null);
- outState.putLong(ID_FEED_STRING, ndf.getIdFeed() != null ? ndf.getIdFeed() : ndf.getIdFolder());
-
- NewsListRecyclerAdapter adapter = (NewsListRecyclerAdapter) ndf.getRecyclerView().getAdapter();
- if (adapter != null) {
- outState.putInt(LIST_ADAPTER_TOTAL_COUNT, adapter.getTotalItemCount());
- outState.putInt(LIST_ADAPTER_PAGE_COUNT, adapter.getCachedPages());
- }
- }
- if(mSearchView != null) {
- mSearchString = mSearchView.getQuery().toString();
- outState.putString(SEARCH_KEY, mSearchString);
+ private void saveInstanceState(Bundle outState) {
+ NewsReaderDetailFragment ndf = getNewsReaderDetailFragment();
+ if (ndf != null) {
+ outState.putLong(OPTIONAL_FOLDER_ID, ndf.getIdFolder());
+ outState.putBoolean(IS_FOLDER_BOOLEAN, ndf.getIdFeed() == null);
+ outState.putLong(ID_FEED_STRING, ndf.getIdFeed() != null ? ndf.getIdFeed() : ndf.getIdFolder());
+
+ NewsListRecyclerAdapter adapter = (NewsListRecyclerAdapter) ndf.getRecyclerView().getAdapter();
+ if (adapter != null) {
+ outState.putInt(LIST_ADAPTER_TOTAL_COUNT, adapter.getTotalItemCount());
+ outState.putInt(LIST_ADAPTER_PAGE_COUNT, adapter.getCachedPages());
+ }
+ }
+ if (mSearchView != null) {
+ mSearchString = mSearchView.getQuery().toString();
+ outState.putString(SEARCH_KEY, mSearchString);
}
}
@@ -327,70 +325,69 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
savedInstanceState.containsKey(IS_FOLDER_BOOLEAN) &&
savedInstanceState.containsKey(OPTIONAL_FOLDER_ID)) {
- NewsListRecyclerAdapter adapter = new NewsListRecyclerAdapter(this, getNewsReaderDetailFragment().binding.list, this, mPostDelayHandler, mPrefs);
-
- adapter.setTotalItemCount(savedInstanceState.getInt(LIST_ADAPTER_TOTAL_COUNT));
- adapter.setCachedPages(savedInstanceState.getInt(LIST_ADAPTER_PAGE_COUNT));
+ NewsListRecyclerAdapter adapter = new NewsListRecyclerAdapter(this, getNewsReaderDetailFragment().binding.list, this, mPostDelayHandler, mPrefs);
- getNewsReaderDetailFragment()
- .getRecyclerView()
- .setAdapter(adapter);
+ adapter.setTotalItemCount(savedInstanceState.getInt(LIST_ADAPTER_TOTAL_COUNT));
+ adapter.setCachedPages(savedInstanceState.getInt(LIST_ADAPTER_PAGE_COUNT));
- updateDetailFragment(savedInstanceState.getLong(ID_FEED_STRING),
- savedInstanceState.getBoolean(IS_FOLDER_BOOLEAN),
- savedInstanceState.getLong(OPTIONAL_FOLDER_ID),
- false);
- }
- mSearchString = savedInstanceState.getString(SEARCH_KEY, null);
- }
+ getNewsReaderDetailFragment()
+ .getRecyclerView()
+ .setAdapter(adapter);
+ updateDetailFragment(savedInstanceState.getLong(ID_FEED_STRING),
+ savedInstanceState.getBoolean(IS_FOLDER_BOOLEAN),
+ savedInstanceState.getLong(OPTIONAL_FOLDER_ID),
+ false);
+ }
+ mSearchString = savedInstanceState.getString(SEARCH_KEY, null);
+ }
- /**
- * This method increases the "pull to open drawer" area by three.
- * This method should be called only once!
- */
- private void adjustEdgeSizeOfDrawer() {
- try {
- // increase the size of the drag margin to prevent starting a star swipe when
- // trying to open the drawer.
- Field mDragger = binding.drawerLayout.getClass().getDeclaredField("mLeftDragger");
- mDragger.setAccessible(true);
- ViewDragHelper draggerObj = (ViewDragHelper) mDragger.get(binding.drawerLayout);
- Field mEdgeSize = draggerObj.getClass().getDeclaredField("mEdgeSize");
- mEdgeSize.setAccessible(true);
- int edge = mEdgeSize.getInt(draggerObj);
- mEdgeSize.setInt(draggerObj, edge * 3);
- } catch (Exception e) {
- Log.e(TAG, "Setting edge width of drawer failed..", e);
- }
- }
+ @Override
+ public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (drawerToggle != null) {
+ drawerToggle.onConfigurationChanged(newConfig);
+ }
+ }
- public int getEdgeSizeOfDrawer() {
- try {
- Field mDragger = binding.drawerLayout.getClass().getDeclaredField("mLeftDragger");
- mDragger.setAccessible(true);
- ViewDragHelper draggerObj = (ViewDragHelper) mDragger.get(binding.drawerLayout);
- Field mEdgeSize = draggerObj.getClass().getDeclaredField("mEdgeSize");
- mEdgeSize.setAccessible(true);
- return mEdgeSize.getInt(draggerObj);
- } catch (Exception e) {
- Log.e(TAG, "Failed to get edge size of drawer", e);
- }
- return 0;
- }
+ /**
+ * This method increases the "pull to open drawer" area by three.
+ * This method should be called only once!
+ */
+ private void adjustEdgeSizeOfDrawer() {
+ try {
+ // increase the size of the drag margin to prevent starting a star swipe when
+ // trying to open the drawer.
+ Field mDragger = Objects.requireNonNull(binding.drawerLayout).getClass().getDeclaredField("mLeftDragger");
+ mDragger.setAccessible(true);
+ ViewDragHelper draggerObj = (ViewDragHelper) mDragger.get(binding.drawerLayout);
+ Field mEdgeSize = Objects.requireNonNull(draggerObj).getClass().getDeclaredField("mEdgeSize");
+ mEdgeSize.setAccessible(true);
+ int edge = mEdgeSize.getInt(draggerObj);
+ mEdgeSize.setInt(draggerObj, edge * 3);
+ } catch (Exception e) {
+ Log.e(TAG, "Setting edge width of drawer failed..", e);
+ }
+ }
- private void showTapLogoToSyncShowcaseView() {
- getSlidingListFragment().showTapLogoToSyncShowcaseView();
- }
+ private void showTapLogoToSyncShowcaseView() {
+ getSlidingListFragment().showTapLogoToSyncShowcaseView();
+ }
- private View.OnClickListener mSnackbarListener = new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- //Toast.makeText(getActivity(), "button 1 pressed", 3000).show();
- updateCurrentRssView();
- }
- };
+ public int getEdgeSizeOfDrawer() {
+ try {
+ Field mDragger = Objects.requireNonNull(binding.drawerLayout).getClass().getDeclaredField("mLeftDragger");
+ mDragger.setAccessible(true);
+ ViewDragHelper draggerObj = (ViewDragHelper) mDragger.get(binding.drawerLayout);
+ Field mEdgeSize = Objects.requireNonNull(draggerObj).getClass().getDeclaredField("mEdgeSize");
+ mEdgeSize.setAccessible(true);
+ return mEdgeSize.getInt(draggerObj);
+ } catch (Exception e) {
+ Log.e(TAG, "Failed to get edge size of drawer", e);
+ }
+ return 0;
+ }
/**
@@ -598,17 +595,10 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
startDialogFragment(idFeed, false);
}
-
private void startDialogFragment(long idFeed, Boolean isFolder) {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(getApplicationContext());
- if (isFolder) {
- /*
- if(idFeed >= 0) {
- //currently no actions for folders
- //String titel = dbConn.getFolderById(idFeed).getLabel();
- }*/
- } else {
+ if (!isFolder) {
String titel = dbConn.getFeedById(idFeed).getFeedTitle();
String iconurl = dbConn.getFeedById(idFeed).getFaviconUrl();
String feedurl = dbConn.getFeedById(idFeed).getLink();
@@ -660,14 +650,14 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
}
- public void UpdateItemList()
- {
- try {
- NewsReaderDetailFragment nrD = getNewsReaderDetailFragment();
- if (nrD != null)
- nrD.getRecyclerView().getAdapter().notifyDataSetChanged();
- } catch (Exception ex) {
- ex.printStackTrace();
+ public void UpdateItemList() {
+ try {
+ NewsReaderDetailFragment nrD = getNewsReaderDetailFragment();
+ if (nrD != null && nrD.getRecyclerView() != null) {
+ nrD.getRecyclerView().getAdapter().notifyDataSetChanged();
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
}
}
@@ -786,14 +776,14 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
public static final int RESULT_ADD_NEW_FEED = 15643;
@Override
- public boolean onOptionsItemSelected(MenuItem item) {
- if(drawerToggle != null && drawerToggle.onOptionsItemSelected(item))
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
+ if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item))
return true;
switch (item.getItemId()) {
case android.R.id.home:
- if(handlePodcastBackPressed())
+ if (handlePodcastBackPressed())
return true;
break;
@@ -860,7 +850,6 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
} else {
Log.e("Permission error","Asking for permission");
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.FOREGROUND_SERVICE}, REQUEST_CODE_PERMISSION_DOWNLOAD_WEB_ARCHIVE);
- return;
}
} else { //you dont need to worry about these stuff below api level 23
Log.v("Permission error","You already have the permission");
@@ -1057,23 +1046,22 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
private void resetUiAndStartSync() {
getSlidingListFragment().loadOwncloudOrNextcloudBanner();
getSlidingListFragment().reloadAdapter();
- updateCurrentRssView();
- startSync();
- getSlidingListFragment().bindUserInfoToUI();
- }
+ updateCurrentRssView();
+ startSync();
+ getSlidingListFragment().bindUserInfoToUI();
+ }
- private void UpdateListView()
- {
- getNewsReaderDetailFragment().notifyDataSetChangedOnAdapter();
- }
+ private void UpdateListView() {
+ getNewsReaderDetailFragment().notifyDataSetChangedOnAdapter();
+ }
- @Override
- public void onClick(ViewHolder vh, int position) {
+ @Override
+ public void onClick(RssItemViewHolder vh, int position) {
if (mPrefs.getBoolean(SettingsActivity.CB_SKIP_DETAILVIEW_AND_OPEN_BROWSER_DIRECTLY_STRING, false)) {
- String currentUrl = vh.getRssItem().getLink();
+ String currentUrl = vh.getRssItem().getLink();
- //Choose Browser based on user settings
+ //Choose Browser based on user settings
//modified copy from NewsDetailFragment.java:loadUrl(String url)
int selectedBrowser = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_DISPLAY_BROWSER, "0"));
if (selectedBrowser == 0) { // Custom Tabs
@@ -1089,7 +1077,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
startActivity(browserIntent);
}
- ((NewsListRecyclerAdapter) getNewsReaderDetailFragment().getRecyclerView().getAdapter()).changeReadStateOfItem(vh, true);
+ ((NewsListRecyclerAdapter) getNewsReaderDetailFragment().getRecyclerView().getAdapter()).changeReadStateOfItem(vh, true);
} else {
Intent intentNewsDetailAct = new Intent(this, NewsDetailActivity.class);
@@ -1100,18 +1088,18 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
}
@Override
- public boolean onLongClick(ViewHolder vh, int position) {
- RssItem rssItem = vh.getRssItem();
- DialogFragment newFragment =
- NewsDetailImageDialogFragment.newInstanceUrl(rssItem.getTitle(), rssItem.getLink());
- FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
- Fragment prev = getSupportFragmentManager().findFragmentByTag("menu_fragment_dialog");
- if (prev != null) {
- ft.remove(prev);
- }
- ft.addToBackStack(null);
- newFragment.show(ft, "menu_fragment_dialog");
- return true;
+ public boolean onLongClick(RssItemViewHolder vh, int position) {
+ RssItem rssItem = vh.getRssItem();
+ DialogFragment newFragment =
+ NewsDetailImageDialogFragment.newInstanceUrl(rssItem.getTitle(), rssItem.getLink());
+ FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
+ Fragment prev = getSupportFragmentManager().findFragmentByTag("menu_fragment_dialog");
+ if (prev != null) {
+ ft.remove(prev);
+ }
+ ft.addToBackStack(null);
+ newFragment.show(ft, "menu_fragment_dialog");
+ return true;
}
@Override
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java
index 1026fd83..f93d2e89 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java
@@ -1,5 +1,6 @@
package de.luhmer.owncloudnewsreader.adapter;
+import android.content.Context;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.util.Log;
@@ -7,6 +8,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import androidx.annotation.NonNull;
import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -22,6 +24,11 @@ import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemCardViewBinding;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemHeadlineBinding;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemTextBinding;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemThumbnailBinding;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemWebLayoutBinding;
import de.luhmer.owncloudnewsreader.events.podcast.PodcastCompletedEvent;
import de.luhmer.owncloudnewsreader.helper.AsyncTaskHelper;
import de.luhmer.owncloudnewsreader.helper.PostDelayHandler;
@@ -74,7 +81,7 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
recyclerView
.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
- public void onScrolled(RecyclerView recyclerView,
+ public void onScrolled(@NonNull RecyclerView recyclerView,
int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
@@ -88,15 +95,13 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
Log.v(TAG, "start load more task...");
- recyclerView.post(new Runnable() {
- public void run() {
- // End has been reached
- // Do something
- lazyList.add(null);
- notifyItemInserted(lazyList.size() - 1);
+ recyclerView.post(() -> {
+ // End has been reached
+ // Do something
+ lazyList.add(null);
+ notifyItemInserted(lazyList.size() - 1);
- AsyncTaskHelper.StartAsyncTask(new LoadMoreItemsAsyncTask());
- }
+ AsyncTaskHelper.StartAsyncTask(new LoadMoreItemsAsyncTask());
});
}
}
@@ -150,50 +155,48 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
}
@Override
- public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+ public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, @NonNull int viewType) {
if (viewType == VIEW_PROG) {
View v = LayoutInflater.from(parent.getContext()).inflate(
R.layout.progressbar_item, parent, false);
-
return new ProgressViewHolder(v);
} else {
- Integer layout = 0;
+ Context context = parent.getContext();
+ RssItemViewHolder viewHolder = null;
switch (Integer.parseInt(mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0"))) {
case 0:
- layout = R.layout.subscription_detail_list_item_thumbnail;
+ viewHolder = new RssItemThumbnailViewHolder(SubscriptionDetailListItemThumbnailBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
break;
case 1:
+ viewHolder = new RssItemTextViewHolder(SubscriptionDetailListItemTextBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
+ break;
case 3:
- layout = R.layout.subscription_detail_list_item_text;
+ viewHolder = new RssItemFullTextViewHolder(SubscriptionDetailListItemTextBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
break;
case 2:
- layout = R.layout.subscription_detail_list_item_web_layout;
+ viewHolder = new RssItemWebViewHolder(SubscriptionDetailListItemWebLayoutBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
break;
case 4:
- layout = R.layout.subscription_detail_list_item_card_view;
+ viewHolder = new RssItemCardViewHolder(SubscriptionDetailListItemCardViewBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
break;
case 5:
- layout = R.layout.subscription_detail_list_item_headline;
+ viewHolder = new RssItemHeadlineViewHolder(SubscriptionDetailListItemHeadlineBinding.inflate(LayoutInflater.from(context), parent, false), mPrefs);
break;
default:
Log.e(TAG, "Unknown layout..");
}
- View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
-
- final ViewHolder holder = new ViewHolder(view, mPrefs);
- holder.starImageView.setOnClickListener(view1 -> toggleStarredStateOfItem(holder));
+ RssItemViewHolder finalViewHolder = viewHolder;
+ viewHolder.getStar().setOnClickListener(view1 -> toggleStarredStateOfItem(finalViewHolder));
- holder.setClickListener((RecyclerItemClickListener) activity);
-
- holder.flPlayPausePodcastWrapper.setOnClickListener(v -> {
- if (holder.isPlaying()) {
+ viewHolder.getPlayPausePodcastWrapper().setOnClickListener(v -> {
+ if (finalViewHolder.isPlaying()) {
playPausePodcastClicked.pausePodcast();
} else {
- playPausePodcastClicked.openPodcast(holder.getRssItem());
+ playPausePodcastClicked.openPodcast(finalViewHolder.getRssItem());
}
});
-
+ viewHolder.setClickListener((RecyclerItemClickListener) activity);
/*
// TODO implement option to delete cached podcasts (https://github.com/nextcloud/news-android/issues/742)
holder.flPlayPausePodcastWrapper.setOnLongClickListener(v -> {
@@ -208,47 +211,48 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
return false;
});
*/
-
- return holder;
+ return viewHolder;
}
}
@Override
- public void onBindViewHolder(final RecyclerView.ViewHolder viewHolder, int position) {
- if(viewHolder instanceof ProgressViewHolder) {
+ public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder viewHolder, int position) {
+ if (viewHolder instanceof ProgressViewHolder) {
((ProgressViewHolder) viewHolder).progressBar.setIndeterminate(true);
} else {
- final ViewHolder holder = (ViewHolder) viewHolder;
+ final RssItemViewHolder holder = (RssItemViewHolder) viewHolder;
RssItem item = lazyList.get(position);
- holder.setRssItem(item);
+ holder.bind(item);
holder.setStayUnread(NewsReaderListActivity.stayUnreadItems.contains(item.getId()));
//Podcast stuff
if (DatabaseConnectionOrm.ALLOWED_PODCASTS_TYPES.contains(item.getEnclosureMime())) {
final boolean isPlaying = idOfCurrentlyPlayedPodcast == item.getId();
//Enable podcast buttons in view
- holder.flPlayPausePodcastWrapper.setVisibility(View.VISIBLE);
+ holder.getPlayPausePodcastWrapper().setVisibility(View.VISIBLE);
holder.setPlaying(isPlaying);
holder.setDownloadPodcastProgressbar();
} else {
- holder.flPlayPausePodcastWrapper.setVisibility(View.GONE);
+ holder.getPlayPausePodcastWrapper().setVisibility(View.GONE);
}
}
}
@Override
- public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
- if(holder instanceof ViewHolder)
+ public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) {
+ if (holder instanceof RssItemViewHolder) {
EventBus.getDefault().unregister(holder);
+ }
}
@Override
- public void onViewAttachedToWindow(RecyclerView.ViewHolder holder) {
- if(holder instanceof ViewHolder)
+ public void onViewAttachedToWindow(@NonNull RecyclerView.ViewHolder holder) {
+ if (holder instanceof RssItemViewHolder) {
EventBus.getDefault().register(holder);
+ }
}
- public void changeReadStateOfItem(ViewHolder viewHolder, boolean isChecked) {
+ public void changeReadStateOfItem(RssItemViewHolder viewHolder, boolean isChecked) {
RssItem rssItem = viewHolder.getRssItem();
if (rssItem.getRead_temp() != isChecked) { // Only perform database operations if really needed
rssItem.setRead_temp(isChecked);
@@ -263,13 +267,13 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
}
}
- public void toggleReadStateOfItem(ViewHolder viewHolder) {
+ public void toggleReadStateOfItem(RssItemViewHolder viewHolder) {
RssItem rssItem = viewHolder.getRssItem();
boolean isRead = !rssItem.getRead_temp();
changeReadStateOfItem(viewHolder, isRead);
}
- public void toggleStarredStateOfItem(ViewHolder viewHolder) {
+ public void toggleStarredStateOfItem(RssItemViewHolder viewHolder) {
RssItem rssItem = viewHolder.getRssItem();
boolean isStarred = !rssItem.getStarred_temp();
rssItem.setStarred_temp(isStarred);
@@ -394,16 +398,8 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(activity);
List<RssItem> items = dbConn.getCurrentRssItemView(cachedPages++);
- /*
- try {
- Thread.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }*/
-
sw.stop();
Log.v(TAG, "Time needed (loading more): " + sw.toString());
-
return items;
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.java
index 114a5a8f..a5095230 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.java
@@ -4,6 +4,7 @@ import android.view.View;
import android.widget.ProgressBar;
import androidx.recyclerview.widget.RecyclerView;
+
import de.luhmer.owncloudnewsreader.R;
public class ProgressViewHolder extends RecyclerView.ViewHolder {
@@ -11,6 +12,6 @@ public class ProgressViewHolder extends RecyclerView.ViewHolder {
public ProgressViewHolder(View v) {
super(v);
- progressBar = (ProgressBar) v.findViewById(R.id.progressBar);
+ progressBar = v.findViewById(R.id.progressBar);
}
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.java
index cffdee0b..0a19bee2 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.java
@@ -1,6 +1,7 @@
package de.luhmer.owncloudnewsreader.adapter;
public interface RecyclerItemClickListener {
- void onClick(ViewHolder vh, int position);
- boolean onLongClick(ViewHolder vh, int position);
+ void onClick(RssItemViewHolder vh, int position);
+
+ boolean onLongClick(RssItemViewHolder vh, int position);
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemCardViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemCardViewHolder.java
new file mode 100644
index 00000000..3bc64691
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemCardViewHolder.java
@@ -0,0 +1,78 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+
+import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemCardViewBinding;
+
+public class RssItemCardViewHolder extends RssItemViewHolder {
+ SubscriptionDetailListItemCardViewBinding binding;
+
+ RssItemCardViewHolder(@NonNull SubscriptionDetailListItemCardViewBinding binding, SharedPreferences sharedPreferences) {
+ super(binding.getRoot(), sharedPreferences);
+ this.binding = binding;
+ }
+
+ @Override
+ protected ImageView getImageViewFavIcon() {
+ return binding.imgViewFavIcon;
+ }
+
+ @Override
+ protected ImageView getStar() {
+ return binding.starImageview;
+ }
+
+ @Override
+ protected ImageView getPlayPausePodcastButton() {
+ return binding.podcastWrapper.btnPlayPausePodcast;
+ }
+
+ @Override
+ protected View getColorFeed() {
+ return binding.colorLineFeed;
+ }
+
+ @Override
+ protected TextView getTextViewTitle() {
+ return binding.tvSubscription;
+ }
+
+ @Override
+ protected TextView getTextViewSummary() {
+ return binding.summary;
+ }
+
+ @Override
+ protected TextView getTextViewBody() {
+ return binding.body;
+ }
+
+ @Override
+ protected TextView getTextViewItemDate() {
+ return binding.tvItemDate;
+ }
+
+ @Override
+ protected FrameLayout getPlayPausePodcastWrapper() {
+ return binding.podcastWrapper.flPlayPausePodcastWrapper;
+ }
+
+ @Override
+ protected ProgressBar getPodcastDownloadProgress() {
+ return binding.podcastWrapper.podcastDownloadProgress;
+ }
+
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
+ super.bind(rssItem);
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemFullTextViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemFullTextViewHolder.java
new file mode 100644
index 00000000..d8db05d3
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemFullTextViewHolder.java
@@ -0,0 +1,13 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+
+import androidx.annotation.NonNull;
+
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemTextBinding;
+
+public class RssItemFullTextViewHolder extends RssItemTextViewHolder {
+ RssItemFullTextViewHolder(@NonNull SubscriptionDetailListItemTextBinding binding, SharedPreferences sharedPreferences) {
+ super(binding, sharedPreferences);
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineViewHolder.java
new file mode 100644
index 00000000..56888c85
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineViewHolder.java
@@ -0,0 +1,78 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+
+import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemHeadlineBinding;
+
+public class RssItemHeadlineViewHolder extends RssItemViewHolder {
+ SubscriptionDetailListItemHeadlineBinding binding;
+
+ RssItemHeadlineViewHolder(@NonNull SubscriptionDetailListItemHeadlineBinding binding, SharedPreferences sharedPreferences) {
+ super(binding.getRoot(), sharedPreferences);
+ this.binding = binding;
+ }
+
+ @Override
+ protected ImageView getImageViewFavIcon() {
+ return binding.imgViewFavIcon;
+ }
+
+ @Override
+ protected ImageView getStar() {
+ return binding.starImageview;
+ }
+
+ @Override
+ protected ImageView getPlayPausePodcastButton() {
+ return binding.podcastWrapper.btnPlayPausePodcast;
+ }
+
+ @Override
+ protected View getColorFeed() {
+ return binding.colorLineFeed;
+ }
+
+ @Override
+ protected TextView getTextViewTitle() {
+ return binding.tvSubscription;
+ }
+
+ @Override
+ protected TextView getTextViewSummary() {
+ return binding.summary;
+ }
+
+ @Override
+ protected TextView getTextViewBody() {
+ return null;
+ }
+
+ @Override
+ protected TextView getTextViewItemDate() {
+ return binding.tvItemDate;
+ }
+
+ @Override
+ protected FrameLayout getPlayPausePodcastWrapper() {
+ return binding.podcastWrapper.flPlayPausePodcastWrapper;
+ }
+
+ @Override
+ protected ProgressBar getPodcastDownloadProgress() {
+ return binding.podcastWrapper.podcastDownloadProgress;
+ }
+
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
+ super.bind(rssItem);
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemTextViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemTextViewHolder.java
new file mode 100644
index 00000000..6623c332
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemTextViewHolder.java
@@ -0,0 +1,78 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+
+import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemTextBinding;
+
+public class RssItemTextViewHolder extends RssItemViewHolder {
+ SubscriptionDetailListItemTextBinding binding;
+
+ RssItemTextViewHolder(@NonNull SubscriptionDetailListItemTextBinding binding, SharedPreferences sharedPreferences) {
+ super(binding.getRoot(), sharedPreferences);
+ this.binding = binding;
+ }
+
+ @Override
+ protected ImageView getImageViewFavIcon() {
+ return binding.imgViewFavIcon;
+ }
+
+ @Override
+ protected ImageView getStar() {
+ return binding.starImageview;
+ }
+
+ @Override
+ protected ImageView getPlayPausePodcastButton() {
+ return binding.podcastWrapper.btnPlayPausePodcast;
+ }
+
+ @Override
+ protected View getColorFeed() {
+ return binding.colorLineFeed;
+ }
+
+ @Override
+ protected TextView getTextViewTitle() {
+ return binding.tvSubscription;
+ }
+
+ @Override
+ protected TextView getTextViewSummary() {
+ return binding.summary;
+ }
+
+ @Override
+ protected TextView getTextViewBody() {
+ return binding.body;
+ }
+
+ @Override
+ protected TextView getTextViewItemDate() {
+ return binding.tvItemDate;
+ }
+
+ @Override
+ protected FrameLayout getPlayPausePodcastWrapper() {
+ return binding.podcastWrapper.flPlayPausePodcastWrapper;
+ }
+
+ @Override
+ protected ProgressBar getPodcastDownloadProgress() {
+ return binding.podcastWrapper.podcastDownloadProgress;
+ }
+
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
+ super.bind(rssItem);
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemThumbnailViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemThumbnailViewHolder.java
new file mode 100644
index 00000000..3be61ffc
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemThumbnailViewHolder.java
@@ -0,0 +1,128 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+import android.graphics.drawable.Drawable;
+import android.view.View;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
+
+import com.nostra13.universalimageloader.core.DisplayImageOptions;
+import com.nostra13.universalimageloader.core.ImageLoader;
+
+import java.util.Collections;
+import java.util.List;
+
+import de.luhmer.owncloudnewsreader.R;
+import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
+import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemThumbnailBinding;
+import de.luhmer.owncloudnewsreader.helper.ImageHandler;
+import de.luhmer.owncloudnewsreader.helper.SquareRoundedBitmapDisplayer;
+
+import static android.view.View.GONE;
+
+public class RssItemThumbnailViewHolder extends RssItemViewHolder {
+ private final DisplayImageOptions displayImageOptionsThumbnail;
+ SubscriptionDetailListItemThumbnailBinding binding;
+
+ RssItemThumbnailViewHolder(@NonNull SubscriptionDetailListItemThumbnailBinding binding, SharedPreferences sharedPreferences) {
+ super(binding.getRoot(), sharedPreferences);
+ this.binding = binding;
+
+
+ Drawable feedIcon = VectorDrawableCompat.create(itemView.getResources(), R.drawable.feed_icon, null);
+ displayImageOptionsThumbnail = new DisplayImageOptions.Builder()
+ .displayer(new SquareRoundedBitmapDisplayer(30))
+ .showImageOnLoading(feedIcon)
+ .showImageForEmptyUri(feedIcon)
+ .showImageOnFail(feedIcon)
+ .cacheOnDisk(true)
+ .cacheInMemory(true)
+ .build();
+ }
+
+ @Override
+ protected ImageView getImageViewFavIcon() {
+ return binding.imgViewFavIcon;
+ }
+
+ @Override
+ protected ImageView getStar() {
+ return binding.starImageview;
+ }
+
+ @Override
+ protected ImageView getPlayPausePodcastButton() {
+ return binding.podcastWrapper.btnPlayPausePodcast;
+ }
+
+ @Override
+ protected View getColorFeed() {
+ return null;
+ }
+
+ @Override
+ protected TextView getTextViewTitle() {
+ return binding.tvSubscription;
+ }
+
+ @Override
+ protected TextView getTextViewSummary() {
+ return binding.summary;
+ }
+
+ @Override
+ protected TextView getTextViewBody() {
+ return binding.body;
+ }
+
+ @Override
+ protected TextView getTextViewItemDate() {
+ return binding.tvItemDate;
+ }
+
+ @Override
+ protected FrameLayout getPlayPausePodcastWrapper() {
+ return binding.podcastWrapper.flPlayPausePodcastWrapper;
+ }
+
+ @Override
+ protected ProgressBar getPodcastDownloadProgress() {
+ return binding.podcastWrapper.podcastDownloadProgress;
+ }
+
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
+ super.bind(rssItem);
+
+ binding.imgViewThumbnail.setColorFilter(null);
+ String body = rssItem.getBody();
+ List<String> images;
+ if (rssItem.getMediaThumbnail() != null && !rssItem.getMediaThumbnail().isEmpty()) {
+ images = Collections.singletonList(rssItem.getMediaThumbnail());
+ } else {
+ images = ImageHandler.getImageLinksFromText(body);
+ }
+
+ if (images.size() > 0) {
+ binding.imgViewThumbnail.setVisibility(View.VISIBLE);
+ ImageLoader.getInstance().displayImage(images.get(0), binding.imgViewThumbnail, displayImageOptionsThumbnail);
+ } else {
+ // Show Podcast Icon if no thumbnail is available but it is a podcast (otherwise the podcast button will go missing)
+ if (DatabaseConnectionOrm.ALLOWED_PODCASTS_TYPES.contains(rssItem.getEnclosureMime())) {
+ binding.imgViewThumbnail.setVisibility(View.VISIBLE);
+ //imgViewThumbnail.setColorFilter(Color.parseColor("#d8d8d8"));
+ Drawable feedIcon = VectorDrawableCompat.create(itemView.getResources(), R.drawable.feed_icon, null);
+ binding.imgViewThumbnail.setImageDrawable(feedIcon);
+ } else {
+ binding.imgViewThumbnail.setVisibility(GONE);
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemViewHolder.java
index 7af3614f..4597e468 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ViewHolder.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemViewHolder.java
@@ -4,253 +4,142 @@ import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Typeface;
-import android.graphics.drawable.Drawable;
import android.text.Html;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.format.DateUtils;
import android.text.style.ForegroundColorSpan;
import android.util.Log;
-import android.util.SparseArray;
+import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.View;
-import android.webkit.WebView;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
-import androidx.annotation.Nullable;
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
import androidx.core.content.ContextCompat;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
-
-import com.nostra13.universalimageloader.core.DisplayImageOptions;
-import com.nostra13.universalimageloader.core.ImageLoader;
import org.greenrobot.eventbus.Subscribe;
-import java.util.ArrayList;
-import java.util.List;
import java.util.regex.Pattern;
-import butterknife.BindView;
-import butterknife.ButterKnife;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.SettingsActivity;
-import de.luhmer.owncloudnewsreader.async_tasks.RssItemToHtmlTask;
-import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
import de.luhmer.owncloudnewsreader.helper.ColorHelper;
import de.luhmer.owncloudnewsreader.helper.FavIconHandler;
-import de.luhmer.owncloudnewsreader.helper.ImageHandler;
-import de.luhmer.owncloudnewsreader.helper.SquareRoundedBitmapDisplayer;
import de.luhmer.owncloudnewsreader.services.PodcastDownloadService;
-import static android.view.View.GONE;
-
-public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
- private final static String TAG = "RecyclerView.ViewHolder";
-
- private static SparseArray<Integer> downloadProgressList = new SparseArray<>();
-
- @Nullable
- @BindView(R.id.star_imageview)
- protected ImageView starImageView;
-
- @BindView(R.id.summary)
- protected TextView textViewSummary;
-
- @BindView(R.id.tv_item_date)
- protected TextView textViewItemDate;
-
- @BindView(R.id.tv_subscription)
- protected TextView textViewTitle;
-
- @Nullable
- @BindView(R.id.imgViewFavIcon)
- protected ImageView imgViewFavIcon;
-
- @Nullable
- @BindView(R.id.imgViewThumbnail)
- protected ImageView imgViewThumbnail;
-
-
- @Nullable
- @BindView(R.id.color_line_feed)
- protected View colorLineFeed;
-
- @BindView(R.id.btn_playPausePodcast)
- protected ImageView btnPlayPausePodcast;
-
- @BindView(R.id.podcastDownloadProgress)
- //protected HoloCircularProgressBar pbPodcastDownloadProgress; // TODO reminder: remove this dependency (and fix podcast progressbar issues)
- protected ProgressBar pbPodcastDownloadProgress;
-
- @BindView(R.id.podcast_wrapper)
- View flPlayPausePodcastWrapper;
-
- // only in extended layout
- @Nullable @BindView(R.id.body)
- protected TextView textViewBody;
-
- // Only in extended with webview layout
- @Nullable @BindView(R.id.webView_body)
- protected WebView webView_body;
+public abstract class RssItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener {
+ private final static String TAG = RssItemViewHolder.class.getCanonicalName();
+ private static final SparseIntArray downloadProgressList = new SparseIntArray();
+ private static FavIconHandler favIconHandler = null;
+ protected final SharedPreferences mPrefs;
+ private final int LengthBody = 400;
+ private final ForegroundColorSpan bodyForegroundColor;
private RecyclerItemClickListener clickListener;
private RssItem rssItem;
private boolean stayUnread = false;
- private static FavIconHandler favIconHandler = null;
- private final int LengthBody = 400;
- private ForegroundColorSpan bodyForegroundColor;
private boolean playing;
- private int selectedListLayout;
private int starColor;
private int inactiveStarColor;
- private DisplayImageOptions displayImageOptionsThumbnail;
-
- private int textSizeSummary;
- private int textSizeTitle;
- private int textSizeItemDate;
- private int textSizeBody = -1;
- private SharedPreferences mPrefs;
- public ViewHolder(View itemView, SharedPreferences prefs) {
+ RssItemViewHolder(@NonNull View itemView, SharedPreferences sharedPreferences) {
super(itemView);
-
- this.mPrefs = prefs;
-
- selectedListLayout = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0"));
+ this.mPrefs = sharedPreferences;
bodyForegroundColor = new ForegroundColorSpan(ContextCompat.getColor(itemView.getContext(), android.R.color.secondary_text_dark));
- if(favIconHandler == null) {
+ if (favIconHandler == null) {
favIconHandler = new FavIconHandler(itemView.getContext());
}
- ButterKnife.bind(this, itemView);
-
- int[] attribute = new int[]{ R.attr.starredColor, R.attr.unstarredColor };
- TypedArray array = starImageView.getContext().getTheme().obtainStyledAttributes(attribute);
- starColor = array.getColor(0, Color.TRANSPARENT);
- inactiveStarColor = array.getColor(1, Color.LTGRAY);
- array.recycle();
-
- // get and store initial item text sizes (can't figure out how to directly get this info from layout definition)
- textSizeSummary = Math.round(textViewSummary.getTextSize());
- textSizeTitle = Math.round(textViewTitle.getTextSize());
- if(textViewBody != null) {
- textSizeBody = Math.round(textViewBody.getTextSize());
- }
- textSizeItemDate = Math.round(textViewItemDate.getTextSize());
-
itemView.setOnClickListener(this);
itemView.setOnLongClickListener(this);
-
- Drawable feedIcon = VectorDrawableCompat.create(itemView.getResources(), R.drawable.feed_icon, null) ;
- displayImageOptionsThumbnail = new DisplayImageOptions.Builder()
- .displayer(new SquareRoundedBitmapDisplayer(30))
- .showImageOnLoading(feedIcon)
- .showImageForEmptyUri(feedIcon)
- .showImageOnFail(feedIcon)
- .cacheOnDisk(true)
- .cacheInMemory(true)
- .build();
}
- @Subscribe
- public void onEvent(PodcastDownloadService.DownloadProgressUpdate downloadProgress) {
- downloadProgressList.put((int) downloadProgress.podcast.itemId, downloadProgress.podcast.downloadProgress);
- if (rssItem.getId().equals(downloadProgress.podcast.itemId)) {
- pbPodcastDownloadProgress.setProgress(downloadProgress.podcast.downloadProgress);
-
- Log.v(TAG, "Progress of download1: " + downloadProgress.podcast.downloadProgress);
+ /**
+ * Apply scaling factor to TextView font size, based on app font-size preference.
+ *
+ * @param tv TextView object to be scaled
+ * @param initialTvSize app layout definition default size of TextView element
+ * @param halfScale if set to true, will only apply half of the scaling factor
+ */
+ private static void scaleTextSize(TextView tv, int initialTvSize, boolean halfScale, SharedPreferences mPrefs) {
+ float scalingFactor = Float.parseFloat(mPrefs.getString(SettingsActivity.SP_FONT_SIZE, "1.0"));
+ if (halfScale) {
+ scalingFactor = scalingFactor + (1 - scalingFactor) / 2;
}
- }
- public void setDownloadPodcastProgressbar() {
- float progress;
- if(PodcastDownloadService.PodcastAlreadyCached(itemView.getContext(), rssItem.getEnclosureLink())) {
- progress = 100;
- } else {
- if(downloadProgressList.get(rssItem.getId().intValue()) != null) {
- progress = downloadProgressList.get(rssItem.getId().intValue());
- } else {
- progress = 0;
- }
+ int initialSize = initialTvSize;
+ if (initialSize < 0) {
+ initialSize = Math.round(tv.getTextSize());
}
- pbPodcastDownloadProgress.setProgress((int) progress);
- Log.v(TAG, "Progress of download2: " + progress);
+ // float sp = initialSize / tv.getContext().getResources().getDisplayMetrics().scaledDensity; // transform scaled pixels, device pixels
+ tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, Math.round(initialSize * scalingFactor));
}
- @Override
- public void onClick(View v) {
- clickListener.onClick(this, getLayoutPosition());
+ /**
+ * Return the number of rss item body text lines, depending on the currently selected font size/scale;
+ * only meant to be used with thumbnail feed view.
+ *
+ * @return number of lines of rss item body text lines to be used in thumbnail feed view
+ */
+ private static int scaleTextLines(SharedPreferences prefs) {
+ float scalingFactor = Float.parseFloat(prefs.getString(SettingsActivity.SP_FONT_SIZE, "1.0"));
+ /* The following formula computes the number of text lines for Simple item view; it simply boils
+ * down to a linear conversion from the font scaling factor from 0.8 -> 6 lines to 1.6 -> 3 lines
+ */
+ return Math.round((scalingFactor * -5) + 10);
}
- public void setClickListener(RecyclerItemClickListener clickListener) {
- this.clickListener = clickListener;
- }
+ abstract protected ImageView getImageViewFavIcon();
- @Override
- public boolean onLongClick(View v) {
- return clickListener.onLongClick(this, getLayoutPosition());
- }
+ abstract protected ImageView getStar();
- private void setFeedColor(int color) {
- if(colorLineFeed != null) {
- colorLineFeed.setBackgroundColor(color);
- }
- }
+ abstract protected ImageView getPlayPausePodcastButton();
- public void setReadState(boolean isRead) {
- if(textViewSummary != null) {
- float alpha = 1f;
- if (isRead) {
- textViewSummary.setTypeface(Typeface.DEFAULT);
- alpha = 0.7f;
- } else {
- textViewSummary.setTypeface(Typeface.DEFAULT_BOLD);
- }
+ abstract protected View getColorFeed();
- ((View) textViewSummary.getParent()).setAlpha(alpha);
- }
- }
+ abstract protected TextView getTextViewTitle();
- public void setStarred(boolean isStarred) {
- int color = isStarred ? starColor : inactiveStarColor;
- int contentDescriptionId = isStarred ?
- R.string.content_desc_remove_from_favorites :
- R.string.content_desc_add_to_favorites;
- starImageView.setColorFilter(color);
- starImageView.setContentDescription(starImageView.getContext().getString(contentDescriptionId));
- }
+ abstract protected TextView getTextViewSummary();
- public void setPlaying(boolean playing) {
- this.playing = playing;
-
- int imageId = playing ? R.drawable.ic_action_pause : R.drawable.ic_action_play;
- int contentDescriptionId = playing ? R.string.content_desc_pause : R.string.content_desc_play;
+ abstract protected TextView getTextViewBody();
- String contentDescription = btnPlayPausePodcast.getContext().getString(contentDescriptionId);
- btnPlayPausePodcast.setContentDescription(contentDescription);
- btnPlayPausePodcast.setImageResource(imageId);
- }
+ abstract protected TextView getTextViewItemDate();
- public boolean isPlaying() {
- return playing;
- }
+ abstract protected FrameLayout getPlayPausePodcastWrapper();
- public RssItem getRssItem() {
- return rssItem;
- }
+ abstract protected ProgressBar getPodcastDownloadProgress();
- public void setRssItem(RssItem rssItem) {
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
this.rssItem = rssItem;
+
+ int[] attribute = new int[]{R.attr.starredColor, R.attr.unstarredColor};
+ TypedArray array = getStar().getContext().getTheme().obtainStyledAttributes(attribute);
+ starColor = array.getColor(0, Color.TRANSPARENT);
+ inactiveStarColor = array.getColor(1, Color.LTGRAY);
+ array.recycle();
+
+ TextView textViewBody = getTextViewBody();
+
+ // get and store initial item text sizes (can't figure out how to directly get this info from layout definition)
+ int textSizeSummary = Math.round(getTextViewSummary().getTextSize());
+ int textSizeTitle = Math.round(getTextViewTitle().getTextSize());
+ int textSizeItemDate = Math.round(getTextViewItemDate().getTextSize());
+
+
String title = null;
String favIconUrl = null;
- if(rssItem.getFeed() != null) {
+ if (rssItem.getFeed() != null) {
title = rssItem.getFeed().getFeedTitle();
favIconUrl = rssItem.getFeed().getFaviconUrl();
} else {
@@ -262,12 +151,9 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
setFeedColor(ColorHelper.getFeedColor(itemView.getContext(), rssItem.getFeed()));
- if(textViewSummary != null) {
+ TextView textViewSummary = getTextViewSummary();
+ if (textViewSummary != null) {
try {
- //byte[] arrByteForSpanish = rssItem.getTitle().getBytes("ISO-8859-1");
- //String spanish = new String(arrByteForSpanish);//.getBytes("UTF-8");
- //textViewSummary.setText(Html.fromHtml(spanish));
-
textViewSummary.setText(Html.fromHtml(rssItem.getTitle()));
scaleTextSize(textViewSummary, textSizeSummary, false, mPrefs);
} catch (Exception e) {
@@ -275,110 +161,77 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
}
}
- if(textViewTitle != null && title != null) {
+ TextView textViewTitle = getTextViewTitle();
+ if (textViewTitle != null && title != null) {
textViewTitle.setText(Html.fromHtml(title));
scaleTextSize(textViewTitle, textSizeTitle, true, mPrefs);
}
- if(textViewBody != null) {
- String body = rssItem.getMediaDescription();
- if(body == null || body.isEmpty()) {
- body = rssItem.getBody();
- }
-
- boolean limitLength = true;
- // Strip html from String
- if(selectedListLayout == 0) {
- textViewBody.setMaxLines(scaleTextLines(mPrefs));
- limitLength = false;
- } else if(selectedListLayout == 3) {
- textViewBody.setMaxLines(200);
- limitLength = false;
- }
- body = getBodyText(body, limitLength);
- textViewBody.setText(Html.fromHtml(body));
- scaleTextSize(textViewBody, textSizeBody, false, mPrefs);
- }
-
int height = 0; // used for feed icon vertical offset calculation
- if(textViewItemDate != null) {
+
+ TextView textViewItemDate = getTextViewItemDate();
+ if (textViewItemDate != null) {
textViewItemDate.setText(DateUtils.getRelativeTimeSpanString(rssItem.getPubDate().getTime()));
scaleTextSize(textViewItemDate, textSizeItemDate, true, mPrefs);
height = Math.round(textViewItemDate.getTextSize());
}
+ ImageView imgViewFavIcon = getImageViewFavIcon();
if (imgViewFavIcon != null) {
- favIconHandler.loadFavIconForFeed(favIconUrl, imgViewFavIcon, Math.round((height-textSizeItemDate)/2));
+ favIconHandler.loadFavIconForFeed(favIconUrl, imgViewFavIcon, Math.round((height - textSizeItemDate) / 2));
}
- if(imgViewThumbnail != null) {
- imgViewThumbnail.setColorFilter(null);
- String body = rssItem.getBody();
- List<String> images;
- if(rssItem.getMediaThumbnail() != null && !rssItem.getMediaThumbnail().isEmpty()) {
- images = new ArrayList();
- images.add(rssItem.getMediaThumbnail());
- } else {
- images = ImageHandler.getImageLinksFromText(body);
+
+ if (textViewBody != null) {
+ int textSizeBody = Math.round(textViewBody.getTextSize());
+
+ String body = rssItem.getMediaDescription();
+ if (body == null || body.isEmpty()) {
+ body = rssItem.getBody();
}
- if(images.size() > 0) {
- imgViewThumbnail.setVisibility(View.VISIBLE);
- ImageLoader.getInstance().displayImage(images.get(0), imgViewThumbnail, displayImageOptionsThumbnail);
- } else {
- // Show Podcast Icon if no thumbnail is available but it is a podcast (otherwise the podcast button will go missing)
- if (DatabaseConnectionOrm.ALLOWED_PODCASTS_TYPES.contains(rssItem.getEnclosureMime())) {
- imgViewThumbnail.setVisibility(View.VISIBLE);
- //imgViewThumbnail.setColorFilter(Color.parseColor("#d8d8d8"));
- Drawable feedIcon = VectorDrawableCompat.create(itemView.getResources(), R.drawable.feed_icon, null) ;
- imgViewThumbnail.setImageDrawable(feedIcon);
- } else {
- imgViewThumbnail.setVisibility(GONE);
- }
+ boolean limitLength = true;
+ // Strip html from String
+ if (this instanceof RssItemFullTextViewHolder) {
+ textViewBody.setMaxLines(200);
+ limitLength = false;
+ } else if (this instanceof RssItemTextViewHolder) {
+ textViewBody.setMaxLines(scaleTextLines(mPrefs));
+ limitLength = false;
}
+ body = getBodyText(body, limitLength);
+ textViewBody.setText(Html.fromHtml(body));
+ scaleTextSize(textViewBody, textSizeBody, false, mPrefs);
}
+ }
- if(webView_body != null) {
- String htmlPage = RssItemToHtmlTask.getHtmlPage(rssItem, false, mPrefs, itemView.getContext());
- webView_body.loadDataWithBaseURL("file:///android_asset/", htmlPage, "text/html", "UTF-8", "");
- }
+ @Override
+ public void onClick(View v) {
+ clickListener.onClick(this, getLayoutPosition());
}
- /**
- * Apply scaling factor to TextView font size, based on app font-size preference.
- *
- * @param tv TextView object to be scaled
- * @param initialTvSize app layout definition default size of TextView element
- * @param halfScale if set to true, will only apply half of the scaling factor
- */
- private static void scaleTextSize(TextView tv, int initialTvSize, boolean halfScale, SharedPreferences mPrefs) {
- float scalingFactor = Float.parseFloat(mPrefs.getString(SettingsActivity.SP_FONT_SIZE, "1.0"));
- if(halfScale) {
- scalingFactor = scalingFactor + (1-scalingFactor)/2;
- }
+ public void setClickListener(RecyclerItemClickListener clickListener) {
+ this.clickListener = clickListener;
+ }
- int initialSize = initialTvSize;
- if(initialSize < 0) {
- initialSize = Math.round(tv.getTextSize());
- }
- // float sp = initialSize / tv.getContext().getResources().getDisplayMetrics().scaledDensity; // transform scaled pixels, device pixels
- tv.setTextSize(TypedValue.COMPLEX_UNIT_PX, Math.round(initialSize*scalingFactor));
+ @Override
+ public boolean onLongClick(View v) {
+ return clickListener.onLongClick(this, getLayoutPosition());
}
- /**
- * Return the number of rss item body text lines, depending on the currently selected font size/scale;
- * only meant to be used with thumbnail feed view.
- *
- * @return number of lines of rss item body text lines to be used in thumbnail feed view
- */
- private static int scaleTextLines(SharedPreferences prefs) {
- float scalingFactor = Float.parseFloat(prefs.getString(SettingsActivity.SP_FONT_SIZE, "1.0"));
- /* The following formula computes the number of text lines for Simple item view; it simply boils
- * down to a linear conversion from the font scaling factor from 0.8 -> 6 lines to 1.6 -> 3 lines
- */
- return Math.round((scalingFactor*-5)+10);
+ public void setStarred(boolean isStarred) {
+ int color = isStarred ? starColor : inactiveStarColor;
+ int contentDescriptionId = isStarred ?
+ R.string.content_desc_remove_from_favorites :
+ R.string.content_desc_add_to_favorites;
+ ImageView star = getStar();
+ star.setColorFilter(color);
+ star.setContentDescription(star.getContext().getString(contentDescriptionId));
}
+ public RssItem getRssItem() {
+ return rssItem;
+ }
public boolean shouldStayUnread() {
return stayUnread;
@@ -388,10 +241,9 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
this.stayUnread = shouldStayUnread;
}
- private String getBodyText(String body, boolean limitLength)
- {
+ private String getBodyText(String body, boolean limitLength) {
if (body.startsWith("<![CDATA[")) {
- body = body.replaceFirst( Pattern.quote("<![CDATA["), "");
+ body = body.replaceFirst(Pattern.quote("<![CDATA["), "");
body = body.replaceFirst("]]>", "");
}
@@ -404,10 +256,68 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
String bodyString = bodyStringSpannable.toString().trim();
- if(limitLength && bodyString.length() > LengthBody) {
+ if (limitLength && bodyString.length() > LengthBody) {
bodyString = bodyString.substring(0, LengthBody) + "...";
}
return bodyString;
}
-}
+
+ private void setFeedColor(int color) {
+ if (getColorFeed() != null) {
+ getColorFeed().setBackgroundColor(color);
+ }
+ }
+
+ public void setReadState(boolean isRead) {
+ TextView textViewSummary = getTextViewSummary();
+ if (textViewSummary != null) {
+ float alpha = 1f;
+ if (isRead) {
+ textViewSummary.setTypeface(Typeface.DEFAULT);
+ alpha = 0.7f;
+ } else {
+ textViewSummary.setTypeface(Typeface.DEFAULT_BOLD);
+ }
+
+ ((View) textViewSummary.getParent()).setAlpha(alpha);
+ }
+ }
+
+ public boolean isPlaying() {
+ return playing;
+ }
+
+ public void setPlaying(boolean playing) {
+ this.playing = playing;
+
+ int imageId = playing ? R.drawable.ic_action_pause : R.drawable.ic_action_play;
+ int contentDescriptionId = playing ? R.string.content_desc_pause : R.string.content_desc_play;
+
+ ImageView playPause = getPlayPausePodcastButton();
+ String contentDescription = playPause.getContext().getString(contentDescriptionId);
+ playPause.setContentDescription(contentDescription);
+ playPause.setImageResource(imageId);
+ }
+
+ public void setDownloadPodcastProgressbar() {
+ float progress;
+ if (PodcastDownloadService.PodcastAlreadyCached(itemView.getContext(), rssItem.getEnclosureLink())) {
+ progress = 100;
+ } else {
+ progress = downloadProgressList.get(rssItem.getId().intValue(), 0);
+ }
+ getPodcastDownloadProgress().setProgress((int) progress);
+ Log.v(TAG, "Progress of download2: " + progress);
+ }
+
+ @Subscribe
+ public void onEvent(PodcastDownloadService.DownloadProgressUpdate downloadProgress) {
+ downloadProgressList.put((int) downloadProgress.podcast.itemId, downloadProgress.podcast.downloadProgress);
+ if (rssItem.getId().equals(downloadProgress.podcast.itemId)) {
+ getPodcastDownloadProgress().setProgress(downloadProgress.podcast.downloadProgress);
+
+ Log.v(TAG, "Progress of download1: " + downloadProgress.podcast.downloadProgress);
+ }
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemWebViewHolder.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemWebViewHolder.java
new file mode 100644
index 00000000..b187face
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemWebViewHolder.java
@@ -0,0 +1,82 @@
+package de.luhmer.owncloudnewsreader.adapter;
+
+import android.content.SharedPreferences;
+import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.TextView;
+
+import androidx.annotation.CallSuper;
+import androidx.annotation.NonNull;
+
+import de.luhmer.owncloudnewsreader.async_tasks.RssItemToHtmlTask;
+import de.luhmer.owncloudnewsreader.database.model.RssItem;
+import de.luhmer.owncloudnewsreader.databinding.SubscriptionDetailListItemWebLayoutBinding;
+
+public class RssItemWebViewHolder extends RssItemViewHolder {
+ SubscriptionDetailListItemWebLayoutBinding binding;
+
+ RssItemWebViewHolder(@NonNull SubscriptionDetailListItemWebLayoutBinding binding, SharedPreferences sharedPreferences) {
+ super(binding.getRoot(), sharedPreferences);
+ this.binding = binding;
+ }
+
+ @Override
+ protected ImageView getImageViewFavIcon() {
+ return binding.layoutThumbnail.imgViewFavIcon;
+ }
+
+ @Override
+ protected ImageView getStar() {
+ return binding.layoutThumbnail.starImageview;
+ }
+
+ @Override
+ protected ImageView getPlayPausePodcastButton() {
+ return binding.layoutThumbnail.podcastWrapper.btnPlayPausePodcast;
+ }
+
+ @Override
+ protected ImageView getColorFeed() {
+ return null;
+ }
+
+ @Override
+ protected TextView getTextViewTitle() {
+ return binding.layoutThumbnail.tvSubscription;
+ }
+
+ @Override
+ protected TextView getTextViewSummary() {
+ return binding.layoutThumbnail.summary;
+ }
+
+ @Override
+ protected TextView getTextViewBody() {
+ return binding.layoutThumbnail.body;
+ }
+
+ @Override
+ protected TextView getTextViewItemDate() {
+ return binding.layoutThumbnail.tvItemDate;
+ }
+
+ @Override
+ protected FrameLayout getPlayPausePodcastWrapper() {
+ return binding.layoutThumbnail.podcastWrapper.flPlayPausePodcastWrapper;
+ }
+
+ @Override
+ protected ProgressBar getPodcastDownloadProgress() {
+ return binding.layoutThumbnail.podcastWrapper.podcastDownloadProgress;
+ }
+
+ @CallSuper
+ public void bind(@NonNull RssItem rssItem) {
+ super.bind(rssItem);
+
+ String htmlPage = RssItemToHtmlTask.getHtmlPage(rssItem, false, mPrefs, itemView.getContext());
+ binding.webViewBody.loadDataWithBaseURL("file:///android_asset/", htmlPage, "text/html", "UTF-8", "");
+
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
index 55d99152..f877a866 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
@@ -27,13 +27,14 @@ import android.util.Log;
import android.view.View;
import android.widget.ImageView;
+import androidx.core.content.ContextCompat;
+import androidx.palette.graphics.Palette;
+
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.listener.ImageLoadingListener;
-import androidx.core.content.ContextCompat;
-import androidx.palette.graphics.Palette;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.model.Feed;
@@ -42,10 +43,7 @@ public class FavIconHandler {
private static final String TAG = FavIconHandler.class.getCanonicalName();
private final DisplayImageOptions displayImageOptions;
- private Context context;
-
public FavIconHandler(Context context) {
- this.context = context;
int placeHolder = FavIconHandler.getResourceIdForRightDefaultFeedIcon();
displayImageOptions = new DisplayImageOptions.Builder()
.showImageOnLoading(placeHolder)
@@ -73,19 +71,18 @@ public class FavIconHandler {
imgView.setTranslationY(offset);
}
- private static int getResourceIdForRightDefaultFeedIcon()
- {
- if(ThemeChooser.getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
+ private static int getResourceIdForRightDefaultFeedIcon() {
+ if (ThemeChooser.getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
return R.drawable.default_feed_icon_dark;
} else {
return R.drawable.default_feed_icon_light;
}
- }
+ }
- public void preCacheFavIcon(final Feed feed) throws IllegalStateException {
- if(feed.getFaviconUrl() == null) {
- Log.v(TAG, "No favicon for "+feed.getFeedTitle());
+ public void preCacheFavIcon(final Feed feed, Context context) throws IllegalStateException {
+ if (feed.getFaviconUrl() == null) {
+ Log.v(TAG, "No favicon for " + feed.getFeedTitle());
return;
}
@@ -103,7 +100,7 @@ public class FavIconHandler {
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
- DownloadFinished(feed.getId(), loadedImage);
+ DownloadFinished(feed.getId(), loadedImage, context);
}
@Override
@@ -113,8 +110,8 @@ public class FavIconHandler {
});
}
- private void DownloadFinished(long feedId, Bitmap bitmap) {
- if(bitmap != null) {
+ private void DownloadFinished(long feedId, Bitmap bitmap, Context context) {
+ if (bitmap != null) {
DatabaseConnectionOrm dbConn = new DatabaseConnectionOrm(context);
Feed feed = dbConn.getFeedById(feedId);
Palette palette = Palette.from(bitmap).generate();