Skip to content

Commit

Permalink
Update app version -> 0.2.1+3
Browse files Browse the repository at this point in the history
Update library and Refactor project
  • Loading branch information
Songpol Anannetikul committed May 25, 2021
1 parent d2f4184 commit f5937d0
Show file tree
Hide file tree
Showing 11 changed files with 258 additions and 192 deletions.
16 changes: 0 additions & 16 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 12 additions & 20 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ android {
applicationId "tk.goshujin.app"
minSdkVersion 16
targetSdkVersion 30
versionCode 2
versionName "0.2.0"
versionCode 3
versionName "0.2.1"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -62,31 +62,23 @@ dependencies {
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.1.0"
implementation "androidx.drawerlayout:drawerlayout:1.1.1"

/*
Jetpack Lifecycle
*/
def lifecycle_version = "2.3.1"
def activity_version = "1.2.3"
implementation "androidx.activity:activity-ktx:$activity_version"

// ViewModel
def lifecycle_version = "2.3.1"
def arch_version = "2.1.0"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor (Java 8)
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-reactivestreams-ktx:$lifecycle_version"
testImplementation "androidx.arch.core:core-testing:$arch_version"

/*
Jetpack Navigation component
*/
def nav_version = "2.3.5"

// Navigation component
implementation "androidx.navigation:navigation-fragment:$nav_version"
implementation "androidx.navigation:navigation-ui:$nav_version"

// KTX
implementation "androidx.navigation:navigation-runtime-ktx:$nav_version"
implementation "androidx.navigation:navigation-fragment-ktx:$nav_version"
implementation "androidx.navigation:navigation-ui-ktx:$nav_version"
implementation "androidx.navigation:navigation-dynamic-features-fragment:$nav_version"
androidTestImplementation "androidx.navigation:navigation-testing:$nav_version"
}
157 changes: 157 additions & 0 deletions app/src/main/java/tk/goshujin/app/HomeFragment.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
package tk.goshujin.app

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.webkit.WebSettings
import android.webkit.WebView
import androidx.activity.addCallback
import androidx.appcompat.widget.Toolbar
import androidx.fragment.app.Fragment
import androidx.swiperefreshlayout.widget.SwipeRefreshLayout
import androidx.webkit.WebSettingsCompat
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import com.google.android.material.progressindicator.LinearProgressIndicator
import tk.goshujin.app.databinding.FragmentHomeBinding

class HomeFragment : Fragment(R.layout.fragment_home) {

companion object {
const val BASE_URL = "https://goshujin.tk/"

fun newInstance() = HomeFragment()
}

private var binding: FragmentHomeBinding? = null
private var isSafeBrowsingInitialized: Boolean = false

override fun onAttach(context: Context) {
super.onAttach(context)
requireActivity().onBackPressedDispatcher.addCallback(this) {
// Check if the key event was the Back button and if there's history
if (binding?.webView?.canGoBack() == true) {
binding?.webView?.goBack()
} else {
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
isEnabled = false
activity?.onBackPressed()
}
}
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding = FragmentHomeBinding.bind(view).apply {
// Toolbar
initToolbar(toolbar, webView)
// WebView and other Views
initWebView(webView, pageLoadingProgress, toolbar, swipeRefreshLayout)
}
}

override fun onDestroyView() {
binding = null
super.onDestroyView()
}

private fun initToolbar(toolbar: Toolbar, webView: WebView) {
toolbar.apply {
inflateMenu(R.menu.menu_webview)
setOnMenuItemClickListener {
return@setOnMenuItemClickListener when (it.itemId) {
R.id.menu_zoomIn -> {
webView.zoomIn()
true
}
R.id.menu_zoomOut -> {
webView.zoomOut()
true
}
R.id.menu_share -> {
startActivity(
Intent.createChooser(
Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, webView.url)
type = "text/plain"
},
null
)
)
true
}
R.id.menu_openInBrowser -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(webView.url)))
true
}
else -> false
}
}
}
}

private fun initWebView(
webView: WebView,
pageLoadingProgress: LinearProgressIndicator,
toolbar: Toolbar,
swipeRefreshLayout: SwipeRefreshLayout
) {
webView.apply {
settings.apply {
@SuppressLint("SetJavaScriptEnabled")
javaScriptEnabled = true
setSupportMultipleWindows(true)
useWideViewPort = true
loadWithOverviewMode = true
setSupportZoom(true)
builtInZoomControls = true
displayZoomControls = false

// To load image properly
loadsImagesAutomatically = true
domStorageEnabled = true
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
}

// Set Page Title to Toolbar and stop SwipeRefreshLayout
webViewClient = MainWebViewClientCompat(context, BASE_URL) { pageTitle ->
toolbar.title = pageTitle
swipeRefreshLayout.isRefreshing = false
}
webChromeClient = MainWebChromeClient { newProgress ->
pageLoadingProgress.apply {
when (newProgress) {
0 -> show()
100 -> hide()
else -> setProgressCompat(newProgress, true)
}
}
}
}

// Dark theme support
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(settings, WebSettingsCompat.FORCE_DARK_AUTO)
}

