Compare commits

...

10 Commits

Author SHA1 Message Date
lunaticbum
01903c15f2 no message 2024-11-18 18:08:25 +09:00
lunaticbum
fc5f17018a ... 2024-11-18 18:04:29 +09:00
lunaticbum
e8ed60f300 ... 2024-11-18 17:36:26 +09:00
aa6fa8a79e ... 2024-09-20 14:04:34 +09:00
0fff1f5aa3 ... 2024-09-07 18:34:52 +09:00
ac6523b2dd ... 2024-09-07 17:55:28 +09:00
f5003d9378 Merge branch 'main' of https://bitbucket.org/gbumhan/tokkiz
# Conflicts:
#	app/src/main/java/com/mime/dualscreenview/webcontents/BaseWebContentsViewer.kt
.
2024-09-07 16:13:11 +09:00
c393439a85 . 2024-09-07 16:12:05 +09:00
lunaticbum
3b1c4a6403 ... 2024-08-26 18:35:11 +09:00
lunaticbum
90e28a9b45 ... 2024-08-26 14:34:32 +09:00
61 changed files with 909 additions and 756 deletions

View File

@ -64,7 +64,7 @@ dependencies {
implementation 'com.google.code.gson:gson:2.10.1' implementation 'com.google.code.gson:gson:2.10.1'
// implementation files('libs/DualScreen.jar') // implementation files('libs/DualScreen.jar')
implementation ("org.jsoup:jsoup:1.18.1")
implementation 'io.realm.kotlin:library-base:2.0.0' implementation 'io.realm.kotlin:library-base:2.0.0'

Binary file not shown.

View File

@ -1,24 +0,0 @@
package com.mime.dualscreenview
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.mime.dualscreenview", appContext.packageName)
}
}

View File

@ -6,6 +6,7 @@
<application <application
android:allowBackup="false" android:allowBackup="false"
android:name=".BaseAppication"
android:dataExtractionRules="@xml/data_extraction_rules" android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules" android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@ -13,6 +14,7 @@
android:usesCleartextTraffic="true" android:usesCleartextTraffic="true"
android:roundIcon="@mipmap/ic_launcher_round" android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true" android:supportsRtl="true"
android:largeHeap="true"
android:theme="@style/Theme.DualScreenView" android:theme="@style/Theme.DualScreenView"
tools:targetApi="31" > tools:targetApi="31" >

View File

@ -1,11 +1,12 @@
package com.mime.dualscreenview package com.mime.dualscreenview
import android.app.Application import android.app.Application
import com.mime.dualscreenview.common.PrefManager
import io.realm.kotlin.Realm import io.realm.kotlin.Realm
class BaseAppication : Application() { class BaseAppication : Application() {
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
PrefManager.init(this)
} }
} }

View File

