make ThemeChooser static / use DI for SharedPreferences

This commit is contained in:
David Luhmer 2019-04-07 15:46:41 -03:00
parent 8716119737
commit 62f79242b4
21 changed files with 142 additions and 141 deletions

View file

@ -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;

View file

@ -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)

View file

@ -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) {

View file

@ -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();

View file

@ -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;
/**

View file

@ -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 {

View file

@ -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;

View file

@ -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);

View file

@ -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);
}

View file

@ -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();

View file

@ -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).

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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("#.#");

View file

@ -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

View file

@ -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);
}

View file

@ -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;

View file

@ -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
}
}