// Safe Browsing
if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
WebViewCompat.startSafeBrowsing(context) { success ->
isSafeBrowsingInitialized = success
loadUrl(BASE_URL)
}
} else {
loadUrl(BASE_URL)
}

swipeRefreshLayout.setOnRefreshListener {
webView.reload()
}
}
}
}
124 changes: 6 additions & 118 deletions app/src/main/java/tk/goshujin/app/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,134 +1,22 @@
package tk.goshujin.app

import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.TypedValue
import android.view.KeyEvent
import android.view.Menu
import android.view.MenuItem
import android.webkit.WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
import androidx.appcompat.app.AppCompatActivity
import androidx.webkit.*
import tk.goshujin.app.databinding.ActivityMainBinding


class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var isSafeBrowsingInitialized: Boolean = false

companion object {
const val BASE_URL = "https://goshujin.tk/"
}
private var binding: ActivityMainBinding? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
supportFragmentManager.fragmentFactory = MainFragmentFactory()
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)

setSupportActionBar(binding.mainToolbar)
binding.mainWebView.apply {
settings.apply {
@SuppressLint("SetJavaScriptEnabled")
javaScriptEnabled = true
setSupportMultipleWindows(true)
useWideViewPort = true
loadWithOverviewMode = true
setSupportZoom(true)
builtInZoomControls = true
displayZoomControls = false

// To load image properly
loadsImagesAutomatically = true
domStorageEnabled = true
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
mixedContentMode = MIXED_CONTENT_ALWAYS_ALLOW
}

webViewClient = MyWebViewClientCompat(this@MainActivity, binding)
webChromeClient = MyWebChromeClient { newProgress ->
if (newProgress == 0) {
binding.mainProgressBar.show()
binding.mainSwipeRefreshLayout.isRefreshing = true
}
binding.mainProgressBar.progress = newProgress
if (newProgress == 100) {
binding.mainProgressBar.hide()
binding.mainSwipeRefreshLayout.isRefreshing = false
}
}
}

// Dark theme support
if (WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) {
WebSettingsCompat.setForceDark(settings, WebSettingsCompat.FORCE_DARK_AUTO)
}

// Safe Browsing
if (WebViewFeature.isFeatureSupported(WebViewFeature.START_SAFE_BROWSING)) {
WebViewCompat.startSafeBrowsing(this@MainActivity) { success ->
isSafeBrowsingInitialized = success
loadUrl(BASE_URL)
}
} else {
loadUrl(BASE_URL)
}
}

// SwipeRefreshLayout
TypedValue().also {
theme.resolveAttribute(R.attr.colorSecondary, it, true)
binding.mainSwipeRefreshLayout.setColorSchemeResources(it.resourceId)
}
binding.mainSwipeRefreshLayout.setOnRefreshListener {
binding.mainWebView.reload()
}
}

override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
// Check if the key event was the Back button and if there's history
if (keyCode == KeyEvent.KEYCODE_BACK && binding.mainWebView.canGoBack()) {
binding.mainWebView.goBack()
return true
}
// If it wasn't the Back key or there's no web page history, bubble up to the default
// system behavior (probably exit the activity)
return super.onKeyDown(keyCode, event)
}

override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_webview, menu)
return true
setContentView(binding?.root)
}

override fun onOptionsItemSelected(item: MenuItem): Boolean {
return when (item.itemId) {
R.id.menu_zoomIn -> {
binding.mainWebView.zoomIn()
true
}
R.id.menu_zoomOut -> {
binding.mainWebView.zoomOut()
true
}
R.id.menu_share -> {
startActivity(
Intent.createChooser(
Intent(Intent.ACTION_SEND).apply {
putExtra(Intent.EXTRA_TEXT, binding.mainWebView.url)
type = "text/plain"
},
null
)
)
true
}
R.id.menu_openInBrowser -> {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(binding.mainWebView.url)))
true
}
else -> super.onOptionsItemSelected(item)
}
override fun onDestroy() {
binding = null
super.onDestroy()
}
}
14 changes: 14 additions & 0 deletions app/src/main/java/tk/goshujin/app/MainFragmentFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package tk.goshujin.app

import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentFactory

class MainFragmentFactory : FragmentFactory() {

override fun instantiate(classLoader: ClassLoader, className: String): Fragment {
return when(className) {
HomeFragment::class.java.name -> HomeFragment.newInstance()
else -> super.instantiate(classLoader, className)
}
}
}
Loading

0 comments on commit f5937d0

Please sign in to comment.