Browser activity

This commit is contained in:
Koitharu
2020-03-19 14:31:25 +02:00
parent 032d671c38
commit db0ee268f9
11 changed files with 250 additions and 0 deletions

View File

@@ -43,6 +43,9 @@
<activity <activity
android:name=".ui.reader.SimpleSettingsActivity" android:name=".ui.reader.SimpleSettingsActivity"
android:label="@string/settings" /> android:label="@string/settings" />
<activity
android:name=".ui.browser.BrowserActivity"
android:launchMode="singleInstance" />
<service <service
android:name=".ui.download.DownloadService" android:name=".ui.download.DownloadService"

View File

@@ -0,0 +1,94 @@
package org.koitharu.kotatsu.ui.browser
import android.annotation.SuppressLint
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import androidx.core.view.isVisible
import kotlinx.android.synthetic.main.activity_browser.*
import org.koitharu.kotatsu.R
import org.koitharu.kotatsu.ui.common.BaseActivity
@SuppressLint("SetJavaScriptEnabled")
class BrowserActivity : BaseActivity(), BrowserCallback {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_browser)
supportActionBar?.run {
setDisplayHomeAsUpEnabled(true)
setHomeAsUpIndicator(R.drawable.ic_cross)
}
with(webView.settings) {
javaScriptEnabled = true
}
webView.webViewClient = BrowserClient(this)
val url = intent?.dataString
if (url.isNullOrEmpty()) {
finish()
} else {
webView.loadUrl(url)
}
}
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.opt_browser, menu)
return super.onCreateOptionsMenu(menu)
}
override fun onOptionsItemSelected(item: MenuItem): Boolean = when (item.itemId) {
android.R.id.home -> {
webView.stopLoading()
finish()
true
}
R.id.action_browser -> {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = Uri.parse(webView.url)
try {
startActivity(Intent.createChooser(intent, item.title))
} catch (_: ActivityNotFoundException) {
}
true
}
else -> super.onOptionsItemSelected(item)
}
override fun onBackPressed() {
if (webView.canGoBack()) {
webView.goBack()
} else {
super.onBackPressed()
}
}
override fun onPause() {
webView.onPause()
super.onPause()
}
override fun onResume() {
super.onResume()
webView.onResume()
}
override fun onLoadingStateChanged(isLoading: Boolean) {
progressBar.isVisible = isLoading
}
override fun onTitleChanged(title: CharSequence, subtitle: CharSequence?) {
this.title = title
supportActionBar?.subtitle = subtitle
}
companion object {
@JvmStatic
fun newIntent(context: Context, url: String) = Intent(context, BrowserActivity::class.java)
.setData(Uri.parse(url))
}
}

View File

@@ -0,0 +1,8 @@
package org.koitharu.kotatsu.ui.browser
interface BrowserCallback {
fun onLoadingStateChanged(isLoading: Boolean)
fun onTitleChanged(title: CharSequence, subtitle: CharSequence?)
}

View File

@@ -0,0 +1,57 @@
package org.koitharu.kotatsu.ui.browser
import android.graphics.Bitmap
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.webkit.WebViewClient
import okhttp3.OkHttpClient
import okhttp3.Request
import org.koin.core.KoinComponent
import org.koin.core.inject
import org.koitharu.kotatsu.utils.ext.safe
class BrowserClient(private val callback: BrowserCallback) : WebViewClient(), KoinComponent {
private val okHttp by inject<OkHttpClient>()
override fun onPageFinished(webView: WebView, url: String) {
super.onPageFinished(webView, url)
callback.onLoadingStateChanged(isLoading = false)
}
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon)
callback.onLoadingStateChanged(isLoading = true)
}
override fun onPageCommitVisible(view: WebView, url: String?) {
super.onPageCommitVisible(view, url)
callback.onTitleChanged(view.title, url)
}
override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?) = false
override fun shouldOverrideUrlLoading(view: WebView, url: String) = false
override fun shouldInterceptRequest(view: WebView?, url: String?): WebResourceResponse? {
return url?.let(::doRequest)
}
override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
return request?.url?.toString()?.let(::doRequest)
}
private fun doRequest(url: String): WebResourceResponse? = safe {
val request = Request.Builder()
.url(url)
.build()
val response = okHttp.newCall(request).execute()
val ct = response.body?.contentType()
WebResourceResponse(
"${ct?.type}/${ct?.subtype}",
ct?.charset()?.name() ?: "utf-8",
response.body?.byteStream()
)
}
}

