make ThemeChooser static / use DI for SharedPreferences
This commit is contained in:
parent
8716119737
commit
62f79242b4
21 changed files with 142 additions and 141 deletions
|
@ -8,9 +8,6 @@ import com.nextcloud.android.sso.model.SingleSignOnAccount;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Named;
|
||||
|
||||
import dagger.Provides;
|
||||
import de.luhmer.owncloudnewsreader.MockSharedPreference;
|
||||
import de.luhmer.owncloudnewsreader.NewsReaderListFragment;
|
||||
import de.luhmer.owncloudnewsreader.SettingsActivity;
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
package de.luhmer.owncloudnewsreader.tests;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
|
||||
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
|
|
|
@ -3,7 +3,6 @@ package de.luhmer.owncloudnewsreader.tests;
|
|||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.preference.Preference;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
|
@ -16,7 +15,9 @@ import java.lang.reflect.Method;
|
|||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.espresso.contrib.RecyclerViewActions;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.rule.ActivityTestRule;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
@ -26,21 +27,15 @@ import de.luhmer.owncloudnewsreader.TestApplication;
|
|||
import de.luhmer.owncloudnewsreader.di.TestComponent;
|
||||
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
|
||||
|
||||
import static androidx.test.espresso.Espresso.onData;
|
||||
import static androidx.test.espresso.Espresso.onView;
|
||||
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
|
||||
import static androidx.test.espresso.action.ViewActions.click;
|
||||
import static androidx.test.espresso.assertion.ViewAssertions.matches;
|
||||
import static androidx.test.espresso.matcher.PreferenceMatchers.withKey;
|
||||
import static androidx.test.espresso.matcher.PreferenceMatchers.withSummary;
|
||||
import static androidx.test.espresso.matcher.PreferenceMatchers.withTitle;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isCompletelyDisplayed;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.withText;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.hamcrest.CoreMatchers.instanceOf;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.core.AllOf.allOf;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.fail;
|
||||
|
@ -111,7 +106,7 @@ public class NightModeTest {
|
|||
navigateUp();
|
||||
|
||||
boolean isDarkTheme = isDarkTheme();
|
||||
assertFalse(ThemeChooser.getInstance(getActivity()).isOledMode(getActivity(), false));
|
||||
assertFalse(ThemeChooser.isOledMode(false));
|
||||
assertFalse(isDarkTheme);
|
||||
assertEquals(ThemeChooser.THEME.LIGHT, getPrivateField("mSelectedTheme"));
|
||||
//sleep();
|
||||
|
@ -126,7 +121,7 @@ public class NightModeTest {
|
|||
navigateUp();
|
||||
sleep();
|
||||
boolean isDarkTheme = isDarkTheme();
|
||||
assertFalse(ThemeChooser.getInstance(getActivity()).isOledMode(getActivity(), false));
|
||||
assertFalse(ThemeChooser.isOledMode(false));
|
||||
assertTrue(isDarkTheme);
|
||||
assertEquals(ThemeChooser.THEME.DARK, getPrivateField("mSelectedTheme"));
|
||||
//sleep();
|
||||
|
@ -142,7 +137,7 @@ public class NightModeTest {
|
|||
navigateUp();
|
||||
sleep();
|
||||
boolean isDarkTheme = isDarkTheme();
|
||||
assertTrue(ThemeChooser.getInstance(getActivity()).isOledMode(getActivity(), false));
|
||||
assertTrue(ThemeChooser.isOledMode(false));
|
||||
assertTrue(isDarkTheme);
|
||||
assertEquals(ThemeChooser.THEME.OLED, getPrivateField("mSelectedTheme"));
|
||||
//sleep();
|
||||
|
@ -166,13 +161,10 @@ public class NightModeTest {
|
|||
|
||||
private void changeAppTheme(int appThemeText) {
|
||||
String title = getActivity().getString(R.string.pref_title_app_theme);
|
||||
onData(allOf(
|
||||
is(instanceOf(Preference.class)),
|
||||
withKey("sp_app_theme"),
|
||||
withTitle(R.string.pref_title_app_theme)))
|
||||
.onChildView(withText(title))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
.perform(click());
|
||||
|
||||
onView(is(instanceOf(RecyclerView.class)))
|
||||
.perform(RecyclerViewActions.scrollTo(hasDescendant(withText(title))))
|
||||
.perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(title)), click()));
|
||||
|
||||
onView(withText(getActivity().getString(appThemeText)))
|
||||
.perform(click());
|
||||
|
@ -180,23 +172,17 @@ public class NightModeTest {
|
|||
|
||||
private void switchOled() {
|
||||
String title = getActivity().getString(R.string.pref_oled_mode);
|
||||
onData(allOf(
|
||||
is(instanceOf(Preference.class)),
|
||||
withKey("cb_oled_mode"),
|
||||
withSummary(R.string.pref_oled_mode_summary),
|
||||
withTitle(R.string.pref_oled_mode)))
|
||||
.onChildView(withText(title))
|
||||
.check(matches(isCompletelyDisplayed()))
|
||||
.perform(click());
|
||||
|
||||
onView(is(instanceOf(RecyclerView.class)))
|
||||
.perform(RecyclerViewActions.scrollTo(hasDescendant(withText(title))))
|
||||
.perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(title)), click()));
|
||||
}
|
||||
|
||||
private boolean isDarkTheme() {
|
||||
ThemeChooser themeChooser = ThemeChooser.getInstance(getActivity());
|
||||
|
||||
try {
|
||||
Method method = ThemeChooser.class.getDeclaredMethod("isDarkTheme", Context.class);
|
||||
method.setAccessible(true);
|
||||
boolean isDarkTheme = (boolean) method.invoke(themeChooser, getActivity());
|
||||
boolean isDarkTheme = (boolean) method.invoke(null, getActivity());
|
||||
return isDarkTheme;
|
||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
||||
fail(e.toString() + " - " + e.getMessage());
|
||||
|
@ -205,14 +191,12 @@ public class NightModeTest {
|
|||
}
|
||||
|
||||
private Object getPrivateField(String fieldName) {
|
||||
ThemeChooser themeChooser = ThemeChooser.getInstance(getActivity());
|
||||
|
||||
try {
|
||||
Field[] fields = ThemeChooser.class.getDeclaredFields();
|
||||
for (Field field : fields) {
|
||||
if(fieldName.equals(field.getName())) {
|
||||
field.setAccessible(true);
|
||||
return field.get(themeChooser);
|
||||
return field.get(null);
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
|
|
|
@ -8,8 +8,6 @@ import android.graphics.drawable.ColorDrawable;
|
|||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.os.Build;
|
||||
import androidx.test.espresso.matcher.BoundedMatcher;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
@ -20,6 +18,9 @@ import org.hamcrest.Matcher;
|
|||
import org.hamcrest.TypeSafeDiagnosingMatcher;
|
||||
import org.hamcrest.TypeSafeMatcher;
|
||||
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.test.espresso.matcher.BoundedMatcher;
|
||||
|
||||
public class CustomMatchers {
|
||||
private static final String TAG = CustomMatchers.class.getCanonicalName();
|
||||
|
||||
|
|
|
@ -27,16 +27,17 @@ package helper;
|
|||
|
||||
import android.app.Activity;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import androidx.test.espresso.UiController;
|
||||
import androidx.test.espresso.ViewAction;
|
||||
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
|
||||
import androidx.test.runner.lifecycle.Stage;
|
||||
import android.view.View;
|
||||
|
||||
import org.hamcrest.Matcher;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
import androidx.test.espresso.UiController;
|
||||
import androidx.test.espresso.ViewAction;
|
||||
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
|
||||
import androidx.test.runner.lifecycle.Stage;
|
||||
|
||||
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package helper;
|
||||
|
||||
import androidx.test.espresso.NoMatchingViewException;
|
||||
import androidx.test.espresso.ViewAssertion;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.view.View;
|
||||
import androidx.test.espresso.NoMatchingViewException;
|
||||
import androidx.test.espresso.ViewAssertion;
|
||||
|
||||
public class RecyclerViewAssertions implements ViewAssertion {
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ import android.widget.LinearLayout;
|
|||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -110,8 +109,7 @@ public class SubscriptionExpandableListAdapter extends BaseExpandableListAdapter
|
|||
}
|
||||
}
|
||||
|
||||
public SubscriptionExpandableListAdapter(Context mContext, DatabaseConnectionOrm dbConn, ListView listView)
|
||||
{
|
||||
public SubscriptionExpandableListAdapter(Context mContext, DatabaseConnectionOrm dbConn, ListView listView) {
|
||||
favIconHandler = new FavIconHandler(mContext);
|
||||
|
||||
this.inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
@ -362,7 +360,7 @@ public class SubscriptionExpandableListAdapter extends BaseExpandableListAdapter
|
|||
|
||||
private int getBtn_rating_star_off_normal_holo_light() {
|
||||
if(btn_rating_star_off_normal_holo_light == null) {
|
||||
if(ThemeChooser.getInstance(mContext).getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
|
||||
if(ThemeChooser.getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
|
||||
btn_rating_star_off_normal_holo_light = R.drawable.ic_action_star_border_light;
|
||||
} else {
|
||||
btn_rating_star_off_normal_holo_light = R.drawable.ic_action_star_border_dark;
|
||||
|
|
|
@ -83,9 +83,9 @@ public class NewFeedActivity extends AppCompatActivity {
|
|||
protected void onCreate(Bundle savedInstanceState) {
|
||||
((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
|
||||
|
||||
ThemeChooser.getInstance(this).chooseTheme(this);
|
||||
ThemeChooser.chooseTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeChooser.getInstance(this).afterOnCreate(this);
|
||||
ThemeChooser.afterOnCreate(this);
|
||||
setContentView(R.layout.activity_new_feed);
|
||||
|
||||
ButterKnife.bind(this);
|
||||
|
|
|
@ -28,8 +28,6 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -55,6 +53,11 @@ import java.net.URL;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.browser.customtabs.CustomTabsIntent;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.fragment.app.DialogFragment;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
@ -80,6 +83,8 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
|
|||
protected @BindView(R.id.progressbar_webview) ProgressBar mProgressbarWebView;
|
||||
protected @BindView(R.id.tv_offline_version) TextView mTvOfflineVersion;
|
||||
|
||||
protected @Inject SharedPreferences mPrefs;
|
||||
|
||||
private int section_number;
|
||||
protected String html;
|
||||
boolean changedUrl = false;
|
||||
|
@ -93,6 +98,12 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
|
|||
return section_number;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
((NewsReaderApplication) getActivity().getApplication()).getAppComponent().injectFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
|
@ -178,7 +189,7 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
|
|||
|
||||
init_webView();
|
||||
RssItem rssItem = ndActivity.rssItems.get(section_number);
|
||||
RssItemToHtmlTask task = new RssItemToHtmlTask(ndActivity, rssItem, this);
|
||||
RssItemToHtmlTask task = new RssItemToHtmlTask(ndActivity, rssItem, this, mPrefs);
|
||||
AsyncTaskHelper.StartAsyncTask(task);
|
||||
}
|
||||
|
||||
|
|
|
@ -267,8 +267,9 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
|
|||
showTapLogoToSyncShowcaseView();
|
||||
}
|
||||
|
||||
Intent intent = new Intent(this, SettingsActivity.class);
|
||||
startActivityForResult(intent, RESULT_SETTINGS);
|
||||
// For testing (start Settings immediately)
|
||||
//Intent intent = new Intent(this, SettingsActivity.class);
|
||||
//startActivityForResult(intent, RESULT_SETTINGS);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
|
@ -997,7 +998,7 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements
|
|||
String oldListLayout = data.getStringExtra(SettingsActivity.SP_FEED_LIST_LAYOUT);
|
||||
String newListLayout = mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT,"0");
|
||||
|
||||
if (ThemeChooser.getInstance(NewsReaderListActivity.this).themeRequiresRestartOfUI(NewsReaderListActivity.this) || !newListLayout.equals(oldListLayout)) {
|
||||
if (ThemeChooser.themeRequiresRestartOfUI() || !newListLayout.equals(oldListLayout)) {
|
||||
NewsReaderListActivity.this.recreate();
|
||||
} else if (data.hasExtra(SettingsActivity.CACHE_CLEARED)) {
|
||||
resetUiAndStartSync();
|
||||
|
|
|
@ -79,6 +79,15 @@ public class NewsReaderListFragment extends Fragment implements OnCreateContextM
|
|||
protected @Inject ApiProvider mApi;
|
||||
protected @Inject SharedPreferences mPrefs;
|
||||
|
||||
private SubscriptionExpandableListAdapter lvAdapter;
|
||||
|
||||
@BindView(R.id.expandableListView) protected ExpandableListView eListView;
|
||||
@BindView(R.id.urlTextView) protected TextView urlTextView;
|
||||
@BindView(R.id.userTextView) protected TextView userTextView;
|
||||
@BindView(R.id.header_view) protected ViewGroup headerView;
|
||||
@BindView(R.id.header_logo) protected ImageView headerLogo;
|
||||
@BindView(R.id.header_logo_progress) protected View headerLogoProgress;
|
||||
|
||||
/**
|
||||
* The fragment's current callback object, which is notified of list item
|
||||
* clicks.
|
||||
|
@ -124,15 +133,6 @@ public class NewsReaderListFragment extends Fragment implements OnCreateContextM
|
|||
void onTopItemLongClicked(long idFeed, boolean isFolder);
|
||||
}
|
||||
|
||||
private SubscriptionExpandableListAdapter lvAdapter;
|
||||
|
||||
@BindView(R.id.expandableListView) protected ExpandableListView eListView;
|
||||
@BindView(R.id.urlTextView) protected TextView urlTextView;
|
||||
@BindView(R.id.userTextView) protected TextView userTextView;
|
||||
@BindView(R.id.header_view) protected ViewGroup headerView;
|
||||
@BindView(R.id.header_logo) protected ImageView headerLogo;
|
||||
@BindView(R.id.header_logo_progress) protected View headerLogoProgress;
|
||||
|
||||
/**
|
||||
* Mandatory empty constructor for the fragment manager to instantiate the
|
||||
* fragment (e.g. upon screen orientation changes).
|
||||
|
|
|
@ -106,9 +106,9 @@ public class PodcastFragmentActivity extends AppCompatActivity implements IPlayP
|
|||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
|
||||
|
||||
ThemeChooser.getInstance(this).chooseTheme(this);
|
||||
ThemeChooser.chooseTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeChooser.getInstance(this).afterOnCreate(this);
|
||||
ThemeChooser.afterOnCreate(this);
|
||||
|
||||
if (mApi.getAPI() instanceof Proxy) { // Single Sign On
|
||||
VersionCheckHelper.verifyMinVersion(this, MIN_NEXTCLOUD_FILES_APP_VERSION_CODE);
|
||||
|
|
|
@ -90,16 +90,16 @@ public class SettingsActivity extends AppCompatActivity {
|
|||
|
||||
public static final String CB_VERSION = "cb_version";
|
||||
|
||||
@Inject SharedPreferences mPrefs;
|
||||
protected @Inject SharedPreferences mPrefs;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
|
||||
|
||||
ThemeChooser.getInstance(this).chooseTheme(this);
|
||||
ThemeChooser.chooseTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeChooser.getInstance(this).afterOnCreate(this);
|
||||
ThemeChooser.afterOnCreate(this);
|
||||
|
||||
setContentView(R.layout.activity_settings);
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
|
@ -17,6 +15,8 @@ import android.view.ViewGroup;
|
|||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.appcompat.widget.Toolbar;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
@ -29,13 +29,15 @@ public class SyncIntervalSelectorActivity extends AppCompatActivity {
|
|||
SharedPreferences mPrefs;
|
||||
PlaceholderFragment mFragment;
|
||||
String[] items_values;
|
||||
@BindView(R.id.toolbar) Toolbar toolbar;
|
||||
protected @BindView(R.id.toolbar) Toolbar toolbar;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
ThemeChooser.getInstance(this).chooseTheme(this);
|
||||
((NewsReaderApplication) getApplication()).getAppComponent().injectActivity(this);
|
||||
|
||||
ThemeChooser.chooseTheme(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
ThemeChooser.getInstance(this).afterOnCreate(this);
|
||||
ThemeChooser.afterOnCreate(this);
|
||||
|
||||
setContentView(R.layout.activity_sync_interval_selector);
|
||||
|
||||
|
|
|
@ -179,7 +179,7 @@ public class NewsListRecyclerAdapter extends RecyclerView.Adapter {
|
|||
}
|
||||
View view = LayoutInflater.from(parent.getContext()).inflate(layout, parent, false);
|
||||
|
||||
final ViewHolder holder = new ViewHolder(view);
|
||||
final ViewHolder holder = new ViewHolder(view, mPrefs);
|
||||
|
||||
holder.starImageView.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
|
|
|
@ -5,8 +5,6 @@ import android.content.res.TypedArray;
|
|||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableString;
|
||||
|
@ -29,6 +27,8 @@ import org.greenrobot.eventbus.Subscribe;
|
|||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import butterknife.BindView;
|
||||
import butterknife.ButterKnife;
|
||||
|
@ -111,10 +111,13 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
private int textSizeItemDate;
|
||||
private int textSizeBody = -1;
|
||||
|
||||
public ViewHolder(View itemView) {
|
||||
SharedPreferences mPrefs;
|
||||
|
||||
public ViewHolder(View itemView, SharedPreferences prefs) {
|
||||
super(itemView);
|
||||
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(itemView.getContext());
|
||||
this.mPrefs = prefs;
|
||||
|
||||
selectedListLayout = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_FEED_LIST_LAYOUT, "0"));
|
||||
|
||||
bodyForegroundColor = new ForegroundColorSpan(ContextCompat.getColor(itemView.getContext(), android.R.color.secondary_text_dark));
|
||||
|
@ -262,7 +265,7 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
//textViewSummary.setText(Html.fromHtml(spanish));
|
||||
|
||||
textViewSummary.setText(Html.fromHtml(rssItem.getTitle()));
|
||||
scaleTextSize(textViewSummary, textSizeSummary, false);
|
||||
scaleTextSize(textViewSummary, textSizeSummary, false, mPrefs);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -270,7 +273,7 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
|
||||
if(textViewTitle != null && title != null) {
|
||||
textViewTitle.setText(Html.fromHtml(title));
|
||||
scaleTextSize(textViewTitle, textSizeTitle, true);
|
||||
scaleTextSize(textViewTitle, textSizeTitle, true, mPrefs);
|
||||
}
|
||||
|
||||
if(textViewBody != null) {
|
||||
|
@ -288,13 +291,13 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
body = getBodyText(body, true);
|
||||
}
|
||||
textViewBody.setText(Html.fromHtml(body));
|
||||
scaleTextSize(textViewBody, textSizeBody, false);
|
||||
scaleTextSize(textViewBody, textSizeBody, false, mPrefs);
|
||||
}
|
||||
|
||||
int height = 0; // used for feed icon vertical offset calculation
|
||||
if(textViewItemDate != null) {
|
||||
textViewItemDate.setText(DateUtils.getRelativeTimeSpanString(rssItem.getPubDate().getTime()));
|
||||
scaleTextSize(textViewItemDate, textSizeItemDate, true);
|
||||
scaleTextSize(textViewItemDate, textSizeItemDate, true, mPrefs);
|
||||
height = Math.round(textViewItemDate.getTextSize());
|
||||
}
|
||||
|
||||
|
@ -323,7 +326,7 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
}
|
||||
|
||||
if(webView_body != null) {
|
||||
String htmlPage = RssItemToHtmlTask.getHtmlPage(itemView.getContext(), rssItem, false);
|
||||
String htmlPage = RssItemToHtmlTask.getHtmlPage(rssItem, false, mPrefs, itemView.getContext());
|
||||
webView_body.loadDataWithBaseURL("file:///android_asset/", htmlPage, "text/html", "UTF-8", "");
|
||||
}
|
||||
}
|
||||
|
@ -335,8 +338,7 @@ public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickL
|
|||
* @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 = PreferenceManager.getDefaultSharedPreferences(tv.getContext());
|
||||
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;
|
||||
|
|
|
@ -3,7 +3,6 @@ package de.luhmer.owncloudnewsreader.async_tasks;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.AsyncTask;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.text.Html;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.Log;
|
||||
|
@ -23,9 +22,9 @@ import de.luhmer.owncloudnewsreader.SettingsActivity;
|
|||
import de.luhmer.owncloudnewsreader.database.model.Feed;
|
||||
import de.luhmer.owncloudnewsreader.database.model.RssItem;
|
||||
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
|
||||
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
|
||||
|
||||
import static de.luhmer.owncloudnewsreader.helper.ThemeChooser.THEME;
|
||||
import static de.luhmer.owncloudnewsreader.helper.ThemeChooser.getInstance;
|
||||
|
||||
|
||||
public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
||||
|
@ -41,10 +40,10 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
private static Pattern PATTERN_AUTOPLAY_VIDEOS_2 = Pattern.compile("(<video[^>]*)(\\sautoplay)(.*?>)");
|
||||
private static Pattern PATTERN_AUTOPLAY_REGEX_CB = Pattern.compile("(.*?)^(Unser Feedsponsor:\\s*<\\/p><p>\\s*.*?\\s*<\\/p>)(.*)", Pattern.MULTILINE);
|
||||
|
||||
|
||||
private Context mContext;
|
||||
private RssItem mRssItem;
|
||||
private Listener mListener;
|
||||
private SharedPreferences mPrefs;
|
||||
private boolean isRightToLeft;
|
||||
|
||||
|
||||
public interface Listener {
|
||||
|
@ -56,15 +55,17 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
}
|
||||
|
||||
|
||||
public RssItemToHtmlTask(Context context, RssItem rssItem, Listener listener) {
|
||||
this.mContext = context;
|
||||
public RssItemToHtmlTask(Context context, RssItem rssItem, Listener listener, SharedPreferences prefs) {
|
||||
this.mRssItem = rssItem;
|
||||
this.mListener = listener;
|
||||
this.mPrefs = prefs;
|
||||
|
||||
this.isRightToLeft = context.getResources().getBoolean(R.bool.is_right_to_left);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Void... params) {
|
||||
return getHtmlPage(mContext, mRssItem, true);
|
||||
return getHtmlPage(mRssItem, true, mPrefs, isRightToLeft);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -73,14 +74,16 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
super.onPostExecute(htmlPage);
|
||||
}
|
||||
|
||||
public static String getHtmlPage(RssItem rssItem, boolean showHeader, SharedPreferences mPrefs, Context context) {
|
||||
return getHtmlPage(rssItem, showHeader, mPrefs, context.getResources().getBoolean(R.bool.is_right_to_left));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param rssItem item to parse
|
||||
* @param showHeader true if a header with item title, feed title, etc. should be included
|
||||
* @return given RSS item as full HTML page
|
||||
*/
|
||||
public static String getHtmlPage(Context context, RssItem rssItem, boolean showHeader) {
|
||||
public static String getHtmlPage(RssItem rssItem, boolean showHeader, SharedPreferences mPrefs, boolean isRightToLeft) {
|
||||
String feedTitle = "Undefined";
|
||||
String favIconUrl = null;
|
||||
|
||||
|
@ -109,7 +112,7 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
}
|
||||
|
||||
String body_id = null;
|
||||
THEME selectedTheme = getInstance(context).getSelectedTheme();
|
||||
THEME selectedTheme = ThemeChooser.getSelectedTheme();
|
||||
switch (selectedTheme) {
|
||||
case LIGHT:
|
||||
body_id = "lightTheme";
|
||||
|
@ -124,7 +127,6 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
|
||||
Log.v(TAG, "Selected Theme: " + body_id);
|
||||
|
||||
boolean isRightToLeft = context.getResources().getBoolean(R.bool.is_right_to_left);
|
||||
String rtlClass = isRightToLeft ? "rtl" : "";
|
||||
//String borderSide = isRightToLeft ? "right" : "left";
|
||||
|
||||
|
@ -135,7 +137,6 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
|
|||
|
||||
|
||||
// font size scaling
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
double scalingFactor = Float.parseFloat(mPrefs.getString(SettingsActivity.SP_FONT_SIZE, "1.0"));
|
||||
DecimalFormat fontFormat = new DecimalFormat("#.#");
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import javax.inject.Singleton;
|
|||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
import de.luhmer.owncloudnewsreader.helper.PostDelayHandler;
|
||||
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
|
||||
import de.luhmer.owncloudnewsreader.ssl.MemorizingTrustManager;
|
||||
import okhttp3.Cache;
|
||||
import okhttp3.OkHttpClient;
|
||||
|
@ -37,7 +38,9 @@ public class ApiModule {
|
|||
// Application reference must come from AppModule.class
|
||||
SharedPreferences providesSharedPreferences() {
|
||||
//return PreferenceManager.getDefaultSharedPreferences(mApplication);
|
||||
return mApplication.getSharedPreferences(providesSharedPreferencesFileName(), Context.MODE_PRIVATE);
|
||||
SharedPreferences mPrefs = mApplication.getSharedPreferences(providesSharedPreferencesFileName(), Context.MODE_PRIVATE);
|
||||
ThemeChooser.init(mPrefs);
|
||||
return mPrefs;
|
||||
}
|
||||
|
||||
// Dagger will only look for methods annotated with @Provides
|
||||
|
|
|
@ -5,12 +5,14 @@ import javax.inject.Singleton;
|
|||
import dagger.Component;
|
||||
import de.luhmer.owncloudnewsreader.LoginDialogFragment;
|
||||
import de.luhmer.owncloudnewsreader.NewFeedActivity;
|
||||
import de.luhmer.owncloudnewsreader.NewsDetailFragment;
|
||||
import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
|
||||
import de.luhmer.owncloudnewsreader.NewsReaderListDialogFragment;
|
||||
import de.luhmer.owncloudnewsreader.NewsReaderListFragment;
|
||||
import de.luhmer.owncloudnewsreader.PodcastFragmentActivity;
|
||||
import de.luhmer.owncloudnewsreader.SettingsActivity;
|
||||
import de.luhmer.owncloudnewsreader.SettingsFragment;
|
||||
import de.luhmer.owncloudnewsreader.SyncIntervalSelectorActivity;
|
||||
import de.luhmer.owncloudnewsreader.authentication.OwnCloudSyncAdapter;
|
||||
import de.luhmer.owncloudnewsreader.services.SyncItemStateService;
|
||||
|
||||
|
@ -26,12 +28,15 @@ public interface AppComponent {
|
|||
void injectActivity(PodcastFragmentActivity activity);
|
||||
void injectActivity(NewFeedActivity activity);
|
||||
void injectActivity(SettingsActivity activity);
|
||||
void injectActivity(SyncIntervalSelectorActivity activity);
|
||||
|
||||
void injectFragment(NewsReaderListDialogFragment fragment);
|
||||
void injectFragment(NewsReaderListFragment fragment);
|
||||
void injectFragment(LoginDialogFragment fragment);
|
||||
void injectFragment(SettingsFragment settingsFragment);
|
||||
void injectFragment(SettingsFragment fragment);
|
||||
void injectFragment(NewsDetailFragment fragment);
|
||||
|
||||
void injectService(SyncItemStateService service);
|
||||
void injectService(OwnCloudSyncAdapter ownCloudSyncAdapter);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,8 +23,6 @@ package de.luhmer.owncloudnewsreader.helper;
|
|||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.palette.graphics.Palette;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
|
@ -34,6 +32,8 @@ 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;
|
||||
|
@ -46,7 +46,7 @@ public class FavIconHandler {
|
|||
|
||||
public FavIconHandler(Context context) {
|
||||
this.context = context;
|
||||
int placeHolder = FavIconHandler.getResourceIdForRightDefaultFeedIcon(context);
|
||||
int placeHolder = FavIconHandler.getResourceIdForRightDefaultFeedIcon();
|
||||
displayImageOptions = new DisplayImageOptions.Builder()
|
||||
.showImageOnLoading(placeHolder)
|
||||
.showImageForEmptyUri(placeHolder)
|
||||
|
@ -73,9 +73,9 @@ public class FavIconHandler {
|
|||
imgView.setTranslationY(offset);
|
||||
}
|
||||
|
||||
private static int getResourceIdForRightDefaultFeedIcon(Context context)
|
||||
private static int getResourceIdForRightDefaultFeedIcon()
|
||||
{
|
||||
if(ThemeChooser.getInstance(context).getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
|
||||
if(ThemeChooser.getSelectedTheme().equals(ThemeChooser.THEME.LIGHT)) {
|
||||
return R.drawable.default_feed_icon_dark;
|
||||
} else {
|
||||
return R.drawable.default_feed_icon_light;
|
||||
|
|
|
@ -25,41 +25,32 @@ import android.app.Activity;
|
|||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.preference.PreferenceManager;
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.app.AppCompatDelegate;
|
||||
import de.luhmer.owncloudnewsreader.R;
|
||||
import de.luhmer.owncloudnewsreader.SettingsActivity;
|
||||
|
||||
public class ThemeChooser {
|
||||
|
||||
private static final String TAG = ThemeChooser.class.getCanonicalName();
|
||||
private static ThemeChooser mInstance;
|
||||
|
||||
public enum THEME { LIGHT, DARK, OLED }
|
||||
|
||||
|
||||
// Contains the selected theme defined in the settings (used for checking whether the app needs
|
||||
// to restart after changing the theme
|
||||
private Integer mSelectedThemeFromPreferences;
|
||||
private Boolean mOledMode;
|
||||
private static Integer mSelectedThemeFromPreferences;
|
||||
private static Boolean mOledMode;
|
||||
private static SharedPreferences mPrefs;
|
||||
|
||||
// Contains the current selected theme
|
||||
public enum THEME { LIGHT, DARK, OLED }
|
||||
private THEME mSelectedTheme = THEME.LIGHT;
|
||||
private static THEME mSelectedTheme = THEME.LIGHT;
|
||||
|
||||
public static ThemeChooser getInstance(Context context) {
|
||||
if(mInstance == null) {
|
||||
mInstance = new ThemeChooser(context);
|
||||
}
|
||||
return mInstance;
|
||||
}
|
||||
private ThemeChooser() { }
|
||||
|
||||
private ThemeChooser(Context context) {
|
||||
getSelectedThemeFromPreferences(context, false); // Init cache
|
||||
isOledMode(context, false); // Init cache
|
||||
}
|
||||
|
||||
public void chooseTheme(Activity act) {
|
||||
switch(getInstance(act).getSelectedThemeFromPreferences(act, false)) {
|
||||
public static void chooseTheme(Activity act) {
|
||||
switch(getSelectedThemeFromPreferences(false)) {
|
||||
case 0: // Auto (Light / Dark)
|
||||
Log.v(TAG, "Auto (Light / Dark)");
|
||||
act.setTheme(R.style.AppTheme);
|
||||
|
@ -88,13 +79,13 @@ public class ThemeChooser {
|
|||
}
|
||||
}
|
||||
|
||||
public void afterOnCreate(Activity act) {
|
||||
public static void afterOnCreate(Activity act) {
|
||||
//int uiNightMode = Configuration.UI_MODE_NIGHT_NO;
|
||||
|
||||
if(isDarkTheme(act)) {
|
||||
mSelectedTheme = THEME.DARK; // this is required for auto mode at night
|
||||
|
||||
if (isOledMode(act, false) && isDarkTheme(act)) {
|
||||
if (isOledMode(false) && isDarkTheme(act)) {
|
||||
act.setTheme(R.style.AppThemeOLED);
|
||||
Log.v(TAG, "activate OLED mode");
|
||||
//uiNightMode = Configuration.UI_MODE_NIGHT_YES;
|
||||
|
@ -113,13 +104,13 @@ public class ThemeChooser {
|
|||
}
|
||||
|
||||
// Check if the currently loaded theme is different from the one set in the settings, or if OLED mode changed
|
||||
public boolean themeRequiresRestartOfUI(Context context) {
|
||||
boolean themeChanged = !mSelectedThemeFromPreferences.equals(getSelectedThemeFromPreferences(context, true));
|
||||
boolean oledChanged = !mOledMode.equals(isOledMode(context, true));
|
||||
public static boolean themeRequiresRestartOfUI() {
|
||||
boolean themeChanged = !mSelectedThemeFromPreferences.equals(getSelectedThemeFromPreferences(true));
|
||||
boolean oledChanged = !mOledMode.equals(isOledMode(true));
|
||||
return themeChanged || oledChanged;
|
||||
}
|
||||
|
||||
private boolean isDarkTheme(Context context) {
|
||||
private static boolean isDarkTheme(Context context) {
|
||||
switch(AppCompatDelegate.getDefaultNightMode()) {
|
||||
case AppCompatDelegate.MODE_NIGHT_YES:
|
||||
Log.v(TAG, "MODE_NIGHT_YES (Dark Theme)");
|
||||
|
@ -142,23 +133,27 @@ public class ThemeChooser {
|
|||
}
|
||||
}
|
||||
|
||||
public boolean isOledMode(Context context, boolean forceReloadCache) {
|
||||
public static boolean isOledMode(boolean forceReloadCache) {
|
||||
if(mOledMode == null || forceReloadCache) {
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
mOledMode = mPrefs.getBoolean(SettingsActivity.CB_OLED_MODE, false);
|
||||
}
|
||||
return mOledMode;
|
||||
}
|
||||
|
||||
public THEME getSelectedTheme() {
|
||||
public static THEME getSelectedTheme() {
|
||||
return mSelectedTheme;
|
||||
}
|
||||
|
||||
private int getSelectedThemeFromPreferences(Context context, boolean forceReloadCache) {
|
||||
private static int getSelectedThemeFromPreferences(boolean forceReloadCache) {
|
||||
if(mSelectedThemeFromPreferences == null || forceReloadCache) {
|
||||
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
mSelectedThemeFromPreferences = Integer.parseInt(mPrefs.getString(SettingsActivity.SP_APP_THEME, "0"));
|
||||
}
|
||||
return mSelectedThemeFromPreferences;
|
||||
}
|
||||
|
||||
public static void init(SharedPreferences prefs) {
|
||||
mPrefs = prefs;
|
||||
getSelectedThemeFromPreferences(false); // Init cache
|
||||
isOledMode(false); // Init cache
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue