Introduce incognito open-in-browser support
This commit is contained in:
parent
d9d71c8745
commit
411dda0e75
1
app/.gitignore
vendored
1
app/.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
*.iml
|
||||
custom.gradle
|
||||
google-services.json
|
||||
output.json
|
@ -213,7 +213,7 @@ dependencies {
|
||||
|
||||
// Conductor
|
||||
implementation "com.github.inorichi.Conductor:conductor:be8b3c5"
|
||||
implementation ("com.bluelinelabs:conductor-support:2.1.5-SNAPSHOT") {
|
||||
implementation("com.bluelinelabs:conductor-support:2.1.5-SNAPSHOT") {
|
||||
exclude group: "com.bluelinelabs", module: "conductor"
|
||||
exclude group: "com.android.support"
|
||||
}
|
||||
@ -246,7 +246,7 @@ dependencies {
|
||||
implementation 'com.andrognito.pinlockview:pinlockview:2.1.0'
|
||||
|
||||
// Reprint (EH)
|
||||
implementation 'com.github.ajalt.reprint:core:3.2.1@aar' // required: supports marshmallow devices
|
||||
implementation 'com.github.ajalt.reprint:core:3.2.1@aar'
|
||||
implementation 'com.github.ajalt.reprint:rxjava:3.2.1@aar' // optional: the RxJava 1 interface
|
||||
|
||||
// Swirl (EH)
|
||||
|
@ -12,31 +12,35 @@
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
|
||||
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS"/>
|
||||
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission
|
||||
android:name="android.permission.PACKAGE_USAGE_STATS"
|
||||
tools:ignore="ProtectedPermissions" />
|
||||
<!-- Lock vibrate -->
|
||||
<uses-permission android:name="android.permission.VIBRATE"/>
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:hardwareAccelerated="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:label="@string/app_name"
|
||||
android:largeHeap="true"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:theme="@style/Theme.Tachiyomi">
|
||||
<activity
|
||||
android:name=".ui.main.MainActivity"
|
||||
android:launchMode="singleTop">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<!--suppress AndroidDomInspection -->
|
||||
<meta-data android:name="android.app.shortcuts" android:resource="@xml/shortcuts"/>
|
||||
<!-- suppress AndroidDomInspection -->
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".ui.reader.ReaderActivity"
|
||||
@ -61,7 +65,7 @@
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".extension.util.ExtensionInstallActivity"
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar"/>
|
||||
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
@ -72,14 +76,12 @@
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/provider_paths" />
|
||||
</provider>
|
||||
|
||||
<provider
|
||||
android:name="eu.kanade.tachiyomi.util.ZipContentProvider"
|
||||
android:name=".util.ZipContentProvider"
|
||||
android:authorities="${applicationId}.zip-provider"
|
||||
android:exported="false" />
|
||||
|
||||
<provider
|
||||
android:name="eu.kanade.tachiyomi.util.RarContentProvider"
|
||||
android:name=".util.RarContentProvider"
|
||||
android:authorities="${applicationId}.rar-provider"
|
||||
android:exported="false" />
|
||||
|
||||
@ -90,22 +92,18 @@
|
||||
<service
|
||||
android:name=".data.library.LibraryUpdateService"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".data.download.DownloadService"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".data.updater.UpdaterService"
|
||||
android:exported="false" />
|
||||
|
||||
<service
|
||||
android:name=".data.backup.BackupCreateService"
|
||||
android:exported="false"/>
|
||||
|
||||
android:exported="false" />
|
||||
<service
|
||||
android:name=".data.backup.BackupRestoreService"
|
||||
android:exported="false"/>
|
||||
android:exported="false" />
|
||||
|
||||
<!-- EH -->
|
||||
<activity
|
||||
@ -113,97 +111,97 @@
|
||||
android:label="TachiyomiEH"
|
||||
android:theme="@style/Theme.EHIntercept">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT"/>
|
||||
<category android:name="android.intent.category.BROWSABLE"/>
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="g.e-hentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="g.e-hentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="e-hentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="e-hentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="exhentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="exhentai.org"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="nhentai.net"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="nhentai.net"
|
||||
android:pathPrefix="/g/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="www.perveden.com"
|
||||
android:pathPattern="/.*/.*-manga/.*"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="www.perveden.com"
|
||||
android:pathPattern="/.*/.*-manga/.*"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="hentai.cafe"
|
||||
android:pathPattern="/.*/.*"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="hentai.cafe"
|
||||
android:pathPattern="/.*/.*"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="www.tsumino.com"
|
||||
android:pathPrefix="/Book/Info/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="www.tsumino.com"
|
||||
android:pathPrefix="/Book/Info/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="www.tsumino.com"
|
||||
android:pathPrefix="/Read/View/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="www.tsumino.com"
|
||||
android:pathPrefix="/Read/View/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="hitomi.la"
|
||||
android:pathPrefix="/galleries/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="hitomi.la"
|
||||
android:pathPrefix="/reader/"
|
||||
android:scheme="http"/>
|
||||
android:scheme="http" />
|
||||
<data
|
||||
android:host="hitomi.la"
|
||||
android:pathPrefix="/galleries/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
<data
|
||||
android:host="hitomi.la"
|
||||
android:pathPrefix="/reader/"
|
||||
android:scheme="https"/>
|
||||
android:scheme="https" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name="exh.ui.captcha.SolveCaptchaActivity"
|
||||
android:launchMode="singleInstance" />
|
||||
|
||||
<activity android:name="exh.ui.webview.WebViewActivity"></activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
@ -178,4 +178,6 @@ object PreferenceKeys {
|
||||
const val eh_cacheSize = "eh_cache_size"
|
||||
|
||||
const val eh_preserveReadingPosition = "eh_preserve_reading_position"
|
||||
|
||||
const val eh_incogWebview = "eh_incognito_webview"
|
||||
}
|
||||
|
@ -249,4 +249,6 @@ class PreferencesHelper(val context: Context) {
|
||||
fun eh_cacheSize() = rxPrefs.getString(Keys.eh_cacheSize, "75")
|
||||
|
||||
fun eh_preserveReadingPosition() = rxPrefs.getBoolean(Keys.eh_preserveReadingPosition, false)
|
||||
|
||||
fun eh_incogWebview() = rxPrefs.getBoolean(Keys.eh_incogWebview, false)
|
||||
}
|
||||
|
@ -20,19 +20,18 @@ import android.widget.Toast
|
||||
import com.afollestad.materialdialogs.MaterialDialog
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||
import com.bumptech.glide.load.resource.bitmap.TransformationUtils.centerCrop
|
||||
import com.bumptech.glide.request.target.SimpleTarget
|
||||
import com.bumptech.glide.request.transition.Transition
|
||||
import com.jakewharton.rxbinding.support.v4.widget.refreshes
|
||||
import com.jakewharton.rxbinding.view.clicks
|
||||
import com.jakewharton.rxbinding.view.longClicks
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.R.id.*
|
||||
import eu.kanade.tachiyomi.data.database.models.Category
|
||||
import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
import eu.kanade.tachiyomi.data.glide.GlideApp
|
||||
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.source.Source
|
||||
import eu.kanade.tachiyomi.source.SourceManager
|
||||
import eu.kanade.tachiyomi.source.model.SManga
|
||||
@ -50,6 +49,7 @@ import eu.kanade.tachiyomi.util.toast
|
||||
import eu.kanade.tachiyomi.util.truncateCenter
|
||||
import exh.EH_SOURCE_ID
|
||||
import exh.EXH_SOURCE_ID
|
||||
import exh.ui.webview.WebViewActivity
|
||||
import jp.wasabeef.glide.transformations.CropSquareTransformation
|
||||
import jp.wasabeef.glide.transformations.MaskTransformation
|
||||
import kotlinx.android.synthetic.main.manga_info_controller.*
|
||||
@ -310,11 +310,20 @@ class MangaInfoController : NucleusController<MangaInfoPresenter>(),
|
||||
val source = presenter.source as? HttpSource ?: return
|
||||
|
||||
try {
|
||||
val url = Uri.parse(source.mangaDetailsRequest(presenter.manga).url().toString())
|
||||
val intent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(context.getResourceColor(R.attr.colorPrimary))
|
||||
.build()
|
||||
intent.launchUrl(activity, url)
|
||||
// --> EH
|
||||
val urlString = source.mangaDetailsRequest(presenter.manga).url().toString()
|
||||
if(preferences.eh_incogWebview().getOrDefault()) {
|
||||
activity?.startActivity(Intent(activity, WebViewActivity::class.java).apply {
|
||||
putExtra(WebViewActivity.KEY_URL, urlString)
|
||||
})
|
||||
} else {
|
||||
val url = Uri.parse(urlString)
|
||||
val intent = CustomTabsIntent.Builder()
|
||||
.setToolbarColor(context.getResourceColor(R.attr.colorPrimary))
|
||||
.build()
|
||||
intent.launchUrl(activity, url)
|
||||
}
|
||||
// <-- EH
|
||||
} catch (e: Exception) {
|
||||
context.toast(e.message)
|
||||
}
|
||||
|
@ -186,6 +186,13 @@ class SettingsGeneralController : SettingsController() {
|
||||
defaultValue = false
|
||||
}
|
||||
|
||||
switchPreference {
|
||||
key = Keys.eh_incogWebview
|
||||
title = "Incognito 'Open in browser'"
|
||||
summary = "Prevent pages viewed from the 'Open in browser' menu option from being placed into Chrome's browsing history. Some browser features will be unavailable."
|
||||
defaultValue = false
|
||||
}
|
||||
|
||||
preferenceCategory {
|
||||
title = "Application lock"
|
||||
|
||||
|
@ -3,11 +3,8 @@ package eu.kanade.tachiyomi.util
|
||||
import android.app.ActivityManager
|
||||
import android.app.Notification
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.*
|
||||
import android.content.Context.VIBRATOR_SERVICE
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.Resources
|
||||
import android.net.ConnectivityManager
|
||||
@ -129,6 +126,14 @@ val Context.powerManager: PowerManager
|
||||
val Context.wifiManager: WifiManager
|
||||
get() = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
|
||||
|
||||
// --> EH
|
||||
/**
|
||||
* Property to get the wifi manager from the context.
|
||||
*/
|
||||
val Context.clipboardManager: ClipboardManager
|
||||
get() = applicationContext.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
||||
// <-- EH
|
||||
|
||||
/**
|
||||
* Function used to send a local broadcast asynchronous
|
||||
*
|
||||
|
126
app/src/main/java/exh/ui/webview/NestedWebView.java
Normal file
126
app/src/main/java/exh/ui/webview/NestedWebView.java
Normal file
@ -0,0 +1,126 @@
|
||||
package exh.ui.webview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.view.MotionEventCompat;
|
||||
import android.support.v4.view.NestedScrollingChild;
|
||||
import android.support.v4.view.NestedScrollingChildHelper;
|
||||
import android.support.v4.view.ViewCompat;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.webkit.WebView;
|
||||
|
||||
public class NestedWebView extends WebView implements NestedScrollingChild {
|
||||
private int mLastY;
|
||||
private final int[] mScrollOffset = new int[2];
|
||||
private final int[] mScrollConsumed = new int[2];
|
||||
private int mNestedOffsetY;
|
||||
private NestedScrollingChildHelper mChildHelper;
|
||||
|
||||
public NestedWebView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public NestedWebView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, android.R.attr.webViewStyle);
|
||||
}
|
||||
|
||||
public NestedWebView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
mChildHelper = new NestedScrollingChildHelper(this);
|
||||
setNestedScrollingEnabled(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent ev) {
|
||||
boolean returnValue = false;
|
||||
|
||||
MotionEvent event = MotionEvent.obtain(ev);
|
||||
final int action = MotionEventCompat.getActionMasked(event);
|
||||
if (action == MotionEvent.ACTION_DOWN) {
|
||||
mNestedOffsetY = 0;
|
||||
}
|
||||
int eventY = (int) event.getY();
|
||||
event.offsetLocation(0, mNestedOffsetY);
|
||||
switch (action) {
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
int deltaY = mLastY - eventY;
|
||||
// NestedPreScroll
|
||||
if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
|
||||
deltaY -= mScrollConsumed[1];
|
||||
mLastY = eventY - mScrollOffset[1];
|
||||
event.offsetLocation(0, -mScrollOffset[1]);
|
||||
mNestedOffsetY += mScrollOffset[1];
|
||||
}
|
||||
returnValue = super.onTouchEvent(event);
|
||||
|
||||
// NestedScroll
|
||||
if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)) {
|
||||
event.offsetLocation(0, mScrollOffset[1]);
|
||||
mNestedOffsetY += mScrollOffset[1];
|
||||
mLastY -= mScrollOffset[1];
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
returnValue = super.onTouchEvent(event);
|
||||
mLastY = eventY;
|
||||
// start NestedScroll
|
||||
startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
case MotionEvent.ACTION_CANCEL:
|
||||
returnValue = super.onTouchEvent(event);
|
||||
// end NestedScroll
|
||||
stopNestedScroll();
|
||||
break;
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
// Nested Scroll implements
|
||||
@Override
|
||||
public void setNestedScrollingEnabled(boolean enabled) {
|
||||
mChildHelper.setNestedScrollingEnabled(enabled);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNestedScrollingEnabled() {
|
||||
return mChildHelper.isNestedScrollingEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startNestedScroll(int axes) {
|
||||
return mChildHelper.startNestedScroll(axes);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stopNestedScroll() {
|
||||
mChildHelper.stopNestedScroll();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasNestedScrollingParent() {
|
||||
return mChildHelper.hasNestedScrollingParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
|
||||
int[] offsetInWindow) {
|
||||
return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
|
||||
return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
|
||||
return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
|
||||
return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
|
||||
}
|
||||
|
||||
}
|
191
app/src/main/java/exh/ui/webview/WebViewActivity.kt
Normal file
191
app/src/main/java/exh/ui/webview/WebViewActivity.kt
Normal file
@ -0,0 +1,191 @@
|
||||
package exh.ui.webview
|
||||
|
||||
import android.content.ClipData
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.TypedValue
|
||||
import android.view.Menu
|
||||
import android.view.MenuItem
|
||||
import android.webkit.CookieManager
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
|
||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
|
||||
import eu.kanade.tachiyomi.ui.base.activity.BaseActivity
|
||||
import eu.kanade.tachiyomi.util.clipboardManager
|
||||
import eu.kanade.tachiyomi.util.toast
|
||||
import exh.ui.login.LoginController
|
||||
import kotlinx.android.synthetic.main.activity_webview.*
|
||||
import uy.kohesive.injekt.injectLazy
|
||||
|
||||
class WebViewActivity : BaseActivity() {
|
||||
private val prefs: PreferencesHelper by injectLazy()
|
||||
private var mobileUserAgent: String? = null
|
||||
private var isDesktop: Boolean = false
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
setTheme(when (prefs.theme()) {
|
||||
2 -> R.style.Theme_Tachiyomi_Dark
|
||||
3 -> R.style.Theme_Tachiyomi_Amoled
|
||||
else -> R.style.Theme_Tachiyomi
|
||||
})
|
||||
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_webview)
|
||||
setSupportActionBar(toolbar)
|
||||
|
||||
// Opaque status bar
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
val typedValue = TypedValue()
|
||||
theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true)
|
||||
window.statusBarColor = typedValue.data
|
||||
}
|
||||
|
||||
// Show close button
|
||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
||||
supportActionBar?.setHomeAsUpIndicator(R.drawable.ic_close_white_24dp)
|
||||
|
||||
val url = intent.getStringExtra(KEY_URL)
|
||||
|
||||
// Set immediately (required for correct title after rotation)
|
||||
title = url
|
||||
// Configure webview
|
||||
webview.settings.javaScriptEnabled = true
|
||||
webview.settings.domStorageEnabled = true
|
||||
webview.settings.databaseEnabled = true
|
||||
webview.webViewClient = object : WebViewClient() {
|
||||
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
|
||||
super.onPageStarted(view, url, favicon)
|
||||
invalidateOptionsMenu()
|
||||
appbar.setExpanded(true, true)
|
||||
title = "Loading: $url"
|
||||
}
|
||||
|
||||
override fun onPageFinished(view: WebView?, url: String?) {
|
||||
super.onPageFinished(view, url)
|
||||
title = url
|
||||
invalidateOptionsMenu()
|
||||
}
|
||||
}
|
||||
|
||||
// Configure E-Hentai/ExHentai cookies
|
||||
for(domain in listOf(
|
||||
"www.exhentai.org",
|
||||
"exhentai.org",
|
||||
"www.e-hentai.org",
|
||||
"e-hentai.org",
|
||||
"g.e-hentai.org"
|
||||
)) {
|
||||
for(cookie in listOf(
|
||||
LoginController.MEMBER_ID_COOKIE to prefs.memberIdVal().getOrDefault(),
|
||||
LoginController.PASS_HASH_COOKIE to prefs.passHashVal().getOrDefault(),
|
||||
LoginController.IGNEOUS_COOKIE to prefs.igneousVal().getOrDefault()
|
||||
)) {
|
||||
val cookieString = "${cookie.first}=${cookie.second}; domain=$domain; path=/;"
|
||||
CookieManager.getInstance().setCookie(domain, cookieString)
|
||||
}
|
||||
}
|
||||
|
||||
// Long-click to copy URL
|
||||
toolbar.setOnLongClickListener {
|
||||
toast("URL copied.")
|
||||
clipboardManager.primaryClip = ClipData.newUri(
|
||||
contentResolver,
|
||||
webview.title,
|
||||
Uri.parse(webview.url)
|
||||
)
|
||||
true
|
||||
}
|
||||
|
||||
if(savedInstanceState == null) {
|
||||
mobileUserAgent = webview.settings.userAgentString
|
||||
|
||||
if(url == null) {
|
||||
toast("No URL supplied!")
|
||||
finish()
|
||||
return
|
||||
}
|
||||
|
||||
webview.loadUrl(url)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onRestoreInstanceState(savedInstanceState: Bundle?) {
|
||||
super.onRestoreInstanceState(savedInstanceState)
|
||||
savedInstanceState?.getString(STATE_KEY_MOBILE_USER_AGENT)?.let {
|
||||
mobileUserAgent = it
|
||||
}
|
||||
savedInstanceState?.getBoolean(STATE_KEY_IS_DESKTOP)?.let {
|
||||
isDesktop = it
|
||||
}
|
||||
webview.restoreState(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle?) {
|
||||
super.onSaveInstanceState(outState)
|
||||
outState?.putString(STATE_KEY_MOBILE_USER_AGENT, mobileUserAgent)
|
||||
outState?.putBoolean(STATE_KEY_IS_DESKTOP, isDesktop)
|
||||
webview.saveState(outState)
|
||||
}
|
||||
|
||||
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
|
||||
menu?.findItem(R.id.action_forward)?.isEnabled = webview.canGoForward()
|
||||
menu?.findItem(R.id.action_desktop_site)?.isChecked = isDesktop
|
||||
|
||||
return super.onPrepareOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
|
||||
menuInflater.inflate(R.menu.menu_webview, menu)
|
||||
return super.onCreateOptionsMenu(menu)
|
||||
}
|
||||
|
||||
override fun onBackPressed() {
|
||||
if(webview.canGoBack())
|
||||
webview.goBack()
|
||||
else
|
||||
super.onBackPressed()
|
||||
}
|
||||
|
||||
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
|
||||
when(item?.itemId) {
|
||||
android.R.id.home -> finish()
|
||||
R.id.action_refresh -> webview.reload()
|
||||
R.id.action_forward -> webview.goForward()
|
||||
R.id.action_desktop_site -> {
|
||||
isDesktop = !item.isChecked
|
||||
item.isChecked = isDesktop
|
||||
|
||||
(if(isDesktop) {
|
||||
mobileUserAgent?.replace("\\([^(]*(Mobile|Android)[^)]*\\)"
|
||||
.toRegex(RegexOption.IGNORE_CASE), "")
|
||||
?.replace("Mobile", "", true)
|
||||
?.replace("Android", "", true)
|
||||
} else {
|
||||
mobileUserAgent
|
||||
})?.let {
|
||||
webview.settings.userAgentString = it
|
||||
}
|
||||
|
||||
webview.settings.useWideViewPort = isDesktop
|
||||
webview.settings.loadWithOverviewMode = isDesktop
|
||||
|
||||
webview.reload()
|
||||
}
|
||||
R.id.action_open_in_browser ->
|
||||
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(webview.url)))
|
||||
}
|
||||
return super.onOptionsItemSelected(item)
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val KEY_URL = "url"
|
||||
|
||||
const val STATE_KEY_MOBILE_USER_AGENT = "mobile_user_agent"
|
||||
const val STATE_KEY_IS_DESKTOP = "is_desktop"
|
||||
}
|
||||
}
|
9
app/src/main/res/drawable/ic_close_white_24dp.xml
Normal file
9
app/src/main/res/drawable/ic_close_white_24dp.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#ffffff"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
@ -0,0 +1,9 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M21,2L3,2c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h7v2L8,20v2h8v-2h-2v-2h7c1.1,0 2,-0.9 2,-2L23,4c0,-1.1 -0.9,-2 -2,-2zM21,16L3,16L3,4h18v12z"/>
|
||||
</vector>
|
37
app/src/main/res/layout/activity_webview.xml
Normal file
37
app/src/main/res/layout/activity_webview.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?attr/colorPrimary"
|
||||
android:theme="?attr/actionBarTheme">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
app:layout_scrollFlags="scroll|enterAlways"
|
||||
android:layout_height="?attr/actionBarSize">
|
||||
|
||||
</android.support.v7.widget.Toolbar>
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.v4.widget.NestedScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fillViewport="true"
|
||||
app:layout_behavior="android.support.design.widget.AppBarLayout$ScrollingViewBehavior">
|
||||
|
||||
<exh.ui.webview.NestedWebView
|
||||
android:id="@+id/webview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:isScrollContainer="false" />
|
||||
</android.support.v4.widget.NestedScrollView>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
19
app/src/main/res/menu/menu_webview.xml
Normal file
19
app/src/main/res/menu/menu_webview.xml
Normal file
@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item
|
||||
android:id="@+id/action_refresh"
|
||||
android:title="Refresh" />
|
||||
<item
|
||||
android:id="@+id/action_forward"
|
||||
android:title="Forward" />
|
||||
<item
|
||||
android:id="@+id/action_desktop_site"
|
||||
android:checkable="true"
|
||||
android:title="Desktop site" />
|
||||
<item
|
||||
android:id="@+id/action_open_in_browser"
|
||||
android:title="Open in browser" />
|
||||
</menu>
|
@ -102,7 +102,7 @@
|
||||
<string name="short_recent_updates">Updates</string>
|
||||
|
||||
<!-- Preferences -->
|
||||
<!-- Subsections -->
|
||||
<!-- Subsections -->
|
||||
<string name="pref_category_general">General</string>
|
||||
<string name="pref_category_reader">Reader</string>
|
||||
<string name="pref_category_downloads">Downloads</string>
|
||||
@ -111,7 +111,7 @@
|
||||
<string name="pref_category_advanced">Advanced</string>
|
||||
<string name="pref_category_about">About</string>
|
||||
|
||||
<!-- General section -->
|
||||
<!-- General section -->
|
||||
<string name="pref_library_columns">Library manga per row</string>
|
||||
<string name="portrait">Portrait</string>
|
||||
<string name="landscape">Landscape</string>
|
||||
@ -166,7 +166,7 @@
|
||||
<string name="ext_language_info">Language: %1$s</string>
|
||||
<string name="ext_empty_preferences">There are no preferences to edit for this extension</string>
|
||||
|
||||
<!-- Reader section -->
|
||||
<!-- Reader section -->
|
||||
<string name="pref_fullscreen">Fullscreen</string>
|
||||
<string name="pref_lock_orientation">Lock orientation</string>
|
||||
<string name="pref_page_transitions">Page transitions</string>
|
||||
@ -217,7 +217,7 @@
|
||||
<string name="color_filter_a_value">A</string>
|
||||
|
||||
|
||||
<!-- Downloads section -->
|
||||
<!-- Downloads section -->
|
||||
<string name="pref_download_directory">Downloads directory</string>
|
||||
<string name="pref_download_only_over_wifi">Only download over Wi-Fi</string>
|
||||
<string name="pref_remove_after_marked_as_read">Remove when marked as read</string>
|
||||
@ -232,7 +232,7 @@
|
||||
<string name="pref_download_new">Download new chapters</string>
|
||||
<string name="pref_download_new_categories">Categories to include in download</string>
|
||||
|
||||
<!-- Sync section -->
|
||||
<!-- Sync section -->
|
||||
<string name="services">Services</string>
|
||||
|
||||
<!-- Backup section -->
|
||||
@ -258,7 +258,7 @@
|
||||
<string name="restoring_backup">Restoring backup</string>
|
||||
<string name="creating_backup">Creating backup</string>
|
||||
|
||||
<!-- Advanced section -->
|
||||
<!-- Advanced section -->
|
||||
<string name="pref_clear_chapter_cache">Clear chapter cache</string>
|
||||
<string name="used_cache">Used: %1$s</string>
|
||||
<string name="cache_deleted">Cache cleared. %1$d files have been deleted</string>
|
||||
@ -275,7 +275,7 @@
|
||||
<string name="pref_refresh_library_tracking">Refresh tracking metadata</string>
|
||||
<string name="pref_refresh_library_tracking_summary">Updates status, score and last chapter read from the tracking services</string>
|
||||
|
||||
<!-- About section -->
|
||||
<!-- About section -->
|
||||
<string name="version">Version</string>
|
||||
<string name="build_time">Build time</string>
|
||||
<string name="pref_enable_automatic_updates">Check for updates</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user