@ -15,6 +15,7 @@ import android.view.KeyEvent.KEYCODE_MEDIA_REWIND
import android.view.KeyEvent.KEYCODE_VOLUME_DOWN import android.view.KeyEvent.KEYCODE_VOLUME_DOWN
import android.view.KeyEvent.KEYCODE_VOLUME_MUTE import android.view.KeyEvent.KEYCODE_VOLUME_MUTE
import android.view.KeyEvent.KEYCODE_VOLUME_UP import android.view.KeyEvent.KEYCODE_VOLUME_UP
import android.view.MotionEvent
import android.widget.Toast import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.mime.dualscreenview.common.Blog import com.mime.dualscreenview.common.Blog
@ -57,6 +58,55 @@ open class Base : AppCompatActivity() {
} }
var actionButtonPressX = 0f
var actionButtonPressY = 0f
override fun dispatchGenericMotionEvent(ev: MotionEvent?): Boolean {
if (ev?.device?.name?.contains("BLE-M3") == true) {
Blog.LOGE("keyEvent >>>>> dispatchGenericMotionEvent ${ev}")
ev?.action?.let { action ->
when(action) {
MotionEvent.ACTION_HOVER_ENTER -> {
return false
}
MotionEvent.ACTION_HOVER_MOVE ->{return false}
MotionEvent.ACTION_BUTTON_PRESS ->{
if (actionButtonPressX * actionButtonPressY == 0f) {
actionButtonPressX = ev.x ?: 0f
actionButtonPressY = ev.y ?: 0f
}
return true
}
MotionEvent.ACTION_BUTTON_RELEASE ->{
if (actionButtonPressY == ev.y) {
if (actionButtonPressX.minus(ev.x ?: 0f) > 0f) {
Blog.LOGE("Arrow Right Click")
onKeyClick(KeyEvent.KEYCODE_VOLUME_DOWN)
} else {
Blog.LOGE("Arrow Left Click")
onKeyClick(KeyEvent.KEYCODE_VOLUME_UP)
}
} else {
if (actionButtonPressY.minus(ev.y ?: 0f) > 0f) {
Blog.LOGE("Arrow Down Click")
} else {
Blog.LOGE("Arrow Up Click")
}
}
return false
}
MotionEvent.ACTION_HOVER_EXIT ->{
actionButtonPressX = 0f
actionButtonPressY = 0f
return false
}
else -> {return false}
}
}
}
return super.dispatchGenericMotionEvent(ev)
}
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean { override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
Blog.LOGD(log = "keyCode : ${keyCode}, event : ${event}") Blog.LOGD(log = "keyCode : ${keyCode}, event : ${event}")

View File

@ -1,42 +1,43 @@
package com.mime.dualscreenview.activity package com.mime.dualscreenview.activity
import android.content.ComponentName
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo import android.content.pm.ActivityInfo
import android.content.pm.PackageManager.NameNotFoundException
import android.content.res.Configuration import android.content.res.Configuration
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri import android.net.Uri
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
import android.os.Looper
import android.os.Message import android.os.Message
import android.text.InputType import android.text.InputType
import android.text.SpannableStringBuilder import android.text.SpannableStringBuilder
import android.text.style.RelativeSizeSpan import android.text.style.RelativeSizeSpan
import android.util.Log import android.util.Log
import android.view.Gravity
import android.view.KeyEvent import android.view.KeyEvent
import android.view.View import android.view.View
import android.view.View.GONE import android.view.View.GONE
import android.view.View.VISIBLE import android.view.View.VISIBLE
import android.view.View.inflate
import android.webkit.JavascriptInterface
import android.webkit.WebSettings import android.webkit.WebSettings
import android.webkit.WebView import android.webkit.WebView
import android.webkit.WebViewClient import android.webkit.WebViewClient
import android.widget.ArrayAdapter import android.widget.ArrayAdapter
import android.widget.EditText import android.widget.EditText
import android.widget.ImageButton
import android.widget.ProgressBar import android.widget.ProgressBar
import android.widget.TextView import android.widget.TextView
import android.widget.Toast import android.widget.Toast
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.constraintlayout.utils.widget.ImageFilterButton import androidx.constraintlayout.utils.widget.ImageFilterButton
import androidx.core.net.toUri
import com.google.gson.Gson import com.google.gson.Gson
import com.mime.dualscreenview.R import com.mime.dualscreenview.R
import com.mime.dualscreenview.common.Blog import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.common.PairArray import com.mime.dualscreenview.common.PairArray
import com.mime.dualscreenview.common.PrefManager
import com.mime.dualscreenview.common.colorz import com.mime.dualscreenview.common.colorz
import com.mime.dualscreenview.common.getIndex import com.mime.dualscreenview.common.getIndex
import com.mime.dualscreenview.common.typesfacez import com.mime.dualscreenview.common.typesfacez
@ -47,51 +48,50 @@ import com.mime.dualscreenview.data.model.BookPageInfosJ
import com.mime.dualscreenview.data.model.HistoryItem import com.mime.dualscreenview.data.model.HistoryItem
import com.mime.dualscreenview.data.model.LastInfo import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.data.model.ReaderConfig import com.mime.dualscreenview.data.model.ReaderConfig
import com.mime.dualscreenview.databinding.IntroBinding
import com.mime.dualscreenview.dialog.DefaultList import com.mime.dualscreenview.dialog.DefaultList
import com.mime.dualscreenview.view.PagedTextLayout import com.mime.dualscreenview.view.PagedTextLayout
import com.mime.dualscreenview.view.PagedTextViewInterface import com.mime.dualscreenview.view.PagedTextViewInterface
import com.mime.dualscreenview.view.TouchArea import com.mime.dualscreenview.view.TouchArea
import com.mime.dualscreenview.webcontents.BaseWebContentsViewer import com.mime.dualscreenview.webcontents.BaseWebContentsViewer
import com.mime.dualscreenview.webcontents.MainControllInterface import com.mime.dualscreenview.webcontents.MainControllInterface
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere
import com.mime.dualscreenview.webcontents.contentsinfo.NewtokiOne
import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.copyFromRealm import io.realm.kotlin.ext.copyFromRealm
import io.realm.kotlin.ext.query import io.realm.kotlin.ext.query
import kotlinx.coroutines.GlobalScope import org.jsoup.Jsoup
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.launch
import java.lang.System.currentTimeMillis import java.lang.System.currentTimeMillis
import java.text.Normalizer
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.Date import java.util.Date
import java.util.regex.Pattern
import kotlin.random.Random import kotlin.random.Random
class Intro : Base() , MainControllInterface, PagedTextViewInterface { class Intro : Base() , MainControllInterface, PagedTextViewInterface {
// Save previous state of dual screens
private lateinit var mBaseWebContentsViewer : BaseWebContentsViewer private lateinit var mBaseWebContentsViewer : BaseWebContentsViewer
var lastInfo : LastInfo? = null var lastInfo : LastInfo? = null
lateinit var paged_layer : PagedTextLayout lateinit var paged_layer : PagedTextLayout
lateinit var textview_title : TextView lateinit var textview_title : TextView
var currentBooinfo : BookPageInfo? = null var currentBooinfo : BookPageInfo? = null
val handle = object : Handler() {
val handle = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) { override fun handleMessage(msg: Message) {
// super.handleMessage(msg)
if (msg.what == 0 ) { if (msg.what == 0 ) {
(msg.obj as? ReaderConfig)?.let { (msg.obj as? ReaderConfig)?.let {
} }
} }
} }
} }
fun getCurrentUrl() : String {
var currentPath = currentBooinfo?.pathUrl ?: mBaseWebContentsViewer.webview.url?.toUri()?.path ?: ""
var domain = PrefManager.getLastDomain()
return domain.plus(if (currentPath.length > 4) currentPath else "")
}
override fun onConfigurationChanged(newConfig: Configuration) { override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig) super.onConfigurationChanged(newConfig)
Blog.LOGD(log= "onConfigurationChanged ${this::class.java.name} >> newConfig ${newConfig}") Blog.LOGD(log= "onConfigurationChanged ${this::class.java.name} >> newConfig ${newConfig}")
@ -99,11 +99,13 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
} }
var contentsSaver : WebView? = null var contentsSaver : WebView? = null
lateinit var binding : IntroBinding
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
Blog.LOGD(log= "onCreate ${this::class.java.name} >> savedInstanceState ${savedInstanceState}") Blog.LOGD(log= "onCreate ${this::class.java.name} >> savedInstanceState ${savedInstanceState}")
setContentView(R.layout.intro) binding = IntroBinding.inflate(layoutInflater)
findViewById<WebView>(R.id.menu_web)?.let { setContentView(binding.root)
binding.menuWeb.let {
it.setOnLongClickListener { it.setOnLongClickListener {
onTouch(TouchArea.Center) onTouch(TouchArea.Center)
return@setOnLongClickListener false return@setOnLongClickListener false
@ -111,21 +113,28 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
mBaseWebContentsViewer = BaseWebContentsViewer(it,this) mBaseWebContentsViewer = BaseWebContentsViewer(it,this)
} }
paged_layer = findViewById<PagedTextLayout>(R.id.paged_layer) paged_layer = binding.pagedLayer
textview_title = findViewById<TextView>(R.id.textview_title) textview_title = binding.textviewTitle
findViewById<ImageButton>(R.id.btn_list).setOnClickListener { v -> binding.btnList.setOnClickListener { v ->
mBaseWebContentsViewer?.webview?.url?.let { mBaseWebContentsViewer?.webview?.url?.let {
Uri.parse(it).path?.let { Uri.parse(it).path?.let {
HistoryManager.getBooInfo(it, { HistoryManager.getBookInfos(it, {
it?.let { showList(it) } it?.let {
it.pages.sortBy { it.pathUrl }
showList(it)
}
}) })
} }
} }
} }
findViewById<WebView>(R.id.hidden_web)?.let { v-> binding.hiddenWeb?.let { v->
contentsSaver = v contentsSaver = v
contentsSaver?.webViewClient = saveClient contentsSaver?.webViewClient = saveClient
try {
contentsSaver?.removeJavascriptInterface("MyJavaScriptInterface")
} catch (e:Exception) {e.printStackTrace()}
contentsSaver?.addJavascriptInterface(SaveHelper(),"MyJavaScriptInterface")
contentsSaver?.settings?.textZoom = 100 contentsSaver?.settings?.textZoom = 100
contentsSaver?.settings?.javaScriptEnabled = true contentsSaver?.settings?.javaScriptEnabled = true
contentsSaver?.settings?.javaScriptCanOpenWindowsAutomatically = false contentsSaver?.settings?.javaScriptCanOpenWindowsAutomatically = false
@ -141,47 +150,20 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
// switcvhOrient() // switcvhOrient()
// } // }
findViewById<View>(R.id.btn_setting).setOnClickListener { v-> binding.btnSetting.setOnClickListener { v->
// var intent = Intent()
// var findIntent = Intent(Intent.ACTION_MAIN,null)
// var list = packageManager.queryIntentActivities(findIntent,0)
// list.forEach {
// Blog.LOGE("activityInfo ============START================")
// val pm = applicationContext.packageManager
// var ai = try {
// pm.getApplicationInfo(it.activityInfo.packageName, 0)
// } catch (e: NameNotFoundException) {
// null
// }
// val applicationName =
// (if (ai != null) pm.getApplicationLabel(ai) else "(unknown)") as String
// Blog.LOGE("applicationName ============:: ${applicationName} ::================")
// Blog.LOGE("it.activityInfo.processName ::=> ${it.activityInfo.processName}")
// Blog.LOGE("it.activityInfo.targetActivity ::=> ${it.activityInfo.targetActivity}")
// Blog.LOGE("it.activityInfo.name ::=> ${it.activityInfo.name}")
// Blog.LOGE("it.activityInfo.packageName ::=> ${it.activityInfo.packageName}")
// Blog.LOGE("it.resolvePackageName ::=> ${it.resolvePackageName}")
// Blog.LOGE("activityInfo ============END================")
// }
//
//
// var startIntene = Intent(Intent.ACTION_MAIN)
// startIntene.setComponent(ComponentName("com.samsung.android.app.interpreter","com.samsung.android.app.interpreter.interpretation.view.InterpretationActivity"))
// startActivity(startIntene)
startActivity(Intent(this@Intro, Settings::class.java)) startActivity(Intent(this@Intro, Settings::class.java))
} }
findViewById<View>(R.id.btn_history).setOnClickListener { v-> binding.btnHistory.setOnClickListener { v->
var realm = openRealm() var realm = openRealm()
realm.query<HistoryItem>()?.find()?.let { realm.query<HistoryItem>().find().let {
showHistory(realm.copyFromRealm(it)) showHistory(realm.copyFromRealm(it))
} }
} }
binding.btnHome.setOnClickListener { v->
findViewById<View>(R.id.btn_home).setOnClickListener { v-> paged_layer.visibility = GONE
paged_layer?.visibility = GONE mBaseWebContentsViewer.loadContents(NewtokiOne)
mBaseWebContentsViewer.loadContents(Booktoki)
} }
loadLastInfo() loadLastInfo()
@ -189,13 +171,12 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
fun loadLastInfo(){ fun loadLastInfo(){
val realm = openRealm() val realm = openRealm()
try { lastInfo = realm?.query<LastInfo>()?.find()?.last()?.copyFromRealm() try { lastInfo = realm.query<LastInfo>().find().last()?.copyFromRealm()
try { try {
if (lastInfo != null) { if (lastInfo != null) {
HistoryManager.getBooPageInfo(Uri.parse(lastInfo!!.pageUrl!!).path!!) { HistoryManager.getBookPageInfo(Uri.parse(lastInfo!!.pageUrl!!).path!!) {
it?.let { it?.let {
currentBooinfo = it currentBooinfo = it
paged_layer.text = it!!.contents!!
paged_layer.visibility = VISIBLE paged_layer.visibility = VISIBLE
if(it?.pathUrl?.length ?: 0 > 0) { if(it?.pathUrl?.length ?: 0 > 0) {
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!)) HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
@ -204,11 +185,11 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})") Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!)) mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else { } else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})") Blog.LOGE("HistoryManager.getNextPage(${NewtokiOne.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!) mBaseWebContentsViewer.webview.loadUrl(NewtokiOne.getLastedDoamin() + it?.pathUrl!!)
} }
it?.pathUrl?.let { it?.pathUrl?.let {
HistoryManager.getBooInfo(it) { HistoryManager.getBookInfos(it) {
saveItem(it) saveItem(it)
} }
} }
@ -217,26 +198,11 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
HistoryManager.openRealm.query<ReaderConfig>()?.find()?.let { HistoryManager.openRealm.query<ReaderConfig>()?.find()?.let {
if (it.size > 0) { if (it.size > 0) {
realm.copyFromRealm(it.first()).let { realm.copyFromRealm(it.first()).let {
runOnUiThread { applyReaderConfig()
paged_layer.setTextSize(it.textSize?.toFloat()?: 14f)
paged_layer.setLineSpacing(it.lineSpace?.toFloat() ?: 1f)
paged_layer.setLetterSpacing(it.letterSpace?.toFloat() ?: 1f)
paged_layer.setPadding(
it.padding ?: 1,
it.padding ?: 1,
it.padding ?: 1,
it.padding ?: 1)
var typeface = typesfacez.get(getIndex(typesfacez as PairArray<Any>,it.font ?: ""))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paged_layer.setTypeface(resources.getFont(typeface.second))
}
val color = colorz.get(it.style ?: 0)
paged_layer.setColorStyle(color.second)
}
} }
} }
} }
paged_layer.text = it!!.contents!!
} }
} }
} }
@ -245,6 +211,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
}} catch (e : Exception) { } }} catch (e : Exception) { }
} }
fun reloadLastInfo() { fun reloadLastInfo() {
val configuration: Configuration = getResources().getConfiguration() val configuration: Configuration = getResources().getConfiguration()
if(lastInfo != null && lastInfo?.displayOrientation != configuration.orientation) { if(lastInfo != null && lastInfo?.displayOrientation != configuration.orientation) {
@ -252,21 +219,22 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
} }
} }
override fun onBookInfos(aInfos: BookPageInfos) {
Blog.LOGE("onBookInfos(aInfos: ${aInfos})")
runOnUiThread {
showList(aInfos)
}
}
override fun onBookInfos(jsonString: String) { override fun onBookInfos(jsonString: String) {
Blog.LOGE("onBookInfos" , "onBookInfos >> ${jsonString}") Blog.LOGE("onBookInfos" , "jsonString >> ${jsonString}")
val realm = openRealm() val realm = openRealm()
var infos : BookPageInfos? = null var infos : BookPageInfos? = null
realm.writeBlocking { realm.writeBlocking {
try { try {
var infosj : BookPageInfosJ? = null var infosj : BookPageInfosJ? = null
infosj = Gson().fromJson(jsonString, BookPageInfosJ::class.java) infosj = Gson().fromJson(jsonString, BookPageInfosJ::class.java)
Blog.LOGE("onBookInfos" , "onBookInfos 2 >> ${infosj}") HistoryManager.getBookInfos(infosj.bookPageUrl!!){
Blog.LOGE("onBookInfos" , "onBookInfos 2 - 1 >> ${infosj?.pages}")
// realm.createObjectFromJson
Blog.LOGE("onBookInfos" , "onBookInfos 2 - 1 >> ${infosj?.getR()}")
HistoryManager.getBooInfo(infosj.bookPageUrl!!){
if (it != null) { if (it != null) {
infos = copyToRealm(it!!, UpdatePolicy.ALL) infos = copyToRealm(it!!, UpdatePolicy.ALL)
@ -275,8 +243,9 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
infos!!.pages.add(item.getRealm()) infos!!.pages.add(item.getRealm())
} }
} }
Blog.LOGE("onBookInfos", "onBookInfos 3 >> ${realm.query<BookPageInfos>().find().size}") if (infos != null) {
Blog.LOGE("onBookInfos", "onBookInfos 4 >> ${realm.query<BookPageInfo>().find().size}") infos = this.copyFromRealm(infos!!)
}
} else { } else {
infos = infosj?.getR() infos = infosj?.getR()
if (infos != null) { if (infos != null) {
@ -284,37 +253,38 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
for (item in infosj.pages) { for (item in infosj.pages) {
infos?.pages?.add(item.getRealm()) infos?.pages?.add(item.getRealm())
} }
Blog.LOGE("onBookInfos", "onBookInfos 3 >> ${realm.query<BookPageInfos>().find().size}") }
Blog.LOGE("onBookInfos", "onBookInfos 4 >> ${realm.query<BookPageInfo>().find().size}") if (infos != null) {
infos = this.copyFromRealm(infos!!)
} }
} }
} }
if (infos != null) {
infos = this.copyFromRealm(infos!!)
}
} catch (e :Exception) { } catch (e :Exception) {
e.printStackTrace() e.printStackTrace()
} } finally {
} infos?.bookPageUrl?.let {
HistoryManager.getBookInfos(it){
infos?.bookPageUrl?.let { it?.let {
HistoryManager.getBooInfo(it){ Blog.LOGE(s(), "onBookInfos it >> ${it}")
it?.let { runOnUiThread {
Blog.LOGE("onBookInfos" , "onBookInfos it >> ${it}") showList(it)
runOnUiThread { }
showList(it) }
} }
} }
} }
} }
} }
private fun s() = "onBookInfos"
fun reloadTo(lastInfo: LastInfo?) { fun reloadTo(lastInfo: LastInfo?) {
findViewById<WebView>(R.id.menu_web)?.postDelayed({ findViewById<WebView>(R.id.menu_web)?.postDelayed({
if (lastInfo != null) { if (lastInfo != null) {
mBaseWebContentsViewer.loadLastInfo(lastInfo!!) mBaseWebContentsViewer.loadLastInfo(lastInfo!!)
} else { } else {
mBaseWebContentsViewer.loadContents(Booktoki) mBaseWebContentsViewer.loadContents(NewtokiOne)
} }
},200L) },200L)
} }
@ -376,7 +346,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
builderInner.setPositiveButton("Ok", builderInner.setPositiveButton("Ok",
DialogInterface.OnClickListener { DialogInterface.OnClickListener {
dialog, which -> dialog, which ->
reloadTo(item.makeLastInfo()) contentsLoad(item.pageUrl)
dialog.dismiss() dialog.dismiss()
}) })
builderInner.setNeutralButton("삭제", builderInner.setNeutralButton("삭제",
@ -408,16 +378,18 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
} }
fun showList(infos: BookPageInfos) { fun showList(infos: BookPageInfos) {
Blog.LOGE("showList infos >>>>${infos}")
if (infos != null && infos.pages.size ?: 0 > 0) { if (infos != null && infos.pages.size ?: 0 > 0) {
var items : ArrayList<BookPageInfo> = arrayListOf() var items : ArrayList<BookPageInfo> = arrayListOf()
for (item in infos.pages) { for (item in infos.pages) {
items.add(item) items.add(item)
} }
items.sortBy { it.chapterNum }
items.sortBy { it.chapterID }
DefaultList.showDefaultList( DefaultList.showDefaultList(
this@Intro, this@Intro,
"현제는 ${currentTitle} - ${(infos.pages.size ?: 0) - currentChapter} -> 다른화를 골라", "현제는 ${currentTitle} - ${currentChapter} -> 다른화를 골라",
items, items,
currentChapter, currentChapter,
{ position -> { position ->
@ -446,92 +418,121 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
return text.trim() return text.trim()
} }
var isLoading = false
var saveClient = object : WebViewClient() { var saveClient = object : WebViewClient() {
override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) {
super.onPageStarted(view, url, favicon) super.onPageStarted(view, url, favicon)
isLoading = true
Blog.LOGE("saveClient >>> ${isLoading} ${url}")
} }
override fun onPageFinished(webView: WebView?, url: String?) { override fun onPageFinished(webView: WebView?, url: String?) {
super.onPageFinished(webView, url) super.onPageFinished(webView, url)
isLoading = false // val delayed = 3500L + Math.abs(Random.nextLong().rem(9999L))
var ramdomTimeSec = 1000L + Random(System.currentTimeMillis()).nextLong().rem(3999) finishedUrl = url ?: ""
Blog.LOGE("ramdomTime >>> ${ramdomTimeSec}") webView?.postDelayed({
webView?.postDelayed( { webView?.evaluateJavascript(
Blog.LOGE("saveClient >>> ${isLoading} ${url}") "function getAll() {\n" +
var findContents = Booktoki.getFindContentsJs() " MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
webView?.evaluateJavascript(findContents){ result: String? -> " };getAll()"
result?.let { string: String -> ) { result ->
Blog.LOGE("saveClient contents >>> ${string.length}") (result as? String)?.let {
if (string.length > 10) {
Blog.LOGE("saveClient it.length >>> ${string.length}")
var contents = string.replace("\\\"","\"")
contents = (contents.replace("\\n", System.getProperty("line.separator")))
contents = (contents.replace("\\n", System.getProperty("line.separator")))
Blog.LOGE("saveClient contents >>> ${contents.length}")
Uri.parse(url)?.let {
it.path?.let {
HistoryManager.getBooPageInfoContentsSave(it, contents.replace(Char(0x20).toString()," "))
HistoryManager.getBooPageInfo(it) { info ->
runOnUiThread {
info?.let {
var origin = info.getTitleItem()
val biggerText = SpannableStringBuilder(origin)
biggerText.setSpan(RelativeSizeSpan(1.6f), 0, origin.length, 0)
Toast.makeText(baseContext,biggerText, Toast.LENGTH_SHORT).apply {
setGravity(Gravity.CENTER, 0, 0)
}.show()
}
}
}
}
}
}
var ramdomTime = 8000L + Random(System.currentTimeMillis()).nextLong().rem(7999)
Blog.LOGE("ramdomTime >>> ${ramdomTime}")
contentsSaver?.postDelayed( { saveItem(null) }, ramdomTime)
} }
}},ramdomTimeSec) }
}, delayed)
}
}
fun showToast(origin: String) {
runOnUiThread {
val toast = Toast(this)
toast.duration = Toast.LENGTH_SHORT
val biggerText = SpannableStringBuilder(origin)
biggerText.setSpan(RelativeSizeSpan(1.6f), 0, origin.length, 0)
val view: View = inflate(this, com.mime.dualscreenview.R.layout.simple_toast,null)
view.findViewById<TextView>(com.mime.dualscreenview.R.id.text).text = biggerText
toast.setView(view)
toast.show()
// Toast.makeText(
// baseContext,
// biggerText,
// Toast.LENGTH_SHORT
// ).show()
}
}
var delayed = 3500L + Math.abs(Random.nextLong().rem(9999L))
var finishedUrl : String? = null
inner class SaveHelper {
@JavascriptInterface
fun sendValueFromHtml(string: String) {
Jsoup.parse(string)?.let { html ->
val view_padding = html.getElementsByClass("view-padding")
if (view_padding.size > 0){
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
val contents = view_padding.get(0).children().html().replace("<p>"," ").replace("</p>","\n\n")
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: view_padding.get(0)\n${contents}")
if (contents.length > 20) {
Uri.parse(finishedUrl).path?.let {
delayed = 3500L + Math.abs(Random.nextLong().rem(9999L))
HistoryManager.getBooPageInfoContentsSave(it, contents).apply {
HistoryManager.getBookPageInfo(it) { book ->
showToast("saved ${book?.getTitleItem()} \n:: lenght = ${contents.length} \n:: saveTarget = ${saveTarget.size}\n:: delayed >> ${delayed}")
}
}.apply {
HistoryManager.getBookInfos(it) { saveItem(it)}
}
}
}
} else {
}
}
} }
} }
var saveTarget : ArrayList<BookPageInfo> = arrayListOf() var saveTarget : ArrayList<BookPageInfo> = arrayListOf()
private fun saveItem(infos: BookPageInfos?) { private fun saveItem(infos: BookPageInfos?) {
Blog.LOGE("saveItem >>> infos?.pages ${infos?.pages?.size ?: 0}") Blog.LOGE("saveItem >>> infos?.pages ${infos?.pages?.size ?: 0}")
var savedCount = Math.abs(Random(System.currentTimeMillis()).nextLong().rem(19) + 6L) var savedCount = Math.abs(Random(System.currentTimeMillis()).nextLong().rem(9) + 6L)
Blog.LOGE("saveItem >>> targetCount = ${savedCount}") Blog.LOGE("saveItem >>> targetCount = ${savedCount}")
infos?.pages?.reversed()?.forEach { infos?.pages?.reversed()?.forEach {
if ((it.contents?.length ?: 0) > 10) { if ((it.contents?.length ?: 0) > 10) {
} else { } else {
if (saveTarget.size < savedCount.toInt()) { if (savedCount.toInt() > 0) {
saveTarget.add(it) saveTarget.add(it)
savedCount = savedCount - 1L
} }
} }
} }
if (savedCount > 0) {
HistoryManager.openRealm.query<BookPageInfo>().find().forEach {
if ((it.contents?.length ?: 0) > 10) {
} else if(savedCount.toInt() > 0) {
saveTarget.add(HistoryManager.openRealm.copyFromRealm(it))
savedCount = savedCount - 1
}
}
}
Blog.LOGE("saveItem >>> saveTarget ${saveTarget.count()}") Blog.LOGE("saveItem >>> saveTarget ${saveTarget.count()}")
if (isLoading == false) { try {
try { saveTarget.removeFirst().let {
saveTarget.removeFirst().let { Blog.LOGE("saveItem >>> ${it.pathUrl}")
Blog.LOGE("saveItem >>> ${it.pathUrl}") runOnUiThread {
runOnUiThread { mBaseWebContentsViewer.webview.url?.let { currentUrl ->
mBaseWebContentsViewer.webview.url?.let { currentUrl -> currentUrl.replace(Uri.parse(currentUrl).path ?: "", it.pathUrl ?: "")
currentUrl.replace(Uri.parse(currentUrl).path ?: "", it.pathUrl ?: "") ?.let { targetUrl ->
?.let { targetUrl -> Blog.LOGE("targetUrl >>> ${targetUrl}")
Blog.LOGE("targetUrl >>> ${targetUrl}") contentsSaver?.loadUrl(targetUrl)
contentsSaver?.loadUrl(targetUrl) }
}
}
} }
} }
} catch ( e : Exception) {
e.printStackTrace()
} }
} catch ( e : Exception) {
e.printStackTrace()
} }
} }
private fun moveTo(item: BookPageInfo?) { private fun moveTo(item: BookPageInfo?) {
@ -578,117 +579,70 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
} }
} }
fun moveToNext(pathUrl : String?) {
if (pathUrl != null && pathUrl.length > 6) {
HistoryManager.getNextPage(pathUrl!!) {
if(it != null && it!!.pathUrl?.length ?: 0 > 6) {contentsLoad(it.pathUrl!!)}
}
}
}
fun moveToPrev(pathUrl : String?) {
if (pathUrl != null && pathUrl.length > 6) {
HistoryManager.getPrevPage(pathUrl!!) {
if(it != null && it!!.pathUrl?.length ?: 0 > 6) {contentsLoad(it.pathUrl!!)}
}
}
}
fun contentsLoad(pathUrl : String) {
HistoryManager.getBookPageInfo(pathUrl) {
Blog.LOGE("contentsLoad :::: pathUrl >> ${pathUrl}")
it?.pathUrl?.let {
Blog.LOGE("contentsLoad :::: pathUrl >> ${it}")
HistoryManager.getBookInfos(it) {
Blog.LOGE("contentsLoad :::: getBookInfos >> ${it}")
saveItem(it)
}
}
if (it != null) currentBooinfo = it
if (it != null && (it?.contents?.length ?: 0) > 10) {
paged_layer.visibility = VISIBLE
if((it?.pathUrl?.length ?: 0) > 0) {
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
mBaseWebContentsViewer.webview.loadUrl(NewtokiOne.getLastedDoamin() + it?.pathUrl!!)
}
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
applyReaderConfig()
paged_layer.text = it!!.contents!!
} else {
if(it?.pathUrl?.length ?: 0 > 0) {
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(NewtokiOne.getLastedDoamin() + it?.pathUrl!!)
}
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
}
}
}
fun actionNextEvent(fast : Boolean = false) { fun actionNextEvent(fast : Boolean = false) {
if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && (paged_layer!!.current() < paged_layer!!.size() - 1) ) { if (paged_layer != null && paged_layer!!.visibility == View.VISIBLE && paged_layer!!.size() > 0 && (paged_layer!!.current() < paged_layer!!.size() - 1) ) {
paged_layer!!.doNext(fast) paged_layer!!.doNext(fast)
updateLastInfo(paged_layer!!) updateLastInfo(paged_layer!!)
} else { } else {
val pathUrl = currentBooinfo?.pathUrl moveToNext(currentBooinfo?.pathUrl ?: mBaseWebContentsViewer.webview.url?.toUri()?.path)
if (pathUrl != null && pathUrl.length > 6) {
HistoryManager.getNextPage(pathUrl) {
currentBooinfo = it
paged_layer.text = it!!.contents!!
Blog.LOGE("HistoryManager.getNextPage(${it})")
if ((it?.contents?.length ?: 0) > 10) {
paged_layer.visibility = VISIBLE
if((it?.pathUrl?.length ?: 0) > 0) {
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
applyReaderConfig()
} else {
if(it?.pathUrl?.length ?: 0 > 0) {
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
}
it?.pathUrl?.let {
HistoryManager.getBooInfo(it) {
saveItem(it)
}
}
}
} else {
Uri.parse(mBaseWebContentsViewer.webview.url)?.let {
it.path?.let {
HistoryManager.getNextPage(it) {
Blog.LOGE("HistoryManager.getNextPage(${it})")
if (it?.contents?.length ?: 0 > 10) {
currentBooinfo = it
paged_layer.text = it!!.contents!!
paged_layer.visibility = VISIBLE
if (it?.pathUrl?.length ?: 0 > 0) {
HistoryManager.save(
historyItem = HistoryItem().putHistory(
it,
mBaseWebContentsViewer.webview.url!!
)
)
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith(
"http"
)
) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
mBaseWebContentsViewer.webview.loadUrl(
lastInfo!!.pageUrl!!.replace(
Uri.parse(lastInfo!!.pageUrl)!!.path!!,
it?.pathUrl!!
)
)
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
it?.pathUrl?.let {
HistoryManager.getBooInfo(it) {
saveItem(it)
}
}
}
} else {
if (it?.pathUrl?.length ?: 0 > 0) {
HistoryManager.save(historyItem = HistoryItem().putHistory(it, mBaseWebContentsViewer.webview.url!!))
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
mBaseWebContentsViewer.webview.loadUrl(
lastInfo!!.pageUrl!!.replace(
Uri.parse(lastInfo!!.pageUrl)!!.path!!,
it?.pathUrl!!
)
)
paged_layer?.visibility = GONE
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
paged_layer?.visibility = GONE
}
}
}
it?.pathUrl?.let { HistoryManager.getBooInfo(it) { saveItem(it) } }
}
}
}
}
// onNextClickAction?.let { it() }
} }
} }
@ -709,6 +663,13 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
if (it.size > 0) { if (it.size > 0) {
realm.copyFromRealm(it.first())?.let { realm.copyFromRealm(it.first())?.let {
runOnUiThread { runOnUiThread {
var typeface = typesfacez.get(getIndex(typesfacez as PairArray<Any>,it.font ?: ""))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paged_layer?.setTypeface(resources.getFont(typeface.second))
}
val color = colorz.get(it.style ?: 0)
paged_layer?.setColorStyle(color.second)
paged_layer.setTextSize(it.textSize?.toFloat()?: 14f) paged_layer.setTextSize(it.textSize?.toFloat()?: 14f)
paged_layer.setLineSpacing(it.lineSpace?.toFloat() ?: 1f) paged_layer.setLineSpacing(it.lineSpace?.toFloat() ?: 1f)
paged_layer.setLetterSpacing(it.letterSpace?.toFloat() ?: 1f) paged_layer.setLetterSpacing(it.letterSpace?.toFloat() ?: 1f)
@ -717,13 +678,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
it.padding ?: 1, it.padding ?: 1,
it.padding ?: 1, it.padding ?: 1,
it.padding ?: 1) it.padding ?: 1)
paged_layer.invalidate()
var typeface = typesfacez.get(getIndex(typesfacez as PairArray<Any>,it.font ?: ""))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
paged_layer?.setTypeface(resources.getFont(typeface.second))
}
val color = colorz.get(it.style ?: 0)
paged_layer?.setColorStyle(color.second)
} }
} }
} }
@ -735,84 +690,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
paged_layer!!.doPrev(fast) paged_layer!!.doPrev(fast)
updateLastInfo(paged_layer!!) updateLastInfo(paged_layer!!)
} else { } else {
if (currentBooinfo != null) { moveToPrev(currentBooinfo?.pathUrl ?: mBaseWebContentsViewer.webview.url?.toUri()?.path)
HistoryManager.getPrevPage(currentBooinfo!!.pathUrl!!) {
Blog.LOGE("HistoryManager.getNextPage(${it})")
if (it?.contents?.length ?: 0 > 10) {
currentBooinfo = it
paged_layer.text = it!!.contents!!
paged_layer.visibility = VISIBLE
if(it?.pathUrl?.length ?: 0 > 0) {
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
}
applyReaderConfig()
} else {
if(it?.pathUrl?.length ?: 0 > 0) {
Blog.LOGE("HistoryManager.getNextPage(${it?.pathUrl})")
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith("http")) {
Blog.LOGE("HistoryManager.getNextPage(${lastInfo?.pageUrl})")
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(lastInfo!!.pageUrl!!.replace(Uri.parse(lastInfo!!.pageUrl)!!.path!!,it?.pathUrl!!))
} else {
Blog.LOGE("HistoryManager.getNextPage(${Booktoki.getLastedDoamin()})")
paged_layer.visibility = GONE
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!))
}
}
if(it?.pathUrl?.length ?: 0 > 0) {
it?.pathUrl?.let {
HistoryManager.getBooInfo(it) {
saveItem(it)
}
}
}
}
} else {
Uri.parse(mBaseWebContentsViewer.webview.url)?.let {
it.path?.let {
HistoryManager.getPrevPage(it) {
if (it?.contents?.length ?: 0 > 10) {
currentBooinfo = it
paged_layer.text = it!!.contents!!
paged_layer.visibility = VISIBLE
}
if (it?.pathUrl?.length ?: 0 > 0) {
HistoryManager.save(
historyItem = HistoryItem().putHistory(
it,
mBaseWebContentsViewer.webview.url!!
)
)
if (lastInfo?.pageUrl?.length ?: 0 > 0 && lastInfo?.pageUrl!!.startsWith(
"http"
)
) {
mBaseWebContentsViewer.webview.loadUrl(
lastInfo!!.pageUrl!!.replace(
Uri.parse(lastInfo!!.pageUrl)!!.path!!,
it?.pathUrl!!
)
)
} else {
mBaseWebContentsViewer.webview.loadUrl(Booktoki.getLastedDoamin() + it?.pathUrl!!)
}
}
}
}
}
}
// onPrevClickAction?.let{ it() }
} }
} }
@ -856,34 +734,41 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
@RequiresApi(Build.VERSION_CODES.O) @RequiresApi(Build.VERSION_CODES.O)
override fun onLoadedContents(aContents: String) { override fun onLoadedContents(aContents: String) {
paged_layer.apply { paged_layer.apply {
if (aContents != null && aContents.length > 10) { paged_layer.post {
var contents = aContents.replace("\\\"","\"") if (aContents != null && aContents.length > 10) {
contents = (contents.replace("\\n", System.getProperty("line.separator"))) var contents = aContents.replace("\\\"", "\"")
contents = (contents.replace("\\n", System.getProperty("line.separator"))) contents = (contents.replace("\\n", System.getProperty("line.separator")))
mPagedTextViewInterface = this@Intro contents = (contents.replace("\\n", System.getProperty("line.separator")))
if(lastInfo != null && mBaseWebContentsViewer.webview.url?.endsWith(lastInfo!!.pageUrl) ?: false) { mPagedTextViewInterface = this@Intro
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = VISIBLE if (lastInfo != null && mBaseWebContentsViewer.webview.url?.endsWith(lastInfo!!.pageUrl) ?: false) {
paged_layer?.postDelayed({ binding.progress.visibility = VISIBLE
this@Intro.findViewById<ProgressBar>(R.id.progress)?.visibility = GONE paged_layer.postDelayed({
},1000) binding.progress.visibility = GONE
} }, 1000)
runOnUiThread { }
text = contents applyReaderConfig()
visibility = VISIBLE runOnUiThread {
} text = contents
applyReaderConfig() visibility = VISIBLE
forceUpdateUI() }
mBaseWebContentsViewer.webview.url?.let { forceUpdateUI()
Uri.parse(it)?.let { mBaseWebContentsViewer.webview.url?.let {
it.path?.let { Uri.parse(it)?.let {
HistoryManager.getBooPageInfo(it){ it.path?.let {
currentBooinfo = it HistoryManager.getBookPageInfo(it) {
currentChapter = it?.chapterNum ?: 0 currentBooinfo = it
currentPage = it?.chapterNum ?: 0 currentChapter = it?.chapterNum ?: 0
HistoryManager.save(historyItem = HistoryItem().putHistory(it,mBaseWebContentsViewer.webview.url!!)) currentPage = it?.chapterNum ?: 0
HistoryManager.save(
historyItem = HistoryItem().putHistory(
it,
mBaseWebContentsViewer.webview.url!!
)
)
}
} }
HistoryManager.getBooPageInfoContentsSave(it!!.path!!, contents)
} }
HistoryManager.getBooPageInfoContentsSave(it!!.path!!,contents)
} }
} }
} }
@ -912,7 +797,6 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
builder.setNegativeButton( builder.setNegativeButton(
"Cancel" "Cancel"
) { dialog, which -> dialog.cancel() } ) { dialog, which -> dialog.cancel() }
builder.show() builder.show()
} }
var testRegex = """[^0-9]""".toRegex(); var testRegex = """[^0-9]""".toRegex();
@ -947,7 +831,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
lastInfo.displayOrientation = configuration?.orientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT lastInfo.displayOrientation = configuration?.orientation ?: ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
saveLastInfo(lastInfo) saveLastInfo(lastInfo)
} }
findViewById<ProgressBar>(R.id.progress).visibility = GONE binding.progress.visibility = GONE
} }
fun saveLastInfo(lastInfo: LastInfo) { fun saveLastInfo(lastInfo: LastInfo) {
@ -980,6 +864,7 @@ class Intro : Base() , MainControllInterface, PagedTextViewInterface {
this.query<LastInfo>()?.find()?.last()?.let{ this.query<LastInfo>()?.find()?.last()?.let{
it.displayOrientation = configuration.orientation it.displayOrientation = configuration.orientation
it.title = currentTitle it.title = currentTitle
// it.pageUrl = currentBooinfo?.pathUrl ?: mBaseWebContentsViewer.webview.url?.toUri()?.path ?: ""
it.chapter = currentChapter it.chapter = currentChapter
it.pageIndex = pagedTextLayout.current() it.pageIndex = pagedTextLayout.current()
this@Intro.lastInfo = copyFromRealm(it) this@Intro.lastInfo = copyFromRealm(it)

View File

@ -13,7 +13,21 @@ val colorz : PairArray<Array<String>> = arrayOf<Pair<String,Array<String>>>(
Pair("color set 07",arrayOf<String>("#F8BBD0", "#263238")), Pair("color set 07",arrayOf<String>("#F8BBD0", "#263238")),
Pair("color set 08",arrayOf<String>("#E6EE9C", "#455A64")), Pair("color set 08",arrayOf<String>("#E6EE9C", "#455A64")),
Pair("color set 09",arrayOf<String>("#CFD8DC", "#455A64")), Pair("color set 09",arrayOf<String>("#CFD8DC", "#455A64")),
Pair("color set 10",arrayOf<String>("#FFF59D", "#37474F")) Pair("color set 10",arrayOf<String>("#FFF59D", "#37474F")),
Pair("color set 21",arrayOf<String>("#263238","#E1F5FE")),
Pair("color set 22",arrayOf<String>("#37474F","#F0F4C3")),
Pair("color set 23",arrayOf<String>("#455A64","#ECEFF1")),
Pair("color set 24",arrayOf<String>("#263238","#E0F7FA")),
Pair("color set 25",arrayOf<String>("#263238","#F5F5F5")),
Pair("color set 26",arrayOf<String>("#263238","#ECEFF1")),
Pair("color set 27",arrayOf<String>("#263238","#F8BBD0")),
Pair("color set 28",arrayOf<String>("#455A64","#E6EE9C")),
Pair("color set 29",arrayOf<String>("#455A64","#CFD8DC")),
Pair("color set 30",arrayOf<String>("#37474F","#FFF59D")),
Pair("color set 31",arrayOf<String>("#FFFFFF","#1C1B1B")),
Pair("color set 32",arrayOf<String>("#272727","#FFFFFF")),
Pair("color set 33",arrayOf<String>("#1C1B1B","#FFFFFF")),
Pair("color set 34",arrayOf<String>("#FFFFFF","#272727"))
) )
val typesfacez : PairArray<Int> = arrayOf<Pair<String,Int>>( val typesfacez : PairArray<Int> = arrayOf<Pair<String,Int>>(
Pair("정선 아리랑 혼", R.font.jsarirang_hon), Pair("정선 아리랑 혼", R.font.jsarirang_hon),
@ -22,6 +36,37 @@ val typesfacez : PairArray<Int> = arrayOf<Pair<String,Int>>(
Pair("손기정체", R.font.kcc_sonkeechung), Pair("손기정체", R.font.kcc_sonkeechung),
Pair("교보 손글씨", R.font.kyobo_handwriting_2021sjy), Pair("교보 손글씨", R.font.kyobo_handwriting_2021sjy),
Pair("태백 은하수", R.font.taebaek_milkyway), Pair("태백 은하수", R.font.taebaek_milkyway),
Pair("taebaek_milkyway",R.font.taebaek_milkyway),
Pair("kccahnjunggeun",R.font.kccahnjunggeun),
Pair("kotra_songeulssi",R.font.kotra_songeulssi),
Pair("kotra_bold",R.font.kotra_bold),
Pair("cafe24oneprettynight",R.font.cafe24oneprettynight),
Pair("nnsgc_wsjidyp",R.font.nnsgc_wsjidyp),
Pair("nnsgc_yjc",R.font.nnsgc_yjc),
Pair("nnsgc_brhp",R.font.nnsgc_brhp),
Pair("nnsgc_md",R.font.nnsgc_md),
Pair("nnsgc_gd_an_gd",R.font.nnsgc_gd_an_gd),
Pair("dovemayo",R.font.dovemayo),
Pair("gabia_solmee",R.font.gabia_solmee),
Pair("ylee_mortal_heart_immortal_memory",R.font.ylee_mortal_heart_immortal_memory),
Pair("kcc_kimhoon",R.font.kcc_kimhoon),
Pair("taefont_tsthlml",R.font.taefont_tsthlml),
Pair("ssshinb7",R.font.ssshinb7),
Pair("godomaum",R.font.godomaum),
Pair("tvn_jguiyg_medium",R.font.tvn_jguiyg_medium),
Pair("tvn_jguiyg_light",R.font.tvn_jguiyg_light),
Pair("on_jsuhr",R.font.on_jsuhr),
Pair("on_jsuhl",R.font.on_jsuhl),
Pair("on_ychyuhr",R.font.on_ychyuhr),
Pair("on_ychyuhl",R.font.on_ychyuhl),
Pair("on_treeususimgul_r",R.font.on_treeususimgul_r),
Pair("on_treeususimgul",R.font.on_treeususimgul),
Pair("on_wibsr",R.font.on_wibsr),
Pair("on_wisbl",R.font.on_wisbl),
Pair("on_sbsjl",R.font.on_sbsjl),
Pair("on_sbsjr",R.font.on_sbsjr),
Pair("wandohoper",R.font.wandohoper),
Pair("ebs_r",R.font.ebs_r),
) )
@JvmName("getIndexAny") @JvmName("getIndexAny")

View File

@ -0,0 +1,30 @@
package com.mime.dualscreenview.common
import android.content.Context
import android.content.SharedPreferences
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.NewtokiOne
object PrefManager {
private val mainName = "Main_Pref_"
private val domainKey = "Last_Domain_"
private lateinit var main : SharedPreferences
fun init(context: Context) {
main = context.getSharedPreferences(mainName,Context.MODE_PRIVATE)
}
fun save(key : String, value : String?) {
main.edit().putString(key,value).apply()
}
fun load(key : String) : String? {
return main.getString(key, "")
}
fun getLastDomain() : String {
return main.getString(domainKey, NewtokiOne.getLastedDoamin()) ?: NewtokiOne.getLastedDoamin()
}
fun putLastDomain(domain : String) {
Blog.LOGE("domain >>> ${domain}")
main.edit().putString(domainKey,domain).apply()
}
}

View File

@ -9,7 +9,6 @@ import com.mime.dualscreenview.data.model.ReaderConfig
import io.realm.kotlin.Realm import io.realm.kotlin.Realm
import io.realm.kotlin.RealmConfiguration import io.realm.kotlin.RealmConfiguration
import io.realm.kotlin.UpdatePolicy import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.log.LogLevel
import io.realm.kotlin.types.BaseRealmObject import io.realm.kotlin.types.BaseRealmObject
import io.realm.kotlin.types.TypedRealmObject import io.realm.kotlin.types.TypedRealmObject
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -54,16 +53,25 @@ object HistoryManager {
} }
} }
fun getBooInfo(url : String ,callback : (BookPageInfos?)->Unit) { fun getBookInfos(aUrl : String, callback : (BookPageInfos?)->Unit) {
var url : String = aUrl
openRealm.apply{ openRealm.apply{
Blog.LOGE("get ${url}" ) if (url.startsWith("//")) {
Blog.LOGE("get ${this.query(BookPageInfo::class).count().find()}" ) while (url.startsWith("//")) {
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find() url = url.replace("//","/").trim()
}
}
Blog.LOGE("aUrl >>> ${aUrl}")
Blog.LOGE("aUrl >>> ${aUrl}")
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0 || bookPageUrl == $0","${url}").find()
if (bookPageInfo != null && bookPageInfo.count() > 0) { if (bookPageInfo != null && bookPageInfo.count() > 0) {
Blog.LOGE("get ${bookPageInfo}" ) Blog.LOGE("get ${bookPageInfo}" )
this.query(BookPageInfos::class,"bookPageUrl == $0",bookPageInfo.first().bookPageUrl).find().first().let { var pgs = this.query(BookPageInfos::class,"bookPageUrl == $0", bookPageInfo.first().bookPageUrl).find()
Blog.LOGE("get ${it} , ${it?.pages}" ) if (pgs.size > 0) {
callback.invoke(this.copyFromRealm(it)) pgs.first().let {
Blog.LOGE("get ${it} , ${it?.pages}")
callback.invoke(this.copyFromRealm(it))
}
} }
} else { } else {
callback.invoke(null) callback.invoke(null)
@ -71,10 +79,14 @@ object HistoryManager {
} }
} }
fun getBooPageInfo(url : String ,callback : (BookPageInfo?)->Unit) { fun getBookPageInfo(aUrl : String, callback : (BookPageInfo?)->Unit) {
var url : String = aUrl
openRealm.apply{ openRealm.apply{
Blog.LOGE("get ${url}" ) if (url.startsWith("//")) {
Blog.LOGE("get ${this.query(BookPageInfo::class).count().find()}" ) while (url.startsWith("//")) {
url = url.replace("//","/").trim()
}
}
var result = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find() var result = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()
if (result.size > 0) { if (result.size > 0) {
var bookPageInfo = result?.first() var bookPageInfo = result?.first()
@ -85,10 +97,10 @@ object HistoryManager {
} }
} }
fun getBooPageInfoContentsSave(url : String, contents : String) { fun getBooPageInfoContentsSave(aUrl : String, contents : String) {
var url : String = aUrl
openRealm.writeBlocking { openRealm.writeBlocking {
Blog.LOGE("get ${url}") Blog.LOGE("getBooPageInfoContentsSave ${url}")
Blog.LOGE("get ${query(BookPageInfo::class).count().find()}")
val result = query(BookPageInfo::class).query("pathUrl == $0", "${url}").find() val result = query(BookPageInfo::class).query("pathUrl == $0", "${url}").find()
if (result.size > 0) { if (result.size > 0) {
result.first().contents = contents result.first().contents = contents
@ -100,42 +112,55 @@ object HistoryManager {
fun getNextPage(url : String ,callback : (BookPageInfo?)->Unit) { fun getNextPage(aUrl : String ,callback : (BookPageInfo?)->Unit) {
var url : String = aUrl
openRealm.apply{ openRealm.apply{
Blog.LOGE("getNextPage ${url}" ) if (url.startsWith("//")) {
Blog.LOGE("getNextPage ${this.query(BookPageInfo::class).count().find()}" ) while (url.startsWith("//")) {
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()?.first() url = url.replace("//","/").trim()
Blog.LOGE("getNextPage 1 ${bookPageInfo}" )
if (bookPageInfo != null) {
Blog.LOGE("getNextPage 2 ${bookPageInfo.chapterNum}" )
Blog.LOGE("getNextPage 2 ${bookPageInfo.bookPageUrl}" )
var results = this.query(BookPageInfo::class).query("chapterNum == $0",bookPageInfo.chapterNum + 1).query("bookPageUrl == $0","${bookPageInfo.bookPageUrl}").find()
if(results.size > 0) {
results.first().let {
Blog.LOGE("getNextPage 2 ${it.pathUrl}" )
callback.invoke(it)
}
} }
} }
var bookPageInfo =
this.query(BookPageInfo::class).query("pathUrl == $0", url).find()
if (bookPageInfo.size > 0) {
Blog.LOGE("getNextPage 2 => chapterNum : ${bookPageInfo.first().chapterNum} , bookPageInfo.bookPageUrl : ${bookPageInfo.first().bookPageUrl}" )
var results = this.query(BookPageInfo::class).query("chapterNum == $0",bookPageInfo.first().chapterNum + 1).query("bookPageUrl == $0","${bookPageInfo.first().bookPageUrl}").find()
if(results.size > 0) {
results.first().let {
Blog.LOGE("getNextPage 2 nextBook pathUrl : ${it.pathUrl}" )
callback.invoke(it)
}
} else {callback.invoke(null)}
} else {callback.invoke(null)}
} }
} }
fun getPrevPage(url : String ,callback : (BookPageInfo?)->Unit) { fun getPrevPage(aUrl : String ,callback : (BookPageInfo?)->Unit) {
var url : String = aUrl
openRealm.apply{ openRealm.apply{
Blog.LOGE("getPrevPage ${url}" ) Blog.LOGE("getPrevPage ${url}" )
Blog.LOGE("getPrevPage ${this.query(BookPageInfo::class).count().find()}" ) if (url.startsWith("//")) {
var bookPageInfo = this.query(BookPageInfo::class).query("pathUrl == $0","${url}").find()?.first() while (url.startsWith("//")) {
Blog.LOGE("getNextPage ${bookPageInfo}" ) url = url.replace("//","/").trim()
if (bookPageInfo != null) { }
Blog.LOGE("getNextPage 2 ${bookPageInfo.chapterNum}" ) }
Blog.LOGE("getNextPage 2 ${bookPageInfo.bookPageUrl}" ) Blog.LOGE("getPrevPage ${url}" )
var results = this.query(BookPageInfo::class).query("chapterNum == $0 && bookPageUrl == $1",bookPageInfo.chapterNum - 1,"${bookPageInfo.bookPageUrl}").find() var bookPageInfo =
this.query(BookPageInfo::class).query("pathUrl == $0", url).find()
Blog.LOGE("getPrevPage ${bookPageInfo}" )
if (bookPageInfo.size > 0) {
Blog.LOGE("getPrevPage 2 ${bookPageInfo?.first()?.chapterNum}" )
Blog.LOGE("getPrevPage 2 ${bookPageInfo?.first()?.bookPageUrl}" )
var results = this.query(BookPageInfo::class).query("chapterNum == $0",bookPageInfo.first().chapterNum - 1).query("bookPageUrl == $0","${bookPageInfo.first().bookPageUrl}").find()
if(results.size > 0) { if(results.size > 0) {
results.first()?.let { results.first()?.let {
callback.invoke(it) callback.invoke(it)
} }
} else {
callback.invoke(null)
} }
} else {
callback.invoke(null)
} }
} }
} }

View File

@ -37,14 +37,21 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
var hiddenTextView : PagedTextView? = null var hiddenTextView : PagedTextView? = null
var guideLine : Guideline? = null var guideLine : Guideline? = null
var pageList: ArrayList<CharSequence>? = null var pageList: ArrayList<CharSequence>? = null
var summaryText : String = ""
var text : String = "" var text : String = ""
set(new) { set(new) {
Blog.LOGE("field >> ${field}") Blog.LOGE("field >> ${field}")
Blog.LOGE("new >> ${new}") Blog.LOGE("new >> ${new}")
field = new field = new
Blog.LOGE("field >> ${field}") val summary = new.replace(" " ,"").replace("\n" ,"").substring(0,Math.min(30,new.length))
hiddenTextView?.setTxtF(field) if (summary.equals(summaryText)) {
hiddenTextView?.visibility = VISIBLE
} else {
Blog.LOGE("field >> ${field}")
hiddenTextView?.setTxtF(field)
hiddenTextView?.visibility = VISIBLE
}
summaryText = summary
} }
private val hanler = Handler() private val hanler = Handler()
@ -279,9 +286,7 @@ class PagedTextLayout : ConstraintLayout , PagedTextGenerateInterface {
} }
fun forceUpdateUI() { fun forceUpdateUI() {
// mPagedTextViewInterface?.onTouch(TouchArea.Center)
hiddenTextView?.doUpdate() hiddenTextView?.doUpdate()
// hanler?.postDelayed(touchTimeover, 3000L)
} }
override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) { override fun setPadding(left: Int, top: Int, right: Int, bottom: Int) {

View File

@ -7,6 +7,7 @@ import android.os.Build
import android.text.Layout import android.text.Layout
import android.text.StaticLayout import android.text.StaticLayout
import android.util.AttributeSet import android.util.AttributeSet
import android.util.TypedValue
import androidx.appcompat.widget.AppCompatTextView import androidx.appcompat.widget.AppCompatTextView
import androidx.core.view.marginBottom import androidx.core.view.marginBottom
import androidx.core.view.marginLeft import androidx.core.view.marginLeft
@ -86,8 +87,15 @@ class PagedTextView : AppCompatTextView {
super.setText(text, type) super.setText(text, type)
} }
override fun setTextSize(size: Float) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size)
}
override fun setTextSize(unit: Int, size: Float) { override fun setTextSize(unit: Int, size: Float) {
super.setTextSize(unit, size) super.setTextSize(unit, size)
paint.textSize = TypedValue.applyDimension(unit, size, context.resources.getDisplayMetrics())
needPaginate = true needPaginate = true
} }
@ -111,6 +119,7 @@ class PagedTextView : AppCompatTextView {
override fun setTypeface(tf: Typeface?) { override fun setTypeface(tf: Typeface?) {
if (typeface != null && tf != typeface) { if (typeface != null && tf != typeface) {
needPaginate = true needPaginate = true
paint.typeface = tf
} }
super.setTypeface(tf) super.setTypeface(tf)
} }
@ -153,7 +162,7 @@ class PagedTextView : AppCompatTextView {
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) { override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh) super.onSizeChanged(w, h, oldw, oldh)
Blog.LOGD(log = "onSizeChanged>> ${this::class.java.name}") Blog.LOGD(log = "onSizeChanged>> ${this::class.java.name}")
pageHeight = ((h - (marginTop + marginBottom + paddingTop + paddingBottom)) * 0.8f).toInt() pageHeight = ((h - (marginTop + marginBottom + paddingTop + paddingBottom)) * 1f).toInt()
} }
override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
@ -181,7 +190,7 @@ class PagedTextView : AppCompatTextView {
val layout = from(layout) val layout = from(layout)
val lines = if(min(maxLines, layout.lineCount) > 10) {min(maxLines, layout.lineCount) - 1} else {min(maxLines, layout.lineCount)} val lines = if(min(maxLines, layout.lineCount) > 10) {min(maxLines, layout.lineCount) - 1} else {min(maxLines, layout.lineCount)}
var startOffset = 0 var startOffset = 0
val heightWithoutPaddings = pageHeight - (marginTop + marginBottom + paddingTop + paddingBottom) val heightWithoutPaddings = pageHeight //- (marginTop + marginBottom + paddingTop + paddingBottom)
var height = heightWithoutPaddings var height = heightWithoutPaddings
for (i in 0 until lines) { for (i in 0 until lines) {
@ -230,7 +239,7 @@ class PagedTextView : AppCompatTextView {
.setUseLineSpacingFromFallbacks() .setUseLineSpacingFromFallbacks()
.setBreakStrategy(breakStrategy) .setBreakStrategy(breakStrategy)
.setHyphenationFrequency(hyphenationFrequency) .setHyphenationFrequency(hyphenationFrequency)
.setJustificationMode() // .setJustificationMode()
.setMaxLines(maxLines) .setMaxLines(maxLines)
.build() .build()
} }

View File

@ -10,14 +10,14 @@ import com.mime.dualscreenview.webcontents.contentsinfo.DidFindContents
abstract class BaseWebContents : ContentsInfoInterface { abstract class BaseWebContents : ContentsInfoInterface {
open var lastNumber : Int = 221 open var lastNumber : Int = 221
var completeAction : ActionByBool? = null var completeAction : ActionByBool? = null
val definedActionCount = 5 // val definedActionCount = 5
var completeActionCount = 0 // var completeActionCount = 0
set(value) { // set(value) {
field = value // field = value
if(field == definedActionCount && completeAction != null) { // if(field == definedActionCount && completeAction != null) {
completeAction?.invoke(true) // completeAction?.invoke(true)
} // }
} // }
fun findListItem(webview: WebView, callBakItems : DidFindContents) { fun findListItem(webview: WebView, callBakItems : DidFindContents) {
webview.evaluateJavascript(getContentsList()) { result -> webview.evaluateJavascript(getContentsList()) { result ->
@ -25,16 +25,15 @@ abstract class BaseWebContents : ContentsInfoInterface {
} }
} }
fun doOnloaded(webview: WebView, findContents : DidFindContents, findTitle : DidFindContents, findNextButton : DidFindContents, fun doOnloaded(webview: WebView, findContents : DidFindContents, completeAction : ActionByBool) {
findPrevButton : DidFindContents, completeAction : ActionByBool) { // completeActionCount = 0
completeActionCount = 0
this.completeAction = completeAction this.completeAction = completeAction
webview.evaluateJavascript(getTitleJs()) { result : String? -> // webview.evaluateJavascript(getTitleJs()) { result : String? ->
result?.let { resultString -> // result?.let { resultString ->
findTitle.invoke(resultString) // findTitle.invoke(resultString)
} // }
completeActionCount = completeActionCount + 1 // completeActionCount = completeActionCount + 1
} // }
webview.evaluateJavascript(getFindContentsJs()) { result : String? -> webview.evaluateJavascript(getFindContentsJs()) { result : String? ->
result?.let { resultString -> result?.let { resultString ->
checkCorrectContents(resultString)?.let { contents -> checkCorrectContents(resultString)?.let { contents ->
@ -45,37 +44,38 @@ abstract class BaseWebContents : ContentsInfoInterface {
} }
} }
} ?: findContents.invoke(null) } ?: findContents.invoke(null)
completeActionCount = completeActionCount + 1 // completeActionCount = completeActionCount + 1
}
webview.evaluateJavascript("document.getElementById('${getNextButtonJs()}')") { result : String? ->
result?.let { resultString ->
Log.e("BaseWebContents", "getNextButtonJs() >> ${resultString}")
if(resultString != null && !"null".equals(resultString)) {
findNextButton.invoke(resultString)
} else {
findNextButton.invoke(null)
}
}
completeActionCount = completeActionCount + 1
} }
// webview.evaluateJavascript("document.getElementById('${getNextButtonJs()}')") { result : String? ->
// result?.let { resultString ->
// Log.e("BaseWebContents", "getNextButtonJs() >> ${resultString}")
// if(resultString != null && !"null".equals(resultString)) {
// findNextButton.invoke(resultString)
// } else {
// findNextButton.invoke(null)
// }
// }
// completeActionCount = completeActionCount + 1
// }
webview.evaluateJavascript("document.getElementById('${getPrevButtonJs()}')") { result : String? -> // webview.evaluateJavascript("document.getElementById('${getPrevButtonJs()}')") { result : String? ->
result?.let { resultString -> // result?.let { resultString ->
Log.e("BaseWebContents", "getPrevButtonJs() >> ${resultString}") // Log.e("BaseWebContents", "getPrevButtonJs() >> ${resultString}")
if(resultString != null && !"null".equals(resultString)) { // if(resultString != null && !"null".equals(resultString)) {
findPrevButton.invoke(resultString) // findPrevButton.invoke(resultString)
}else { // }else {
findPrevButton.invoke(null) // findPrevButton.invoke(null)
} // }
} // }
completeActionCount = completeActionCount + 1 // completeActionCount = completeActionCount + 1
} // }
webview.evaluateJavascript(onLoadedJs()) { webview.evaluateJavascript(onLoadedJs()) {
Log.e("BaseWebContents", "onLoadedJs() >> ${it}") Log.e("BaseWebContents", "onLoadedJs() >> ${it}")
completeActionCount = completeActionCount + 1 // completeActionCount = completeActionCount + 1
} }
completeAction?.invoke(true)
} }
} }

View File

@ -1,19 +1,29 @@
package com.mime.dualscreenview.webcontents package com.mime.dualscreenview.webcontents
import android.annotation.SuppressLint
import android.app.AlertDialog import android.app.AlertDialog
import android.graphics.Bitmap import android.graphics.Bitmap
import android.net.Uri import android.net.Uri
import android.net.http.SslError import android.net.http.SslError
import android.util.Log import android.util.Log
import android.webkit.* import android.webkit.*
import androidx.core.net.toUri
import com.google.gson.Gson
import com.mime.dualscreenview.common.Blog import com.mime.dualscreenview.common.Blog
import com.mime.dualscreenview.common.PrefManager
import com.mime.dualscreenview.data.HistoryManager import com.mime.dualscreenview.data.HistoryManager
import com.mime.dualscreenview.data.model.BookPageInfo
import com.mime.dualscreenview.data.model.BookPageInfos
import com.mime.dualscreenview.data.model.LastInfo import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.DidFindContents import com.mime.dualscreenview.webcontents.contentsinfo.DidFindContents
import io.realm.kotlin.UpdatePolicy
import io.realm.kotlin.ext.realmListOf
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONObject import org.json.JSONObject
import org.jsoup.Jsoup
import org.jsoup.select.Elements
open class BaseWebContentsViewer { open class BaseWebContentsViewer {
@ -36,6 +46,7 @@ open class BaseWebContentsViewer {
} }
} }
@SuppressLint("JavascriptInterface")
constructor(webview : WebView, mainControllInterface : MainControllInterface ) { constructor(webview : WebView, mainControllInterface : MainControllInterface ) {
this.webview = webview this.webview = webview
this.mainControllInterface = mainControllInterface this.mainControllInterface = mainControllInterface
@ -49,6 +60,10 @@ open class BaseWebContentsViewer {
webview.settings.setPluginState(WebSettings.PluginState.ON) webview.settings.setPluginState(WebSettings.PluginState.ON)
webview.settings.domStorageEnabled = true webview.settings.domStorageEnabled = true
webview.clearCache(true); webview.clearCache(true);
try {
webview.removeJavascriptInterface("MyJavaScriptInterface")
}catch (e :Exception){e.printStackTrace()}
webview.addJavascriptInterface( BookHelper(),"MyJavaScriptInterface")
webview.clearHistory(); webview.clearHistory();
webview.clearSslPreferences(); webview.clearSslPreferences();
WebView.setWebContentsDebuggingEnabled(true) WebView.setWebContentsDebuggingEnabled(true)
@ -76,37 +91,20 @@ open class BaseWebContentsViewer {
fun loadLastInfo(lastInfo: LastInfo) { fun loadLastInfo(lastInfo: LastInfo) {
lastInfo?.let { last -> lastInfo?.let { last ->
Blog.LOGE("last.pageUrl >>> ${last.pageUrl}")
currentContentsProvider = WebContentsManger.getBaseWebContentsBy(last.contentsName) currentContentsProvider = WebContentsManger.getBaseWebContentsBy(last.contentsName)
// HistoryManager.getBooPageInfo(last.pageUrl,{ page ->
// if(page != null){
// if(page.contents?.length ?: 0 > 0) {
// mainControllInterface?.onLoadedContents(page.contents!!)
// } else {
// webview.loadUrl(last.pageUrl)
// }
// } else {
if (last.pageUrl.startsWith("https://")) { if (last.pageUrl.startsWith("https://")) {
webview.loadUrl(last.pageUrl) webview.loadUrl(last.pageUrl)
} else { } else {
try { try {
var uri = Uri.parse(webview.url) webview.loadUrl(PrefManager.getLastDomain().plus(last.pageUrl))
uri.path?.let {
webview.loadUrl(uri.toString().replace(it,last.pageUrl))
}
} catch (e : Exception) { } catch (e : Exception) {
webview.loadUrl(Booktoki.getLastedDoamin().plus("/").plus(last.pageUrl)) webview.loadUrl(PrefManager.getLastDomain())
} }
} }
// }
// })
} }
} }
val rootWebViewClient = object : WebViewClient() { val rootWebViewClient = object : WebViewClient() {
override fun shouldInterceptRequest( override fun shouldInterceptRequest(
view: WebView?, view: WebView?,
request: WebResourceRequest? request: WebResourceRequest?
@ -126,48 +124,7 @@ open class BaseWebContentsViewer {
super.onPageStarted(view, url, favicon) super.onPageStarted(view, url, favicon)
mainControllInterface?.onStartLoad() mainControllInterface?.onStartLoad()
} }
var alertDialogs : ArrayList<AlertDialog> = arrayListOf()
// override fun onReceivedError(
// view: WebView?,
// request: WebResourceRequest?,
// error: WebResourceError?
// ) {
// super.onReceivedError(view, request, error)
// if (error != null && error.errorCode < 0) {
//
// webview.postDelayed({
// val builder = AlertDialog.Builder(webview.context)
//
//
// builder.setTitle("로딩 에러").setMessage("${currentContentsProvider?.getWebcontentsName()} ${currentContentsProvider?.lastNumber?.inc()} 여기로 다시 시도?!!")
// builder.setPositiveButton(
// "오키 ${currentContentsProvider?.lastNumber?.inc()} 레고!"
// ) { dialog, id ->
// dialog.dismiss()
// currentContentsProvider?.lastNumber = currentContentsProvider?.lastNumber!!.inc()
// loadContents(currentContentsProvider!!)
// }
//
// builder.setNegativeButton(
// "포기하자"
// ) { dialog, id ->
// dialog.dismiss()
// }
// builder.setNeutralButton(
// "같은 주소로 다시 도전"
// ) { dialog, id ->
// loadContents(currentContentsProvider!!)
// dialog.dismiss()
// }
// alertDialogs.add(builder.create())
//
// alertDialogs.last()?.show()
//
// },500)
// }
//
// }
//
override fun onReceivedSslError( override fun onReceivedSslError(
view: WebView?, view: WebView?,
handler: SslErrorHandler?, handler: SslErrorHandler?,
@ -186,37 +143,42 @@ open class BaseWebContentsViewer {
// super.onReceivedHttpError(view, request, errorResponse) // super.onReceivedHttpError(view, request, errorResponse)
} }
override fun onPageFinished(view: WebView?, url: String?) { override fun onPageFinished(view: WebView?, url: String?) {
super.onPageFinished(view, url) super.onPageFinished(view, url)
finishedUrl = url ?: ""
view?.let { view?.let {
url?.toUri()?.let {
PrefManager.putLastDomain(it.scheme.plus("::/").plus(it.host))
}
if(url?.contains("/list/") ?: false && url?.contains("agit") ?: false){ if(url?.contains("/list/") ?: false && url?.contains("agit") ?: false){
findListItem { findListItem {
Blog.LOGE("onPageFinished", url ?: "") Blog.LOGE("onPageFinished", url ?: "")
} }
} else if (url?.contains("booktoki") ?: false){ } else if (url?.contains("booktoki") ?: false){
findListItem { // findListItem {
Blog.LOGE("onPageFinished", url ?: "") // Blog.LOGE("onPageFinished", url ?: "")
} // }
} }
view?.postDelayed({
view?.evaluateJavascript(
"function getAll() {\n" +
" MyJavaScriptInterface.sendValueFromHtml(document.getElementsByTagName('html')[0].innerHTML)" +
" };getAll()"
) { result ->
(result as? String)?.let {
}
}
}, 500L)
currentContentsProvider?.doOnloaded(it , { result -> currentContentsProvider?.doOnloaded(it , { result ->
result?.let { mainControllInterface.onLoadedContents(it) } result?.let { mainControllInterface.onLoadedContents(it) }
} , { } , { complete ->
it?.let { mainControllInterface.onFindTitle(it.replace("\"","")) }
}, {btn ->
mainControllInterface?.showNextBtn (btn != null){
webview?.evaluateJavascript("if(document.getElementById('${currentContentsProvider!!.getNextButtonJs()}') != null) document.getElementById('${currentContentsProvider!!.getNextButtonJs()}').click()") {
}
}
},{btn ->
mainControllInterface?.showPrevBtn(btn != null) {
webview?.evaluateJavascript("if(document.getElementById('${currentContentsProvider!!.getPrevButtonJs()}') != null) document.getElementById('${currentContentsProvider!!.getPrevButtonJs()}').click()") {
}
}
}, { complete ->
if(complete) { if(complete) {
mainControllInterface?.completePageLoad(LastInfo().apply { mainControllInterface?.completePageLoad(LastInfo().apply {
this.pageUrl = url ?: currentContentsProvider?.getLastedDoamin() ?: "" this.pageUrl = url?.toUri()?.path ?: currentContentsProvider?.getLastedDoamin() ?: ""
this.contentsName = currentContentsProvider?.getWebcontentsName() ?: "" this.contentsName = currentContentsProvider?.getWebcontentsName() ?: ""
this.pageIndex = 0 this.pageIndex = 0
}) })
@ -225,4 +187,65 @@ open class BaseWebContentsViewer {
} }
} }
} }
} var finishedUrl : String = ""
inner class BookHelper {
@JavascriptInterface
fun sendValueFromHtml(string: String) {
Jsoup.parse(string)?.let { html ->
val toon_intro = html.getElementById("toon_intro")
val view_padding = html.getElementsByClass("view-padding")
if (toon_intro != null) {
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
val bookPageInfos = BookPageInfos()
bookPageInfos.bookPageUrl = Uri.parse(finishedUrl).path
bookPageInfos.bookTitle = if (toon_intro.getElementsByTag("h3").size > 0) toon_intro.getElementsByTag("h3").get(0).text() else ""
bookPageInfos.pages = realmListOf<BookPageInfo>()
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookPageInfos >>>> ${Gson().toJson(bookPageInfos)}")
val listParent = html.getElementById("list_type")
if (listParent != null) {
listParent.getElementsByClass("row").forEach { bookitem ->
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookItemInfo ${bookitem}")
try {
val bookPageInfo = BookPageInfo()
bookPageInfo.bookTitle = bookPageInfos.bookTitle
bookPageInfo.chapterNum = bookitem.getElementsByClass("cell_num").getT().toInt()
bookPageInfo.chapterID = bookitem.getElementsByClass("cell_num").getT().toInt()
bookPageInfo.chapterTitle = bookitem.getElementsByTag("a").getT()
bookPageInfo.bookPageUrl = bookPageInfos.bookPageUrl
val href = bookitem.getElementsByTag("a").get(0).attr("href")
bookPageInfo.pathUrl = Uri.parse(href).path
bookPageInfos.pages.add(bookPageInfo)
}catch (nfe : NumberFormatException) {
nfe.printStackTrace()
}
}.apply {
HistoryManager.openRealm.writeBlocking {
copyToRealm(bookPageInfos, UpdatePolicy.ALL)
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: bookPageInfos saved >>>> ${bookPageInfos.bookPageUrl}")
}
mainControllInterface.onBookInfos(bookPageInfos)
}
}
}else if (view_padding.size > 0){
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
val contents = view_padding.get(0).children().html().replace("<p>"," ").replace("</p>","\n\n")
// Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: view_padding.get(0)\n${contents}")
if (contents.length > 20) {
Uri.parse(finishedUrl).path?.let {
HistoryManager.getBooPageInfoContentsSave(it, contents)
mainControllInterface.onLoadedContents(contents)
}
}
} else {
Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: ${html.title()}")
Blog.LOGE("finishedUrl >>> ${finishedUrl} :::: whole body ${html}")
}
}
}
}
}
fun Elements.getT() = if (size > 0) get(0).text() else ""

View File

@ -1,5 +1,6 @@
package com.mime.dualscreenview.webcontents package com.mime.dualscreenview.webcontents
import com.mime.dualscreenview.data.model.BookPageInfos
import com.mime.dualscreenview.data.model.LastInfo import com.mime.dualscreenview.data.model.LastInfo
import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere import com.mime.dualscreenview.webcontents.contentsinfo.GotoSomeWhere
@ -16,5 +17,6 @@ interface MainControllInterface {
fun onFindTitle(contents :String) fun onFindTitle(contents :String)
fun onBookInfos(jsonString : String) fun onBookInfos(jsonString : String)
fun onBookInfos(infos : BookPageInfos)
} }

View File

@ -2,9 +2,10 @@ package com.mime.dualscreenview.webcontents
import com.mime.dualscreenview.webcontents.contentsinfo.Agit import com.mime.dualscreenview.webcontents.contentsinfo.Agit
import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki import com.mime.dualscreenview.webcontents.contentsinfo.Booktoki
import com.mime.dualscreenview.webcontents.contentsinfo.NewtokiOne
object WebContentsManger { object WebContentsManger {
val allContentsList : ArrayList<BaseWebContents> = arrayListOf(Booktoki) val allContentsList : ArrayList<BaseWebContents> = arrayListOf(NewtokiOne)
fun getBaseWebContentsBy(name : String) : BaseWebContents { fun getBaseWebContentsBy(name : String) : BaseWebContents {
var correctContents : BaseWebContents = Booktoki var correctContents : BaseWebContents = Booktoki

View File

@ -4,7 +4,7 @@ import com.mime.dualscreenview.webcontents.BaseWebContents
object Booktoki : BaseWebContents() { object Booktoki : BaseWebContents() {
override var lastNumber : Int = 350 override var lastNumber : Int = 351
override fun getWebcontentsName(): String { override fun getWebcontentsName(): String {
return "Booktoki" return "Booktoki"

View File

@ -0,0 +1,95 @@
package com.mime.dualscreenview.webcontents.contentsinfo
import com.mime.dualscreenview.webcontents.BaseWebContents
object NewtokiOne : BaseWebContents() {
override var lastNumber : Int = 351
override fun getWebcontentsName(): String {
return "newtokione"
}
override fun getLastedDoamin(): String {
return "https://newtoki.one"
}
override fun getContentsList(): String {
return "function getList() {\n" +
" const contentsArray = [];\n" +
" var children = document.getElementsByClassName('list-body')[0].children;\n" +
" var maxCount = children.length;\n" +
" for (i= 0; i < maxCount; i++) {\n" +
" var chapterNum = children[i].getElementsByClassName('wr-num')[0].textContent;\n" +
" var pageUrl = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].href;\n" +
" if (pageUrl != null && pageUrl.length > 0 && pageUrl.startsWith(\"http\")) {\n" +
" pageUrl = new URL(pageUrl).pathname;\n" +
" }\n" +
" var chapterTitle = children[i].getElementsByClassName('wr-subject')[0].getElementsByTagName('a')[0].innerText;\n" +
" if(chapterTitle.split('\\n').length > 1) {\n" +
" chapterTitle = chapterTitle.split('\\n')[1];\n" +
" }\n" +
"\n" +
" var bookPageUrl = location.pathname;\n" +
" var bookTitle = document.getElementsByClassName('view-title')[0].getElementsByTagName('span')[0].innerText;\n" +
" var data = {\n" +
" 'chapterID': Number(chapterNum),\n" +
" 'chapterNum': Number(chapterNum),\n" +
" 'pathUrl': pageUrl,\n" +
" 'bookPageUrl': bookPageUrl,\n" +
" 'chapterTitle': chapterTitle,\n" +
" 'bookTitle': bookTitle,\n" +
" };\n" +
" contentsArray.push(\n" +
" data\n" +
" );\n" +
" }\n" +
" \n" +
" if(contentsArray.length > 0) {\n" +
" PAgit.onBookInfo(JSON.stringify({\n" +
" 'bookTitle': bookTitle,\n" +
" 'bookPageUrl': new URL(location.href).pathname,\n" +
" 'pages': contentsArray ,\n" +
" }));\n" +
" }\n" +
"}\n" +
"getList()\n" +
""
}
override fun acccceptResourceKeyword(): String {
return "toki"
}
override fun getNextButtonJs(): String {
return "goNextBtn"
}
override fun getPrevButtonJs(): String {
return "goPrevBtn"
}
override fun getTitleJs(): String {
return "document.getElementsByClassName(\"toon-title\").length > 0 ? document.getElementsByClassName(\"toon-title\")[0].title : null"
}
override fun getFindContentsJs(): String {
return "document.getElementById(\"novel_content\") != null ? document.getElementById(\"novel_content\").innerText : null"
}
override fun checkCorrectContents(contents: String): String {
return if (contents != null && !contents.isNullOrEmpty()) {
contents
} else {
"fail load"
}
}
// "if(document.getElementsByClassName(\"hd_pops\") != null && document.getElementsByClassName(\"hd_pops\").length > 0) document.getElementsByClassName(\"hd_pops\")[0].remove();" +
// "if(document.getElementsByClassName(\"hd_pops\") != null && document.getElementsByClassName(\"hd_pops\").length > 0) document.getElementsByClassName(\"hd_pops\")[0].remove();" +
// "if(document.getElementById(\"main-banner-view\") != null) document.getElementById(\"main-banner-view\").remove();" +
// "if(document.getElementsByClassName(\"board-tail-banner\") != null && document.getElementsByClassName(\"board-tail-banner\").length > 0)document.getElementsByClassName(\"board-tail-banner\")[0].remove();" +
// "if(document.getElementById(\"id_mbv\") != null)document.getElementById(\"id_mbv\").remove();"
override fun onLoadedJs(): String {
return ""
}
}

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<corners android:radius="10dp"/>
<solid android:color="#44ffffff"/>
<stroke android:color="@color/white" android:width="1dp"/>
</shape>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,181 +1,182 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" <layout>
xmlns:app="http://schemas.android.com/apk/res-auto" <androidx.constraintlayout.widget.ConstraintLayout 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" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/intro_bg"
android:layout_height="match_parent"
tools:context=".activity.Intro">
<WebView
android:id="@+id/hidden_web"
android:layout_margin="60dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:id="@+id/intro_bg"
android:layout_height="match_parent" android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent" tools:context=".activity.Intro">
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" <WebView
app:layout_constraintBottom_toBottomOf="parent"/> android:id="@+id/hidden_web"
android:layout_margin="60dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<WebView <WebView
android:id="@+id/menu_web" android:id="@+id/menu_web"
android:layout_margin="20dp" android:layout_margin="20dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_left" app:layout_constraintBottom_toTopOf="@id/btn_left"
app:layout_constraintTop_toBottomOf="@id/textview_title" /> app:layout_constraintTop_toBottomOf="@id/textview_title" />
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/btn_home" android:id="@+id/btn_home"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@drawable/home" android:src="@drawable/home"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
tools:ignore="MissingConstraints" /> tools:ignore="MissingConstraints" />
<TextView <TextView
android:id="@+id/textview_title" android:id="@+id/textview_title"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:text="@string/app_name" android:text="@string/app_name"
android:gravity="center" android:gravity="center"
android:textSize="24sp" android:textSize="24sp"
app:layout_constraintRight_toLeftOf="@id/btn_list" app:layout_constraintRight_toLeftOf="@id/btn_list"
app:layout_constraintLeft_toRightOf="@id/btn_home" app:layout_constraintLeft_toRightOf="@id/btn_home"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:id="@+id/btn_list" android:id="@+id/btn_list"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="centerInside" android:scaleType="centerInside"
android:src="@drawable/bookmark" android:src="@drawable/bookmark"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toRightOf="@id/textview_title" app:layout_constraintLeft_toRightOf="@id/textview_title"
app:layout_constraintRight_toLeftOf="@+id/btn_history" app:layout_constraintRight_toLeftOf="@+id/btn_history"
app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintHorizontal_chainStyle="spread_inside"
/> />
<!-- <androidx.constraintlayout.utils.widget.ImageFilterButton--> <!-- <androidx.constraintlayout.utils.widget.ImageFilterButton-->
<!-- android:id="@+id/btn_rotate"--> <!-- android:id="@+id/btn_rotate"-->
<!-- android:layout_width="wrap_content"--> <!-- android:layout_width="wrap_content"-->
<!-- android:layout_height="@dimen/main_top_height"--> <!-- android:layout_height="@dimen/main_top_height"-->
<!-- android:adjustViewBounds="true"--> <!-- android:adjustViewBounds="true"-->
<!-- android:scaleType="centerInside"--> <!-- android:scaleType="centerInside"-->
<!-- android:visibility="gone"--> <!-- android:visibility="gone"-->
<!-- android:src="@drawable/rotation"--> <!-- android:src="@drawable/rotation"-->
<!-- android:background="#8FFF"--> <!-- android:background="#8FFF"-->
<!-- app:layout_constraintTop_toTopOf="parent"--> <!-- app:layout_constraintTop_toTopOf="parent"-->
<!-- app:layout_constraintLeft_toRightOf="@id/btn_list"--> <!-- app:layout_constraintLeft_toRightOf="@id/btn_list"-->
<!-- app:layout_constraintRight_toLeftOf="@+id/btn_history"--> <!-- app:layout_constraintRight_toLeftOf="@+id/btn_history"-->
<!-- app:layout_constraintHorizontal_chainStyle="spread_inside"--> <!-- app:layout_constraintHorizontal_chainStyle="spread_inside"-->
<!-- />--> <!-- />-->
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/btn_history" android:id="@+id/btn_history"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:src="@drawable/saved" android:src="@drawable/saved"
android:background="@android:color/transparent" android:background="@android:color/transparent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:layout_constraintHorizontal_chainStyle="spread_inside" app:layout_constraintHorizontal_chainStyle="spread_inside"
/> />
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/btn_left" android:id="@+id/btn_left"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:tag="1" android:tag="1"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:text="@string/display_the_second_screen" android:text="@string/display_the_second_screen"
android:visibility="visible" android:visibility="visible"
android:src="@drawable/angle_left" android:src="@drawable/angle_left"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintHorizontal_chainStyle="spread"
/> />
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/btn_setting" android:id="@+id/btn_setting"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:src="@drawable/settings" android:src="@drawable/settings"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:background="@android:color/transparent" android:background="@android:color/transparent"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/btn_left" app:layout_constraintLeft_toRightOf="@+id/btn_left"
app:layout_constraintRight_toLeftOf="@+id/btn_right" app:layout_constraintRight_toLeftOf="@+id/btn_right"
app:layout_constraintHorizontal_chainStyle="spread" app:layout_constraintHorizontal_chainStyle="spread"
/> />
<androidx.constraintlayout.utils.widget.ImageFilterButton <androidx.constraintlayout.utils.widget.ImageFilterButton
android:id="@+id/btn_right" android:id="@+id/btn_right"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="@dimen/main_top_height" android:layout_height="@dimen/main_top_height"
android:layout_marginStart="16dp" android:layout_marginStart="16dp"
android:tag="0" android:tag="0"
android:background="@android:color/transparent" android:background="@android:color/transparent"
android:src="@drawable/angle_right" android:src="@drawable/angle_right"
android:adjustViewBounds="true" android:adjustViewBounds="true"
android:scaleType="fitCenter" android:scaleType="fitCenter"
android:visibility="visible" android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintHorizontal_chainStyle="spread" /> app:layout_constraintHorizontal_chainStyle="spread" />
<com.mime.dualscreenview.view.PagedTextLayout <com.mime.dualscreenview.view.PagedTextLayout
android:id="@+id/paged_layer" android:id="@+id/paged_layer"
android:layout_margin="1dp" android:layout_margin="1dp"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:orientation="vertical"
android:visibility="gone" android:visibility="gone"
android:elevation="5dp" android:elevation="5dp"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toTopOf="@id/btn_setting" app:layout_constraintBottom_toTopOf="@id/btn_setting"
app:layout_constraintTop_toBottomOf="@id/textview_title" /> app:layout_constraintTop_toBottomOf="@id/textview_title" />
<ProgressBar <ProgressBar
android:id="@+id/progress" android:id="@+id/progress"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_gravity="center" android:layout_gravity="center"
android:layout_marginTop="48dp" android:layout_marginTop="48dp"
android:indeterminate="false" android:indeterminate="false"
android:max="100" android:max="100"
android:progressBackgroundTint="#FBE7C6" android:progressBackgroundTint="#FBE7C6"
android:progressDrawable="@drawable/circle_progressbar" android:progressDrawable="@drawable/circle_progressbar"
android:progressTint="#edbf41" android:progressTint="#edbf41"
android:visibility="gone" android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" /> app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
<!--//style="@style/Widget.AppCompat.ProgressBar.Horizontal"--> </layout>

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:background="@drawable/simple_bg"
android:layout_height="wrap_content">
<TextView
android:layout_gravity="center"
android:gravity="left"
android:id="@+id/text"
android:textColor="@color/black"
android:background="@null"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</FrameLayout>

View File

@ -1,17 +0,0 @@
package com.mime.dualscreenview
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}