View File

@@ -21,6 +21,7 @@ import org.koitharu.kotatsu.core.model.FavouriteCategory
import org.koitharu.kotatsu.core.model.Manga import org.koitharu.kotatsu.core.model.Manga
import org.koitharu.kotatsu.core.model.MangaHistory import org.koitharu.kotatsu.core.model.MangaHistory
import org.koitharu.kotatsu.core.model.MangaSource import org.koitharu.kotatsu.core.model.MangaSource
import org.koitharu.kotatsu.ui.browser.BrowserActivity
import org.koitharu.kotatsu.ui.common.BaseActivity import org.koitharu.kotatsu.ui.common.BaseActivity
import org.koitharu.kotatsu.ui.download.DownloadService import org.koitharu.kotatsu.ui.download.DownloadService
import org.koitharu.kotatsu.utils.ShareHelper import org.koitharu.kotatsu.utils.ShareHelper
@@ -123,6 +124,12 @@ class MangaDetailsActivity : BaseActivity(), MangaDetailsView {
} }
true true
} }
R.id.action_browser -> {
manga?.let {
startActivity(BrowserActivity.newIntent(this, it.url))
}
true
}
R.id.action_shortcut -> { R.id.action_shortcut -> {
manga?.let { manga?.let {
lifecycleScope.launch { lifecycleScope.launch {

View File

@@ -0,0 +1,11 @@
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:tint="?attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M19,19H5V5h7V3H5c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2v-7h-2v7zM14,3v2h3.59l-9.83,9.83 1.41,1.41L19,6.41V10h2V3h-7z" />
</vector>

View File

@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">
<com.google.android.material.appbar.AppBarLayout
android:id="@+id/appbar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="?colorPrimary"
android:fitsSystemWindows="true"
android:theme="@style/AppToolbarTheme"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.Toolbar
android:id="@id/toolbar"
android:layout_width="match_parent"
android:layout_height="?android:actionBarSize"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="@style/AppPopupTheme" />
</com.google.android.material.appbar.AppBarLayout>
<WebView
android:id="@+id/webView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar" />
<ProgressBar
android:id="@+id/progressBar"
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:indeterminate="true"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/appbar"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/appbar"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_browser"
android:icon="@drawable/ic_open_external"
android:title="@string/open_in_browser"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -20,6 +20,11 @@
android:visible="false" android:visible="false"
app:showAsAction="never" /> app:showAsAction="never" />
<item
android:id="@+id/action_browser"
android:title="@string/open_in_browser"
app:showAsAction="never" />
<item <item
android:id="@+id/action_shortcut" android:id="@+id/action_shortcut"
android:title="@string/create_shortcut" android:title="@string/create_shortcut"

View File

@@ -108,4 +108,5 @@
<string name="app_update_available">Доступно обновление приложения</string> <string name="app_update_available">Доступно обновление приложения</string>
<string name="about_app">О программе</string> <string name="about_app">О программе</string>
<string name="show_notification_app_update">Показывать уведомление при наличии новой версии</string> <string name="show_notification_app_update">Показывать уведомление при наличии новой версии</string>
<string name="open_in_browser">Открыть в браузере</string>
</resources> </resources>

View File

@@ -109,4 +109,5 @@
<string name="app_update_available">Application update is available</string> <string name="app_update_available">Application update is available</string>
<string name="about_app">About</string> <string name="about_app">About</string>
<string name="show_notification_app_update">Show notification if update is available</string> <string name="show_notification_app_update">Show notification if update is available</string>
<string name="open_in_browser">Open in browser</string>
</resources> </resources>