first working implementation of incognito mode

This commit is contained in:
David Luhmer 2019-09-26 21:55:06 +02:00
parent 09550b2532
commit 227b149ff4
7 changed files with 162 additions and 35 deletions

View file

@ -53,16 +53,13 @@ body#darkTheme a:visited {
}
*/
body, blockquote, img, iframe, video, div, table, tbody, tr, td, pre, code, blockquote, p, em, b {
body, blockquote, img, iframe, video, div, table, tbody, tr, td, pre, code, blockquote, p, em, b, span {
width: auto !important;
height: auto !important;
max-width: 100% !important;
}
span {
width: auto !important;
height: auto !important;
max-width: 100% !important;
display: block;
}

View file

@ -26,7 +26,9 @@ import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.text.Html;
import android.util.Log;
import android.util.SparseArray;
@ -34,8 +36,11 @@ import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.ViewGroup;
import android.webkit.WebView;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.browser.customtabs.CustomTabsIntent;
import androidx.core.content.ContextCompat;
@ -58,6 +63,7 @@ import butterknife.ButterKnife;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm;
import de.luhmer.owncloudnewsreader.database.DatabaseConnectionOrm.SORT_DIRECTION;
import de.luhmer.owncloudnewsreader.database.model.RssItem;
import de.luhmer.owncloudnewsreader.helper.ThemeUtils;
import de.luhmer.owncloudnewsreader.model.PodcastItem;
import de.luhmer.owncloudnewsreader.model.TTSItem;
import de.luhmer.owncloudnewsreader.widget.WidgetProvider;
@ -65,6 +71,7 @@ import de.luhmer.owncloudnewsreader.widget.WidgetProvider;
public class NewsDetailActivity extends PodcastFragmentActivity {
private static final String TAG = NewsDetailActivity.class.getCanonicalName();
public static final String INCOGNITO_MODE_ENABLED = "INCOGNITO_MODE_ENABLED";
/**
* The {@link PagerAdapter} that will provide
* fragments for each of the sections. We use a
@ -76,6 +83,7 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
private SectionsPagerAdapter mSectionsPagerAdapter;
protected @BindView(R.id.toolbar) Toolbar toolbar;
protected @BindView(R.id.progressIndicator) ProgressBar progressIndicator;
protected @BindView(R.id.btn_disable_incognito) ImageButton mBtnDisableIncognito;
/**
* The {@link ViewPager} that will host the section contents.
@ -101,7 +109,14 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_news_detail);
ButterKnife.bind(this);
/*
// For Debugging the WebView using Chrome Remote Debugging
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
WebView.setWebContentsDebuggingEnabled(true);
}
*/
ButterKnife.bind(this);
if (toolbar != null) {
setSupportActionBar(toolbar);
@ -170,7 +185,21 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
}
mViewPager.addOnPageChangeListener(onPageChangeListener);
}
mBtnDisableIncognito.setOnClickListener(v -> {
// toggle incognito mode
setIncognitoEnabled(!isIncognitoEnabled());
for(int i = currentPosition-1; i <= currentPosition+1; i++) {
Log.d(TAG, "change incognito for idx: " + i);
WeakReference<NewsDetailFragment> ndf = mSectionsPagerAdapter.items.get(i);
if(ndf != null) {
ndf.get().syncIncognitoState();
ndf.get().startLoadRssItemToWebViewTask();
}
}
});
}
@Override
protected void onDestroy() {
@ -337,7 +366,7 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
menuItem_Read = menu.findItem(R.id.action_read);
menuItem_PlayPodcast = menu.findItem(R.id.action_playPodcast);
Set<String> selections = mPrefs.getStringSet("sp_news_detail_actionbar_icons", new HashSet<String>());
Set<String> selections = mPrefs.getStringSet("sp_news_detail_actionbar_icons", new HashSet<>());
String[] selected = selections.toArray(new String[] {});
for(String selection : selected) {
switch(selection) {
@ -358,6 +387,8 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
updateActionBarIcons();
initIncognitoMode();
return true;
}
@ -510,6 +541,21 @@ public class NewsDetailActivity extends PodcastFragmentActivity {
super.finish();
}
public boolean isIncognitoEnabled() {
return mPrefs.getBoolean(INCOGNITO_MODE_ENABLED, false);
}
public void setIncognitoEnabled(boolean enabled) {
mPrefs.edit().putBoolean(INCOGNITO_MODE_ENABLED, enabled).commit();
initIncognitoMode();
}
public void initIncognitoMode() {
int color = getResources().getColor(isIncognitoEnabled() ? R.color.material_grey_900 : R.color.colorPrimary);
ThemeUtils.colorizeToolbar(toolbar, color);
ThemeUtils.changeStatusBarColor(this, color);
}
/**
* A {@link FragmentPagerAdapter} that returns a fragment corresponding to
* one of the sections/tabs/pages.

View file

@ -42,6 +42,7 @@ import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.TextView;
@ -85,8 +86,6 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
protected @BindView(R.id.progressBarLoading) ProgressBar mProgressBarLoading;
protected @BindView(R.id.progressbar_webview) ProgressBar mProgressbarWebView;
protected @BindView(R.id.tv_offline_version) TextView mTvOfflineVersion;
protected @BindView(R.id.btn_disable_incognito) Button mBtnDisableIncognito;
protected @Inject SharedPreferences mPrefs;
@ -183,19 +182,24 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
} else {
mWebView.restoreState(savedInstanceState);
mProgressBarLoading.setVisibility(View.GONE);
// Make sure to sync the incognitio on retained views
syncIncognitoState();
}
setUpGestureDetector();
mBtnDisableIncognito.setOnClickListener(v -> {
mWebView.getSettings().setBlockNetworkLoads(false);
mWebView.getSettings().setBlockNetworkImage(false);
mWebView.reload();
});
return rootView;
}
void syncIncognitoState() {
NewsDetailActivity ndActivity = ((NewsDetailActivity)getActivity());
boolean isIncognito = ndActivity.isIncognitoEnabled();
mWebView.getSettings().setBlockNetworkLoads(isIncognito);
mWebView.getSettings().setBlockNetworkImage(isIncognito);
}
@Override
public void onSaveInstanceState(Bundle outState) {
mWebView.saveState(outState);
@ -233,7 +237,7 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
});
}
private void startLoadRssItemToWebViewTask() {
void startLoadRssItemToWebViewTask() {
Log.d(TAG, "startLoadRssItemToWebViewTask() called");
mWebView.setVisibility(View.GONE);
mProgressBarLoading.setVisibility(View.VISIBLE);
@ -304,11 +308,7 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
webSettings.setAppCacheEnabled(true);
webSettings.setMediaPlaybackRequiresUserGesture(true);
//if(true) {
//webSettings.setLoadsImagesAutomatically(false);
webSettings.setBlockNetworkImage(true);
webSettings.setBlockNetworkLoads(true);
//}
syncIncognitoState();
registerForContextMenu(mWebView);
@ -411,7 +411,7 @@ public class NewsDetailFragment extends Fragment implements RssItemToHtmlTask.Li
String imgaltval;
String imgsrcval;
imgsrcval = imageUrl.substring(imageUrl.lastIndexOf('/') + 1, imageUrl.length());
imgsrcval = imageUrl.substring(imageUrl.lastIndexOf('/') + 1);
Elements imgtag = htmlDoc.getElementsByAttributeValueContaining("src", imageUrl);
try {

View file

@ -24,6 +24,7 @@ import de.luhmer.owncloudnewsreader.database.model.RssItem;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
import static de.luhmer.owncloudnewsreader.NewsDetailActivity.INCOGNITO_MODE_ENABLED;
import static de.luhmer.owncloudnewsreader.helper.ThemeChooser.THEME;
@ -84,6 +85,8 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
* @return given RSS item as full HTML page
*/
public static String getHtmlPage(RssItem rssItem, boolean showHeader, SharedPreferences mPrefs, boolean isRightToLeft) {
boolean incognitoMode = mPrefs.getBoolean(INCOGNITO_MODE_ENABLED, false);
String favIconUrl = null;
Feed feed = rssItem.getFeed();
@ -122,7 +125,14 @@ public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
}
String description = rssItem.getBody();
description = getDescriptionWithCachedImages(description).trim();
if(!incognitoMode) {
// If incognito mode is disabled, try getting images from cache
description = getDescriptionWithCachedImages(description).trim();
} else {
// When incognito is on, we need to provide some error handling
//description = description.replaceAll("<img", "<img onerror=\"this.style='width: 40px !important; height: 40px !important'\" ");
description = description.replaceAll("<img", "<img width=\"40px\" height=\"40px\" ");
}
description = replacePatternInText(PATTERN_PRELOAD_VIDEOS_REMOVE, description, "$1 $3"); // remove whatever preload is there
description = replacePatternInText(PATTERN_PRELOAD_VIDEOS_INSERT, description, "$1 preload=\"metadata\" $3"); // add preload attribute
description = replacePatternInText(PATTERN_AUTOPLAY_VIDEOS_1, description, "$1 $3");

View file

@ -1,14 +1,43 @@
/**
* Android ownCloud News
*
* @author David Luhmer
* @copyright 2019 David Luhmer david-dev@live.de
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
* License as published by the Free Software Foundation; either
* version 3 of the License, or any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU AFFERO GENERAL PUBLIC LICENSE for more details.
*
* You should have received a copy of the GNU Affero General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package de.luhmer.owncloudnewsreader.helper;
import android.app.Activity;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.SearchView;
import android.widget.TextView;
import java.lang.reflect.Field;
import androidx.annotation.ColorInt;
import androidx.appcompat.widget.ActionMenuView;
import androidx.appcompat.widget.Toolbar;
import androidx.core.content.ContextCompat;
import de.luhmer.owncloudnewsreader.R;
@ -67,4 +96,42 @@ public class ThemeUtils {
}
}
/**
* Use this method to colorize the toolbar to the desired target color
* @param toolbarView toolbar view being colored
* @param toolbarBackgroundColor the target background color
*/
public static void colorizeToolbar(Toolbar toolbarView, @ColorInt int toolbarBackgroundColor) {
toolbarView.setBackgroundColor(toolbarBackgroundColor);
for(int i = 0; i < toolbarView.getChildCount(); i++) {
final View v = toolbarView.getChildAt(i);
v.setBackgroundColor(toolbarBackgroundColor);
if(v instanceof ActionMenuView) {
for(int j = 0; j < ((ActionMenuView)v).getChildCount(); j++) {
v.setBackgroundColor(toolbarBackgroundColor);
}
}
}
}
/**
* Use this method to colorize the status bar to the desired target color
* @param activity
* @param statusBarColor
*/
public static void changeStatusBarColor(Activity activity, @ColorInt int statusBarColor) {
Window window = activity.getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:
window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the window
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
window.setStatusBarColor(statusBarColor);
}
}
}

View file

@ -1,8 +1,8 @@
<androidx.coordinatorlayout.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_height="match_parent"
android:layout_width="match_parent">
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<!-- SlidingUpPanelLayout doesn't work with layout_behavior, use marginTop -->
<de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout
@ -48,6 +48,21 @@
</de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:layout_marginBottom="16dp">
<ImageButton
android:id="@+id/btn_disable_incognito"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:srcCompat="@drawable/incognito"/>
</LinearLayout>
<include
android:id="@+id/toolbar_layout"
layout="@layout/toolbar_layout" />

View file

@ -1,10 +1,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".NewsDetailFragment" >
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
@ -42,12 +42,4 @@
android:background="@color/material_red_600"
android:visibility="gone" />
<Button
android:id="@+id/btn_disable_incognito"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Disable Incognito"
android:layout_alignParentBottom="true" />
</RelativeLayout>